mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2025-01-31 18:50:33 +00:00
Merge branch 'master' of https://github.com/coelckers/gzdoom
# Conflicts: # src/r_things.cpp # src/r_things.h
This commit is contained in:
commit
4292311f53
86 changed files with 1893 additions and 908 deletions
|
@ -284,7 +284,7 @@ enum ActorFlag4
|
|||
enum ActorFlag5
|
||||
{
|
||||
MF5_DONTDRAIN = 0x00000001, // cannot be drained health from.
|
||||
MF5_INSTATECALL = 0x00000002, // This actor is being run through CallStateChain
|
||||
/* FREE SLOT 0x00000002*/
|
||||
MF5_NODROPOFF = 0x00000004, // cannot drop off under any circumstances.
|
||||
MF5_NOFORWARDFALL = 0x00000008, // Does not make any actor fall forward by being damaged by this
|
||||
MF5_COUNTSECRET = 0x00000010, // From Doom 64: actor acts like a secret
|
||||
|
@ -408,9 +408,11 @@ enum ActorRenderFlag
|
|||
RF_SPRITETYPEMASK = 0x7000, // ---Different sprite types, not all implemented
|
||||
RF_FACESPRITE = 0x0000, // Face sprite
|
||||
RF_WALLSPRITE = 0x1000, // Wall sprite
|
||||
RF_FLOORSPRITE = 0x2000, // Floor sprite
|
||||
RF_FLATSPRITE = 0x2000, // Flat sprite
|
||||
RF_VOXELSPRITE = 0x3000, // Voxel object
|
||||
RF_INVISIBLE = 0x8000, // Don't bother drawing this actor
|
||||
RF_ROLLSPRITE = 0x40000, //[marrub]roll the sprite billboard
|
||||
RF_DONTFLIP = 0x80000, // Don't flip it when viewed from behind.
|
||||
|
||||
RF_FORCEYBILLBOARD = 0x10000, // [BB] OpenGL only: draw with y axis billboard, i.e. anchored to the floor (overrides gl_billboard_mode setting)
|
||||
RF_FORCEXYBILLBOARD = 0x20000, // [BB] OpenGL only: draw with xy axis billboard, i.e. unanchored (overrides gl_billboard_mode setting)
|
||||
|
|
|
@ -1488,6 +1488,44 @@ FBaseCVar *FindCVarSub (const char *var_name, int namelen)
|
|||
return var;
|
||||
}
|
||||
|
||||
FBaseCVar *GetCVar(AActor *activator, const char *cvarname)
|
||||
{
|
||||
FBaseCVar *cvar = FindCVar(cvarname, nullptr);
|
||||
// Either the cvar doesn't exist, or it's for a mod that isn't loaded, so return nullptr.
|
||||
if (cvar == nullptr || (cvar->GetFlags() & CVAR_IGNORE))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
// For userinfo cvars, redirect to GetUserCVar
|
||||
if (cvar->GetFlags() & CVAR_USERINFO)
|
||||
{
|
||||
if (activator == nullptr || activator->player == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return GetUserCVar(int(activator->player - players), cvarname);
|
||||
}
|
||||
return cvar;
|
||||
}
|
||||
}
|
||||
|
||||
FBaseCVar *GetUserCVar(int playernum, const char *cvarname)
|
||||
{
|
||||
if ((unsigned)playernum >= MAXPLAYERS || !playeringame[playernum])
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
FBaseCVar **cvar_p = players[playernum].userinfo.CheckKey(FName(cvarname, true));
|
||||
FBaseCVar *cvar;
|
||||
if (cvar_p == nullptr || (cvar = *cvar_p) == nullptr || (cvar->GetFlags() & CVAR_IGNORE))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return cvar;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// C_CreateCVar
|
||||
|
|
|
@ -186,6 +186,10 @@ void C_BackupCVars (void);
|
|||
FBaseCVar *FindCVar (const char *var_name, FBaseCVar **prev);
|
||||
FBaseCVar *FindCVarSub (const char *var_name, int namelen);
|
||||
|
||||
// Used for ACS and DECORATE.
|
||||
FBaseCVar *GetCVar(AActor *activator, const char *cvarname);
|
||||
FBaseCVar *GetUserCVar(int playernum, const char *cvarname);
|
||||
|
||||
// Create a new cvar with the specified name and type
|
||||
FBaseCVar *C_CreateCVar(const char *var_name, ECVarType var_type, DWORD flags);
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include <stdarg.h>
|
||||
|
||||
// the dec offsetof macro doesnt work very well...
|
||||
#define myoffsetof(type,identifier) ((size_t)&((type *)1)->identifier - 1)
|
||||
#define myoffsetof(type,identifier) ((size_t)&((type *)alignof(type))->identifier - alignof(type))
|
||||
|
||||
int Q_filelength (FILE *f);
|
||||
bool FileExists (const char *filename);
|
||||
|
|
|
@ -807,11 +807,12 @@ void SetDehParams(FState *state, int codepointer)
|
|||
VMFunctionBuilder buildit;
|
||||
// Allocate registers used to pass parameters in.
|
||||
// self, stateowner, state (all are pointers)
|
||||
buildit.Registers[REGT_POINTER].Get(3);
|
||||
buildit.Registers[REGT_POINTER].Get(NAP);
|
||||
// Emit code to pass the standard action function parameters.
|
||||
buildit.Emit(OP_PARAM, 0, REGT_POINTER, 0);
|
||||
buildit.Emit(OP_PARAM, 0, REGT_POINTER, 1);
|
||||
buildit.Emit(OP_PARAM, 0, REGT_POINTER, 2);
|
||||
for (int i = 0; i < NAP; i++)
|
||||
{
|
||||
buildit.Emit(OP_PARAM, 0, REGT_POINTER, i);
|
||||
}
|
||||
// Emit code for action parameters.
|
||||
int argcount = MBFCodePointerFactories[codepointer](buildit, value1, value2);
|
||||
buildit.Emit(OP_TAIL_K, buildit.GetConstantAddress(sym->Variants[0].Implementation, ATAG_OBJECT), NAP + argcount, 0);
|
||||
|
@ -2114,7 +2115,7 @@ static int PatchCodePtrs (int dummy)
|
|||
else
|
||||
{
|
||||
TArray<DWORD> &args = sym->Variants[0].ArgFlags;
|
||||
if ((sym->Flags & (VARF_Method | VARF_Action)) != (VARF_Method | VARF_Action) || (args.Size() > 3 && !(args[3] & VARF_Optional)))
|
||||
if ((sym->Flags & (VARF_Method | VARF_Action)) != (VARF_Method | VARF_Action) || (args.Size() > NAP && !(args[NAP] & VARF_Optional)))
|
||||
{
|
||||
Printf("Frame %d: Incompatible code pointer '%s'\n", frame, Line2);
|
||||
sym = NULL;
|
||||
|
@ -2726,7 +2727,7 @@ static bool LoadDehSupp ()
|
|||
else
|
||||
{
|
||||
TArray<DWORD> &args = sym->Variants[0].ArgFlags;
|
||||
if ((sym->Flags & (VARF_Method|VARF_Action)) != (VARF_Method | VARF_Action) || (args.Size() > 3 && !(args[3] & VARF_Optional)))
|
||||
if ((sym->Flags & (VARF_Method|VARF_Action)) != (VARF_Method | VARF_Action) || (args.Size() > NAP && !(args[NAP] & VARF_Optional)))
|
||||
{
|
||||
sc.ScriptMessage("Incompatible code pointer '%s'", sc.String);
|
||||
}
|
||||
|
@ -3123,22 +3124,29 @@ bool ADehackedPickup::TryPickup (AActor *&toucher)
|
|||
|
||||
const char *ADehackedPickup::PickupMessage ()
|
||||
{
|
||||
return RealPickup->PickupMessage ();
|
||||
if (RealPickup != nullptr)
|
||||
return RealPickup->PickupMessage ();
|
||||
else return "";
|
||||
}
|
||||
|
||||
bool ADehackedPickup::ShouldStay ()
|
||||
{
|
||||
return RealPickup->ShouldStay ();
|
||||
if (RealPickup != nullptr)
|
||||
return RealPickup->ShouldStay ();
|
||||
else return true;
|
||||
}
|
||||
|
||||
bool ADehackedPickup::ShouldRespawn ()
|
||||
{
|
||||
return RealPickup->ShouldRespawn ();
|
||||
if (RealPickup != nullptr)
|
||||
return RealPickup->ShouldRespawn ();
|
||||
else return false;
|
||||
}
|
||||
|
||||
void ADehackedPickup::PlayPickupSound (AActor *toucher)
|
||||
{
|
||||
RealPickup->PlayPickupSound (toucher);
|
||||
if (RealPickup != nullptr)
|
||||
RealPickup->PlayPickupSound (toucher);
|
||||
}
|
||||
|
||||
void ADehackedPickup::DoPickupSpecial (AActor *toucher)
|
||||
|
@ -3146,19 +3154,19 @@ void ADehackedPickup::DoPickupSpecial (AActor *toucher)
|
|||
Super::DoPickupSpecial (toucher);
|
||||
// If the real pickup hasn't joined the toucher's inventory, make sure it
|
||||
// doesn't stick around.
|
||||
if (RealPickup->Owner != toucher)
|
||||
if (RealPickup != nullptr && RealPickup->Owner != toucher)
|
||||
{
|
||||
RealPickup->Destroy ();
|
||||
}
|
||||
RealPickup = NULL;
|
||||
RealPickup = nullptr;
|
||||
}
|
||||
|
||||
void ADehackedPickup::Destroy ()
|
||||
{
|
||||
if (RealPickup != NULL)
|
||||
if (RealPickup != nullptr)
|
||||
{
|
||||
RealPickup->Destroy ();
|
||||
RealPickup = NULL;
|
||||
RealPickup = nullptr;
|
||||
}
|
||||
Super::Destroy ();
|
||||
}
|
||||
|
|
|
@ -557,7 +557,7 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL)
|
|||
case 1: // Doom2.exe compatible with a few relaxed settings
|
||||
v = COMPATF_SHORTTEX|COMPATF_STAIRINDEX|COMPATF_USEBLOCKING|COMPATF_NODOORLIGHT|COMPATF_SPRITESORT|
|
||||
COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_DEHHEALTH|COMPATF_CROSSDROPOFF|
|
||||
COMPATF_LIGHT;
|
||||
COMPATF_LIGHT|COMPATF_MASKEDMIDTEX;
|
||||
w= COMPATF2_FLOORMOVE;
|
||||
break;
|
||||
|
||||
|
@ -570,7 +570,7 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL)
|
|||
break;
|
||||
|
||||
case 3: // Boom compat mode
|
||||
v = COMPATF_TRACE|COMPATF_SOUNDTARGET|COMPATF_BOOMSCROLL|COMPATF_MISSILECLIP;
|
||||
v = COMPATF_TRACE|COMPATF_SOUNDTARGET|COMPATF_BOOMSCROLL|COMPATF_MISSILECLIP|COMPATF_MASKEDMIDTEX;
|
||||
break;
|
||||
|
||||
case 4: // Old ZDoom compat mode
|
||||
|
@ -580,12 +580,12 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL)
|
|||
|
||||
case 5: // MBF compat mode
|
||||
v = COMPATF_TRACE|COMPATF_SOUNDTARGET|COMPATF_BOOMSCROLL|COMPATF_MISSILECLIP|COMPATF_MUSHROOM|
|
||||
COMPATF_MBFMONSTERMOVE|COMPATF_NOBLOCKFRIENDS;
|
||||
COMPATF_MBFMONSTERMOVE|COMPATF_NOBLOCKFRIENDS|COMPATF_MASKEDMIDTEX;
|
||||
break;
|
||||
|
||||
case 6: // Boom with some added settings to reenable some 'broken' behavior
|
||||
v = COMPATF_TRACE|COMPATF_SOUNDTARGET|COMPATF_BOOMSCROLL|COMPATF_MISSILECLIP|COMPATF_NO_PASSMOBJ|
|
||||
COMPATF_INVISIBILITY|COMPATF_CORPSEGIBS|COMPATF_HITSCAN|COMPATF_WALLRUN|COMPATF_NOTOSSDROPS;
|
||||
COMPATF_INVISIBILITY|COMPATF_CORPSEGIBS|COMPATF_HITSCAN|COMPATF_WALLRUN|COMPATF_NOTOSSDROPS|COMPATF_MASKEDMIDTEX;
|
||||
w = COMPATF2_POINTONLINE;
|
||||
break;
|
||||
|
||||
|
|
|
@ -381,6 +381,7 @@ class player_t
|
|||
{
|
||||
public:
|
||||
player_t();
|
||||
~player_t();
|
||||
player_t &operator= (const player_t &p);
|
||||
|
||||
void Serialize (FArchive &arc);
|
||||
|
@ -436,6 +437,7 @@ public:
|
|||
|
||||
AWeapon *ReadyWeapon;
|
||||
AWeapon *PendingWeapon; // WP_NOCHANGE if not changing
|
||||
TObjPtr<DPSprite> psprites; // view sprites (gun, etc)
|
||||
|
||||
int cheats; // bit flags
|
||||
int timefreezer; // Player has an active time freezer
|
||||
|
@ -455,7 +457,6 @@ public:
|
|||
int extralight; // so gun flashes light up areas
|
||||
short fixedcolormap; // can be set to REDCOLORMAP, etc.
|
||||
short fixedlightlevel;
|
||||
pspdef_t psprites[NUMPSPRITES]; // view sprites (gun, etc)
|
||||
int morphTics; // player is a chicken/pig if > 0
|
||||
PClassPlayerPawn *MorphedPlayerClass; // [MH] (for SBARINFO) class # for this player instance when morphed
|
||||
int MorphStyle; // which effects to apply for this player instance when morphed
|
||||
|
@ -527,6 +528,12 @@ public:
|
|||
}
|
||||
|
||||
int GetSpawnClass();
|
||||
|
||||
// PSprite layers
|
||||
void TickPSprites();
|
||||
void DestroyPSprites();
|
||||
DPSprite *FindPSprite(int layer);
|
||||
DPSprite *GetPSprite(PSPLayers layer); // Used ONLY for compatibility with the old hardcoded layers.
|
||||
};
|
||||
|
||||
// Bookkeeping on players - state.
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
EXTERN_CVAR(Bool, strictdecorate);
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
|
@ -3067,7 +3068,8 @@ void PClass::InsertIntoHash ()
|
|||
if (found != NULL)
|
||||
{ // This type has already been inserted
|
||||
// ... but there is no need whatsoever to make it a fatal error!
|
||||
Printf (TEXTCOLOR_RED"Tried to register class '%s' more than once.\n", TypeName.GetChars());
|
||||
if (!strictdecorate) Printf (TEXTCOLOR_RED"Tried to register class '%s' more than once.\n", TypeName.GetChars());
|
||||
else I_Error("Tried to register class '%s' more than once.\n", TypeName.GetChars());
|
||||
TypeTable.ReplaceType(this, found, bucket);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -127,11 +127,11 @@ DMovingCeiling::DMovingCeiling ()
|
|||
{
|
||||
}
|
||||
|
||||
DMovingCeiling::DMovingCeiling (sector_t *sector)
|
||||
DMovingCeiling::DMovingCeiling (sector_t *sector, bool interpolate)
|
||||
: DMover (sector)
|
||||
{
|
||||
sector->ceilingdata = this;
|
||||
interpolation = sector->SetInterpolation(sector_t::CeilingMove, true);
|
||||
if (interpolate) interpolation = sector->SetInterpolation(sector_t::CeilingMove, true);
|
||||
}
|
||||
|
||||
bool sector_t::MoveAttached(int crush, double move, int floorOrCeiling, bool resetfailed)
|
||||
|
|
|
@ -49,7 +49,7 @@ class DMovingCeiling : public DMover
|
|||
{
|
||||
DECLARE_CLASS (DMovingCeiling, DMover)
|
||||
public:
|
||||
DMovingCeiling (sector_t *sector);
|
||||
DMovingCeiling (sector_t *sector, bool interpolate = true);
|
||||
protected:
|
||||
DMovingCeiling ();
|
||||
};
|
||||
|
|
|
@ -1573,7 +1573,7 @@ void FParser::SF_FloorHeight(void)
|
|||
sectors[i].floorplane.PointToDist (sectors[i].centerspot, dest),
|
||||
crush? 10:-1,
|
||||
(dest > sectors[i].CenterFloor()) ? 1 : -1,
|
||||
false) != EMoveResult::crushed)
|
||||
false) == EMoveResult::crushed)
|
||||
{
|
||||
returnval = 0;
|
||||
}
|
||||
|
@ -1662,7 +1662,7 @@ void FParser::SF_CeilingHeight(void)
|
|||
sectors[i].ceilingplane.PointToDist (sectors[i].centerspot, dest),
|
||||
crush? 10:-1,
|
||||
(dest > sectors[i].CenterCeiling()) ? 1 : -1,
|
||||
false) != EMoveResult::crushed)
|
||||
false) == EMoveResult::crushed)
|
||||
{
|
||||
returnval = 0;
|
||||
}
|
||||
|
@ -3473,12 +3473,7 @@ void FParser::SF_Resurrect()
|
|||
mo->SetState(state);
|
||||
mo->Height = mo->GetDefault()->Height;
|
||||
mo->radius = mo->GetDefault()->radius;
|
||||
mo->flags = mo->GetDefault()->flags;
|
||||
mo->flags2 = mo->GetDefault()->flags2;
|
||||
mo->flags3 = mo->GetDefault()->flags3;
|
||||
mo->flags4 = mo->GetDefault()->flags4;
|
||||
mo->flags5 = mo->GetDefault()->flags5;
|
||||
mo->health = mo->GetDefault()->health;
|
||||
mo->Revive();
|
||||
mo->target = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -3766,30 +3761,6 @@ void FParser::SF_SetCorona(void)
|
|||
t_return.value.i = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// new for GZDoom: Call a Hexen line special (deprecated, superseded by direct use)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FParser::SF_Ls()
|
||||
{
|
||||
int args[5]={0,0,0,0,0};
|
||||
int spc;
|
||||
|
||||
if (CheckArgs(1))
|
||||
{
|
||||
spc=intvalue(t_argv[0]);
|
||||
for(int i=0;i<5;i++)
|
||||
{
|
||||
if (t_argc>=i+2) args[i]=intvalue(t_argv[i+1]);
|
||||
}
|
||||
if (spc>=0 && spc<256)
|
||||
P_ExecuteSpecial(spc, NULL,Script->trigger,false, args[0],args[1],args[2],args[3],args[4]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// new for GZDoom: Gets the levelnum
|
||||
|
@ -4024,17 +3995,6 @@ void FParser::SF_KillInSector()
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// new for GZDoom: Sets a sector's type
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FParser::SF_SectorType(void)
|
||||
{
|
||||
// I don't think this was ever used publicly so I'm not going to bother fixing it.
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// new for GZDoom: Sets a new line trigger type (Doom format!)
|
||||
|
@ -4069,30 +4029,6 @@ void FParser::SF_SetLineTrigger()
|
|||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FParser::SF_ChangeTag()
|
||||
{
|
||||
// Development garbage!
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FParser::SF_WallGlow()
|
||||
{
|
||||
// Development garbage!
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// new for GZDoom: Call a Hexen line special
|
||||
|
@ -4510,13 +4446,10 @@ void init_functions(void)
|
|||
// new for GZDoom
|
||||
gscr->NewFunction("spawnshot2", &FParser::SF_SpawnShot2);
|
||||
gscr->NewFunction("setcolor", &FParser::SF_SetColor);
|
||||
gscr->NewFunction("sectortype", &FParser::SF_SectorType);
|
||||
gscr->NewFunction("wallglow", &FParser::SF_WallGlow);
|
||||
gscr->NewFunction("objradius", &FParser::SF_MobjRadius);
|
||||
gscr->NewFunction("objheight", &FParser::SF_MobjHeight);
|
||||
gscr->NewFunction("thingcount", &FParser::SF_ThingCount);
|
||||
gscr->NewFunction("killinsector", &FParser::SF_KillInSector);
|
||||
gscr->NewFunction("changetag", &FParser::SF_ChangeTag);
|
||||
gscr->NewFunction("levelnum", &FParser::SF_LevelNum);
|
||||
|
||||
// new inventory
|
||||
|
@ -4525,8 +4458,6 @@ void init_functions(void)
|
|||
gscr->NewFunction("checkinventory", &FParser::SF_CheckInventory);
|
||||
gscr->NewFunction("setweapon", &FParser::SF_SetWeapon);
|
||||
|
||||
gscr->NewFunction("ls", &FParser::SF_Ls); // execute Hexen type line special
|
||||
|
||||
// Dummies - shut up warnings
|
||||
gscr->NewFunction("setcorona", &FParser::SF_SetCorona);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Punch)
|
|||
if (self->player != NULL)
|
||||
{
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL && !(weapon->WeaponFlags & WIF_DEHAMMO) && ACTION_CALL_FROM_WEAPON())
|
||||
if (weapon != NULL && !(weapon->WeaponFlags & WIF_DEHAMMO) && ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return 0;
|
||||
|
@ -73,16 +73,15 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePistol)
|
|||
|
||||
bool accurate;
|
||||
|
||||
if (self->player != NULL)
|
||||
if (self->player != nullptr)
|
||||
{
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
|
||||
if (weapon != nullptr && ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
|
||||
return 0;
|
||||
|
||||
P_SetPsprite (self->player, ps_flash, weapon->FindState(NAME_Flash));
|
||||
self->player->psprites[ps_flash].processPending = true;
|
||||
P_SetPsprite(self->player, PSP_FLASH, weapon->FindState(NAME_Flash), true);
|
||||
}
|
||||
self->player->mo->PlayAttacking2 ();
|
||||
|
||||
|
@ -161,7 +160,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Saw)
|
|||
slope = P_AimLineAttack (self, angle, range, &t) + spread_z * (pr_saw.Random2() / 255.);
|
||||
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if ((weapon != NULL) && !(flags & SF_NOUSEAMMO) && !(!t.linetarget && (flags & SF_NOUSEAMMOMISS)) && !(weapon->WeaponFlags & WIF_DEHAMMO) && ACTION_CALL_FROM_WEAPON())
|
||||
if ((weapon != NULL) && !(flags & SF_NOUSEAMMO) && !(!t.linetarget && (flags & SF_NOUSEAMMOMISS)) && !(weapon->WeaponFlags & WIF_DEHAMMO) && ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return 0;
|
||||
|
@ -263,19 +262,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun)
|
|||
int i;
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
if (nullptr == (player = self->player))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
S_Sound (self, CHAN_WEAPON, "weapons/shotgf", 1, ATTN_NORM);
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
|
||||
if (weapon != nullptr && ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
|
||||
return 0;
|
||||
P_SetPsprite (player, ps_flash, weapon->FindState(NAME_Flash));
|
||||
self->player->psprites[ps_flash].processPending = true;
|
||||
P_SetPsprite(player, PSP_FLASH, weapon->FindState(NAME_Flash), true);
|
||||
}
|
||||
player->mo->PlayAttacking2 ();
|
||||
|
||||
|
@ -300,19 +298,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireShotgun2)
|
|||
int damage;
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
if (nullptr == (player = self->player))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
S_Sound (self, CHAN_WEAPON, "weapons/sshotf", 1, ATTN_NORM);
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
|
||||
if (weapon != nullptr && ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 2))
|
||||
return 0;
|
||||
P_SetPsprite (player, ps_flash, weapon->FindState(NAME_Flash));
|
||||
self->player->psprites[ps_flash].processPending = true;
|
||||
P_SetPsprite(player, PSP_FLASH, weapon->FindState(NAME_Flash), true);
|
||||
}
|
||||
player->mo->PlayAttacking2 ();
|
||||
|
||||
|
@ -384,15 +381,13 @@ void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int i
|
|||
if (flashstate + index < cls->OwnedStates + cls->NumOwnedStates)
|
||||
{
|
||||
// we're ok so set the state
|
||||
P_SetPsprite (player, ps_flash, flashstate + index);
|
||||
player->psprites[ps_flash].processPending = true;
|
||||
P_SetPsprite(player, PSP_FLASH, flashstate + index, true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// oh, no! The state is beyond the end of the state table so use the original flash state.
|
||||
P_SetPsprite (player, ps_flash, flashstate);
|
||||
player->psprites[ps_flash].processPending = true;
|
||||
P_SetPsprite(player, PSP_FLASH, flashstate, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -408,8 +403,7 @@ void P_SetSafeFlash(AWeapon *weapon, player_t *player, FState *flashstate, int i
|
|||
{ // Invalid state. With no index offset, it should at least be valid.
|
||||
index = 0;
|
||||
}
|
||||
P_SetPsprite (player, ps_flash, flashstate + index);
|
||||
player->psprites[ps_flash].processPending = true;
|
||||
P_SetPsprite(player, PSP_FLASH, flashstate + index, true);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -421,13 +415,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCGun)
|
|||
|
||||
player_t *player;
|
||||
|
||||
if (self == NULL || NULL == (player = self->player))
|
||||
if (self == nullptr || nullptr == (player = self->player))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
AWeapon *weapon = player->ReadyWeapon;
|
||||
if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
|
||||
if (weapon != nullptr && ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
|
||||
return 0;
|
||||
|
@ -435,12 +429,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireCGun)
|
|||
S_Sound (self, CHAN_WEAPON, "weapons/chngun", 1, ATTN_NORM);
|
||||
|
||||
FState *flash = weapon->FindState(NAME_Flash);
|
||||
if (flash != NULL)
|
||||
if (flash != nullptr)
|
||||
{
|
||||
// [RH] Fix for Sparky's messed-up Dehacked patch! Blargh!
|
||||
FState * atk = weapon->FindState(NAME_Fire);
|
||||
|
||||
int theflash = clamp (int(player->psprites[ps_weapon].state - atk), 0, 1);
|
||||
int theflash = clamp (int(player->GetPSprite(PSP_WEAPON)->GetState() - atk), 0, 1);
|
||||
|
||||
if (flash[theflash].sprite != flash->sprite)
|
||||
{
|
||||
|
@ -471,7 +465,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMissile)
|
|||
return 0;
|
||||
}
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
|
||||
if (weapon != NULL && ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
|
||||
return 0;
|
||||
|
@ -498,7 +492,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireSTGrenade)
|
|||
return 0;
|
||||
}
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
|
||||
if (weapon != NULL && ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return 0;
|
||||
|
@ -526,7 +520,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePlasma)
|
|||
return 0;
|
||||
}
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
|
||||
if (weapon != NULL && ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
|
||||
return 0;
|
||||
|
@ -581,21 +575,21 @@ static void FireRailgun(AActor *self, int offset_xy, bool fromweapon)
|
|||
DEFINE_ACTION_FUNCTION(AActor, A_FireRailgun)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
FireRailgun(self, 0, ACTION_CALL_FROM_WEAPON());
|
||||
FireRailgun(self, 0, ACTION_CALL_FROM_PSPRITE());
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireRailgunRight)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
FireRailgun(self, 10, ACTION_CALL_FROM_WEAPON());
|
||||
FireRailgun(self, 10, ACTION_CALL_FROM_PSPRITE());
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_FireRailgunLeft)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
FireRailgun(self, -10, ACTION_CALL_FROM_WEAPON());
|
||||
FireRailgun(self, -10, ACTION_CALL_FROM_PSPRITE());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -621,7 +615,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBFG)
|
|||
}
|
||||
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL && ACTION_CALL_FROM_WEAPON())
|
||||
if (weapon != NULL && ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire, true, deh.BFGCells))
|
||||
return 0;
|
||||
|
@ -636,6 +630,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireBFG)
|
|||
// A_BFGSpray
|
||||
// Spawn a BFG explosion on every monster in view
|
||||
//
|
||||
enum BFG_Flags
|
||||
{
|
||||
BFGF_HURTSOURCE = 1,
|
||||
BFGF_MISSILEORIGIN = 2,
|
||||
};
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
@ -646,12 +646,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
|
|||
PARAM_FLOAT_OPT (distance) { distance = 0; }
|
||||
PARAM_ANGLE_OPT (vrange) { vrange = 0.; }
|
||||
PARAM_INT_OPT (defdamage) { defdamage = 0; }
|
||||
PARAM_INT_OPT (flags) { flags = 0; }
|
||||
|
||||
int i;
|
||||
int j;
|
||||
int damage;
|
||||
DAngle an;
|
||||
FTranslatedLineTarget t;
|
||||
AActor *originator;
|
||||
|
||||
if (spraytype == NULL) spraytype = PClass::FindActor("BFGExtra");
|
||||
if (numrays <= 0) numrays = 40;
|
||||
|
@ -664,13 +666,16 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
|
|||
if (!self->target)
|
||||
return 0;
|
||||
|
||||
// [XA] Set the originator of the rays to the projectile (self) if
|
||||
// the new flag is set, else set it to the player (self->target)
|
||||
originator = (flags & BFGF_MISSILEORIGIN) ? self : (AActor *)(self->target);
|
||||
|
||||
// offset angles from its attack angle
|
||||
for (i = 0; i < numrays; i++)
|
||||
{
|
||||
an = self->Angles.Yaw - angle / 2 + angle / numrays*i;
|
||||
|
||||
// self->target is the originator (player) of the missile
|
||||
P_AimLineAttack(self->target, an, distance, &t, vrange);
|
||||
P_AimLineAttack(originator, an, distance, &t, vrange);
|
||||
|
||||
if (t.linetarget != NULL)
|
||||
{
|
||||
|
@ -681,7 +686,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
|
|||
|
||||
if (spray != NULL)
|
||||
{
|
||||
if (spray->flags6 & MF6_MTHRUSPECIES && self->target->GetSpecies() == t.linetarget->GetSpecies())
|
||||
if ((spray->flags6 & MF6_MTHRUSPECIES && self->target->GetSpecies() == t.linetarget->GetSpecies()) ||
|
||||
(!(flags & BFGF_HURTSOURCE) && self->target == t.linetarget)) // [XA] Don't hit oneself unless we say so.
|
||||
{
|
||||
spray->Destroy(); // [MC] Remove it because technically, the spray isn't trying to "hit" them.
|
||||
continue;
|
||||
|
@ -704,7 +710,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_BFGSpray)
|
|||
damage = defdamage;
|
||||
}
|
||||
|
||||
int newdam = P_DamageMobj(t.linetarget, self->target, self->target, damage, dmgType, dmgFlags|DMG_USEANGLE, t.angleFromSource.Degrees);
|
||||
int newdam = P_DamageMobj(t.linetarget, originator, self->target, damage, dmgType, dmgFlags|DMG_USEANGLE, t.angleFromSource.Degrees);
|
||||
P_TraceBleed(newdam > 0 ? newdam : damage, &t, self);
|
||||
}
|
||||
}
|
||||
|
@ -745,7 +751,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireOldBFG)
|
|||
}
|
||||
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (!ACTION_CALL_FROM_WEAPON()) weapon = NULL;
|
||||
if (!ACTION_CALL_FROM_PSPRITE()) weapon = NULL;
|
||||
if (weapon != NULL)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire, true, 1))
|
||||
|
|
|
@ -1751,6 +1751,8 @@ void G_DoPlayerPop(int playernum)
|
|||
players[playernum].mo = NULL;
|
||||
players[playernum].camera = NULL;
|
||||
}
|
||||
|
||||
players[playernum].DestroyPSprites();
|
||||
}
|
||||
|
||||
void G_ScreenShot (char *filename)
|
||||
|
|
|
@ -123,9 +123,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_Feathers)
|
|||
|
||||
void P_UpdateBeak (AActor *self)
|
||||
{
|
||||
if (self->player != NULL)
|
||||
if (self->player != nullptr)
|
||||
{
|
||||
self->player->psprites[ps_weapon].sy = WEAPONTOP + self->player->chickenPeck / 2;
|
||||
self->player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP + self->player->chickenPeck / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,12 +141,12 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakRaise)
|
|||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
if (nullptr == (player = self->player))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
player->psprites[ps_weapon].sy = WEAPONTOP;
|
||||
P_SetPsprite (player, ps_weapon, player->ReadyWeapon->GetReadyState());
|
||||
player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP;
|
||||
P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetReadyState());
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL1)
|
|||
}
|
||||
P_PlayPeck (player->mo);
|
||||
player->chickenPeck = 12;
|
||||
player->psprites[ps_weapon].tics -= pr_beakatkpl1() & 7;
|
||||
player->GetPSprite(PSP_WEAPON)->Tics -= pr_beakatkpl1() & 7;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -227,6 +227,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_BeakAttackPL2)
|
|||
}
|
||||
P_PlayPeck (player->mo);
|
||||
player->chickenPeck = 12;
|
||||
player->psprites[ps_weapon].tics -= pr_beakatkpl2()&3;
|
||||
player->GetPSprite(PSP_WEAPON)->Tics -= pr_beakatkpl2()&3;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -287,8 +287,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_GenWizard)
|
|||
self->SetState (self->FindState(NAME_Death));
|
||||
self->flags &= ~MF_MISSILE;
|
||||
mo->master = self->target;
|
||||
// Heretic did not offset it by TELEFOGHEIGHT, so I won't either.
|
||||
Spawn<ATeleportFog> (self->Pos(), ALLOW_REPLACE);
|
||||
P_SpawnTeleportFog(self, self->Pos(), false, true);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "farchive.h"
|
||||
#include "d_player.h"
|
||||
#include "a_morph.h"
|
||||
#include "p_spec.h"
|
||||
|
||||
// Include all the other Heretic stuff here to reduce compile time
|
||||
#include "a_chicken.cpp"
|
||||
|
|
|
@ -259,7 +259,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack)
|
|||
FTranslatedLineTarget t;
|
||||
int actualdamage = 0;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
if (nullptr == (player = self->player))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -267,13 +267,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GauntletAttack)
|
|||
PARAM_INT(power);
|
||||
|
||||
AWeapon *weapon = player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
if (weapon != nullptr)
|
||||
{
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return 0;
|
||||
|
||||
player->GetPSprite(PSP_WEAPON)->x = ((pr_gatk() & 3) - 2);
|
||||
player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP + (pr_gatk() & 3);
|
||||
}
|
||||
player->psprites[ps_weapon].sx = ((pr_gatk()&3)-2);
|
||||
player->psprites[ps_weapon].sy = WEAPONTOP + (pr_gatk()&3);
|
||||
Angle = self->Angles.Yaw;
|
||||
if (power)
|
||||
{
|
||||
|
@ -425,7 +426,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL1)
|
|||
AActor *ball;
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
if (nullptr == (player = self->player))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -436,13 +437,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMacePL1)
|
|||
return 0;
|
||||
}
|
||||
AWeapon *weapon = player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
if (weapon != nullptr)
|
||||
{
|
||||
if (!weapon->DepleteAmmo(weapon->bAltFire))
|
||||
return 0;
|
||||
|
||||
player->GetPSprite(PSP_WEAPON)->x = ((pr_maceatk() & 3) - 2);
|
||||
player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP + (pr_maceatk() & 3);
|
||||
}
|
||||
player->psprites[ps_weapon].sx = ((pr_maceatk() & 3) - 2);
|
||||
player->psprites[ps_weapon].sy = WEAPONTOP + (pr_maceatk() & 3);
|
||||
ball = P_SpawnPlayerMissile(self, PClass::FindActor("MaceFX1"), self->Angles.Yaw + (((pr_maceatk() & 7) - 4) * (360. / 256)));
|
||||
if (ball)
|
||||
{
|
||||
|
@ -1158,11 +1160,11 @@ IMPLEMENT_CLASS (APhoenixRodPowered)
|
|||
|
||||
void APhoenixRodPowered::EndPowerup ()
|
||||
{
|
||||
P_SetPsprite (Owner->player, ps_weapon, SisterWeapon->GetReadyState());
|
||||
DepleteAmmo (bAltFire);
|
||||
Owner->player->refire = 0;
|
||||
S_StopSound (Owner, CHAN_WEAPON);
|
||||
Owner->player->ReadyWeapon = SisterWeapon;
|
||||
P_SetPsprite(Owner->player, PSP_WEAPON, SisterWeapon->GetReadyState());
|
||||
}
|
||||
|
||||
class APhoenixFX1 : public AActor
|
||||
|
@ -1298,7 +1300,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2)
|
|||
player_t *player;
|
||||
APhoenixRod *flamethrower;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
if (nullptr == (player = self->player))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -1306,9 +1308,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_FirePhoenixPL2)
|
|||
soundid = "weapons/phoenixpowshoot";
|
||||
|
||||
flamethrower = static_cast<APhoenixRod *> (player->ReadyWeapon);
|
||||
if (flamethrower == NULL || --flamethrower->FlameCount == 0)
|
||||
if (flamethrower == nullptr || --flamethrower->FlameCount == 0)
|
||||
{ // Out of flame
|
||||
P_SetPsprite (player, ps_weapon, flamethrower->FindState("Powerdown"));
|
||||
P_SetPsprite(player, PSP_WEAPON, flamethrower->FindState("Powerdown"));
|
||||
player->refire = 0;
|
||||
S_StopSound (self, CHAN_WEAPON);
|
||||
return 0;
|
||||
|
|
|
@ -106,7 +106,7 @@ DEFINE_ACTION_FUNCTION_PARAMS (AActor, A_Blast)
|
|||
AActor *mo;
|
||||
TThinkerIterator<AActor> iterator;
|
||||
|
||||
if (self->player && (blastflags & BF_USEAMMO) && ACTION_CALL_FROM_WEAPON())
|
||||
if (self->player && (blastflags & BF_USEAMMO) && ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
if (weapon != NULL && !weapon->DepleteAmmo(weapon->bAltFire))
|
||||
|
|
|
@ -58,7 +58,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
|
|||
FTranslatedLineTarget t;
|
||||
PClassActor *puff;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
if (nullptr == (player = self->player))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
|
|||
if (t.linetarget)
|
||||
{
|
||||
P_LineAttack(pmo, angle, 1.5 * MELEERANGE, slope, damage, NAME_Melee, puff, false, &t);
|
||||
if (t.linetarget != NULL)
|
||||
if (t.linetarget != nullptr)
|
||||
{
|
||||
pmo->Angles.Yaw = t.angleFromSource;
|
||||
if (((t.linetarget->player && (!t.linetarget->IsTeammate(pmo) || level.teamdamage != 0)) || t.linetarget->flags3&MF3_ISMONSTER)
|
||||
|
@ -89,13 +89,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheck)
|
|||
{
|
||||
pmo->health = player->health = newLife;
|
||||
}
|
||||
if (weapon != NULL)
|
||||
if (weapon != nullptr)
|
||||
{
|
||||
FState * newstate = weapon->FindState("Drain");
|
||||
if (newstate != NULL) P_SetPsprite(player, ps_weapon, newstate);
|
||||
if (newstate != nullptr) P_SetPsprite(player, PSP_WEAPON, newstate);
|
||||
}
|
||||
}
|
||||
if (weapon != NULL)
|
||||
if (weapon != nullptr)
|
||||
{
|
||||
weapon->DepleteAmmo(weapon->bAltFire, false);
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CStaffCheckBlink)
|
|||
{
|
||||
if (!--self->weaponspecial)
|
||||
{
|
||||
P_SetPsprite (self->player, ps_weapon, self->player->ReadyWeapon->FindState ("Blink"));
|
||||
P_SetPsprite(self->player, PSP_WEAPON, self->player->ReadyWeapon->FindState ("Blink"));
|
||||
self->weaponspecial = (pr_blink()+50)>>2;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -70,13 +70,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReady)
|
|||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
if (nullptr == (player = self->player))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (player->ReadyWeapon->Ammo1->Amount)
|
||||
{
|
||||
P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState ("ReadyGlow"));
|
||||
P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("ReadyGlow"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -97,13 +97,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckReadyG)
|
|||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
if (nullptr == (player = self->player))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (player->ReadyWeapon->Ammo1->Amount <= 0)
|
||||
{
|
||||
P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState ("Ready"));
|
||||
P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("Ready"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -124,13 +124,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUp)
|
|||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
if (nullptr == (player = self->player))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (player->ReadyWeapon->Ammo1->Amount)
|
||||
{
|
||||
P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState ("SelectGlow"));
|
||||
P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("SelectGlow"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -151,13 +151,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckUpG)
|
|||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
if (nullptr == (player = self->player))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (player->ReadyWeapon->Ammo1->Amount <= 0)
|
||||
{
|
||||
P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState ("Select"));
|
||||
P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("Select"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -178,13 +178,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeCheckAtk)
|
|||
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
if (nullptr == (player = self->player))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (player->ReadyWeapon->Ammo1->Amount)
|
||||
{
|
||||
P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState ("FireGlow"));
|
||||
P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("FireGlow"));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack)
|
|||
PClassActor *pufftype;
|
||||
FTranslatedLineTarget t;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
if (nullptr == (player = self->player))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -241,7 +241,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FAxeAttack)
|
|||
if (t.linetarget)
|
||||
{
|
||||
P_LineAttack(pmo, angle, AXERANGE, slope, damage, NAME_Melee, pufftype, true, &t);
|
||||
if (t.linetarget != NULL)
|
||||
if (t.linetarget != nullptr)
|
||||
{
|
||||
if (t.linetarget->flags3&MF3_ISMONSTER || t.linetarget->player)
|
||||
{
|
||||
|
@ -265,15 +265,15 @@ axedone:
|
|||
if (useMana == 2)
|
||||
{
|
||||
AWeapon *weapon = player->ReadyWeapon;
|
||||
if (weapon != NULL)
|
||||
if (weapon != nullptr)
|
||||
{
|
||||
weapon->DepleteAmmo (weapon->bAltFire, false);
|
||||
|
||||
if ((weapon->Ammo1 == NULL || weapon->Ammo1->Amount == 0) &&
|
||||
if ((weapon->Ammo1 == nullptr || weapon->Ammo1->Amount == 0) &&
|
||||
(!(weapon->WeaponFlags & WIF_PRIMARY_USES_BOTH) ||
|
||||
weapon->Ammo2 == NULL || weapon->Ammo2->Amount == 0))
|
||||
weapon->Ammo2 == nullptr || weapon->Ammo2->Amount == 0))
|
||||
{
|
||||
P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState ("Fire") + 5);
|
||||
P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState ("Fire") + 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack)
|
|||
int i;
|
||||
player_t *player;
|
||||
|
||||
if (NULL == (player = self->player))
|
||||
if (nullptr == (player = self->player))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_FPunchAttack)
|
|||
if (pmo->weaponspecial >= 3)
|
||||
{
|
||||
pmo->weaponspecial = 0;
|
||||
P_SetPsprite (player, ps_weapon, player->ReadyWeapon->FindState("Fire2"));
|
||||
P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState("Fire2"));
|
||||
S_Sound (pmo, CHAN_VOICE, "*fistgrunt", 1, ATTN_NORM);
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -37,9 +37,9 @@ void APigPlayer::MorphPlayerThink ()
|
|||
}
|
||||
if(Vel.X == 0 && Vel.Y == 0 && pr_pigplayerthink() < 64)
|
||||
{ // Snout sniff
|
||||
if (player->ReadyWeapon != NULL)
|
||||
if (player->ReadyWeapon != nullptr)
|
||||
{
|
||||
P_SetPsprite(player, ps_weapon, player->ReadyWeapon->FindState("Grunt"));
|
||||
P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->FindState("Grunt"));
|
||||
}
|
||||
S_Sound (this, CHAN_VOICE, "PigActive1", 1, ATTN_NORM); // snort
|
||||
return;
|
||||
|
|
|
@ -372,9 +372,9 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
|
|||
bool wantFast;
|
||||
int i;
|
||||
|
||||
G_ClearHubInfo();
|
||||
if (!savegamerestore)
|
||||
{
|
||||
G_ClearHubInfo();
|
||||
G_ClearSnapshots ();
|
||||
P_RemoveDefereds ();
|
||||
|
||||
|
|
|
@ -1109,17 +1109,17 @@ void APowerWeaponLevel2::InitEffect ()
|
|||
|
||||
Super::InitEffect();
|
||||
|
||||
if (Owner->player == NULL)
|
||||
if (Owner->player == nullptr)
|
||||
return;
|
||||
|
||||
weapon = Owner->player->ReadyWeapon;
|
||||
|
||||
if (weapon == NULL)
|
||||
if (weapon == nullptr)
|
||||
return;
|
||||
|
||||
sister = weapon->SisterWeapon;
|
||||
|
||||
if (sister == NULL)
|
||||
if (sister == nullptr)
|
||||
return;
|
||||
|
||||
if (!(sister->WeaponFlags & WIF_POWERED_UP))
|
||||
|
@ -1131,7 +1131,7 @@ void APowerWeaponLevel2::InitEffect ()
|
|||
|
||||
if (weapon->GetReadyState() != sister->GetReadyState())
|
||||
{
|
||||
P_SetPsprite (Owner->player, ps_weapon, sister->GetReadyState());
|
||||
P_SetPsprite(Owner->player, PSP_WEAPON, sister->GetReadyState());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1294,29 +1294,42 @@ void APowerTargeter::Travelled ()
|
|||
|
||||
void APowerTargeter::InitEffect ()
|
||||
{
|
||||
// Why is this called when the inventory isn't even attached yet
|
||||
// in APowerup::CreateCopy?
|
||||
if (!Owner->FindInventory(GetClass(), true))
|
||||
return;
|
||||
|
||||
player_t *player;
|
||||
|
||||
Super::InitEffect();
|
||||
|
||||
if ((player = Owner->player) == NULL)
|
||||
if ((player = Owner->player) == nullptr)
|
||||
return;
|
||||
|
||||
FState *state = FindState("Targeter");
|
||||
|
||||
if (state != NULL)
|
||||
if (state != nullptr)
|
||||
{
|
||||
P_SetPsprite (player, ps_targetcenter, state + 0);
|
||||
P_SetPsprite (player, ps_targetleft, state + 1);
|
||||
P_SetPsprite (player, ps_targetright, state + 2);
|
||||
P_SetPsprite(player, PSP_TARGETCENTER, state + 0);
|
||||
P_SetPsprite(player, PSP_TARGETLEFT, state + 1);
|
||||
P_SetPsprite(player, PSP_TARGETRIGHT, state + 2);
|
||||
}
|
||||
|
||||
player->psprites[ps_targetcenter].sx = (160-3);
|
||||
player->psprites[ps_targetcenter].sy =
|
||||
player->psprites[ps_targetleft].sy =
|
||||
player->psprites[ps_targetright].sy = (100-3);
|
||||
player->GetPSprite(PSP_TARGETCENTER)->x = (160-3);
|
||||
player->GetPSprite(PSP_TARGETCENTER)->y =
|
||||
player->GetPSprite(PSP_TARGETLEFT)->y =
|
||||
player->GetPSprite(PSP_TARGETRIGHT)->y = (100-3);
|
||||
PositionAccuracy ();
|
||||
}
|
||||
|
||||
void APowerTargeter::AttachToOwner(AActor *other)
|
||||
{
|
||||
Super::AttachToOwner(other);
|
||||
|
||||
// Let's actually properly call this for the targeters.
|
||||
InitEffect();
|
||||
}
|
||||
|
||||
bool APowerTargeter::HandlePickup(AInventory *item)
|
||||
{
|
||||
if (Super::HandlePickup(item))
|
||||
|
@ -1327,13 +1340,11 @@ bool APowerTargeter::HandlePickup(AInventory *item)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void APowerTargeter::DoEffect ()
|
||||
{
|
||||
Super::DoEffect ();
|
||||
|
||||
if (Owner != NULL && Owner->player != NULL)
|
||||
if (Owner != nullptr && Owner->player != nullptr)
|
||||
{
|
||||
player_t *player = Owner->player;
|
||||
|
||||
|
@ -1342,17 +1353,17 @@ void APowerTargeter::DoEffect ()
|
|||
{
|
||||
FState *state = FindState("Targeter");
|
||||
|
||||
if (state != NULL)
|
||||
if (state != nullptr)
|
||||
{
|
||||
if (EffectTics & 32)
|
||||
{
|
||||
P_SetPsprite (player, ps_targetright, NULL);
|
||||
P_SetPsprite (player, ps_targetleft, state+1);
|
||||
P_SetPsprite(player, PSP_TARGETRIGHT, nullptr);
|
||||
P_SetPsprite(player, PSP_TARGETLEFT, state + 1);
|
||||
}
|
||||
else if (EffectTics & 16)
|
||||
{
|
||||
P_SetPsprite (player, ps_targetright, state+2);
|
||||
P_SetPsprite (player, ps_targetleft, NULL);
|
||||
P_SetPsprite(player, PSP_TARGETRIGHT, state + 2);
|
||||
P_SetPsprite(player, PSP_TARGETLEFT, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1362,11 +1373,17 @@ void APowerTargeter::DoEffect ()
|
|||
void APowerTargeter::EndEffect ()
|
||||
{
|
||||
Super::EndEffect();
|
||||
if (Owner != NULL && Owner->player != NULL)
|
||||
if (Owner != nullptr && Owner->player != nullptr)
|
||||
{
|
||||
P_SetPsprite (Owner->player, ps_targetcenter, NULL);
|
||||
P_SetPsprite (Owner->player, ps_targetleft, NULL);
|
||||
P_SetPsprite (Owner->player, ps_targetright, NULL);
|
||||
// Calling GetPSprite here could crash if we're creating a new game.
|
||||
// This is because P_SetupLevel nulls the player's mo before destroying
|
||||
// every DThinker which in turn ends up calling this.
|
||||
// However P_SetupLevel is only called after G_NewInit which calls
|
||||
// every player's dtor which destroys all their psprites.
|
||||
DPSprite *pspr;
|
||||
if ((pspr = Owner->player->FindPSprite(PSP_TARGETCENTER)) != nullptr) pspr->SetState(nullptr);
|
||||
if ((pspr = Owner->player->FindPSprite(PSP_TARGETLEFT)) != nullptr) pspr->SetState(nullptr);
|
||||
if ((pspr = Owner->player->FindPSprite(PSP_TARGETRIGHT)) != nullptr) pspr->SetState(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1374,10 +1391,10 @@ void APowerTargeter::PositionAccuracy ()
|
|||
{
|
||||
player_t *player = Owner->player;
|
||||
|
||||
if (player != NULL)
|
||||
if (player != nullptr)
|
||||
{
|
||||
player->psprites[ps_targetleft].sx = (160-3) - ((100 - player->mo->accuracy));
|
||||
player->psprites[ps_targetright].sx = (160-3)+ ((100 - player->mo->accuracy));
|
||||
player->GetPSprite(PSP_TARGETLEFT)->x = (160-3) - ((100 - player->mo->accuracy));
|
||||
player->GetPSprite(PSP_TARGETRIGHT)->x = (160-3)+ ((100 - player->mo->accuracy));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -182,6 +182,7 @@ protected:
|
|||
void EndEffect ();
|
||||
void PositionAccuracy ();
|
||||
void Travelled ();
|
||||
void AttachToOwner(AActor *other);
|
||||
bool HandlePickup(AInventory *item);
|
||||
};
|
||||
|
||||
|
|
|
@ -608,15 +608,18 @@ bool AWeapon::DepleteAmmo (bool altFire, bool checkEnough, int ammouse)
|
|||
|
||||
void AWeapon::PostMorphWeapon ()
|
||||
{
|
||||
if (Owner == NULL)
|
||||
DPSprite *pspr;
|
||||
if (Owner == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Owner->player->PendingWeapon = WP_NOCHANGE;
|
||||
Owner->player->ReadyWeapon = this;
|
||||
Owner->player->psprites[ps_weapon].sy = WEAPONBOTTOM;
|
||||
Owner->player->refire = 0;
|
||||
P_SetPsprite (Owner->player, ps_weapon, GetUpState());
|
||||
|
||||
pspr = Owner->player->GetPSprite(PSP_WEAPON);
|
||||
pspr->y = WEAPONBOTTOM;
|
||||
pspr->SetState(GetUpState());
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -2786,7 +2786,7 @@ class CommandDrawBar : public SBarInfoCommand
|
|||
// [BL] Since we used a percentage (in order to get the most fluid animation)
|
||||
// we need to establish a cut off point so the last pixel won't hang as the animation slows
|
||||
if(pixel == -1 && statusBar->Images[foreground])
|
||||
pixel = MAX(1., 1./statusBar->Images[foreground]->GetWidth());
|
||||
pixel = MAX(1 / 65536., 1./statusBar->Images[foreground]->GetWidth());
|
||||
|
||||
if(fabs(drawValue - value) < pixel)
|
||||
drawValue = value;
|
||||
|
|
|
@ -115,7 +115,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Beacon)
|
|||
|
||||
rebel->SetState (rebel->SeeState);
|
||||
rebel->Angles.Yaw = self->Angles.Yaw;
|
||||
Spawn<ATeleportFog> (rebel->Vec3Angle(20., self->Angles.Yaw, TELEFOGHEIGHT), ALLOW_REPLACE);
|
||||
P_SpawnTeleportFog(rebel, rebel->Vec3Angle(20., self->Angles.Yaw, 0), false, true);
|
||||
if (--self->health < 0)
|
||||
{
|
||||
self->SetState(self->FindState(NAME_Death));
|
||||
|
|
|
@ -317,7 +317,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckTerrain)
|
|||
int anglespeed = tagManager.GetFirstSectorTag(sec) - 100;
|
||||
double speed = (anglespeed % 10) / 16.;
|
||||
DAngle an = (anglespeed / 10) * (360 / 8.);
|
||||
self->VelFromAngle(an, speed);
|
||||
self->Thrust(an, speed);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -350,14 +350,24 @@ DEFINE_ACTION_FUNCTION(AActor, A_ItBurnsItBurns)
|
|||
|
||||
S_Sound (self, CHAN_VOICE, "human/imonfire", 1, ATTN_NORM);
|
||||
|
||||
if (self->player != NULL && self->player->mo == self)
|
||||
if (self->player != nullptr && self->player->mo == self)
|
||||
{
|
||||
P_SetPsprite (self->player, ps_weapon, self->FindState("FireHands"));
|
||||
P_SetPsprite (self->player, ps_flash, NULL);
|
||||
self->player->ReadyWeapon = NULL;
|
||||
self->player->PendingWeapon = WP_NOCHANGE;
|
||||
self->player->playerstate = PST_LIVE;
|
||||
self->player->extralight = 3;
|
||||
FState *firehands = self->FindState("FireHands");
|
||||
if (firehands != NULL)
|
||||
{
|
||||
DPSprite *psp = self->player->GetPSprite(PSP_STRIFEHANDS);
|
||||
if (psp != nullptr)
|
||||
{
|
||||
psp->SetState(firehands);
|
||||
psp->Flags &= PSPF_ADDWEAPON | PSPF_ADDBOB;
|
||||
psp->y = WEAPONTOP;
|
||||
}
|
||||
|
||||
self->player->ReadyWeapon = nullptr;
|
||||
self->player->PendingWeapon = WP_NOCHANGE;
|
||||
self->player->playerstate = PST_LIVE;
|
||||
self->player->extralight = 3;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -376,12 +386,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrispyPlayer)
|
|||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->player != NULL && self->player->mo == self)
|
||||
if (self->player != nullptr && self->player->mo == self)
|
||||
{
|
||||
self->player->playerstate = PST_DEAD;
|
||||
P_SetPsprite (self->player, ps_weapon,
|
||||
self->player->psprites[ps_weapon].state +
|
||||
(self->FindState("FireHandsLower") - self->FindState("FireHands")));
|
||||
|
||||
DPSprite *psp;
|
||||
psp = self->player->GetPSprite(PSP_STRIFEHANDS);
|
||||
FState *firehandslower = self->FindState("FireHandsLower");
|
||||
FState *firehands = self->FindState("FireHands");
|
||||
if (firehandslower != NULL && firehands != NULL && firehands < firehandslower)
|
||||
psp->SetState(psp->GetState() + (firehandslower - firehands));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -390,13 +404,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_HandLower)
|
|||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->player != NULL)
|
||||
if (self->player != nullptr)
|
||||
{
|
||||
pspdef_t *psp = &self->player->psprites[ps_weapon];
|
||||
psp->sy += 9;
|
||||
if (psp->sy > WEAPONBOTTOM*2)
|
||||
DPSprite *psp = self->player->GetPSprite(PSP_STRIFEHANDS);
|
||||
psp->y += 9;
|
||||
if (psp->y > WEAPONBOTTOM*2)
|
||||
{
|
||||
P_SetPsprite (self->player, ps_weapon, NULL);
|
||||
psp->SetState(nullptr);
|
||||
}
|
||||
if (self->player->extralight > 0) self->player->extralight--;
|
||||
}
|
||||
|
|
|
@ -216,10 +216,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_ClearFlash)
|
|||
|
||||
player_t *player = self->player;
|
||||
|
||||
if (player == NULL)
|
||||
if (player == nullptr)
|
||||
return 0;
|
||||
|
||||
P_SetPsprite (player, ps_flash, NULL);
|
||||
P_SetPsprite (player, PSP_FLASH, nullptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -233,9 +233,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_ShowElectricFlash)
|
|||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
if (self->player != NULL)
|
||||
if (self->player != nullptr)
|
||||
{
|
||||
P_SetPsprite (self->player, ps_flash, self->player->ReadyWeapon->FindState(NAME_Flash));
|
||||
P_SetPsprite (self->player, PSP_FLASH, self->player->ReadyWeapon->FindState(NAME_Flash));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -498,10 +498,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_FireMauler2Pre)
|
|||
|
||||
S_Sound (self, CHAN_WEAPON, "weapons/mauler2charge", 1, ATTN_NORM);
|
||||
|
||||
if (self->player != NULL)
|
||||
if (self->player != nullptr)
|
||||
{
|
||||
self->player->psprites[ps_weapon].sx += pr_mauler2.Random2() / 64.;
|
||||
self->player->psprites[ps_weapon].sy += pr_mauler2.Random2() / 64.;
|
||||
self->player->GetPSprite(PSP_WEAPON)->x += pr_mauler2.Random2() / 64.;
|
||||
self->player->GetPSprite(PSP_WEAPON)->y += pr_mauler2.Random2() / 64.;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -698,24 +698,23 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireGrenade)
|
|||
DAngle an;
|
||||
AWeapon *weapon;
|
||||
|
||||
if (player == NULL || grenadetype == NULL)
|
||||
if (player == nullptr || grenadetype == nullptr)
|
||||
return 0;
|
||||
|
||||
if ((weapon = player->ReadyWeapon) == NULL)
|
||||
if ((weapon = player->ReadyWeapon) == nullptr)
|
||||
return 0;
|
||||
|
||||
if (!weapon->DepleteAmmo (weapon->bAltFire))
|
||||
return 0;
|
||||
|
||||
P_SetPsprite (player, ps_flash, flash);
|
||||
self->player->psprites[ps_flash].processPending = true;
|
||||
P_SetPsprite (player, PSP_FLASH, flash, true);
|
||||
|
||||
if (grenadetype != NULL)
|
||||
if (grenadetype != nullptr)
|
||||
{
|
||||
self->AddZ(32);
|
||||
grenade = P_SpawnSubMissile (self, grenadetype, self);
|
||||
self->AddZ(-32);
|
||||
if (grenade == NULL)
|
||||
if (grenade == nullptr)
|
||||
return 0;
|
||||
|
||||
if (grenade->SeeSound != 0)
|
||||
|
@ -849,15 +848,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_SelectSigilView)
|
|||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
DPSprite *pspr;
|
||||
int pieces;
|
||||
|
||||
if (self->player == NULL)
|
||||
if (self->player == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
pieces = static_cast<ASigil*>(self->player->ReadyWeapon)->NumPieces;
|
||||
P_SetPsprite (self->player, ps_weapon,
|
||||
self->player->psprites[ps_weapon].state + pieces);
|
||||
pspr = self->player->GetPSprite(PSP_WEAPON);
|
||||
pspr->SetState(pspr->GetState() + pieces);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -875,9 +875,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_SelectSigilDown)
|
|||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
DPSprite *pspr;
|
||||
int pieces;
|
||||
|
||||
if (self->player == NULL)
|
||||
if (self->player == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -887,8 +888,8 @@ DEFINE_ACTION_FUNCTION(AActor, A_SelectSigilDown)
|
|||
{
|
||||
pieces = static_cast<ASigil*>(self->player->ReadyWeapon)->NumPieces;
|
||||
}
|
||||
P_SetPsprite (self->player, ps_weapon,
|
||||
self->player->psprites[ps_weapon].state + pieces);
|
||||
pspr = self->player->GetPSprite(PSP_WEAPON);
|
||||
pspr->SetState(pspr->GetState() + pieces);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -904,15 +905,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_SelectSigilAttack)
|
|||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
|
||||
DPSprite *pspr;
|
||||
int pieces;
|
||||
|
||||
if (self->player == NULL)
|
||||
if (self->player == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
pieces = static_cast<ASigil*>(self->player->ReadyWeapon)->NumPieces;
|
||||
P_SetPsprite (self->player, ps_weapon,
|
||||
self->player->psprites[ps_weapon].state + 4*pieces - 3);
|
||||
pspr = self->player->GetPSprite(PSP_WEAPON);
|
||||
pspr->SetState(pspr->GetState() + 4*pieces - 3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -456,7 +456,7 @@ bool gl_SetupLightTexture()
|
|||
{
|
||||
if (GLRenderer->gllight == nullptr) return false;
|
||||
FMaterial * pat = FMaterial::ValidateTexture(GLRenderer->gllight, false);
|
||||
pat->Bind(CLAMP_XY_NOMIP, 0);
|
||||
gl_RenderState.SetMaterial(pat, CLAMP_XY_NOMIP, 0, -1, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -484,7 +484,7 @@ bool GLWall::PutWallCompat(int passflag)
|
|||
}
|
||||
else if (sub)
|
||||
{
|
||||
if (sub->lighthead != nullptr) return false;
|
||||
if (sub->lighthead == nullptr) return false;
|
||||
}
|
||||
|
||||
bool foggy = !gl_isBlack(Colormap.FadeColor) || (level.flags&LEVEL_HASFADETABLE) || gl_lights_additive;
|
||||
|
@ -673,7 +673,7 @@ void GLFlat::DrawLightsCompat(int pass)
|
|||
|
||||
while (node)
|
||||
{
|
||||
DrawSubsectorLights(sub, pass);
|
||||
DrawSubsectorLights(node->sub, pass);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -348,7 +348,7 @@ static void PrepareTransparentDoors(sector_t * sector)
|
|||
|
||||
int side = sector->lines[i]->sidedef[0]->sector == sec;
|
||||
|
||||
if (sector->GetPlaneTexZ(sector_t::floor)!=sec->GetPlaneTexZ(sector_t::floor)+1.)
|
||||
if (sector->GetPlaneTexZ(sector_t::floor)!=sec->GetPlaneTexZ(sector_t::floor)+1. || sec->floorplane.isSlope())
|
||||
{
|
||||
sector->transdoor=false;
|
||||
return;
|
||||
|
|
|
@ -1019,10 +1019,10 @@ void gl_RenderModel(GLSprite * spr)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void gl_RenderHUDModel(pspdef_t *psp, float ofsX, float ofsY)
|
||||
void gl_RenderHUDModel(DPSprite *psp, float ofsX, float ofsY)
|
||||
{
|
||||
AActor * playermo=players[consoleplayer].camera;
|
||||
FSpriteModelFrame *smf = gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->state->sprite, psp->state->GetFrame(), false);
|
||||
FSpriteModelFrame *smf = gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false);
|
||||
|
||||
// [BB] No model found for this sprite, so we can't render anything.
|
||||
if ( smf == nullptr )
|
||||
|
@ -1062,7 +1062,7 @@ void gl_RenderHUDModel(pspdef_t *psp, float ofsX, float ofsY)
|
|||
gl_RenderState.mViewMatrix.rotate(-smf->rolloffset, 1, 0, 0);
|
||||
gl_RenderState.ApplyMatrices();
|
||||
|
||||
gl_RenderFrameModels( smf, psp->state, psp->tics, playermo->player->ReadyWeapon->GetClass(), nullptr, 0 );
|
||||
gl_RenderFrameModels( smf, psp->GetState(), psp->GetTics(), playermo->player->ReadyWeapon->GetClass(), nullptr, 0 );
|
||||
|
||||
glDepthFunc(GL_LESS);
|
||||
if (!( playermo->RenderStyle == LegacyRenderStyles[STYLE_Normal] ))
|
||||
|
@ -1077,10 +1077,15 @@ void gl_RenderHUDModel(pspdef_t *psp, float ofsX, float ofsY)
|
|||
|
||||
bool gl_IsHUDModelForPlayerAvailable (player_t * player)
|
||||
{
|
||||
if ( (player == nullptr) || (player->ReadyWeapon == nullptr) || (player->psprites[0].state == nullptr) )
|
||||
if (player == nullptr || player->ReadyWeapon == nullptr)
|
||||
return false;
|
||||
|
||||
FState* state = player->psprites[0].state;
|
||||
DPSprite *psp = player->FindPSprite(PSP_WEAPON);
|
||||
|
||||
if (psp == nullptr || psp->GetState() == nullptr)
|
||||
return false;
|
||||
|
||||
FState* state = psp->GetState();
|
||||
FSpriteModelFrame *smf = gl_FindModelFrame(player->ReadyWeapon->GetClass(), state->sprite, state->GetFrame(), false);
|
||||
return ( smf != nullptr );
|
||||
}
|
||||
|
|
|
@ -371,7 +371,7 @@ FSpriteModelFrame * gl_FindModelFrame(const PClass * ti, int sprite, int frame,
|
|||
|
||||
void gl_RenderModel(GLSprite * spr);
|
||||
// [BB] HUD weapon model rendering functions.
|
||||
void gl_RenderHUDModel(pspdef_t *psp, float ofsx, float ofsy);
|
||||
void gl_RenderHUDModel(DPSprite *psp, float ofsx, float ofsy);
|
||||
bool gl_IsHUDModelForPlayerAvailable (player_t * player);
|
||||
|
||||
|
||||
|
|
|
@ -13,11 +13,11 @@ class FFlatVertexBuffer;
|
|||
class FSkyVertexBuffer;
|
||||
class OpenGLFrameBuffer;
|
||||
struct FDrawInfo;
|
||||
struct pspdef_t;
|
||||
class FShaderManager;
|
||||
class GLPortal;
|
||||
class FLightBuffer;
|
||||
class FSamplerManager;
|
||||
class DPSprite;
|
||||
|
||||
inline float DEG2RAD(float deg)
|
||||
{
|
||||
|
@ -53,6 +53,12 @@ struct GL_IRECT
|
|||
}
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DM_MAINVIEW,
|
||||
DM_OFFSCREEN,
|
||||
DM_PORTAL
|
||||
};
|
||||
|
||||
class FGLRenderer
|
||||
{
|
||||
|
@ -106,10 +112,10 @@ public:
|
|||
void RenderMultipassStuff();
|
||||
void RenderScene(int recursion);
|
||||
void RenderTranslucent();
|
||||
void DrawScene(bool toscreen = false);
|
||||
void DrawScene(int drawmode);
|
||||
void DrawBlend(sector_t * viewsector);
|
||||
|
||||
void DrawPSprite (player_t * player,pspdef_t *psp,float sx, float sy, bool hudModelStep, int OverrideShader, bool alphatexture);
|
||||
void DrawPSprite (player_t * player,DPSprite *psp,float sx, float sy, bool hudModelStep, int OverrideShader, bool alphatexture);
|
||||
void DrawPlayerSprites(sector_t * viewsector, bool hudModelStep);
|
||||
void DrawTargeterSprites();
|
||||
|
||||
|
|
|
@ -306,9 +306,10 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
|||
savedAngle = ViewAngle;
|
||||
savedviewactor=GLRenderer->mViewActor;
|
||||
savedviewarea=in_area;
|
||||
savedshowviewer = r_showviewer;
|
||||
savedviewpath[0] = ViewPath[0];
|
||||
savedviewpath[1] = ViewPath[1];
|
||||
savedvisibility = camera ? camera->renderflags & RF_INVISIBLE : ActorRenderFlags::FromInt(0);
|
||||
|
||||
|
||||
PrevPortal = GLRenderer->mCurrentPortal;
|
||||
PrevClipPortal = GLRenderer->mClipPortal;
|
||||
|
@ -375,7 +376,7 @@ void GLPortal::End(bool usestencil)
|
|||
ViewAngle = savedAngle;
|
||||
GLRenderer->mViewActor=savedviewactor;
|
||||
in_area=savedviewarea;
|
||||
r_showviewer = savedshowviewer;
|
||||
if (camera != nullptr) camera->renderflags = (camera->renderflags & ~RF_INVISIBLE) | savedvisibility;
|
||||
GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1));
|
||||
|
||||
{
|
||||
|
@ -432,7 +433,7 @@ void GLPortal::End(bool usestencil)
|
|||
ViewAngle = savedAngle;
|
||||
GLRenderer->mViewActor=savedviewactor;
|
||||
in_area=savedviewarea;
|
||||
r_showviewer = savedshowviewer;
|
||||
if (camera != nullptr) camera->renderflags |= savedvisibility;
|
||||
GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
|
||||
|
||||
// This draws a valid z-buffer into the stencil's contents to ensure it
|
||||
|
@ -665,7 +666,7 @@ void GLSkyboxPortal::DrawContents()
|
|||
SaveMapSection();
|
||||
currentmapsection[mapsection >> 3] |= 1 << (mapsection & 7);
|
||||
|
||||
GLRenderer->DrawScene();
|
||||
GLRenderer->DrawScene(DM_PORTAL);
|
||||
portal->mFlags &= ~PORTSF_INSKYBOX;
|
||||
inskybox = false;
|
||||
gl_RenderState.SetDepthClamp(oldclamp);
|
||||
|
@ -755,7 +756,7 @@ void GLSectorStackPortal::DrawContents()
|
|||
SaveMapSection();
|
||||
SetupCoverage();
|
||||
ClearClipper();
|
||||
GLRenderer->DrawScene();
|
||||
GLRenderer->DrawScene(DM_PORTAL);
|
||||
RestoreMapSection();
|
||||
|
||||
if (origin->plane != -1) instack[origin->plane]--;
|
||||
|
@ -791,14 +792,13 @@ void GLPlaneMirrorPortal::DrawContents()
|
|||
ViewPos.Z = 2 * planez - ViewPos.Z;
|
||||
GLRenderer->mViewActor = NULL;
|
||||
PlaneMirrorMode = origin->fC() < 0 ? -1 : 1;
|
||||
r_showviewer = true;
|
||||
|
||||
|
||||
PlaneMirrorFlag++;
|
||||
GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
|
||||
ClearClipper();
|
||||
|
||||
gl_RenderState.SetClipHeight(planez, PlaneMirrorMode < 0? -1.f : 1.f);
|
||||
GLRenderer->DrawScene();
|
||||
GLRenderer->DrawScene(DM_PORTAL);
|
||||
gl_RenderState.SetClipHeight(0.f, 0.f);
|
||||
PlaneMirrorFlag--;
|
||||
PlaneMirrorMode=old_pm;
|
||||
|
@ -955,7 +955,6 @@ void GLMirrorPortal::DrawContents()
|
|||
ViewAngle = linedef->Delta().Angle() * 2. - StartAngle;
|
||||
|
||||
GLRenderer->mViewActor = NULL;
|
||||
r_showviewer = true;
|
||||
|
||||
MirrorFlag++;
|
||||
GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
|
||||
|
@ -971,7 +970,7 @@ void GLMirrorPortal::DrawContents()
|
|||
|
||||
gl_RenderState.SetClipLine(linedef);
|
||||
gl_RenderState.EnableClipLine(true);
|
||||
GLRenderer->DrawScene();
|
||||
GLRenderer->DrawScene(DM_PORTAL);
|
||||
gl_RenderState.EnableClipLine(false);
|
||||
|
||||
MirrorFlag--;
|
||||
|
@ -1009,7 +1008,7 @@ void GLLineToLinePortal::DrawContents()
|
|||
P_TranslatePortalZ(origin, ViewPos.Z);
|
||||
P_TranslatePortalXY(origin, ViewPath[0].X, ViewPath[0].Y);
|
||||
P_TranslatePortalXY(origin, ViewPath[1].X, ViewPath[1].Y);
|
||||
if (!r_showviewer)
|
||||
if (!r_showviewer && camera != nullptr && P_PointOnLineSidePrecise(ViewPath[0], glport->lines[0]->mDestination) != P_PointOnLineSidePrecise(ViewPath[1], glport->lines[0]->mDestination))
|
||||
{
|
||||
double distp = (ViewPath[0] - ViewPath[1]).Length();
|
||||
if (distp > EQUAL_EPSILON)
|
||||
|
@ -1017,9 +1016,9 @@ void GLLineToLinePortal::DrawContents()
|
|||
double dist1 = (ViewPos - ViewPath[0]).Length();
|
||||
double dist2 = (ViewPos - ViewPath[1]).Length();
|
||||
|
||||
if (dist1 + dist2 > distp + 1)
|
||||
if (dist1 + dist2 < distp + 1)
|
||||
{
|
||||
r_showviewer = true;
|
||||
camera->renderflags |= RF_INVISIBLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1044,7 +1043,7 @@ void GLLineToLinePortal::DrawContents()
|
|||
ClearClipper();
|
||||
gl_RenderState.SetClipLine(glport->lines[0]->mDestination);
|
||||
gl_RenderState.EnableClipLine(true);
|
||||
GLRenderer->DrawScene();
|
||||
GLRenderer->DrawScene(DM_PORTAL);
|
||||
gl_RenderState.EnableClipLine(false);
|
||||
RestoreMapSection();
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ private:
|
|||
DAngle savedAngle;
|
||||
AActor * savedviewactor;
|
||||
area_t savedviewarea;
|
||||
bool savedshowviewer;
|
||||
ActorRenderFlags savedvisibility;
|
||||
DVector3 savedviewpath[2];
|
||||
GLPortal *PrevPortal;
|
||||
GLPortal *PrevClipPortal;
|
||||
|
|
|
@ -98,6 +98,7 @@ EXTERN_CVAR (Bool, r_deathcamera)
|
|||
|
||||
extern int viewpitch;
|
||||
extern bool NoInterpolateView;
|
||||
extern bool r_showviewer;
|
||||
|
||||
DWORD gl_fixedcolormap;
|
||||
area_t in_area;
|
||||
|
@ -501,16 +502,29 @@ void FGLRenderer::RenderTranslucent()
|
|||
//-----------------------------------------------------------------------------
|
||||
EXTERN_CVAR(Bool, gl_draw_sync)
|
||||
|
||||
void FGLRenderer::DrawScene(bool toscreen)
|
||||
void FGLRenderer::DrawScene(int drawmode)
|
||||
{
|
||||
static int recursion=0;
|
||||
|
||||
CreateScene();
|
||||
if (camera != nullptr)
|
||||
{
|
||||
ActorRenderFlags savedflags = camera->renderflags;
|
||||
if (drawmode != DM_PORTAL && !r_showviewer)
|
||||
{
|
||||
camera->renderflags |= RF_INVISIBLE;
|
||||
}
|
||||
CreateScene();
|
||||
camera->renderflags = savedflags;
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateScene();
|
||||
}
|
||||
GLRenderer->mClipPortal = NULL; // this must be reset before any portal recursion takes place.
|
||||
|
||||
// Up to this point in the main draw call no rendering is performed so we can wait
|
||||
// with swapping the render buffer until now.
|
||||
if (!gl_draw_sync && toscreen)
|
||||
if (!gl_draw_sync && drawmode == DM_MAINVIEW)
|
||||
{
|
||||
All.Unclock();
|
||||
static_cast<OpenGLFrameBuffer*>(screen)->Swap();
|
||||
|
@ -734,7 +748,7 @@ void FGLRenderer::ProcessScene(bool toscreen)
|
|||
int mapsection = R_PointInSubsector(ViewPos)->mapsection;
|
||||
memset(¤tmapsection[0], 0, currentmapsection.Size());
|
||||
currentmapsection[mapsection>>3] |= 1 << (mapsection & 7);
|
||||
DrawScene(toscreen);
|
||||
DrawScene(toscreen ? DM_MAINVIEW : DM_OFFSCREEN);
|
||||
FDrawInfo::EndDrawInfo();
|
||||
|
||||
}
|
||||
|
|
|
@ -81,7 +81,6 @@ CUSTOM_CVAR(Int, gl_fuzztype, 0, CVAR_ARCHIVE)
|
|||
if (self < 0 || self > 7) self = 0;
|
||||
}
|
||||
|
||||
extern bool r_showviewer;
|
||||
EXTERN_CVAR (Float, transsouls)
|
||||
|
||||
extern TArray<spritedef_t> sprites;
|
||||
|
@ -239,7 +238,9 @@ void GLSprite::Draw(int pass)
|
|||
secplane_t *topplane = i == 0 ? &topp : &(*lightlist)[i].plane;
|
||||
secplane_t *lowplane = i == (*lightlist).Size() - 1 ? &bottomp : &(*lightlist)[i + 1].plane;
|
||||
|
||||
int thisll = (*lightlist)[i].caster != NULL ? gl_ClampLight(*(*lightlist)[i].p_lightlevel) : lightlevel;
|
||||
int thislight = (*lightlist)[i].caster != NULL ? gl_ClampLight(*(*lightlist)[i].p_lightlevel) : lightlevel;
|
||||
int thisll = actor == nullptr? thislight : (uint8_t)gl_CheckSpriteGlow(actor->Sector, thislight, actor->InterpolatedPosition(r_TicFracF));
|
||||
|
||||
FColormap thiscm;
|
||||
thiscm.FadeColor = Colormap.FadeColor;
|
||||
thiscm.CopyFrom3DLight(&(*lightlist)[i]);
|
||||
|
@ -249,6 +250,10 @@ void GLSprite::Draw(int pass)
|
|||
}
|
||||
|
||||
gl_SetColor(thisll, rel, thiscm, trans);
|
||||
if (!foglayer)
|
||||
{
|
||||
gl_SetFog(thislight, rel, &thiscm, additivefog);
|
||||
}
|
||||
gl_RenderState.SetSplitPlanes(*topplane, *lowplane);
|
||||
}
|
||||
else if (clipping)
|
||||
|
@ -264,7 +269,8 @@ void GLSprite::Draw(int pass)
|
|||
&& (gl_billboard_mode == 1 || (actor && actor->renderflags & RF_FORCEXYBILLBOARD))));
|
||||
|
||||
const bool drawBillboardFacingCamera = gl_billboard_faces_camera;
|
||||
|
||||
// [Nash] has +ROLLSPRITE
|
||||
const bool drawRollSpriteActor = (actor != NULL && actor->renderflags & RF_ROLLSPRITE);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
FVector3 v1;
|
||||
|
@ -272,7 +278,16 @@ void GLSprite::Draw(int pass)
|
|||
FVector3 v3;
|
||||
FVector3 v4;
|
||||
|
||||
if (drawWithXYBillboard || drawBillboardFacingCamera)
|
||||
// [fgsfds] check sprite type mask
|
||||
DWORD spritetype = (DWORD)-1;
|
||||
if (actor != NULL) spritetype = actor->renderflags & RF_SPRITETYPEMASK;
|
||||
|
||||
// [Nash] is a flat sprite
|
||||
const bool isFlatSprite = (actor != NULL) && (spritetype == RF_WALLSPRITE || spritetype == RF_FLATSPRITE);
|
||||
const bool dontFlip = (actor != nullptr) && (actor->renderflags & RF_DONTFLIP);
|
||||
|
||||
// [Nash] check for special sprite drawing modes
|
||||
if (drawWithXYBillboard || drawBillboardFacingCamera || drawRollSpriteActor || isFlatSprite)
|
||||
{
|
||||
// Compute center of sprite
|
||||
float xcenter = (x1 + x2)*0.5;
|
||||
|
@ -284,7 +299,8 @@ void GLSprite::Draw(int pass)
|
|||
mat.Translate(xcenter, zcenter, ycenter); // move to sprite center
|
||||
|
||||
// Order of rotations matters. Perform yaw rotation (Y, face camera) before pitch (X, tilt up/down).
|
||||
if (drawBillboardFacingCamera) {
|
||||
if (drawBillboardFacingCamera)
|
||||
{
|
||||
// [CMB] Rotate relative to camera XY position, not just camera direction,
|
||||
// which is nicer in VR
|
||||
float xrel = xcenter - ViewPos.X;
|
||||
|
@ -296,13 +312,62 @@ void GLSprite::Draw(int pass)
|
|||
mat.Rotate(0, 1, 0, relAngleDeg);
|
||||
}
|
||||
|
||||
if (drawWithXYBillboard)
|
||||
// [fgsfds] calculate yaw vectors
|
||||
float yawvecX = 0, yawvecY = 0, rollDegrees = 0;
|
||||
float angleRad = (270. - GLRenderer->mAngles.Yaw).Radians();
|
||||
if (actor) rollDegrees = actor->Angles.Roll.Degrees;
|
||||
if (isFlatSprite)
|
||||
{
|
||||
yawvecX = actor->Angles.Yaw.Cos();
|
||||
yawvecY = actor->Angles.Yaw.Sin();
|
||||
}
|
||||
|
||||
// [MC] This is the only thing that I changed in Nash's submission which
|
||||
// was constantly applying roll to everything. That was wrong. Flat sprites
|
||||
// with roll literally look like paper thing space ships trying to swerve.
|
||||
// However, it does well with wall sprites.
|
||||
// Also, renamed FLOORSPRITE to FLATSPRITE because that's technically incorrect.
|
||||
// I plan on adding proper FLOORSPRITEs which can actually curve along sloped
|
||||
// 3D floors later... if possible.
|
||||
|
||||
// Here we need some form of priority in order to work.
|
||||
if (spritetype == RF_FLATSPRITE)
|
||||
{
|
||||
DVector3 diff = actor->Vec3To(GLRenderer->mViewActor);
|
||||
DAngle angto = diff.Angle();
|
||||
angto = deltaangle(actor->Angles.Yaw, angto);
|
||||
|
||||
float pitchDegrees = actor->Angles.Pitch.Degrees;
|
||||
bool noFlipSprite = (!dontFlip || (fabs(angto) < 90.));
|
||||
mat.Rotate(0, 1, 0, (noFlipSprite) ? 0 : 180);
|
||||
mat.Rotate(-yawvecY, 0, yawvecX, (noFlipSprite) ? -pitchDegrees : pitchDegrees);
|
||||
if (drawRollSpriteActor)
|
||||
{
|
||||
mat.Rotate(yawvecX, 0, yawvecY, (noFlipSprite) ? -rollDegrees : rollDegrees);
|
||||
}
|
||||
}
|
||||
// [fgsfds] Rotate the sprite about the sight vector (roll)
|
||||
else if (spritetype == RF_WALLSPRITE)
|
||||
{
|
||||
mat.Rotate(0, 1, 0, 0);
|
||||
if (drawRollSpriteActor)
|
||||
mat.Rotate(yawvecX, 0, yawvecY, rollDegrees);
|
||||
}
|
||||
else if (drawRollSpriteActor)
|
||||
{
|
||||
if (drawWithXYBillboard)
|
||||
{
|
||||
mat.Rotate(-sin(angleRad), 0, cos(angleRad), -GLRenderer->mAngles.Pitch.Degrees);
|
||||
}
|
||||
mat.Rotate(cos(angleRad), 0, sin(angleRad), rollDegrees);
|
||||
}
|
||||
|
||||
// apply the transform
|
||||
else if (drawWithXYBillboard)
|
||||
{
|
||||
// Rotate the sprite about the vector starting at the center of the sprite
|
||||
// triangle strip and with direction orthogonal to where the player is looking
|
||||
// in the x/y plane.
|
||||
float angleRad = (270. - GLRenderer->mAngles.Yaw).Radians();
|
||||
|
||||
mat.Rotate(-sin(angleRad), 0, cos(angleRad), -GLRenderer->mAngles.Pitch.Degrees);
|
||||
}
|
||||
mat.Translate(-xcenter, -zcenter, -ycenter); // retreat from sprite center
|
||||
|
@ -546,8 +611,6 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
|
|||
{
|
||||
sector_t rs;
|
||||
sector_t * rendersector;
|
||||
// don't draw the thing that's used as camera (for viewshifts during quakes!)
|
||||
if (thing == GLRenderer->mViewActor || (thing == players[consoleplayer].camera && !r_showviewer)) return;
|
||||
|
||||
// Don't waste time projecting sprites that are definitely not visible.
|
||||
if (thing == NULL || thing->sprite == 0 || !thing->IsVisibleToPlayer())
|
||||
|
@ -555,6 +618,12 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
|
|||
return;
|
||||
}
|
||||
|
||||
if (thing->renderflags & RF_INVISIBLE || !thing->RenderStyle.IsVisible(thing->Alpha))
|
||||
{
|
||||
if (!(thing->flags & MF_STEALTH) || !gl_fixedcolormap || !gl_enhanced_nightvision || thing == camera)
|
||||
return;
|
||||
}
|
||||
|
||||
int spritenum = thing->sprite;
|
||||
DVector2 sprscale = thing->Scale;
|
||||
if (thing->player != NULL)
|
||||
|
@ -562,12 +631,6 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
|
|||
P_CheckPlayerSprite(thing, spritenum, sprscale);
|
||||
}
|
||||
|
||||
if (thing->renderflags & RF_INVISIBLE || !thing->RenderStyle.IsVisible(thing->Alpha))
|
||||
{
|
||||
if (!(thing->flags & MF_STEALTH) || !gl_fixedcolormap || !gl_enhanced_nightvision)
|
||||
return;
|
||||
}
|
||||
|
||||
// If this thing is in a map section that's not in view it can't possibly be visible
|
||||
if (!thruportal && !(currentmapsection[thing->subsector->mapsection >> 3] & (1 << (thing->subsector->mapsection & 7)))) return;
|
||||
|
||||
|
@ -626,9 +689,11 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
|
|||
topclip = rendersector->PortalBlocksMovement(sector_t::ceiling) ? LARGE_VALUE : rendersector->GetPortalPlaneZ(sector_t::ceiling);
|
||||
bottomclip = rendersector->PortalBlocksMovement(sector_t::floor) ? -LARGE_VALUE : rendersector->GetPortalPlaneZ(sector_t::floor);
|
||||
|
||||
DWORD spritetype = (thing->renderflags & RF_SPRITETYPEMASK);
|
||||
x = thingpos.X;
|
||||
z = thingpos.Z - thing->Floorclip;
|
||||
z = thingpos.Z;
|
||||
y = thingpos.Y;
|
||||
if (spritetype == RF_FLATSPRITE) z -= thing->Floorclip;
|
||||
|
||||
// [RH] Make floatbobbing a renderer-only effect.
|
||||
if (thing->flags2 & MF2_FLOATBOB)
|
||||
|
@ -636,7 +701,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
|
|||
float fz = thing->GetBobOffset(r_TicFracF);
|
||||
z += fz;
|
||||
}
|
||||
|
||||
|
||||
modelframe = gl_FindModelFrame(thing->GetClass(), spritenum, thing->frame, !!(thing->flags & MF_DROPPED));
|
||||
if (!modelframe)
|
||||
{
|
||||
|
@ -681,7 +746,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
|
|||
|
||||
float viewvecX;
|
||||
float viewvecY;
|
||||
switch (thing->renderflags & RF_SPRITETYPEMASK)
|
||||
switch (spritetype)
|
||||
{
|
||||
case RF_FACESPRITE:
|
||||
viewvecX = GLRenderer->mViewVector.X;
|
||||
|
@ -693,6 +758,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal)
|
|||
y2 = y + viewvecX*rightfac;
|
||||
break;
|
||||
|
||||
case RF_FLATSPRITE:
|
||||
case RF_WALLSPRITE:
|
||||
viewvecX = thing->Angles.Yaw.Cos();
|
||||
viewvecY = thing->Angles.Yaw.Sin();
|
||||
|
@ -930,7 +996,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
|
|||
|
||||
lightlevel = gl_ClampLight(sector->GetTexture(sector_t::ceiling) == skyflatnum ?
|
||||
sector->GetCeilingLight() : sector->GetFloorLight());
|
||||
foglevel = sector->lightlevel;
|
||||
foglevel = (BYTE)clamp<short>(sector->lightlevel, 0, 255);
|
||||
|
||||
if (gl_fixedcolormap)
|
||||
{
|
||||
|
|
|
@ -272,7 +272,7 @@ void GLWall::SplitWallComplex(sector_t * frontsector, bool translucent, float ma
|
|||
if ((maplightbottomleft<ztop[0] && maplightbottomright>ztop[1]) ||
|
||||
(maplightbottomleft>ztop[0] && maplightbottomright<ztop[1]))
|
||||
{
|
||||
float clen = MAX<float>(fabsf(glseg.x2 - glseg.x1), fabsf(glseg.y2 - glseg.y2));
|
||||
float clen = MAX<float>(fabsf(glseg.x2 - glseg.x1), fabsf(glseg.y2 - glseg.y1));
|
||||
|
||||
float dch = ztop[1] - ztop[0];
|
||||
float dfh = maplightbottomright - maplightbottomleft;
|
||||
|
@ -312,7 +312,7 @@ void GLWall::SplitWallComplex(sector_t * frontsector, bool translucent, float ma
|
|||
if ((maplightbottomleft<zbottom[0] && maplightbottomright>zbottom[1]) ||
|
||||
(maplightbottomleft>zbottom[0] && maplightbottomright<zbottom[1]))
|
||||
{
|
||||
float clen = MAX<float>(fabsf(glseg.x2 - glseg.x1), fabsf(glseg.y2 - glseg.y2));
|
||||
float clen = MAX<float>(fabsf(glseg.x2 - glseg.x1), fabsf(glseg.y2 - glseg.y1));
|
||||
|
||||
float dch = zbottom[1] - zbottom[0];
|
||||
float dfh = maplightbottomright - maplightbottomleft;
|
||||
|
@ -395,25 +395,25 @@ void GLWall::SplitWall(sector_t * frontsector, bool translucent)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (gl.glslversion >= 1.3f)
|
||||
// check for an intersection with the upper and lower planes of the wall segment
|
||||
if ((maplightbottomleft<ztop[0] && maplightbottomright>ztop[1]) ||
|
||||
(maplightbottomleft > ztop[0] && maplightbottomright < ztop[1]) ||
|
||||
(maplightbottomleft<zbottom[0] && maplightbottomright>zbottom[1]) ||
|
||||
(maplightbottomleft > zbottom[0] && maplightbottomright < zbottom[1]))
|
||||
{
|
||||
// check for an intersection with the upper and lower planes of the wall segment
|
||||
if ((maplightbottomleft<ztop[0] && maplightbottomright>ztop[1]) ||
|
||||
(maplightbottomleft > ztop[0] && maplightbottomright < ztop[1]) ||
|
||||
(maplightbottomleft<zbottom[0] && maplightbottomright>zbottom[1]) ||
|
||||
(maplightbottomleft > zbottom[0] && maplightbottomright < zbottom[1]))
|
||||
if (gl.glslversion >= 1.3f)
|
||||
{
|
||||
// Use hardware clipping if this cannot be done cleanly.
|
||||
this->lightlist = &lightlist;
|
||||
PutWall(translucent);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// crappy fallback if no clip planes available
|
||||
SplitWallComplex(frontsector, translucent, maplightbottomleft, maplightbottomright);
|
||||
return;
|
||||
else
|
||||
{
|
||||
// crappy fallback if no clip planes available
|
||||
SplitWallComplex(frontsector, translucent, maplightbottomleft, maplightbottomright);
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
// 3D floor is completely within this light
|
||||
|
|
|
@ -71,7 +71,7 @@ EXTERN_CVAR (Bool, r_deathcamera)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp, float sx, float sy, bool hudModelStep, int OverrideShader, bool alphatexture)
|
||||
void FGLRenderer::DrawPSprite (player_t * player,DPSprite *psp, float sx, float sy, bool hudModelStep, int OverrideShader, bool alphatexture)
|
||||
{
|
||||
float fU1,fV1;
|
||||
float fU2,fV2;
|
||||
|
@ -86,13 +86,13 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp, float sx, float
|
|||
// [BB] In the HUD model step we just render the model and break out.
|
||||
if ( hudModelStep )
|
||||
{
|
||||
gl_RenderHUDModel( psp, sx, sy);
|
||||
gl_RenderHUDModel(psp, sx, sy);
|
||||
return;
|
||||
}
|
||||
|
||||
// decide which patch to use
|
||||
bool mirror;
|
||||
FTextureID lump = gl_GetSpriteFrame(psp->sprite, psp->frame, 0, 0, &mirror);
|
||||
FTextureID lump = gl_GetSpriteFrame(psp->GetSprite(), psp->GetFrame(), 0, 0, &mirror);
|
||||
if (!lump.isValid()) return;
|
||||
|
||||
FMaterial * tex = FMaterial::ValidateTexture(lump, true, false);
|
||||
|
@ -174,6 +174,29 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp, float sx, float
|
|||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static bool isBright(DPSprite *psp)
|
||||
{
|
||||
if (psp != nullptr && psp->GetState() != nullptr)
|
||||
{
|
||||
bool disablefullbright = false;
|
||||
FTextureID lump = gl_GetSpriteFrame(psp->GetSprite(), psp->GetFrame(), 0, 0, NULL);
|
||||
if (lump.isValid())
|
||||
{
|
||||
FMaterial * tex = FMaterial::ValidateTexture(lump, false, false);
|
||||
if (tex)
|
||||
disablefullbright = tex->tex->gl_info.bDisableFullbright;
|
||||
}
|
||||
return psp->GetState()->GetFullbright() && !disablefullbright;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_DrawPlayerSprites
|
||||
|
@ -184,11 +207,9 @@ EXTERN_CVAR(Bool, gl_brightfog)
|
|||
|
||||
void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
||||
{
|
||||
bool statebright[2] = {false, false};
|
||||
bool brightflash = false;
|
||||
unsigned int i;
|
||||
pspdef_t *psp;
|
||||
int lightlevel=0;
|
||||
float ofsx, ofsy;
|
||||
FColormap cm;
|
||||
sector_t * fakesec, fs;
|
||||
AActor * playermo=players[consoleplayer].camera;
|
||||
|
@ -202,33 +223,35 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
(r_deathcamera && camera->health <= 0))
|
||||
return;
|
||||
|
||||
P_BobWeapon (player, &player->psprites[ps_weapon], &ofsx, &ofsy, r_TicFracF);
|
||||
float bobx, boby, wx, wy;
|
||||
DPSprite *weapon;
|
||||
|
||||
// check for fullbright
|
||||
if (player->fixedcolormap==NOFIXEDCOLORMAP)
|
||||
P_BobWeapon(camera->player, &bobx, &boby, r_TicFracF);
|
||||
|
||||
// Interpolate the main weapon layer once so as to be able to add it to other layers.
|
||||
if ((weapon = camera->player->FindPSprite(PSP_WEAPON)) != nullptr)
|
||||
{
|
||||
for (i = 0, psp = player->psprites; i <= ps_flash; i++, psp++)
|
||||
if (weapon->firstTic)
|
||||
{
|
||||
if (psp->state != NULL)
|
||||
{
|
||||
bool disablefullbright = false;
|
||||
FTextureID lump = gl_GetSpriteFrame(psp->sprite, psp->frame, 0, 0, NULL);
|
||||
if (lump.isValid())
|
||||
{
|
||||
FMaterial * tex=FMaterial::ValidateTexture(lump, false, false);
|
||||
if (tex)
|
||||
disablefullbright = tex->tex->gl_info.bDisableFullbright;
|
||||
}
|
||||
statebright[i] = !!psp->state->GetFullbright() && !disablefullbright;
|
||||
}
|
||||
wx = weapon->x;
|
||||
wy = weapon->y;
|
||||
}
|
||||
else
|
||||
{
|
||||
wx = weapon->oldx + (weapon->x - weapon->oldx) * r_TicFracF;
|
||||
wy = weapon->oldy + (weapon->y - weapon->oldy) * r_TicFracF;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wx = 0;
|
||||
wy = 0;
|
||||
}
|
||||
|
||||
if (gl_fixedcolormap)
|
||||
{
|
||||
lightlevel=255;
|
||||
cm.Clear();
|
||||
statebright[0] = statebright[1] = true;
|
||||
fakesec = viewsector;
|
||||
}
|
||||
else
|
||||
|
@ -237,20 +260,6 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
|
||||
// calculate light level for weapon sprites
|
||||
lightlevel = gl_ClampLight(fakesec->lightlevel);
|
||||
if (glset.lightmode == 8)
|
||||
{
|
||||
lightlevel = gl_CalcLightLevel(lightlevel, getExtraLight(), true);
|
||||
|
||||
// Korshun: the way based on max possible light level for sector like in software renderer.
|
||||
float min_L = 36.0/31.0 - ((lightlevel/255.0) * (63.0/31.0)); // Lightlevel in range 0-63
|
||||
if (min_L < 0)
|
||||
min_L = 0;
|
||||
else if (min_L > 1.0)
|
||||
min_L = 1.0;
|
||||
|
||||
lightlevel = (1.0 - min_L) * 255;
|
||||
}
|
||||
lightlevel = gl_CheckSpriteGlow(viewsector, lightlevel, playermo->Pos());
|
||||
|
||||
// calculate colormap for weapon sprites
|
||||
if (viewsector->e->XFloor.ffloors.Size() && !glset.nocoloredspritelighting)
|
||||
|
@ -282,8 +291,27 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
cm=fakesec->ColorMap;
|
||||
if (glset.nocoloredspritelighting) cm.ClearColor();
|
||||
}
|
||||
}
|
||||
|
||||
lightlevel = gl_CalcLightLevel(lightlevel, getExtraLight(), true);
|
||||
|
||||
if (glset.lightmode == 8)
|
||||
{
|
||||
// Korshun: the way based on max possible light level for sector like in software renderer.
|
||||
float min_L = 36.0 / 31.0 - ((lightlevel / 255.0) * (63.0 / 31.0)); // Lightlevel in range 0-63
|
||||
if (min_L < 0)
|
||||
min_L = 0;
|
||||
else if (min_L > 1.0)
|
||||
min_L = 1.0;
|
||||
|
||||
lightlevel = (1.0 - min_L) * 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
lightlevel = (2 * lightlevel + 255) / 3;
|
||||
}
|
||||
lightlevel = gl_CheckSpriteGlow(viewsector, lightlevel, playermo->Pos());
|
||||
|
||||
}
|
||||
|
||||
// Korshun: fullbright fog in opengl, render weapon sprites fullbright (but don't cancel out the light color!)
|
||||
if (glset.brightfog && ((level.flags&LEVEL_HASFADETABLE) || cm.FadeColor != 0))
|
||||
|
@ -332,7 +360,6 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
vis.RenderStyle.BlendOp = STYLEOP_Shadow;
|
||||
}
|
||||
}
|
||||
statebright[0] = statebright[1] = false;
|
||||
}
|
||||
|
||||
gl_SetRenderStyle(vis.RenderStyle, false, false);
|
||||
|
@ -356,24 +383,19 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold);
|
||||
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
||||
if (statebright[0] || statebright[1])
|
||||
{
|
||||
// brighten the weapon to reduce the difference between
|
||||
// normal sprite and fullbright flash.
|
||||
if (glset.lightmode != 8) lightlevel = (2*lightlevel+255)/3;
|
||||
}
|
||||
|
||||
|
||||
// hack alert! Rather than changing everything in the underlying lighting code let's just temporarily change
|
||||
// light mode here to draw the weapon sprite.
|
||||
int oldlightmode = glset.lightmode;
|
||||
if (glset.lightmode == 8) glset.lightmode = 2;
|
||||
|
||||
for (i=0, psp=player->psprites; i<=ps_flash; i++,psp++)
|
||||
|
||||
for(DPSprite *psp = player->psprites; psp != nullptr && psp->GetID() < PSP_TARGETCENTER; psp = psp->GetNext())
|
||||
{
|
||||
if (psp->state)
|
||||
if (psp->GetState() != nullptr)
|
||||
{
|
||||
FColormap cmc = cm;
|
||||
if (statebright[i])
|
||||
int ll = lightlevel;
|
||||
if (isBright(psp))
|
||||
{
|
||||
if (fakesec == viewsector || in_area != area_below)
|
||||
{
|
||||
|
@ -388,6 +410,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
cmc.LightColor.g = (3*cmc.LightColor.g + 0xff)/4;
|
||||
cmc.LightColor.b = (3*cmc.LightColor.b + 0xff)/4;
|
||||
}
|
||||
ll = 255;
|
||||
}
|
||||
// set the lighting parameters
|
||||
if (vis.RenderStyle.BlendOp == STYLEOP_Shadow)
|
||||
|
@ -400,9 +423,33 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
{
|
||||
gl_SetDynSpriteLight(playermo, NULL);
|
||||
}
|
||||
gl_SetColor(statebright[i] ? 255 : lightlevel, 0, cmc, trans, true);
|
||||
gl_SetColor(ll, 0, cmc, trans, true);
|
||||
}
|
||||
DrawPSprite(player, psp, psp->sx + ofsx, psp->sy + ofsy, hudModelStep, OverrideShader, !!(vis.RenderStyle.Flags & STYLEF_RedIsAlpha));
|
||||
|
||||
if (psp->firstTic)
|
||||
{ // Can't interpolate the first tic.
|
||||
psp->firstTic = false;
|
||||
psp->oldx = psp->x;
|
||||
psp->oldy = psp->y;
|
||||
}
|
||||
|
||||
float sx = psp->oldx + (psp->x - psp->oldx) * r_TicFracF;
|
||||
float sy = psp->oldy + (psp->y - psp->oldy) * r_TicFracF;
|
||||
|
||||
if (psp->Flags & PSPF_ADDBOB)
|
||||
{
|
||||
sx += bobx;
|
||||
sy += boby;
|
||||
}
|
||||
|
||||
if (psp->Flags & PSPF_ADDWEAPON && psp->GetID() != PSP_WEAPON)
|
||||
{
|
||||
sx += wx;
|
||||
sy += wy;
|
||||
}
|
||||
|
||||
|
||||
DrawPSprite(player, psp, sx, sy, hudModelStep, OverrideShader, !!(vis.RenderStyle.Flags & STYLEF_RedIsAlpha));
|
||||
}
|
||||
}
|
||||
gl_RenderState.SetObjectColor(0xffffffff);
|
||||
|
@ -419,8 +466,6 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
|
||||
void FGLRenderer::DrawTargeterSprites()
|
||||
{
|
||||
int i;
|
||||
pspdef_t *psp;
|
||||
AActor * playermo=players[consoleplayer].camera;
|
||||
player_t * player=playermo->player;
|
||||
|
||||
|
@ -435,6 +480,8 @@ void FGLRenderer::DrawTargeterSprites()
|
|||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
|
||||
// The Targeter's sprites are always drawn normally.
|
||||
for (i=ps_targetcenter, psp = &player->psprites[ps_targetcenter]; i<NUMPSPRITES; i++,psp++)
|
||||
if (psp->state) DrawPSprite (player,psp,psp->sx, psp->sy, false, 0, false);
|
||||
for (DPSprite *psp = player->FindPSprite(PSP_TARGETCENTER); psp != nullptr; psp = psp->GetNext())
|
||||
{
|
||||
if (psp->GetState() != nullptr) DrawPSprite(player, psp, psp->x, psp->y, false, 0, false);
|
||||
}
|
||||
}
|
|
@ -69,14 +69,14 @@ void FState::SetAction(const char *name)
|
|||
ActionFunc = FindGlobalActionFunction(name)->Variants[0].Implementation;
|
||||
}
|
||||
|
||||
bool FState::CallAction(AActor *self, AActor *stateowner, FState **stateret)
|
||||
bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, FState **stateret)
|
||||
{
|
||||
if (ActionFunc != NULL)
|
||||
{
|
||||
ActionCycles.Clock();
|
||||
|
||||
static VMFrameStack stack;
|
||||
VMValue params[3] = { self, stateowner, VMValue(this, ATAG_STATE) };
|
||||
VMValue params[3] = { self, stateowner, VMValue(info, ATAG_STATEINFO) };
|
||||
// If the function returns a state, store it at *stateret.
|
||||
// If it doesn't return a state but stateret is non-NULL, we need
|
||||
// to set *stateret to NULL.
|
||||
|
|
19
src/info.h
19
src/info.h
|
@ -55,6 +55,21 @@ struct FActorInfo;
|
|||
class FArchive;
|
||||
class FIntCVar;
|
||||
|
||||
enum EStateType
|
||||
{
|
||||
STATE_Actor,
|
||||
STATE_Psprite,
|
||||
STATE_StateChain,
|
||||
};
|
||||
|
||||
struct FStateParamInfo
|
||||
{
|
||||
FState *mCallingState;
|
||||
EStateType mStateType;
|
||||
int mPSPIndex;
|
||||
};
|
||||
|
||||
|
||||
// Sprites that are fixed in position because they can have special meanings.
|
||||
enum
|
||||
{
|
||||
|
@ -129,7 +144,7 @@ struct FState
|
|||
void SetAction(VMFunction *func) { ActionFunc = func; }
|
||||
void ClearAction() { ActionFunc = NULL; }
|
||||
void SetAction(const char *name);
|
||||
bool CallAction(AActor *self, AActor *stateowner, FState **stateret);
|
||||
bool CallAction(AActor *self, AActor *stateowner, FStateParamInfo *stateinfo, FState **stateret);
|
||||
static PClassActor *StaticFindStateOwner (const FState *state);
|
||||
static PClassActor *StaticFindStateOwner (const FState *state, PClassActor *info);
|
||||
static FRandom pr_statetics;
|
||||
|
@ -338,7 +353,7 @@ void AddStateLight(FState *state, const char *lname);
|
|||
PARAM_PROLOGUE; \
|
||||
PARAM_OBJECT (self, type); \
|
||||
PARAM_OBJECT_OPT (stateowner, AActor) { stateowner = self; } \
|
||||
PARAM_STATE_OPT (callingstate) { callingstate = NULL; } \
|
||||
PARAM_STATEINFO_OPT (stateinfo) { stateinfo = nullptr; } \
|
||||
|
||||
#define PARAM_ACTION_PROLOGUE PARAM_ACTION_PROLOGUE_TYPE(AActor)
|
||||
|
||||
|
|
|
@ -315,7 +315,7 @@ void cht_DoCheat (player_t *player, int cheat)
|
|||
|
||||
// [GRB]
|
||||
case CHT_RESSURECT:
|
||||
if (player->playerstate != PST_LIVE && player->mo != NULL)
|
||||
if (player->playerstate != PST_LIVE && player->mo != nullptr)
|
||||
{
|
||||
if (player->mo->IsKindOf(RUNTIME_CLASS(APlayerChunk)))
|
||||
{
|
||||
|
@ -344,9 +344,9 @@ void cht_DoCheat (player_t *player, int cheat)
|
|||
player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players));
|
||||
}
|
||||
player->mo->DamageType = NAME_None;
|
||||
if (player->ReadyWeapon != NULL)
|
||||
if (player->ReadyWeapon != nullptr)
|
||||
{
|
||||
P_SetPsprite(player, ps_weapon, player->ReadyWeapon->GetUpState());
|
||||
P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetUpState());
|
||||
}
|
||||
|
||||
if (player->morphTics > 0)
|
||||
|
@ -933,10 +933,8 @@ void cht_Take (player_t *player, const char *name, int amount)
|
|||
if (weapon)
|
||||
weapon->Destroy ();
|
||||
|
||||
player->ReadyWeapon = NULL;
|
||||
player->ReadyWeapon = nullptr;
|
||||
player->PendingWeapon = WP_NOCHANGE;
|
||||
player->psprites[ps_weapon].state = NULL;
|
||||
player->psprites[ps_flash].state = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -302,7 +302,15 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
|
|||
int y = sc.Number;
|
||||
sc.MustGetStringName(",");
|
||||
sc.MustGetString();
|
||||
FListMenuItem *it = new FListMenuItemStaticText(x, y, sc.String, desc->mFont, desc->mFontColor, centered);
|
||||
FString label = sc.String;
|
||||
EColorRange cr = desc->mFontColor;
|
||||
if (sc.CheckString(","))
|
||||
{
|
||||
sc.MustGetString();
|
||||
cr = V_FindFontColor(sc.String);
|
||||
if (cr == CR_UNTRANSLATED && !sc.Compare("untranslated")) cr = desc->mFontColor;
|
||||
}
|
||||
FListMenuItem *it = new FListMenuItemStaticText(x, y, label, desc->mFont, cr, centered);
|
||||
desc->mItems.Push(it);
|
||||
}
|
||||
else if (sc.Compare("PatchItem"))
|
||||
|
@ -644,6 +652,21 @@ static void ParseOptionSettings(FScanner &sc)
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
static EColorRange ParseOptionColor(FScanner &sc, FOptionMenuDescriptor *desc)
|
||||
{
|
||||
EColorRange cr = OptionSettings.mFontColor;
|
||||
if (sc.CheckString(","))
|
||||
{
|
||||
sc.MustGetString();
|
||||
EColorRange cr = V_FindFontColor(sc.String);
|
||||
if (cr == CR_UNTRANSLATED && !sc.Compare("untranslated") && isdigit(sc.String[0]))
|
||||
{
|
||||
if (strtol(sc.String, NULL, 0)) cr = OptionSettings.mFontColorHeader;
|
||||
}
|
||||
}
|
||||
return cr;
|
||||
}
|
||||
|
||||
static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc)
|
||||
{
|
||||
sc.MustGetStringName("{");
|
||||
|
@ -780,12 +803,7 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc)
|
|||
{
|
||||
sc.MustGetString();
|
||||
FString label = sc.String;
|
||||
bool cr = false;
|
||||
if (sc.CheckString(","))
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
cr = !!sc.Number;
|
||||
}
|
||||
EColorRange cr = ParseOptionColor(sc, desc);
|
||||
FOptionMenuItem *it = new FOptionMenuItemStaticText(label, cr);
|
||||
desc->mItems.Push(it);
|
||||
}
|
||||
|
@ -799,12 +817,7 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc)
|
|||
sc.MustGetStringName(",");
|
||||
sc.MustGetString();
|
||||
FName action = sc.String;
|
||||
bool cr = false;
|
||||
if (sc.CheckString(","))
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
cr = !!sc.Number;
|
||||
}
|
||||
EColorRange cr = ParseOptionColor(sc, desc);
|
||||
FOptionMenuItem *it = new FOptionMenuItemStaticTextSwitchable(label, label2, action, cr);
|
||||
desc->mItems.Push(it);
|
||||
}
|
||||
|
|
|
@ -483,7 +483,13 @@ public:
|
|||
FOptionMenuItemStaticText(const char *label, bool header)
|
||||
: FOptionMenuItem(label, NAME_None, true)
|
||||
{
|
||||
mColor = header? OptionSettings.mFontColorHeader : OptionSettings.mFontColor;
|
||||
mColor = header ? OptionSettings.mFontColorHeader : OptionSettings.mFontColor;
|
||||
}
|
||||
|
||||
FOptionMenuItemStaticText(const char *label, EColorRange cr)
|
||||
: FOptionMenuItem(label, NAME_None, true)
|
||||
{
|
||||
mColor = cr;
|
||||
}
|
||||
|
||||
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected)
|
||||
|
@ -512,10 +518,10 @@ class FOptionMenuItemStaticTextSwitchable : public FOptionMenuItem
|
|||
int mCurrent;
|
||||
|
||||
public:
|
||||
FOptionMenuItemStaticTextSwitchable(const char *label, const char *label2, FName action, bool header)
|
||||
FOptionMenuItemStaticTextSwitchable(const char *label, const char *label2, FName action, EColorRange cr)
|
||||
: FOptionMenuItem(label, action, true)
|
||||
{
|
||||
mColor = header? OptionSettings.mFontColorHeader : OptionSettings.mFontColor;
|
||||
mColor = cr;
|
||||
mAltText = label2;
|
||||
mCurrent = 0;
|
||||
}
|
||||
|
|
127
src/p_acs.cpp
127
src/p_acs.cpp
|
@ -3968,6 +3968,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
|
|||
|
||||
case APROP_Friction:
|
||||
actor->Friction = ACSToDouble(value);
|
||||
break;
|
||||
|
||||
case APROP_MaxStepHeight:
|
||||
actor->MaxStepHeight = ACSToDouble(value);
|
||||
|
@ -4189,31 +4190,6 @@ bool DLevelScript::DoCheckActorTexture(int tid, AActor *activator, int string, b
|
|||
return tex == TexMan[secpic];
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
// These are the original inputs sent by the player.
|
||||
INPUT_OLDBUTTONS,
|
||||
INPUT_BUTTONS,
|
||||
INPUT_PITCH,
|
||||
INPUT_YAW,
|
||||
INPUT_ROLL,
|
||||
INPUT_FORWARDMOVE,
|
||||
INPUT_SIDEMOVE,
|
||||
INPUT_UPMOVE,
|
||||
|
||||
// These are the inputs, as modified by P_PlayerThink().
|
||||
// Most of the time, these will match the original inputs, but
|
||||
// they can be different if a player is frozen or using a
|
||||
// chainsaw.
|
||||
MODINPUT_OLDBUTTONS,
|
||||
MODINPUT_BUTTONS,
|
||||
MODINPUT_PITCH,
|
||||
MODINPUT_YAW,
|
||||
MODINPUT_ROLL,
|
||||
MODINPUT_FORWARDMOVE,
|
||||
MODINPUT_SIDEMOVE,
|
||||
MODINPUT_UPMOVE
|
||||
};
|
||||
|
||||
int DLevelScript::GetPlayerInput(int playernum, int inputnum)
|
||||
{
|
||||
|
@ -4240,28 +4216,7 @@ int DLevelScript::GetPlayerInput(int playernum, int inputnum)
|
|||
return 0;
|
||||
}
|
||||
|
||||
switch (inputnum)
|
||||
{
|
||||
case INPUT_OLDBUTTONS: return p->original_oldbuttons; break;
|
||||
case INPUT_BUTTONS: return p->original_cmd.buttons; break;
|
||||
case INPUT_PITCH: return p->original_cmd.pitch; break;
|
||||
case INPUT_YAW: return p->original_cmd.yaw; break;
|
||||
case INPUT_ROLL: return p->original_cmd.roll; break;
|
||||
case INPUT_FORWARDMOVE: return p->original_cmd.forwardmove; break;
|
||||
case INPUT_SIDEMOVE: return p->original_cmd.sidemove; break;
|
||||
case INPUT_UPMOVE: return p->original_cmd.upmove; break;
|
||||
|
||||
case MODINPUT_OLDBUTTONS: return p->oldbuttons; break;
|
||||
case MODINPUT_BUTTONS: return p->cmd.ucmd.buttons; break;
|
||||
case MODINPUT_PITCH: return p->cmd.ucmd.pitch; break;
|
||||
case MODINPUT_YAW: return p->cmd.ucmd.yaw; break;
|
||||
case MODINPUT_ROLL: return p->cmd.ucmd.roll; break;
|
||||
case MODINPUT_FORWARDMOVE: return p->cmd.ucmd.forwardmove; break;
|
||||
case MODINPUT_SIDEMOVE: return p->cmd.ucmd.sidemove; break;
|
||||
case MODINPUT_UPMOVE: return p->cmd.ucmd.upmove; break;
|
||||
|
||||
default: return 0; break;
|
||||
}
|
||||
return P_Thing_CheckInputNum(p, inputnum);
|
||||
}
|
||||
|
||||
enum
|
||||
|
@ -4656,7 +4611,11 @@ static int DoGetCVar(FBaseCVar *cvar, bool is_string)
|
|||
{
|
||||
UCVarValue val;
|
||||
|
||||
if (is_string)
|
||||
if (cvar == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (is_string)
|
||||
{
|
||||
val = cvar->GetGenericRep(CVAR_String);
|
||||
return GlobalACSStrings.AddString(val.String);
|
||||
|
@ -4673,44 +4632,6 @@ static int DoGetCVar(FBaseCVar *cvar, bool is_string)
|
|||
}
|
||||
}
|
||||
|
||||
static int GetUserCVar(int playernum, const char *cvarname, bool is_string)
|
||||
{
|
||||
if ((unsigned)playernum >= MAXPLAYERS || !playeringame[playernum])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
FBaseCVar **cvar_p = players[playernum].userinfo.CheckKey(FName(cvarname, true));
|
||||
FBaseCVar *cvar;
|
||||
if (cvar_p == NULL || (cvar = *cvar_p) == NULL || (cvar->GetFlags() & CVAR_IGNORE))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return DoGetCVar(cvar, is_string);
|
||||
}
|
||||
|
||||
static int GetCVar(AActor *activator, const char *cvarname, bool is_string)
|
||||
{
|
||||
FBaseCVar *cvar = FindCVar(cvarname, NULL);
|
||||
// Either the cvar doesn't exist, or it's for a mod that isn't loaded, so return 0.
|
||||
if (cvar == NULL || (cvar->GetFlags() & CVAR_IGNORE))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// For userinfo cvars, redirect to GetUserCVar
|
||||
if (cvar->GetFlags() & CVAR_USERINFO)
|
||||
{
|
||||
if (activator == NULL || activator->player == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return GetUserCVar(int(activator->player - players), cvarname, is_string);
|
||||
}
|
||||
return DoGetCVar(cvar, is_string);
|
||||
}
|
||||
}
|
||||
|
||||
static int SetUserCVar(int playernum, const char *cvarname, int value, bool is_string)
|
||||
{
|
||||
if ((unsigned)playernum >= MAXPLAYERS || !playeringame[playernum])
|
||||
|
@ -5395,7 +5316,7 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
|
|||
case ACSF_GetCVarString:
|
||||
if (argCount == 1)
|
||||
{
|
||||
return GetCVar(activator, FBehavior::StaticLookupString(args[0]), true);
|
||||
return DoGetCVar(GetCVar(activator, FBehavior::StaticLookupString(args[0])), true);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -5416,14 +5337,14 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args)
|
|||
case ACSF_GetUserCVar:
|
||||
if (argCount == 2)
|
||||
{
|
||||
return GetUserCVar(args[0], FBehavior::StaticLookupString(args[1]), false);
|
||||
return DoGetCVar(GetUserCVar(args[0], FBehavior::StaticLookupString(args[1])), false);
|
||||
}
|
||||
break;
|
||||
|
||||
case ACSF_GetUserCVarString:
|
||||
if (argCount == 2)
|
||||
{
|
||||
return GetUserCVar(args[0], FBehavior::StaticLookupString(args[1]), true);
|
||||
return DoGetCVar(GetUserCVar(args[0], FBehavior::StaticLookupString(args[1])), true);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -6047,7 +5968,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
PalEntry color = args[0];
|
||||
bool fullbright = argCount > 1 ? !!args[1] : false;
|
||||
int lifetime = argCount > 2 ? args[2] : 35;
|
||||
int size = argCount > 3 ? args[3] : 1;
|
||||
double size = argCount > 3 ? args[3] : 1.;
|
||||
int x = argCount > 4 ? args[4] : 0;
|
||||
int y = argCount > 5 ? args[5] : 0;
|
||||
int z = argCount > 6 ? args[6] : 0;
|
||||
|
@ -6059,17 +5980,18 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
int accelz = argCount > 12 ? args[12] : 0;
|
||||
int startalpha = argCount > 13 ? args[13] : 0xFF; // Byte trans
|
||||
int fadestep = argCount > 14 ? args[14] : -1;
|
||||
double endsize = argCount > 15 ? args[15] : -1.;
|
||||
|
||||
startalpha = clamp<int>(startalpha, 0, 255); // Clamp to byte
|
||||
lifetime = clamp<int>(lifetime, 0, 255); // Clamp to byte
|
||||
fadestep = clamp<int>(fadestep, -1, 255); // Clamp to byte inc. -1 (indicating automatic)
|
||||
size = clamp<int>(size, 0, 65535); // Clamp to word
|
||||
size = fabs(size);
|
||||
|
||||
if (lifetime != 0)
|
||||
P_SpawnParticle(DVector3(ACSToDouble(x), ACSToDouble(y), ACSToDouble(z)),
|
||||
DVector3(ACSToDouble(xvel), ACSToDouble(yvel), ACSToDouble(zvel)),
|
||||
DVector3(ACSToDouble(accelx), ACSToDouble(accely), ACSToDouble(accelz)),
|
||||
color, fullbright, startalpha/255., lifetime, size, fadestep/255.);
|
||||
color, startalpha/255., lifetime, size, endsize, fadestep/255., fullbright);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -8126,6 +8048,17 @@ scriptwait:
|
|||
break;
|
||||
|
||||
// [BC] Start ST PCD's
|
||||
case PCD_ISNETWORKGAME:
|
||||
PushToStack(netgame);
|
||||
break;
|
||||
|
||||
case PCD_PLAYERTEAM:
|
||||
if ( activator && activator->player )
|
||||
PushToStack( activator->player->userinfo.GetTeam() );
|
||||
else
|
||||
PushToStack( 0 );
|
||||
break;
|
||||
|
||||
case PCD_PLAYERHEALTH:
|
||||
if (activator)
|
||||
PushToStack (activator->health);
|
||||
|
@ -8162,7 +8095,7 @@ scriptwait:
|
|||
break;
|
||||
|
||||
case PCD_SINGLEPLAYER:
|
||||
PushToStack (!netgame);
|
||||
PushToStack (!multiplayer);
|
||||
break;
|
||||
// [BC] End ST PCD's
|
||||
|
||||
|
@ -9130,7 +9063,7 @@ scriptwait:
|
|||
break;
|
||||
|
||||
case PCD_GETCVAR:
|
||||
STACK(1) = GetCVar(activator, FBehavior::StaticLookupString(STACK(1)), false);
|
||||
STACK(1) = DoGetCVar(GetCVar(activator, FBehavior::StaticLookupString(STACK(1))), false);
|
||||
break;
|
||||
|
||||
case PCD_SETHUDSIZE:
|
||||
|
@ -9606,8 +9539,12 @@ scriptwait:
|
|||
break;
|
||||
|
||||
case PCD_CONSOLECOMMAND:
|
||||
case PCD_CONSOLECOMMANDDIRECT:
|
||||
Printf (TEXTCOLOR_RED GAMENAME " doesn't support execution of console commands from scripts\n");
|
||||
sp -= 3;
|
||||
if (pcd == PCD_CONSOLECOMMAND)
|
||||
sp -= 3;
|
||||
else
|
||||
pc += 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -504,7 +504,7 @@ public:
|
|||
PCD_PLAYERGOLDSKULL,
|
||||
PCD_PLAYERBLACKCARD,
|
||||
PCD_PLAYERSILVERCARD,
|
||||
PCD_PLAYERONTEAM,
|
||||
PCD_ISNETWORKGAME,
|
||||
PCD_PLAYERTEAM,
|
||||
/*120*/ PCD_PLAYERHEALTH,
|
||||
PCD_PLAYERARMORPOINTS,
|
||||
|
@ -519,7 +519,7 @@ public:
|
|||
/*130*/ PCD_LSPEC6DIRECT, // be given names like PCD_DUMMY.
|
||||
PCD_PRINTNAME,
|
||||
PCD_MUSICCHANGE,
|
||||
PCD_TEAM2FRAGPOINTS,
|
||||
PCD_CONSOLECOMMANDDIRECT,
|
||||
PCD_CONSOLECOMMAND,
|
||||
PCD_SINGLEPLAYER, // [RH] End of Skull Tag p-codes
|
||||
PCD_FIXEDMUL,
|
||||
|
|
|
@ -527,7 +527,7 @@ DAnimatedDoor::DAnimatedDoor ()
|
|||
}
|
||||
|
||||
DAnimatedDoor::DAnimatedDoor (sector_t *sec)
|
||||
: DMovingCeiling (sec)
|
||||
: DMovingCeiling (sec, false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -689,14 +689,11 @@ void DAnimatedDoor::Tick ()
|
|||
//============================================================================
|
||||
|
||||
DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay, FDoorAnimation *anim)
|
||||
: DMovingCeiling (sec)
|
||||
: DMovingCeiling (sec, false)
|
||||
{
|
||||
double topdist;
|
||||
FTextureID picnum;
|
||||
|
||||
// The DMovingCeiling constructor automatically sets up an interpolation for us.
|
||||
// Stop it, since the ceiling is moving instantly here.
|
||||
StopInterpolation();
|
||||
m_DoorAnim = anim;
|
||||
|
||||
m_Line1 = line;
|
||||
|
|
|
@ -252,7 +252,6 @@ void P_InitEffects ()
|
|||
blood2 = ParticleColor(RPART(kind)/3, GPART(kind)/3, BPART(kind)/3);
|
||||
}
|
||||
|
||||
|
||||
void P_ThinkParticles ()
|
||||
{
|
||||
int i;
|
||||
|
@ -262,13 +261,19 @@ void P_ThinkParticles ()
|
|||
prev = NULL;
|
||||
while (i != NO_PARTICLE)
|
||||
{
|
||||
BYTE oldtrans;
|
||||
|
||||
particle = Particles + i;
|
||||
i = particle->tnext;
|
||||
if (!particle->notimefreeze && ((bglobal.freeze) || (level.flags2 & LEVEL2_FROZEN)))
|
||||
{
|
||||
prev = particle;
|
||||
continue;
|
||||
}
|
||||
|
||||
BYTE oldtrans;
|
||||
oldtrans = particle->trans;
|
||||
particle->trans -= particle->fade;
|
||||
if (oldtrans < particle->trans || --particle->ttl == 0)
|
||||
particle->size += particle->sizestep;
|
||||
if (oldtrans < particle->trans || --particle->ttl <= 0 || (particle->size <= 0))
|
||||
{ // The particle has expired, so free it
|
||||
memset (particle, 0, sizeof(particle_t));
|
||||
if (prev)
|
||||
|
@ -309,8 +314,14 @@ void P_ThinkParticles ()
|
|||
}
|
||||
}
|
||||
|
||||
enum PSFlag
|
||||
{
|
||||
PS_FULLBRIGHT = 1,
|
||||
PS_NOTIMEFREEZE = 1 << 5,
|
||||
};
|
||||
|
||||
void P_SpawnParticle(const DVector3 &pos, const DVector3 &vel, const DVector3 &accel, PalEntry color, bool fullbright, double startalpha, int lifetime, WORD size, double fadestep)
|
||||
void P_SpawnParticle(const DVector3 &pos, const DVector3 &vel, const DVector3 &accel, PalEntry color, double startalpha, int lifetime, double size,
|
||||
double fadestep, double sizestep, int flags)
|
||||
{
|
||||
particle_t *particle = NewParticle();
|
||||
|
||||
|
@ -324,8 +335,10 @@ void P_SpawnParticle(const DVector3 &pos, const DVector3 &vel, const DVector3 &a
|
|||
if (fadestep < 0) particle->fade = FADEFROMTTL(lifetime);
|
||||
else particle->fade = int(fadestep * 255);
|
||||
particle->ttl = lifetime;
|
||||
particle->bright = fullbright;
|
||||
particle->size = (WORD)size;
|
||||
particle->bright = !!(flags & PS_FULLBRIGHT);
|
||||
particle->size = size;
|
||||
particle->sizestep = sizestep;
|
||||
particle->notimefreeze = !!(flags & PS_NOTIMEFREEZE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -462,8 +475,8 @@ void P_RunEffect (AActor *actor, int effects)
|
|||
speed = (M_Random () - 128) * (1./200);
|
||||
particle->Vel.X += speed * an.Cos();
|
||||
particle->Vel.Y += speed * an.Sin();
|
||||
particle->Vel.Z -= 1. / 80;
|
||||
particle->Acc.Z -= 1. / 40;
|
||||
particle->Vel.Z += 1. / 80;
|
||||
particle->Acc.Z += 1. / 40;
|
||||
if (M_Random () & 7)
|
||||
particle->color = grey2;
|
||||
else
|
||||
|
|
|
@ -59,13 +59,15 @@ struct particle_t
|
|||
DVector3 Acc;
|
||||
BYTE ttl;
|
||||
BYTE trans;
|
||||
WORD size;
|
||||
double size;
|
||||
double sizestep;
|
||||
BYTE bright;
|
||||
BYTE fade;
|
||||
int color;
|
||||
WORD tnext;
|
||||
WORD snext;
|
||||
subsector_t * subsector;
|
||||
bool notimefreeze;
|
||||
};
|
||||
|
||||
extern particle_t *Particles;
|
||||
|
@ -83,7 +85,7 @@ particle_t *JitterParticle (int ttl);
|
|||
particle_t *JitterParticle (int ttl, double drift);
|
||||
|
||||
void P_ThinkParticles (void);
|
||||
void P_SpawnParticle(const DVector3 &pos, const DVector3 &vel, const DVector3 &accel, PalEntry color, bool fullbright, double startalpha, int lifetime, WORD size, double fadestep);
|
||||
void P_SpawnParticle(const DVector3 &pos, const DVector3 &vel, const DVector3 &accel, PalEntry color, double startalpha, int lifetime, double size, double fadestep, double sizestep, int flags = 0);
|
||||
void P_InitEffects (void);
|
||||
void P_RunEffects (void);
|
||||
|
||||
|
|
|
@ -77,7 +77,6 @@ extern int bmapnegy;
|
|||
// P_PSPR
|
||||
//
|
||||
void P_SetupPsprites (player_t* curplayer, bool startweaponup);
|
||||
void P_MovePsprites (player_t* curplayer);
|
||||
void P_DropWeapon (player_t* player);
|
||||
|
||||
|
||||
|
@ -161,9 +160,35 @@ bool P_Thing_Raise(AActor *thing, AActor *raiser);
|
|||
bool P_Thing_CanRaise(AActor *thing);
|
||||
PClassActor *P_GetSpawnableType(int spawnnum);
|
||||
void InitSpawnablesFromMapinfo();
|
||||
int P_Thing_CheckInputNum(player_t *p, int inputnum);
|
||||
int P_Thing_Warp(AActor *caller, AActor *reference, double xofs, double yofs, double zofs, DAngle angle, int flags, double heightoffset, double radiusoffset, DAngle pitch);
|
||||
bool P_Thing_CheckProximity(AActor *self, PClass *classname, double distance, int count, int flags, int ptr);
|
||||
|
||||
enum
|
||||
{
|
||||
// These are the original inputs sent by the player.
|
||||
INPUT_OLDBUTTONS,
|
||||
INPUT_BUTTONS,
|
||||
INPUT_PITCH,
|
||||
INPUT_YAW,
|
||||
INPUT_ROLL,
|
||||
INPUT_FORWARDMOVE,
|
||||
INPUT_SIDEMOVE,
|
||||
INPUT_UPMOVE,
|
||||
|
||||
// These are the inputs, as modified by P_PlayerThink().
|
||||
// Most of the time, these will match the original inputs, but
|
||||
// they can be different if a player is frozen or using a
|
||||
// chainsaw.
|
||||
MODINPUT_OLDBUTTONS,
|
||||
MODINPUT_BUTTONS,
|
||||
MODINPUT_PITCH,
|
||||
MODINPUT_YAW,
|
||||
MODINPUT_ROLL,
|
||||
MODINPUT_FORWARDMOVE,
|
||||
MODINPUT_SIDEMOVE,
|
||||
MODINPUT_UPMOVE
|
||||
};
|
||||
enum CPXF
|
||||
{
|
||||
CPXF_ANCESTOR = 1 << 0,
|
||||
|
@ -335,6 +360,7 @@ struct FRailParams
|
|||
double drift = 1.0;
|
||||
PClassActor *spawnclass = nullptr;
|
||||
int SpiralOffset = 270;
|
||||
int limit = 0;
|
||||
}; // [RH] Shoot a railgun
|
||||
|
||||
void P_RailAttack(FRailParams *params);
|
||||
|
|
|
@ -4611,6 +4611,8 @@ struct RailData
|
|||
bool ThruSpecies;
|
||||
bool MThruSpecies;
|
||||
bool ThruActors;
|
||||
int limit;
|
||||
int count;
|
||||
};
|
||||
|
||||
static ETraceStatus ProcessRailHit(FTraceResults &res, void *userdata)
|
||||
|
@ -4665,7 +4667,11 @@ static ETraceStatus ProcessRailHit(FTraceResults &res, void *userdata)
|
|||
}
|
||||
data->RailHits.Push(newhit);
|
||||
|
||||
return data->StopAtOne ? TRACE_Stop : TRACE_Continue;
|
||||
if (data->limit)
|
||||
{
|
||||
data->count++;
|
||||
}
|
||||
return (data->StopAtOne || (data->limit && (data->count >= data->limit))) ? TRACE_Stop : TRACE_Continue;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -4707,7 +4713,8 @@ void P_RailAttack(FRailParams *p)
|
|||
|
||||
RailData rail_data;
|
||||
rail_data.Caller = source;
|
||||
|
||||
rail_data.limit = p->limit;
|
||||
rail_data.count = 0;
|
||||
rail_data.StopAtOne = !!(p->flags & RAF_NOPIERCE);
|
||||
start.X = xy.X;
|
||||
start.Y = xy.Y;
|
||||
|
@ -5460,14 +5467,25 @@ bool P_AdjustFloorCeil(AActor *thing, FChangePosition *cpos)
|
|||
}
|
||||
|
||||
bool isgood = P_CheckPosition(thing, thing->Pos(), tm);
|
||||
thing->floorz = tm.floorz;
|
||||
thing->ceilingz = tm.ceilingz;
|
||||
thing->dropoffz = tm.dropoffz; // killough 11/98: remember dropoffs
|
||||
thing->floorpic = tm.floorpic;
|
||||
thing->floorterrain = tm.floorterrain;
|
||||
thing->floorsector = tm.floorsector;
|
||||
thing->ceilingpic = tm.ceilingpic;
|
||||
thing->ceilingsector = tm.ceilingsector;
|
||||
if (!(thing->flags4 & MF4_ACTLIKEBRIDGE))
|
||||
{
|
||||
thing->floorz = tm.floorz;
|
||||
thing->ceilingz = tm.ceilingz;
|
||||
thing->dropoffz = tm.dropoffz; // killough 11/98: remember dropoffs
|
||||
thing->floorpic = tm.floorpic;
|
||||
thing->floorterrain = tm.floorterrain;
|
||||
thing->floorsector = tm.floorsector;
|
||||
thing->ceilingpic = tm.ceilingpic;
|
||||
thing->ceilingsector = tm.ceilingsector;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bridges only keep the info at their spawn position
|
||||
// This is necessary to prevent moving sectors from altering the bridge's z-position.
|
||||
// The bridge should remain at its current z, even if the sector change would cause
|
||||
// floorz or ceilingz to be changed in a way that would make P_ZMovement adjust the bridge.
|
||||
P_FindFloorCeiling(thing, FFCF_ONLYSPAWNPOS);
|
||||
}
|
||||
|
||||
// restore the PASSMOBJ flag but leave the other flags alone.
|
||||
thing->flags2 = (thing->flags2 & ~MF2_PASSMOBJ) | flags2;
|
||||
|
|
|
@ -38,18 +38,17 @@ struct intercept_t
|
|||
|
||||
inline int P_PointOnLineSidePrecise(double x, double y, const line_t *line)
|
||||
{
|
||||
return (y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - x) * line->Delta().Y > -EQUAL_EPSILON;
|
||||
return (y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - x) * line->Delta().Y > EQUAL_EPSILON;
|
||||
}
|
||||
|
||||
inline int P_PointOnLineSidePrecise(const DVector2 &pt, const line_t *line)
|
||||
{
|
||||
return (pt.Y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - pt.X) * line->Delta().Y > -EQUAL_EPSILON;
|
||||
return (pt.Y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - pt.X) * line->Delta().Y > EQUAL_EPSILON;
|
||||
}
|
||||
|
||||
inline int P_PointOnLineSide (double x, double y, const line_t *line)
|
||||
{
|
||||
extern int P_VanillaPointOnLineSide(double x, double y, const line_t* line);
|
||||
|
||||
return i_compatflags2 & COMPATF2_POINTONLINE
|
||||
? P_VanillaPointOnLineSide(x, y, line) : P_PointOnLineSidePrecise(x, y, line);
|
||||
}
|
||||
|
@ -73,12 +72,12 @@ inline int P_PointOnLineSide(const DVector2 & p, const line_t *line)
|
|||
|
||||
inline int P_PointOnDivlineSide(double x, double y, const divline_t *line)
|
||||
{
|
||||
return (y - line->y) * line->dx + (line->x - x) * line->dy > -EQUAL_EPSILON;
|
||||
return (y - line->y) * line->dx + (line->x - x) * line->dy > EQUAL_EPSILON;
|
||||
}
|
||||
|
||||
inline int P_PointOnDivlineSide(const DVector2 &pos, const divline_t *line)
|
||||
{
|
||||
return (pos.Y - line->y) * line->dx + (line->x - pos.X) * line->dy > -EQUAL_EPSILON;
|
||||
return (pos.Y - line->y) * line->dx + (line->x - pos.X) * line->dy > EQUAL_EPSILON;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -557,7 +557,8 @@ bool AActor::SetState (FState *newstate, bool nofunction)
|
|||
if (!nofunction)
|
||||
{
|
||||
FState *returned_state;
|
||||
if (newstate->CallAction(this, this, &returned_state))
|
||||
FStateParamInfo stp = { newstate, STATE_Actor, PSP_WEAPON };
|
||||
if (newstate->CallAction(this, this, &stp, &returned_state))
|
||||
{
|
||||
// Check whether the called action function resulted in destroying the actor
|
||||
if (ObjectFlags & OF_EuthanizeMe)
|
||||
|
@ -998,12 +999,10 @@ void AActor::ClearInventory()
|
|||
invp = &inv->Inventory;
|
||||
}
|
||||
}
|
||||
if (player != NULL)
|
||||
if (player != nullptr)
|
||||
{
|
||||
player->ReadyWeapon = NULL;
|
||||
player->ReadyWeapon = nullptr;
|
||||
player->PendingWeapon = WP_NOCHANGE;
|
||||
player->psprites[ps_weapon].state = NULL;
|
||||
player->psprites[ps_flash].state = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2790,10 +2789,10 @@ void P_NightmareRespawn (AActor *mobj)
|
|||
mo->Prev.Z = z; // Do not interpolate Z position if we changed it since spawning.
|
||||
|
||||
// spawn a teleport fog at old spot because of removal of the body?
|
||||
P_SpawnTeleportFog(mobj, mobj->PosPlusZ(TELEFOGHEIGHT), true, true);
|
||||
P_SpawnTeleportFog(mobj, mobj->Pos(), true, true);
|
||||
|
||||
// spawn a teleport fog at the new spot
|
||||
P_SpawnTeleportFog(mobj, DVector3(mobj->SpawnPoint, z + TELEFOGHEIGHT), false, true);
|
||||
P_SpawnTeleportFog(mobj, DVector3(mobj->SpawnPoint, z), false, true);
|
||||
|
||||
// remove the old monster
|
||||
mobj->Destroy ();
|
||||
|
@ -3869,7 +3868,8 @@ bool AActor::CheckNoDelay()
|
|||
// For immediately spawned objects with the NoDelay flag set for their
|
||||
// Spawn state, explicitly call the current state's function.
|
||||
FState *newstate;
|
||||
if (state->CallAction(this, this, &newstate))
|
||||
FStateParamInfo stp = { state, STATE_Actor, PSP_WEAPON };
|
||||
if (state->CallAction(this, this, &stp, &newstate))
|
||||
{
|
||||
if (ObjectFlags & OF_EuthanizeMe)
|
||||
{
|
||||
|
@ -4686,7 +4686,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
|
|||
|
||||
if (multiplayer)
|
||||
{
|
||||
Spawn ("TeleportFog", mobj->Vec3Angle(20., mobj->Angles.Yaw, TELEFOGHEIGHT), ALLOW_REPLACE);
|
||||
P_SpawnTeleportFog(mobj, mobj->Vec3Angle(20., mobj->Angles.Yaw, 0.), false, true);
|
||||
}
|
||||
|
||||
// "Fix" for one of the starts on exec.wad MAP01: If you start inside the ceiling,
|
||||
|
|
732
src/p_pspr.cpp
732
src/p_pspr.cpp
File diff suppressed because it is too large
Load diff
96
src/p_pspr.h
96
src/p_pspr.h
|
@ -35,59 +35,83 @@
|
|||
// the right spot at 320x200.
|
||||
#define WEAPONTOP (32+6./16)
|
||||
|
||||
class AInventory;
|
||||
class FArchive;
|
||||
|
||||
//
|
||||
// Overlay psprites are scaled shapes
|
||||
// drawn directly on the view screen,
|
||||
// coordinates are given for a 320*200 view screen.
|
||||
//
|
||||
typedef enum
|
||||
enum PSPLayers // These are all called by the owner's ReadyWeapon.
|
||||
{
|
||||
ps_weapon,
|
||||
ps_flash,
|
||||
ps_targetcenter,
|
||||
ps_targetleft,
|
||||
ps_targetright,
|
||||
NUMPSPRITES
|
||||
|
||||
} psprnum_t;
|
||||
|
||||
/*
|
||||
inline FArchive &operator<< (FArchive &arc, psprnum_t &i)
|
||||
{
|
||||
BYTE val = (BYTE)i;
|
||||
arc << val;
|
||||
i = (psprnum_t)val;
|
||||
return arc;
|
||||
}
|
||||
*/
|
||||
|
||||
struct pspdef_t
|
||||
{
|
||||
FState* state; // a NULL state means not active
|
||||
int tics;
|
||||
double sx;
|
||||
double sy;
|
||||
int sprite;
|
||||
int frame;
|
||||
bool processPending; // true: waiting for periodic processing on this tick
|
||||
PSP_STRIFEHANDS = -1,
|
||||
PSP_WEAPON = 1,
|
||||
PSP_FLASH = 1000,
|
||||
PSP_TARGETCENTER = INT_MAX - 2,
|
||||
PSP_TARGETLEFT,
|
||||
PSP_TARGETRIGHT,
|
||||
};
|
||||
|
||||
class FArchive;
|
||||
enum PSPFlags
|
||||
{
|
||||
PSPF_ADDWEAPON = 1 << 0,
|
||||
PSPF_ADDBOB = 1 << 1,
|
||||
PSPF_POWDOUBLE = 1 << 2,
|
||||
PSPF_CVARFAST = 1 << 3,
|
||||
};
|
||||
|
||||
FArchive &operator<< (FArchive &, pspdef_t &);
|
||||
class DPSprite : public DObject
|
||||
{
|
||||
DECLARE_CLASS (DPSprite, DObject)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
DPSprite(player_t *owner, AActor *caller, int id);
|
||||
|
||||
class player_t;
|
||||
class AActor;
|
||||
struct FState;
|
||||
static void NewTick();
|
||||
void SetState(FState *newstate, bool pending = false);
|
||||
|
||||
int GetID() const { return ID; }
|
||||
int GetSprite() const { return Sprite; }
|
||||
int GetFrame() const { return Frame; }
|
||||
int GetTics() const { return Tics; }
|
||||
FState* GetState() const { return State; }
|
||||
DPSprite* GetNext() { return Next; }
|
||||
AActor* GetCaller() { return Caller; }
|
||||
|
||||
double x, y;
|
||||
double oldx, oldy;
|
||||
bool firstTic;
|
||||
int Tics;
|
||||
int Flags;
|
||||
|
||||
private:
|
||||
DPSprite () {}
|
||||
|
||||
void Serialize(FArchive &arc);
|
||||
void Tick();
|
||||
void Destroy();
|
||||
|
||||
TObjPtr<AActor> Caller;
|
||||
TObjPtr<DPSprite> Next;
|
||||
player_t *Owner;
|
||||
FState *State;
|
||||
int Sprite;
|
||||
int Frame;
|
||||
int ID;
|
||||
bool processPending; // true: waiting for periodic processing on this tick
|
||||
|
||||
friend class player_t;
|
||||
friend void CopyPlayer(player_t *dst, player_t *src, const char *name);
|
||||
};
|
||||
|
||||
void P_NewPspriteTick();
|
||||
void P_SetPsprite (player_t *player, int position, FState *state, bool nofunction=false);
|
||||
void P_CalcSwing (player_t *player);
|
||||
void P_SetPsprite(player_t *player, PSPLayers id, FState *state, bool pending = false);
|
||||
void P_BringUpWeapon (player_t *player);
|
||||
void P_FireWeapon (player_t *player);
|
||||
void P_DropWeapon (player_t *player);
|
||||
void P_BobWeapon (player_t *player, pspdef_t *psp, float *x, float *y, double ticfrac);
|
||||
void P_BobWeapon (player_t *player, float *x, float *y, double ticfrac);
|
||||
DAngle P_BulletSlope (AActor *mo, FTranslatedLineTarget *pLineTarget = NULL, int aimflags = 0);
|
||||
|
||||
void P_GunShot (AActor *mo, bool accurate, PClassActor *pufftype, DAngle pitch);
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
#include "p_acs.h"
|
||||
#include "p_terrain.h"
|
||||
|
||||
static void CopyPlayer (player_t *dst, player_t *src, const char *name);
|
||||
void CopyPlayer (player_t *dst, player_t *src, const char *name);
|
||||
static void ReadOnePlayer (FArchive &arc, bool skipload);
|
||||
static void ReadMultiplePlayers (FArchive &arc, int numPlayers, int numPlayersNow, bool skipload);
|
||||
static void SpawnExtraPlayers ();
|
||||
|
@ -255,7 +255,7 @@ static void ReadMultiplePlayers (FArchive &arc, int numPlayers, int numPlayersNo
|
|||
delete[] nametemp;
|
||||
}
|
||||
|
||||
static void CopyPlayer (player_t *dst, player_t *src, const char *name)
|
||||
void CopyPlayer (player_t *dst, player_t *src, const char *name)
|
||||
{
|
||||
// The userinfo needs to be saved for real players, but it
|
||||
// needs to come from the save for bots.
|
||||
|
@ -274,7 +274,7 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name)
|
|||
|
||||
dst->cheats |= chasecam;
|
||||
|
||||
if (dst->Bot != NULL)
|
||||
if (dst->Bot != nullptr)
|
||||
{
|
||||
botinfo_t *thebot = bglobal.botinfo;
|
||||
while (thebot && stricmp (name, thebot->name))
|
||||
|
@ -296,10 +296,23 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name)
|
|||
dst->userinfo.SkinNumChanged(R_FindSkin(skins[dst->userinfo.GetSkin()].name, dst->CurrentPlayerClass));
|
||||
|
||||
// Make sure the player pawn points to the proper player struct.
|
||||
if (dst->mo != NULL)
|
||||
if (dst->mo != nullptr)
|
||||
{
|
||||
dst->mo->player = dst;
|
||||
}
|
||||
|
||||
// Same for the psprites.
|
||||
DPSprite *pspr = dst->psprites;
|
||||
while (pspr)
|
||||
{
|
||||
pspr->Owner = dst;
|
||||
|
||||
pspr = pspr->Next;
|
||||
}
|
||||
|
||||
// Don't let the psprites be destroyed when src is destroyed.
|
||||
src->psprites = nullptr;
|
||||
|
||||
// These 2 variables may not be overwritten.
|
||||
dst->attackdown = attackdown;
|
||||
dst->usedown = usedown;
|
||||
|
|
|
@ -3193,50 +3193,32 @@ static void P_GroupLines (bool buildmap)
|
|||
{
|
||||
if (linesDoneInEachSector[i] != sector->linecount)
|
||||
{
|
||||
I_Error ("P_GroupLines: miscounted");
|
||||
I_Error("P_GroupLines: miscounted");
|
||||
}
|
||||
if (sector->linecount != 0)
|
||||
if (sector->linecount > 3)
|
||||
{
|
||||
bbox.ClearBox ();
|
||||
bbox.ClearBox();
|
||||
for (j = 0; j < sector->linecount; ++j)
|
||||
{
|
||||
li = sector->lines[j];
|
||||
bbox.AddToBox (li->v1->fPos());
|
||||
bbox.AddToBox (li->v2->fPos());
|
||||
bbox.AddToBox(li->v1->fPos());
|
||||
bbox.AddToBox(li->v2->fPos());
|
||||
}
|
||||
|
||||
// set the center to the middle of the bounding box
|
||||
sector->centerspot.X = (bbox.Right() + bbox.Left()) / 2;
|
||||
sector->centerspot.Y = (bbox.Top() + bbox.Bottom()) / 2;
|
||||
}
|
||||
|
||||
// set the center to the middle of the bounding box
|
||||
sector->centerspot.X = (bbox.Right() + bbox.Left()) / 2;
|
||||
sector->centerspot.Y = (bbox.Top() + bbox.Bottom()) / 2;
|
||||
|
||||
// For triangular sectors the above does not calculate good points unless the longest of the triangle's lines is perfectly horizontal and vertical
|
||||
if (sector->linecount == 3)
|
||||
else if (sector->linecount > 0)
|
||||
{
|
||||
vertex_t *Triangle[2];
|
||||
Triangle[0] = sector->lines[0]->v1;
|
||||
Triangle[1] = sector->lines[0]->v2;
|
||||
if (sector->linecount > 1)
|
||||
// For triangular sectors the above does not calculate good points unless the longest of the triangle's lines is perfectly horizontal and vertical
|
||||
DVector2 pos = { 0,0 };
|
||||
for (int i = 0; i < sector->linecount; i++)
|
||||
{
|
||||
double dx = Triangle[1]->fX() - Triangle[0]->fX();
|
||||
double dy = Triangle[1]->fY() - Triangle[0]->fY();
|
||||
// Find another point in the sector that does not lie
|
||||
// on the same line as the first two points.
|
||||
for (j = 0; j < 2; ++j)
|
||||
{
|
||||
vertex_t *v;
|
||||
|
||||
v = (j == 1) ? sector->lines[1]->v1 : sector->lines[1]->v2;
|
||||
if ( (v->fY() - Triangle[0]->fY()) * dx + (Triangle[0]->fX() - v->fX() * dy) != 0)
|
||||
{
|
||||
sector->centerspot.X = (Triangle[0]->fX() / 3 + Triangle[1]->fX() / 3 + v->fX() / 3);
|
||||
sector->centerspot.Y = (Triangle[0]->fY() / 3 + Triangle[1]->fY() / 3 + v->fY() / 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pos += sector->lines[i]->v1->fPos() + sector->lines[i]->v2->fPos();
|
||||
}
|
||||
sector->centerspot = pos / (2 * sector->linecount);
|
||||
}
|
||||
|
||||
}
|
||||
delete[] linesDoneInEachSector;
|
||||
times[3].Unclock();
|
||||
|
@ -3330,14 +3312,17 @@ void P_LoadReject (MapData * map, bool junk)
|
|||
//
|
||||
// [RH] P_LoadBehavior
|
||||
//
|
||||
void P_LoadBehavior (MapData * map)
|
||||
void P_LoadBehavior(MapData * map)
|
||||
{
|
||||
map->Seek(ML_BEHAVIOR);
|
||||
FBehavior::StaticLoadModule (-1, map->file, map->Size(ML_BEHAVIOR));
|
||||
if (!FBehavior::StaticCheckAllGood ())
|
||||
if (map->Size(ML_BEHAVIOR) > 0)
|
||||
{
|
||||
Printf ("ACS scripts unloaded.\n");
|
||||
FBehavior::StaticUnloadModules ();
|
||||
map->Seek(ML_BEHAVIOR);
|
||||
FBehavior::StaticLoadModule(-1, map->file, map->Size(ML_BEHAVIOR));
|
||||
}
|
||||
if (!FBehavior::StaticCheckAllGood())
|
||||
{
|
||||
Printf("ACS scripts unloaded.\n");
|
||||
FBehavior::StaticUnloadModules();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -89,7 +89,8 @@ void P_SpawnTeleportFog(AActor *mobj, const DVector3 &pos, bool beforeTele, bool
|
|||
}
|
||||
else
|
||||
{
|
||||
mo = Spawn((beforeTele ? mobj->TeleFogSourceType : mobj->TeleFogDestType), pos, ALLOW_REPLACE);
|
||||
double fogDelta = mobj->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT;
|
||||
mo = Spawn((beforeTele ? mobj->TeleFogSourceType : mobj->TeleFogDestType), DVector3(pos, pos.Z + fogDelta), ALLOW_REPLACE);
|
||||
}
|
||||
|
||||
if (mo != NULL && setTarget)
|
||||
|
@ -192,10 +193,9 @@ bool P_Teleport (AActor *thing, DVector3 pos, DAngle angle, int flags)
|
|||
{
|
||||
if (!predicting)
|
||||
{
|
||||
double fogDelta = thing->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT;
|
||||
DVector2 vector = angle.ToVector(20);
|
||||
DVector2 fogpos = P_GetOffsetPosition(pos.X, pos.Y, vector.X, vector.Y);
|
||||
P_SpawnTeleportFog(thing, DVector3(fogpos, thing->Z() + fogDelta), false, true);
|
||||
P_SpawnTeleportFog(thing, DVector3(fogpos, thing->Z()), false, true);
|
||||
|
||||
}
|
||||
if (thing->player)
|
||||
|
|
|
@ -98,7 +98,7 @@ bool P_Thing_Spawn (int tid, AActor *source, int type, DAngle angle, bool fog, i
|
|||
mobj->Angles.Yaw = (angle != 1000000. ? angle : spot->Angles.Yaw);
|
||||
if (fog)
|
||||
{
|
||||
P_SpawnTeleportFog(mobj, spot->PosPlusZ(TELEFOGHEIGHT), false, true);
|
||||
P_SpawnTeleportFog(mobj, spot->Pos(), false, true);
|
||||
}
|
||||
if (mobj->flags & MF_SPECIAL)
|
||||
mobj->flags |= MF_DROPPED; // Don't respawn
|
||||
|
@ -666,14 +666,43 @@ void InitSpawnablesFromMapinfo()
|
|||
InitClassMap(SpawnableThings, SpawnablesFromMapinfo);
|
||||
InitClassMap(StrifeTypes, ConversationIDsFromMapinfo);
|
||||
}
|
||||
int P_Thing_CheckInputNum(player_t *p, int inputnum)
|
||||
{
|
||||
int renum = 0;
|
||||
if (p)
|
||||
{
|
||||
switch (inputnum)
|
||||
{
|
||||
case INPUT_OLDBUTTONS: renum = p->original_oldbuttons; break;
|
||||
case INPUT_BUTTONS: renum = p->original_cmd.buttons; break;
|
||||
case INPUT_PITCH: renum = p->original_cmd.pitch; break;
|
||||
case INPUT_YAW: renum = p->original_cmd.yaw; break;
|
||||
case INPUT_ROLL: renum = p->original_cmd.roll; break;
|
||||
case INPUT_FORWARDMOVE: renum = p->original_cmd.forwardmove; break;
|
||||
case INPUT_SIDEMOVE: renum = p->original_cmd.sidemove; break;
|
||||
case INPUT_UPMOVE: renum = p->original_cmd.upmove; break;
|
||||
|
||||
case MODINPUT_OLDBUTTONS: renum = p->oldbuttons; break;
|
||||
case MODINPUT_BUTTONS: renum = p->cmd.ucmd.buttons; break;
|
||||
case MODINPUT_PITCH: renum = p->cmd.ucmd.pitch; break;
|
||||
case MODINPUT_YAW: renum = p->cmd.ucmd.yaw; break;
|
||||
case MODINPUT_ROLL: renum = p->cmd.ucmd.roll; break;
|
||||
case MODINPUT_FORWARDMOVE: renum = p->cmd.ucmd.forwardmove; break;
|
||||
case MODINPUT_SIDEMOVE: renum = p->cmd.ucmd.sidemove; break;
|
||||
case MODINPUT_UPMOVE: renum = p->cmd.ucmd.upmove; break;
|
||||
|
||||
default: renum = 0; break;
|
||||
}
|
||||
}
|
||||
return renum;
|
||||
}
|
||||
bool P_Thing_CheckProximity(AActor *self, PClass *classname, double distance, int count, int flags, int ptr)
|
||||
{
|
||||
AActor *ref = COPY_AAPTR(self, ptr);
|
||||
|
||||
// We need these to check out.
|
||||
if (!ref || !classname || distance <= 0)
|
||||
return nullptr;
|
||||
return false;
|
||||
|
||||
int counter = 0;
|
||||
bool result = false;
|
||||
|
|
|
@ -88,7 +88,7 @@ void P_Ticker (void)
|
|||
if (paused || P_CheckTickerPaused())
|
||||
return;
|
||||
|
||||
P_NewPspriteTick();
|
||||
DPSprite::NewTick();
|
||||
|
||||
// [RH] Frozen mode is only changed every 4 tics, to make it work with A_Tracer().
|
||||
if ((level.time & 3) == 0)
|
||||
|
@ -118,10 +118,7 @@ void P_Ticker (void)
|
|||
// Since things will be moving, it's okay to interpolate them in the renderer.
|
||||
r_NoInterpolate = false;
|
||||
|
||||
if (!bglobal.freeze && !(level.flags2 & LEVEL2_FROZEN))
|
||||
{
|
||||
P_ThinkParticles (); // [RH] make the particles think
|
||||
}
|
||||
P_ThinkParticles(); // [RH] make the particles think
|
||||
|
||||
for (i = 0; i<MAXPLAYERS; i++)
|
||||
if (playeringame[i] &&
|
||||
|
|
|
@ -434,7 +434,7 @@ bool FTraceInfo::LineCheck(intercept_t *in, double dist, DVector3 hit)
|
|||
sector_t *hsec = CurSector->GetHeightSec();
|
||||
if (Results->CrossedWater == NULL &&
|
||||
hsec != NULL &&
|
||||
//CurSector->heightsec->waterzone &&
|
||||
Start.Z > hsec->floorplane.ZatPoint(Start) &&
|
||||
hit.Z <= hsec->floorplane.ZatPoint(hit))
|
||||
{
|
||||
// hit crossed a water plane
|
||||
|
@ -846,6 +846,7 @@ bool FTraceInfo::TraceTraverse (int ptflags)
|
|||
|
||||
if (Results->CrossedWater == NULL &&
|
||||
CurSector->heightsec != NULL &&
|
||||
CurSector->heightsec->floorplane.ZatPoint(Start) < Start.Z &&
|
||||
CurSector->heightsec->floorplane.ZatPoint(Results->HitPos) >= Results->HitPos.Z)
|
||||
{
|
||||
// Save the result so that the water check doesn't destroy it.
|
||||
|
|
|
@ -271,6 +271,7 @@ player_t::player_t()
|
|||
WeaponState(0),
|
||||
ReadyWeapon(0),
|
||||
PendingWeapon(0),
|
||||
psprites(0),
|
||||
cheats(0),
|
||||
timefreezer(0),
|
||||
refire(0),
|
||||
|
@ -316,7 +317,11 @@ player_t::player_t()
|
|||
{
|
||||
memset (&cmd, 0, sizeof(cmd));
|
||||
memset (frags, 0, sizeof(frags));
|
||||
memset (psprites, 0, sizeof(psprites));
|
||||
}
|
||||
|
||||
player_t::~player_t()
|
||||
{
|
||||
DestroyPSprites();
|
||||
}
|
||||
|
||||
player_t &player_t::operator=(const player_t &p)
|
||||
|
@ -372,7 +377,7 @@ player_t &player_t::operator=(const player_t &p)
|
|||
extralight = p.extralight;
|
||||
fixedcolormap = p.fixedcolormap;
|
||||
fixedlightlevel = p.fixedlightlevel;
|
||||
memcpy(psprites, &p.psprites, sizeof(psprites));
|
||||
psprites = p.psprites;
|
||||
morphTics = p.morphTics;
|
||||
MorphedPlayerClass = p.MorphedPlayerClass;
|
||||
MorphStyle = p.MorphStyle;
|
||||
|
@ -434,6 +439,7 @@ size_t player_t::FixPointers (const DObject *old, DObject *rep)
|
|||
if (ReadyWeapon == old) ReadyWeapon = static_cast<AWeapon *>(rep), changed++;
|
||||
if (PendingWeapon == old) PendingWeapon = static_cast<AWeapon *>(rep), changed++;
|
||||
if (*&PremorphWeapon == old) PremorphWeapon = static_cast<AWeapon *>(rep), changed++;
|
||||
if (psprites == old) psprites = static_cast<DPSprite *>(rep), changed++;
|
||||
if (*&ConversationNPC == old) ConversationNPC = replacement, changed++;
|
||||
if (*&ConversationPC == old) ConversationPC = replacement, changed++;
|
||||
if (*&MUSINFOactor == old) MUSINFOactor = replacement, changed++;
|
||||
|
@ -452,6 +458,7 @@ size_t player_t::PropagateMark()
|
|||
GC::Mark(ConversationPC);
|
||||
GC::Mark(MUSINFOactor);
|
||||
GC::Mark(PremorphWeapon);
|
||||
GC::Mark(psprites);
|
||||
if (PendingWeapon != WP_NOCHANGE)
|
||||
{
|
||||
GC::Mark(PendingWeapon);
|
||||
|
@ -1371,34 +1378,37 @@ void APlayerPawn::ActivateMorphWeapon ()
|
|||
{
|
||||
PClassActor *morphweapon = PClass::FindActor (MorphWeapon);
|
||||
player->PendingWeapon = WP_NOCHANGE;
|
||||
player->psprites[ps_weapon].sy = WEAPONTOP;
|
||||
|
||||
if (morphweapon == NULL || !morphweapon->IsDescendantOf (RUNTIME_CLASS(AWeapon)))
|
||||
if (player->ReadyWeapon != nullptr)
|
||||
{
|
||||
player->GetPSprite(PSP_WEAPON)->y = WEAPONTOP;
|
||||
}
|
||||
|
||||
if (morphweapon == nullptr || !morphweapon->IsDescendantOf (RUNTIME_CLASS(AWeapon)))
|
||||
{ // No weapon at all while morphed!
|
||||
player->ReadyWeapon = NULL;
|
||||
P_SetPsprite (player, ps_weapon, NULL);
|
||||
player->ReadyWeapon = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->ReadyWeapon = static_cast<AWeapon *>(player->mo->FindInventory (morphweapon));
|
||||
if (player->ReadyWeapon == NULL)
|
||||
if (player->ReadyWeapon == nullptr)
|
||||
{
|
||||
player->ReadyWeapon = static_cast<AWeapon *>(player->mo->GiveInventoryType (morphweapon));
|
||||
if (player->ReadyWeapon != NULL)
|
||||
if (player->ReadyWeapon != nullptr)
|
||||
{
|
||||
player->ReadyWeapon->GivenAsMorphWeapon = true; // flag is used only by new beastweap semantics in P_UndoPlayerMorph
|
||||
}
|
||||
}
|
||||
if (player->ReadyWeapon != NULL)
|
||||
if (player->ReadyWeapon != nullptr)
|
||||
{
|
||||
P_SetPsprite (player, ps_weapon, player->ReadyWeapon->GetReadyState());
|
||||
}
|
||||
else
|
||||
{
|
||||
P_SetPsprite (player, ps_weapon, NULL);
|
||||
P_SetPsprite(player, PSP_WEAPON, player->ReadyWeapon->GetReadyState());
|
||||
}
|
||||
}
|
||||
P_SetPsprite (player, ps_flash, NULL);
|
||||
|
||||
if (player->ReadyWeapon != nullptr)
|
||||
{
|
||||
P_SetPsprite(player, PSP_FLASH, nullptr);
|
||||
}
|
||||
|
||||
player->PendingWeapon = WP_NOCHANGE;
|
||||
}
|
||||
|
@ -2115,7 +2125,7 @@ void P_DeathThink (player_t *player)
|
|||
int dir;
|
||||
DAngle delta;
|
||||
|
||||
P_MovePsprites (player);
|
||||
player->TickPSprites();
|
||||
|
||||
player->onground = (player->mo->Z() <= player->mo->floorz);
|
||||
if (player->mo->IsKindOf (RUNTIME_CLASS(APlayerChunk)))
|
||||
|
@ -2635,7 +2645,7 @@ void P_PlayerThink (player_t *player)
|
|||
}
|
||||
}
|
||||
// Cycle psprites
|
||||
P_MovePsprites (player);
|
||||
player->TickPSprites();
|
||||
|
||||
// Other Counters
|
||||
if (player->damagecount)
|
||||
|
@ -3065,8 +3075,56 @@ void player_t::Serialize (FArchive &arc)
|
|||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
arc << frags[i];
|
||||
for (i = 0; i < NUMPSPRITES; i++)
|
||||
arc << psprites[i];
|
||||
|
||||
if (SaveVersion < 4547)
|
||||
{
|
||||
int layer = PSP_WEAPON;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
FState *state;
|
||||
int tics;
|
||||
double sx, sy;
|
||||
int sprite;
|
||||
int frame;
|
||||
|
||||
arc << state << tics
|
||||
<< sx << sy
|
||||
<< sprite << frame;
|
||||
|
||||
if (state != nullptr &&
|
||||
((layer < PSP_TARGETCENTER && ReadyWeapon != nullptr) ||
|
||||
(layer >= PSP_TARGETCENTER && mo->FindInventory(RUNTIME_CLASS(APowerTargeter), true))))
|
||||
{
|
||||
DPSprite *pspr;
|
||||
pspr = GetPSprite(PSPLayers(layer));
|
||||
pspr->State = state;
|
||||
pspr->Tics = tics;
|
||||
pspr->Sprite = sprite;
|
||||
pspr->Frame = frame;
|
||||
pspr->Owner = this;
|
||||
|
||||
if (layer == PSP_FLASH)
|
||||
{
|
||||
pspr->x = 0;
|
||||
pspr->y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pspr->x = sx;
|
||||
pspr->y = sy;
|
||||
}
|
||||
}
|
||||
|
||||
if (layer == PSP_WEAPON)
|
||||
layer = PSP_FLASH;
|
||||
else if (layer == PSP_FLASH)
|
||||
layer = PSP_TARGETCENTER;
|
||||
else
|
||||
layer++;
|
||||
}
|
||||
}
|
||||
else
|
||||
arc << psprites;
|
||||
|
||||
arc << CurrentPlayerClass;
|
||||
|
||||
|
|
|
@ -270,14 +270,31 @@ static line_t *FindDestination(line_t *src, int tag)
|
|||
|
||||
static void SetRotation(FLinePortal *port)
|
||||
{
|
||||
if (port != NULL && port->mDestination != NULL)
|
||||
if (port != nullptr && port->mDestination != nullptr)
|
||||
{
|
||||
line_t *dst = port->mDestination;
|
||||
line_t *line = port->mOrigin;
|
||||
DAngle angle = dst->Delta().Angle() - line->Delta().Angle() + 180.;
|
||||
port->mSinRot = sindeg(angle.Degrees); // Here precision matters so use the slower but more precise versions.
|
||||
port->mCosRot = cosdeg(angle.Degrees);
|
||||
port->mAngleDiff = angle;
|
||||
if (port->mType != PORTT_LINKED)
|
||||
{
|
||||
line_t *dst = port->mDestination;
|
||||
line_t *line = port->mOrigin;
|
||||
DAngle angle = dst->Delta().Angle() - line->Delta().Angle() + 180.;
|
||||
port->mSinRot = sindeg(angle.Degrees); // Here precision matters so use the slower but more precise versions.
|
||||
port->mCosRot = cosdeg(angle.Degrees);
|
||||
port->mAngleDiff = angle;
|
||||
if ((line->sidedef[0]->Flags & WALLF_POLYOBJ) || (dst->sidedef[0]->Flags & WALLF_POLYOBJ))
|
||||
{
|
||||
port->mFlags |= PORTF_POLYOBJ;
|
||||
}
|
||||
else
|
||||
{
|
||||
port->mFlags &= ~PORTF_POLYOBJ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Linked portals have no angular difference.
|
||||
port->mSinRot = port->mCosRot = 0.;
|
||||
port->mAngleDiff = 0.;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -323,11 +340,6 @@ void P_SpawnLinePortal(line_t* line)
|
|||
{
|
||||
port->mDefFlags = port->mType == PORTT_VISUAL ? PORTF_VISIBLE : port->mType == PORTT_TELEPORT ? PORTF_TYPETELEPORT : PORTF_TYPEINTERACTIVE;
|
||||
}
|
||||
|
||||
// Get the angle between the two linedefs, for rotating
|
||||
// orientation and velocity. Rotate 180 degrees, and flip
|
||||
// the position across the exit linedef, if reversed.
|
||||
SetRotation(port);
|
||||
}
|
||||
else if (line->args[2] == PORTT_LINKEDEE && line->args[0] == 0)
|
||||
{
|
||||
|
@ -348,7 +360,6 @@ void P_SpawnLinePortal(line_t* line)
|
|||
port->mType = PORTT_LINKED;
|
||||
port->mAlign = PORG_ABSOLUTE;
|
||||
port->mDefFlags = PORTF_TYPEINTERACTIVE;
|
||||
SetRotation(port);
|
||||
|
||||
// we need to create the backlink here, too.
|
||||
lines[i].portalindex = linePortals.Reserve(1);
|
||||
|
@ -360,8 +371,6 @@ void P_SpawnLinePortal(line_t* line)
|
|||
port->mType = PORTT_LINKED;
|
||||
port->mAlign = PORG_ABSOLUTE;
|
||||
port->mDefFlags = PORTF_TYPEINTERACTIVE;
|
||||
|
||||
SetRotation(port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -411,6 +420,9 @@ void P_UpdatePortal(FLinePortal *port)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cache the angle between the two linedefs, for rotating.
|
||||
SetRotation(port);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -591,6 +603,7 @@ void P_TranslatePortalXY(line_t* src, double& x, double& y)
|
|||
if (!src) return;
|
||||
FLinePortal *port = src->getPortal();
|
||||
if (!port) return;
|
||||
if (port->mFlags & PORTF_POLYOBJ) SetRotation(port); // update the angle for polyportals.
|
||||
|
||||
// offsets from line
|
||||
double nposx = x - src->v1->fX();
|
||||
|
@ -618,6 +631,7 @@ void P_TranslatePortalVXVY(line_t* src, double &velx, double &vely)
|
|||
if (!src) return;
|
||||
FLinePortal *port = src->getPortal();
|
||||
if (!port) return;
|
||||
if (port->mFlags & PORTF_POLYOBJ) SetRotation(port); // update the angle for polyportals.
|
||||
|
||||
double orig_velx = velx;
|
||||
double orig_vely = vely;
|
||||
|
@ -636,6 +650,7 @@ void P_TranslatePortalAngle(line_t* src, DAngle& angle)
|
|||
if (!src) return;
|
||||
FLinePortal *port = src->getPortal();
|
||||
if (!port) return;
|
||||
if (port->mFlags & PORTF_POLYOBJ) SetRotation(port); // update the angle for polyportals.
|
||||
angle = (angle + port->mAngleDiff).Normalized360();
|
||||
}
|
||||
|
||||
|
|
|
@ -145,6 +145,7 @@ enum
|
|||
PORTF_PASSABLE = 2,
|
||||
PORTF_SOUNDTRAVERSE = 4,
|
||||
PORTF_INTERACTIVE = 8,
|
||||
PORTF_POLYOBJ = 16,
|
||||
|
||||
PORTF_TYPETELEPORT = PORTF_VISIBLE | PORTF_PASSABLE | PORTF_SOUNDTRAVERSE,
|
||||
PORTF_TYPEINTERACTIVE = PORTF_VISIBLE | PORTF_PASSABLE | PORTF_SOUNDTRAVERSE | PORTF_INTERACTIVE,
|
||||
|
|
|
@ -1038,11 +1038,17 @@ FScriptPosition &FScriptPosition::operator=(const FScriptPosition &other)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
CVAR(Bool, strictdecorate, false, CVAR_GLOBALCONFIG|CVAR_ARCHIVE)
|
||||
|
||||
void FScriptPosition::Message (int severity, const char *message, ...) const
|
||||
{
|
||||
FString composed;
|
||||
|
||||
if ((severity == MSG_DEBUG || severity == MSG_DEBUGLOG) && !developer) return;
|
||||
if (severity == MSG_OPTERROR)
|
||||
{
|
||||
severity = strictdecorate ? MSG_ERROR : MSG_WARNING;
|
||||
}
|
||||
|
||||
if (message == NULL)
|
||||
{
|
||||
|
|
|
@ -124,6 +124,7 @@ enum
|
|||
MSG_WARNING,
|
||||
MSG_FATAL,
|
||||
MSG_ERROR,
|
||||
MSG_OPTERROR,
|
||||
MSG_DEBUG,
|
||||
MSG_LOG,
|
||||
MSG_DEBUGLOG,
|
||||
|
|
|
@ -431,11 +431,11 @@ void LoadActors ()
|
|||
FScanner sc(lump);
|
||||
ParseDecorate (sc);
|
||||
}
|
||||
FinishThingdef();
|
||||
if (FScriptPosition::ErrorCounter > 0)
|
||||
{
|
||||
I_Error("%d errors while parsing DECORATE scripts", FScriptPosition::ErrorCounter);
|
||||
}
|
||||
FinishThingdef();
|
||||
timer.Unclock();
|
||||
if (!batchrun) Printf("DECORATE parsing took %.2f ms\n", timer.TimeMS());
|
||||
// Base time: ~52 ms
|
||||
|
|
|
@ -350,7 +350,7 @@ int MatchString (const char *in, const char **strings);
|
|||
//#define PUSH_PARAMINFO self, stateowner, CallingState, ParameterIndex, statecall
|
||||
|
||||
#define CALL_ACTION(name,self) { /*AF_##name(self, self, NULL, 0, NULL)*/ \
|
||||
VMValue params[3] = { self, self, VMValue(NULL, ATAG_STATE) }; \
|
||||
VMValue params[3] = { self, self, VMValue(NULL, ATAG_STATEINFO) }; \
|
||||
stack->Call(name##_VMPtr, params, countof(params), NULL, 0, NULL); \
|
||||
}
|
||||
|
||||
|
@ -360,7 +360,7 @@ int MatchString (const char *in, const char **strings);
|
|||
#define ACTION_RETURN_BOOL(v) ACTION_RETURN_INT(v)
|
||||
|
||||
// Checks to see what called the current action function
|
||||
#define ACTION_CALL_FROM_ACTOR() (callingstate == self->state)
|
||||
#define ACTION_CALL_FROM_WEAPON() (self->player && callingstate != self->state && !(stateowner->flags5 & MF5_INSTATECALL))
|
||||
#define ACTION_CALL_FROM_INVENTORY() (!(stateowner->flags5 & MF5_INSTATECALL))
|
||||
#define ACTION_CALL_FROM_ACTOR() (stateinfo == nullptr || stateinfo->mStateType == STATE_Actor)
|
||||
#define ACTION_CALL_FROM_PSPRITE() (self->player && stateinfo != nullptr && stateinfo->mStateType == STATE_Psprite)
|
||||
#define ACTION_CALL_FROM_INVENTORY() (stateinfo != nullptr && stateinfo->mStateType == STATE_StateChain)
|
||||
#endif
|
||||
|
|
|
@ -95,6 +95,7 @@ static FRandom pr_spawnitemex ("SpawnItemEx");
|
|||
static FRandom pr_burst ("Burst");
|
||||
static FRandom pr_monsterrefire ("MonsterRefire");
|
||||
static FRandom pr_teleport("A_Teleport");
|
||||
static FRandom pr_bfgselfdamage("BFGSelfDamage");
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -119,7 +120,6 @@ bool ACustomInventory::CallStateChain (AActor *actor, FState *state)
|
|||
ret[0].PointerAt((void **)&nextstate);
|
||||
ret[1].IntAt(&retval);
|
||||
|
||||
this->flags5 |= MF5_INSTATECALL;
|
||||
FState *savedstate = this->state;
|
||||
|
||||
while (state != NULL)
|
||||
|
@ -132,8 +132,9 @@ bool ACustomInventory::CallStateChain (AActor *actor, FState *state)
|
|||
VMFrameStack stack;
|
||||
PPrototype *proto = state->ActionFunc->Proto;
|
||||
VMReturn *wantret;
|
||||
FStateParamInfo stp = { state, STATE_StateChain, PSP_WEAPON };
|
||||
|
||||
params[2] = VMValue(state, ATAG_STATE);
|
||||
params[2] = VMValue(&stp, ATAG_STATEINFO);
|
||||
retval = true; // assume success
|
||||
wantret = NULL; // assume no return value wanted
|
||||
numret = 0;
|
||||
|
@ -189,7 +190,6 @@ bool ACustomInventory::CallStateChain (AActor *actor, FState *state)
|
|||
}
|
||||
state = nextstate;
|
||||
}
|
||||
this->flags5 &= ~MF5_INSTATECALL;
|
||||
this->state = savedstate;
|
||||
return !!result;
|
||||
}
|
||||
|
@ -312,6 +312,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetDistance)
|
|||
DVector3 diff = self->Vec3To(target);
|
||||
if (checkz)
|
||||
diff.Z += (target->Height - self->Height) / 2;
|
||||
else
|
||||
diff.Z = 0.;
|
||||
|
||||
ret->SetFloat(diff.Length());
|
||||
}
|
||||
|
@ -513,6 +515,69 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetCrouchFactor)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetCVar
|
||||
//
|
||||
// NON-ACTION function that works like ACS's GetCVar.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetCVar)
|
||||
{
|
||||
if (numret > 0)
|
||||
{
|
||||
assert(ret != nullptr);
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_STRING(cvarname);
|
||||
|
||||
FBaseCVar *cvar = GetCVar(self, cvarname);
|
||||
if (cvar == nullptr)
|
||||
{
|
||||
ret->SetFloat(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret->SetFloat(cvar->GetGenericRep(CVAR_Float).Float);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetPlayerInput
|
||||
//
|
||||
// NON-ACTION function that works like ACS's GetPlayerInput.
|
||||
// Takes a pointer as anyone may or may not be a player.
|
||||
//==========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, GetPlayerInput)
|
||||
{
|
||||
if (numret > 0)
|
||||
{
|
||||
assert(ret != nullptr);
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_INT (inputnum);
|
||||
PARAM_INT_OPT (ptr) { ptr = AAPTR_DEFAULT; }
|
||||
|
||||
AActor *mobj = COPY_AAPTR(self, ptr);
|
||||
|
||||
//Need a player.
|
||||
if (!mobj || !mobj->player)
|
||||
{
|
||||
ret->SetInt(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret->SetInt(P_Thing_CheckInputNum(mobj->player, inputnum));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// __decorate_internal_state__
|
||||
|
@ -1304,6 +1369,72 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusThrust)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// A_RadiusDamageSelf
|
||||
//
|
||||
//==========================================================================
|
||||
enum
|
||||
{
|
||||
RDSF_BFGDAMAGE = 1,
|
||||
};
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusDamageSelf)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_INT_OPT(damage) { damage = 128; }
|
||||
PARAM_FLOAT_OPT(distance) { distance = 128; }
|
||||
PARAM_INT_OPT(flags) { flags = 0; }
|
||||
PARAM_CLASS_OPT(flashtype, AActor) { flashtype = NULL; }
|
||||
|
||||
int i;
|
||||
int damageSteps;
|
||||
int actualDamage;
|
||||
double actualDistance;
|
||||
|
||||
actualDistance = self->Distance3D(self->target);
|
||||
if (actualDistance < distance)
|
||||
{
|
||||
// [XA] Decrease damage with distance. Use the BFG damage
|
||||
// calculation formula if the flag is set (essentially
|
||||
// a generalization of SMMU's BFG11K behavior, used
|
||||
// with fraggle's blessing.)
|
||||
damageSteps = damage - int(damage * actualDistance / distance);
|
||||
if (flags & RDSF_BFGDAMAGE)
|
||||
{
|
||||
actualDamage = 0;
|
||||
for (i = 0; i < damageSteps; ++i)
|
||||
actualDamage += (pr_bfgselfdamage() & 7) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
actualDamage = damageSteps;
|
||||
}
|
||||
|
||||
// optional "flash" effect -- spawn an actor on
|
||||
// the player to indicate bad things happened.
|
||||
AActor *flash = NULL;
|
||||
if(flashtype != NULL)
|
||||
flash = Spawn(flashtype, self->target->PosPlusZ(self->target->Height / 4), ALLOW_REPLACE);
|
||||
|
||||
int dmgFlags = 0;
|
||||
FName dmgType = NAME_BFGSplash;
|
||||
|
||||
if (flash != NULL)
|
||||
{
|
||||
if (flash->flags5 & MF5_PUFFGETSOWNER) flash->target = self->target;
|
||||
if (flash->flags3 & MF3_FOILINVUL) dmgFlags |= DMG_FOILINVUL;
|
||||
if (flash->flags7 & MF7_FOILBUDDHA) dmgFlags |= DMG_FOILBUDDHA;
|
||||
dmgType = flash->DamageType;
|
||||
}
|
||||
|
||||
int newdam = P_DamageMobj(self->target, self, self->target, actualDamage, dmgType, dmgFlags);
|
||||
P_TraceBleed(newdam > 0 ? newdam : actualDamage, self->target, self);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Execute a line special / script
|
||||
|
@ -1644,7 +1775,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfNoAmmo)
|
|||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_STATE(jump);
|
||||
|
||||
if (!ACTION_CALL_FROM_WEAPON())
|
||||
if (!ACTION_CALL_FROM_PSPRITE() || self->player->ReadyWeapon == nullptr)
|
||||
{
|
||||
ACTION_RETURN_STATE(NULL);
|
||||
}
|
||||
|
@ -1693,7 +1824,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireBullets)
|
|||
DAngle bslope = 0.;
|
||||
int laflags = (flags & FBF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0;
|
||||
|
||||
if ((flags & FBF_USEAMMO) && weapon && ACTION_CALL_FROM_WEAPON())
|
||||
if ((flags & FBF_USEAMMO) && weapon && ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
if (!weapon->DepleteAmmo(weapon->bAltFire, true))
|
||||
return 0; // out of ammo
|
||||
|
@ -1784,7 +1915,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FireCustomMissile)
|
|||
FTranslatedLineTarget t;
|
||||
|
||||
// Only use ammo if called from a weapon
|
||||
if (useammo && ACTION_CALL_FROM_WEAPON() && weapon)
|
||||
if (useammo && ACTION_CALL_FROM_PSPRITE() && weapon)
|
||||
{
|
||||
if (!weapon->DepleteAmmo(weapon->bAltFire, true))
|
||||
return 0; // out of ammo
|
||||
|
@ -1876,7 +2007,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch)
|
|||
pitch = P_AimLineAttack (self, angle, range, &t);
|
||||
|
||||
// only use ammo when actually hitting something!
|
||||
if ((flags & CPF_USEAMMO) && t.linetarget && weapon && ACTION_CALL_FROM_WEAPON())
|
||||
if ((flags & CPF_USEAMMO) && t.linetarget && weapon && ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
if (!weapon->DepleteAmmo(weapon->bAltFire, true))
|
||||
return 0; // out of ammo
|
||||
|
@ -1966,6 +2097,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RailAttack)
|
|||
PARAM_CLASS_OPT (spawnclass, AActor){ spawnclass = NULL; }
|
||||
PARAM_FLOAT_OPT (spawnofs_z) { spawnofs_z = 0; }
|
||||
PARAM_INT_OPT (SpiralOffset) { SpiralOffset = 270; }
|
||||
PARAM_INT_OPT (limit) { limit = 0; }
|
||||
|
||||
if (range == 0) range = 8192;
|
||||
if (sparsity == 0) sparsity=1.0;
|
||||
|
@ -1976,7 +2108,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RailAttack)
|
|||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
|
||||
// only use ammo when actually hitting something!
|
||||
if (useammo && weapon != NULL && ACTION_CALL_FROM_WEAPON())
|
||||
if (useammo && weapon != NULL && ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
if (!weapon->DepleteAmmo(weapon->bAltFire, true))
|
||||
return 0; // out of ammo
|
||||
|
@ -2006,6 +2138,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RailAttack)
|
|||
p.drift = driftspeed;
|
||||
p.spawnclass = spawnclass;
|
||||
p.SpiralOffset = SpiralOffset;
|
||||
p.limit = limit;
|
||||
P_RailAttack(&p);
|
||||
return 0;
|
||||
}
|
||||
|
@ -2043,6 +2176,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun)
|
|||
PARAM_CLASS_OPT (spawnclass, AActor){ spawnclass = NULL; }
|
||||
PARAM_FLOAT_OPT (spawnofs_z) { spawnofs_z = 0; }
|
||||
PARAM_INT_OPT (SpiralOffset) { SpiralOffset = 270; }
|
||||
PARAM_INT_OPT (limit) { limit = 0; }
|
||||
|
||||
if (range == 0) range = 8192.;
|
||||
if (sparsity == 0) sparsity = 1;
|
||||
|
@ -2125,6 +2259,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomRailgun)
|
|||
p.drift = driftspeed;
|
||||
p.spawnclass = spawnclass;
|
||||
p.SpiralOffset = SpiralOffset;
|
||||
p.limit = 0;
|
||||
P_RailAttack(&p);
|
||||
|
||||
self->SetXYZ(savedpos);
|
||||
|
@ -2560,7 +2695,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItem)
|
|||
ACTION_RETURN_BOOL(true);
|
||||
}
|
||||
|
||||
if (ACTION_CALL_FROM_WEAPON())
|
||||
if (ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
// Used from a weapon, so use some ammo
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
|
@ -2685,7 +2820,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ThrowGrenade)
|
|||
{
|
||||
ACTION_RETURN_BOOL(true);
|
||||
}
|
||||
if (ACTION_CALL_FROM_WEAPON())
|
||||
if (ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
// Used from a weapon, so use some ammo
|
||||
AWeapon *weapon = self->player->ReadyWeapon;
|
||||
|
@ -3147,6 +3282,7 @@ enum SPFflag
|
|||
SPF_RELVEL = 1 << 2,
|
||||
SPF_RELACCEL = 1 << 3,
|
||||
SPF_RELANG = 1 << 4,
|
||||
SPF_NOTIMEFREEZE = 1 << 5,
|
||||
};
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnParticle)
|
||||
|
@ -3155,7 +3291,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnParticle)
|
|||
PARAM_COLOR (color);
|
||||
PARAM_INT_OPT (flags) { flags = 0; }
|
||||
PARAM_INT_OPT (lifetime) { lifetime = 35; }
|
||||
PARAM_INT_OPT (size) { size = 1; }
|
||||
PARAM_FLOAT_OPT (size) { size = 1.; }
|
||||
PARAM_ANGLE_OPT (angle) { angle = 0.; }
|
||||
PARAM_FLOAT_OPT (xoff) { xoff = 0; }
|
||||
PARAM_FLOAT_OPT (yoff) { yoff = 0; }
|
||||
|
@ -3168,11 +3304,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnParticle)
|
|||
PARAM_FLOAT_OPT (accelz) { accelz = 0; }
|
||||
PARAM_FLOAT_OPT (startalpha) { startalpha = 1.; }
|
||||
PARAM_FLOAT_OPT (fadestep) { fadestep = -1.; }
|
||||
PARAM_FLOAT_OPT (sizestep) { sizestep = 0.; }
|
||||
|
||||
startalpha = clamp(startalpha, 0., 1.);
|
||||
if (fadestep > 0) fadestep = clamp(fadestep, 0., 1.);
|
||||
size = clamp<int>(size, 0, 65535); // Clamp to word
|
||||
|
||||
size = fabs(size);
|
||||
if (lifetime != 0)
|
||||
{
|
||||
if (flags & SPF_RELANG) angle += self->Angles.Yaw;
|
||||
|
@ -3199,7 +3335,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnParticle)
|
|||
acc.X = accelx * c + accely * s;
|
||||
acc.Y = accelx * s - accely * c;
|
||||
}
|
||||
P_SpawnParticle(self->Vec3Offset(pos), vel, acc, color, !!(flags & SPF_FULLBRIGHT), startalpha, lifetime, size, fadestep);
|
||||
P_SpawnParticle(self->Vec3Offset(pos), vel, acc, color, startalpha, lifetime, size, fadestep, sizestep, flags);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -5737,19 +5873,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetTics)
|
|||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_INT(tics_to_set);
|
||||
|
||||
if (stateowner != self && self->player != NULL && stateowner->IsKindOf(RUNTIME_CLASS(AWeapon)))
|
||||
{ // Is this a weapon? Need to check psp states for a match, then. Blah.
|
||||
for (int i = 0; i < NUMPSPRITES; ++i)
|
||||
if (ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
DPSprite *pspr = self->player->FindPSprite(stateinfo->mPSPIndex);
|
||||
if (pspr != nullptr)
|
||||
{
|
||||
if (self->player->psprites[i].state == callingstate)
|
||||
{
|
||||
self->player->psprites[i].tics = tics_to_set;
|
||||
return 0;
|
||||
}
|
||||
pspr->Tics = tics_to_set;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// Just set tics for self.
|
||||
self->tics = tics_to_set;
|
||||
else if (ACTION_CALL_FROM_ACTOR())
|
||||
{
|
||||
// Just set tics for self.
|
||||
self->tics = tics_to_set;
|
||||
}
|
||||
// for inventory state chains this needs to be ignored.
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -6900,10 +7038,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMovementDirection)
|
|||
{
|
||||
DAngle current = mobj->Angles.Pitch;
|
||||
const DVector2 velocity = mobj->Vel.XY();
|
||||
DAngle pitch = VecToAngle(velocity.Length(), -mobj->Vel.Z);
|
||||
DAngle pitch = VecToAngle(velocity.Length(), mobj->Vel.Z);
|
||||
if (pitchlimit > 0)
|
||||
{
|
||||
DAngle pdelta = deltaangle(current, pitch);
|
||||
DAngle pdelta = deltaangle(-current, pitch);
|
||||
|
||||
if (fabs(pdelta) > pitchlimit)
|
||||
{
|
||||
|
@ -6930,3 +7068,4 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMovementDirection)
|
|||
}
|
||||
ACTION_RETURN_BOOL(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -265,6 +265,11 @@ static FFlagDef ActorFlagDefs[]=
|
|||
DEFINE_FLAG(RF, INVISIBLE, AActor, renderflags),
|
||||
DEFINE_FLAG(RF, FORCEYBILLBOARD, AActor, renderflags),
|
||||
DEFINE_FLAG(RF, FORCEXYBILLBOARD, AActor, renderflags),
|
||||
DEFINE_FLAG(RF, ROLLSPRITE, AActor, renderflags), // [marrub] roll the sprite billboard
|
||||
// [fgsfds] Flat sprites
|
||||
DEFINE_FLAG(RF, FLATSPRITE, AActor, renderflags),
|
||||
DEFINE_FLAG(RF, WALLSPRITE, AActor, renderflags),
|
||||
DEFINE_FLAG(RF, DONTFLIP, AActor, renderflags),
|
||||
|
||||
// Bounce flags
|
||||
DEFINE_FLAG2(BOUNCE_Walls, BOUNCEONWALLS, AActor, BounceFlags),
|
||||
|
|
|
@ -208,7 +208,7 @@ public:
|
|||
virtual bool isConstant() const;
|
||||
virtual void RequestAddress();
|
||||
virtual VMFunction *GetDirectFunction();
|
||||
bool IsNumeric() const { return ValueType->GetRegType() == REGT_INT || ValueType->GetRegType() == REGT_FLOAT; }
|
||||
bool IsNumeric() const { return ValueType != TypeName && (ValueType->GetRegType() == REGT_INT || ValueType->GetRegType() == REGT_FLOAT); }
|
||||
bool IsPointer() const { return ValueType->GetRegType() == REGT_POINTER; }
|
||||
|
||||
virtual ExpEmit Emit(VMFunctionBuilder *build);
|
||||
|
|
|
@ -358,10 +358,22 @@ FxExpression *FxIntCast::Resolve(FCompileContext &ctx)
|
|||
|
||||
if (basex->ValueType->GetRegType() == REGT_INT)
|
||||
{
|
||||
FxExpression *x = basex;
|
||||
basex = NULL;
|
||||
delete this;
|
||||
return x;
|
||||
if (basex->ValueType != TypeName)
|
||||
{
|
||||
FxExpression *x = basex;
|
||||
basex = NULL;
|
||||
delete this;
|
||||
return x;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ugh. This should abort, but too many mods fell into this logic hole somewhere, so this seroious error needs to be reduced to a warning. :(
|
||||
if (!basex->isConstant()) ScriptPosition.Message(MSG_OPTERROR, "Numeric type expected, got a name");
|
||||
else ScriptPosition.Message(MSG_OPTERROR, "Numeric type expected, got \"%s\"", static_cast<FxConstant*>(basex)->GetValue().GetName().GetChars());
|
||||
FxExpression * x = new FxConstant(0, ScriptPosition);
|
||||
delete this;
|
||||
return x;
|
||||
}
|
||||
}
|
||||
else if (basex->ValueType->GetRegType() == REGT_FLOAT)
|
||||
{
|
||||
|
@ -374,12 +386,9 @@ FxExpression *FxIntCast::Resolve(FCompileContext &ctx)
|
|||
}
|
||||
return this;
|
||||
}
|
||||
else
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Numeric type expected");
|
||||
delete this;
|
||||
return NULL;
|
||||
}
|
||||
ScriptPosition.Message(MSG_ERROR, "Numeric type expected");
|
||||
delete this;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -443,14 +452,26 @@ FxExpression *FxFloatCast::Resolve(FCompileContext &ctx)
|
|||
}
|
||||
else if (basex->ValueType->GetRegType() == REGT_INT)
|
||||
{
|
||||
if (basex->isConstant())
|
||||
if (basex->ValueType != TypeName)
|
||||
{
|
||||
ExpVal constval = static_cast<FxConstant *>(basex)->GetValue();
|
||||
FxExpression *x = new FxConstant(constval.GetFloat(), ScriptPosition);
|
||||
if (basex->isConstant())
|
||||
{
|
||||
ExpVal constval = static_cast<FxConstant *>(basex)->GetValue();
|
||||
FxExpression *x = new FxConstant(constval.GetFloat(), ScriptPosition);
|
||||
delete this;
|
||||
return x;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ugh. This should abort, but too many mods fell into this logic hole somewhere, so this seroious error needs to be reduced to a warning. :(
|
||||
if (!basex->isConstant()) ScriptPosition.Message(MSG_OPTERROR, "Numeric type expected, got a name");
|
||||
else ScriptPosition.Message(MSG_OPTERROR, "Numeric type expected, got \"%s\"", static_cast<FxConstant*>(basex)->GetValue().GetName().GetChars());
|
||||
FxExpression *x = new FxConstant(0.0, ScriptPosition);
|
||||
delete this;
|
||||
return x;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2895,7 +2916,7 @@ ExpEmit FxDamage::Emit(VMFunctionBuilder *build)
|
|||
build->Emit(OP_LO, dmgfunc.RegNum, 0/*self*/, build->GetConstantInt(myoffsetof(AActor, Damage)));
|
||||
|
||||
// If it's non-null...
|
||||
build->Emit(OP_EQA_K, 1, dmgfunc.RegNum, build->GetConstantAddress(0, ATAG_GENERIC));
|
||||
build->Emit(OP_EQA_K, 1, dmgfunc.RegNum, build->GetConstantAddress(nullptr, ATAG_GENERIC));
|
||||
size_t nulljump = build->Emit(OP_JMP, 0);
|
||||
|
||||
// ...call it
|
||||
|
@ -3903,7 +3924,7 @@ FxExpression *FxClassTypeCast::Resolve(FCompileContext &ctx)
|
|||
{
|
||||
/* lax */
|
||||
// Since this happens in released WADs it must pass without a terminal error... :(
|
||||
ScriptPosition.Message(MSG_WARNING,
|
||||
ScriptPosition.Message(MSG_OPTERROR,
|
||||
"Unknown class name '%s'",
|
||||
clsname.GetChars(), desttype->TypeName.GetChars());
|
||||
}
|
||||
|
@ -4074,7 +4095,7 @@ FxExpression *FxMultiNameState::Resolve(FCompileContext &ctx)
|
|||
destination = scope->FindState(names.Size()-1, &names[1], false);
|
||||
if (destination == NULL)
|
||||
{
|
||||
ScriptPosition.Message(MSG_WARNING, "Unknown state jump destination");
|
||||
ScriptPosition.Message(MSG_OPTERROR, "Unknown state jump destination");
|
||||
/* lax */
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -457,7 +457,7 @@ DEFINE_PROPERTY(skip_super, 0, Actor)
|
|||
}
|
||||
if (bag.StateSet)
|
||||
{
|
||||
bag.ScriptPosition.Message(MSG_WARNING,
|
||||
bag.ScriptPosition.Message(MSG_OPTERROR,
|
||||
"'skip_super' must appear before any state definitions.");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -152,6 +152,7 @@ enum
|
|||
ATAG_AREGISTER, // pointer to an address register
|
||||
|
||||
ATAG_STATE, // pointer to FState
|
||||
ATAG_STATEINFO, // FState plus some info.
|
||||
ATAG_RNG, // pointer to FRandom
|
||||
};
|
||||
|
||||
|
@ -914,6 +915,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
|
|||
#define PARAM_ANGLE_OPT_AT(p,x) DAngle x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_FLOAT); x = param[p].f; } else
|
||||
#define PARAM_STRING_OPT_AT(p,x) FString x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_STRING); x = param[p].s(); } else
|
||||
#define PARAM_STATE_OPT_AT(p,x) FState *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_STATE || param[p].a == NULL)); x = (FState *)param[p].a; } else
|
||||
#define PARAM_STATEINFO_OPT_AT(p,x) FStateParamInfo *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_STATEINFO || param[p].a == NULL)); x = (FStateParamInfo *)param[p].a; } else
|
||||
#define PARAM_POINTER_OPT_AT(p,x,type) type *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER); x = (type *)param[p].a; } else
|
||||
#define PARAM_OBJECT_OPT_AT(p,x,type) type *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); x = (type *)param[p].a; assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type))); } else
|
||||
#define PARAM_CLASS_OPT_AT(p,x,base) base::MetaClass *x; if ((p) < numparam && param[p].Type != REGT_NIL) { assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); x = (base::MetaClass *)param[p].a; assert(x == NULL || x->IsDescendantOf(RUNTIME_CLASS(base))); } else
|
||||
|
@ -943,6 +945,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
|
|||
#define PARAM_ANGLE_OPT(x) ++paramnum; PARAM_ANGLE_OPT_AT(paramnum,x)
|
||||
#define PARAM_STRING_OPT(x) ++paramnum; PARAM_STRING_OPT_AT(paramnum,x)
|
||||
#define PARAM_STATE_OPT(x) ++paramnum; PARAM_STATE_OPT_AT(paramnum,x)
|
||||
#define PARAM_STATEINFO_OPT(x) ++paramnum; PARAM_STATEINFO_OPT_AT(paramnum,x)
|
||||
#define PARAM_POINTER_OPT(x,type) ++paramnum; PARAM_POINTER_OPT_AT(paramnum,x,type)
|
||||
#define PARAM_OBJECT_OPT(x,type) ++paramnum; PARAM_OBJECT_OPT_AT(paramnum,x,type)
|
||||
#define PARAM_CLASS_OPT(x,base) ++paramnum; PARAM_CLASS_OPT_AT(paramnum,x,base)
|
||||
|
|
|
@ -153,7 +153,7 @@ static void InitTokenMap()
|
|||
TOKENDEF (TK_NoDelay, ZCC_NODELAY);
|
||||
TOKENDEF (TK_Offset, ZCC_OFFSET);
|
||||
TOKENDEF (TK_CanRaise, ZCC_CANRAISE);
|
||||
TOKENDEF (TK_Light, ZCC_CANRAISE);
|
||||
TOKENDEF (TK_Light, ZCC_LIGHT);
|
||||
|
||||
ZCC_InitOperators();
|
||||
ZCC_InitConversions();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#library "strfhelp"
|
||||
|
||||
#include "zcommon.acs"
|
||||
|
||||
#library "strfhelp"
|
||||
|
||||
#define VDOORSPEED 16
|
||||
#define VDOORWAIT 150
|
||||
|
@ -69,6 +70,7 @@ script << 0 >> (int type, int tag)
|
|||
|
||||
case 230:
|
||||
i = GetLineRowOffset() & 31;
|
||||
if (i == 0) break;
|
||||
if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH)
|
||||
{
|
||||
Door_Open (tag, VDOORSPEED);
|
||||
|
@ -78,6 +80,7 @@ script << 0 >> (int type, int tag)
|
|||
|
||||
case 227:
|
||||
i = GetLineRowOffset() & 31;
|
||||
if (i == 0) break;
|
||||
if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH)
|
||||
{
|
||||
Door_Close (tag, VDOORSPEED);
|
||||
|
@ -126,6 +129,7 @@ script << 0 >> (int type, int tag)
|
|||
|
||||
case 193:
|
||||
i = GetLineRowOffset() & 31;
|
||||
if (i == 0) break;
|
||||
if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH)
|
||||
{
|
||||
Floor_LowerToLowest (tag, 8);
|
||||
|
@ -158,6 +162,7 @@ script << 0 >> (int type, int tag)
|
|||
|
||||
case 187:
|
||||
i = GetLineRowOffset() & 31;
|
||||
if (i == 0) break;
|
||||
if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH)
|
||||
{
|
||||
ClearForceField (tag);
|
||||
|
@ -203,6 +208,7 @@ script << 0 >> (int type, int tag)
|
|||
|
||||
case 216:
|
||||
i = GetLineRowOffset() & 31;
|
||||
if (i == 0) break;
|
||||
if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH)
|
||||
{
|
||||
Door_Raise (tag, VDOORSPEED, VDOORWAIT);
|
||||
|
|
|
@ -34,8 +34,7 @@ ACTOR Actor native //: Thinker
|
|||
DefThreshold 100
|
||||
BloodType "Blood", "BloodSplatter", "AxeBlood"
|
||||
ExplosionDamage 128
|
||||
MissileHeight 32
|
||||
|
||||
MissileHeight 32
|
||||
|
||||
// Functions
|
||||
native bool CheckClass(class<Actor> checkclass, int ptr_select = AAPTR_DEFAULT, bool match_superclass = false);
|
||||
|
@ -47,6 +46,8 @@ ACTOR Actor native //: Thinker
|
|||
native int GetSpawnHealth();
|
||||
native int GetGibHealth();
|
||||
native float GetCrouchFactor(int ptr = AAPTR_PLAYER1);
|
||||
native float GetCVar(string cvar);
|
||||
native int GetPlayerInput(int inputnum, int ptr = AAPTR_DEFAULT);
|
||||
|
||||
// Action functions
|
||||
// Meh, MBF redundant functions. Only for DeHackEd support.
|
||||
|
@ -55,7 +56,7 @@ ACTOR Actor native //: Thinker
|
|||
// End of MBF redundant functions.
|
||||
|
||||
action native A_MonsterRail();
|
||||
action native A_BFGSpray(class<Actor> spraytype = "BFGExtra", int numrays = 40, int damagecount = 15, float/*angle*/ angle = 90, float distance = 16*64, float/*angle*/ vrange = 32, int damage = 0);
|
||||
action native A_BFGSpray(class<Actor> spraytype = "BFGExtra", int numrays = 40, int damagecount = 15, float/*angle*/ angle = 90, float distance = 16*64, float/*angle*/ vrange = 32, int damage = 0, int flags = 0);
|
||||
action native A_Pain();
|
||||
action native A_NoBlocking();
|
||||
action native A_XScream();
|
||||
|
@ -189,7 +190,7 @@ ACTOR Actor native //: Thinker
|
|||
native state A_Jump(int chance = 256, state label, ...);
|
||||
native void A_CustomMissile(class<Actor> missiletype, float spawnheight = 32, float spawnofs_xy = 0, float angle = 0, int flags = 0, float pitch = 0, int ptr = AAPTR_TARGET);
|
||||
native void A_CustomBulletAttack(float/*angle*/ spread_xy, float/*angle*/ spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", float range = 0, int flags = 0, int ptr = AAPTR_TARGET);
|
||||
native void A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = "", color color2 = "", int flags = 0, int aim = 0, float maxdiff = 0, class<Actor> pufftype = "BulletPuff", float/*angle*/ spread_xy = 0, float/*angle*/ spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270);
|
||||
native void A_CustomRailgun(int damage, int spawnofs_xy = 0, color color1 = "", color color2 = "", int flags = 0, int aim = 0, float maxdiff = 0, class<Actor> pufftype = "BulletPuff", float/*angle*/ spread_xy = 0, float/*angle*/ spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270, int limit = 0);
|
||||
native state A_JumpIfHealthLower(int health, state label, int ptr_selector = AAPTR_DEFAULT);
|
||||
native state A_JumpIfCloser(float distance, state label, bool noz = false);
|
||||
native state A_JumpIfTracerCloser(float distance, state label, bool noz = false);
|
||||
|
@ -214,7 +215,7 @@ ACTOR Actor native //: Thinker
|
|||
native void A_SetScale(float scalex, float scaley = 0, int ptr = AAPTR_DEFAULT, bool usezero = false);
|
||||
native void A_SetMass(int mass);
|
||||
native void A_SpawnDebris(class<Actor> spawntype, bool transfer_translation = false, float mult_h = 1, float mult_v = 1);
|
||||
native void A_SpawnParticle(color color1, int flags = 0, int lifetime = 35, int size = 1, float angle = 0, float xoff = 0, float yoff = 0, float zoff = 0, float velx = 0, float vely = 0, float velz = 0, float accelx = 0, float accely = 0, float accelz = 0, float startalphaf = 1, float fadestepf = -1);
|
||||
native void A_SpawnParticle(color color1, int flags = 0, int lifetime = 35, float size = 1, float angle = 0, float xoff = 0, float yoff = 0, float zoff = 0, float velx = 0, float vely = 0, float velz = 0, float accelx = 0, float accely = 0, float accelz = 0, float startalphaf = 1, float fadestepf = -1, float sizestep = 0);
|
||||
native state A_CheckSight(state label);
|
||||
native void A_ExtChase(bool usemelee, bool usemissile, bool playactive = true, bool nightmarefast = false);
|
||||
native void A_DropInventory(class<Inventory> itemtype);
|
||||
|
@ -246,6 +247,7 @@ ACTOR Actor native //: Thinker
|
|||
native void A_Burst(class<Actor> chunktype);
|
||||
action native A_Blast(int flags = 0, float strength = 255, float radius = 255, float speed = 20, class<Actor> blasteffect = "BlastEffect", sound blastsound = "BlastRadius");
|
||||
action native A_RadiusThrust(int force = 128, int distance = -1, int flags = RTF_AFFECTSOURCE, int fullthrustdistance = 0);
|
||||
action native A_RadiusDamageSelf(int damage = 128, float distance = 128, int flags = 0, class<Actor> flashtype = "None");
|
||||
action native A_Explode(int damage = -1, int distance = -1, int flags = XF_HURTSOURCE, bool alert = false, int fulldamagedistance = 0, int nails = 0, int naildamage = 10, class<Actor> pufftype = "BulletPuff");
|
||||
action native A_Stop();
|
||||
action native A_Respawn(int flags = 1);
|
||||
|
@ -327,11 +329,17 @@ ACTOR Actor native //: Thinker
|
|||
native state A_CheckSightOrRange(float distance, state label, bool two_dimension = false);
|
||||
native state A_CheckRange(float distance, state label, bool two_dimension = false);
|
||||
action native bool A_FaceMovementDirection(float offset = 0, float anglelimit = 0, float pitchlimit = 0, int flags = 0, int ptr = AAPTR_DEFAULT);
|
||||
action native int A_ClearOverlays(int sstart = 0, int sstop = 0, bool safety = true);
|
||||
|
||||
native void A_RearrangePointers(int newtarget, int newmaster = AAPTR_DEFAULT, int newtracer = AAPTR_DEFAULT, int flags=0);
|
||||
native void A_TransferPointer(int ptr_source, int ptr_recepient, int sourcefield, int recepientfield=AAPTR_DEFAULT, int flags=0);
|
||||
action native A_CopyFriendliness(int ptr_source = AAPTR_MASTER);
|
||||
|
||||
action native bool A_Overlay(int layer, state start = "", bool nooverride = false);
|
||||
action native A_WeaponOffset(float wx = 0, float wy = 32, int flags = 0);
|
||||
action native A_OverlayOffset(int layer = PSP_WEAPON, float wx = 0, float wy = 32, int flags = 0);
|
||||
action native A_OverlayFlags(int layer, int flags, bool set);
|
||||
|
||||
native int ACS_NamedExecute(name script, int mapnum=0, int arg1=0, int arg2=0, int arg3=0);
|
||||
native int ACS_NamedSuspend(name script, int mapnum=0);
|
||||
native int ACS_NamedTerminate(name script, int mapnum=0);
|
||||
|
|
|
@ -18,6 +18,10 @@ const int SF_NOPULLIN = 32;
|
|||
const int SF_NOTURN = 64;
|
||||
const int SF_STEALARMOR = 128;
|
||||
|
||||
// Flags for A_BFGSpray
|
||||
const int BFGF_HURTSOURCE = 1;
|
||||
const int BFGF_MISSILEORIGIN = 2;
|
||||
|
||||
// Flags for A_CustomMissile
|
||||
const int CMF_AIMOFFSET = 1;
|
||||
const int CMF_AIMDIRECTION = 2;
|
||||
|
@ -180,6 +184,9 @@ const int RTF_NOIMPACTDAMAGE = 2;
|
|||
const int RTF_NOTMISSILE = 4;
|
||||
const int RTF_THRUSTZ = 16;
|
||||
|
||||
// Flags for A_RadiusDamageSelf
|
||||
const int RDSF_BFGDAMAGE = 1;
|
||||
|
||||
// Flags for A_Blast
|
||||
const int BF_USEAMMO = 1;
|
||||
const int BF_DONTWARN = 2;
|
||||
|
@ -539,6 +546,7 @@ enum
|
|||
SPF_RELVEL = 1 << 2,
|
||||
SPF_RELACCEL = 1 << 3,
|
||||
SPF_RELANG = 1 << 4,
|
||||
SPF_NOTIMEFREEZE = 1 << 5,
|
||||
|
||||
SPF_RELATIVE = SPF_RELPOS|SPF_RELVEL|SPF_RELACCEL|SPF_RELANG
|
||||
};
|
||||
|
@ -568,4 +576,79 @@ enum
|
|||
WOF_KEEPX = 1,
|
||||
WOF_KEEPY = 1 << 1,
|
||||
WOF_ADD = 1 << 2,
|
||||
};
|
||||
};
|
||||
|
||||
// Flags for psprite layers
|
||||
enum
|
||||
{
|
||||
PSPF_ADDWEAPON = 1 << 0,
|
||||
PSPF_ADDBOB = 1 << 1,
|
||||
PSPF_POWDOUBLE = 1 << 2,
|
||||
PSPF_CVARFAST = 1 << 3,
|
||||
};
|
||||
|
||||
// Default psprite layers
|
||||
enum
|
||||
{
|
||||
PSP_WEAPON = 1,
|
||||
PSP_FLASH = 1000,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
// These are the original inputs sent by the player.
|
||||
INPUT_OLDBUTTONS,
|
||||
INPUT_BUTTONS,
|
||||
INPUT_PITCH,
|
||||
INPUT_YAW,
|
||||
INPUT_ROLL,
|
||||
INPUT_FORWARDMOVE,
|
||||
INPUT_SIDEMOVE,
|
||||
INPUT_UPMOVE,
|
||||
|
||||
// These are the inputs, as modified by P_PlayerThink().
|
||||
// Most of the time, these will match the original inputs, but
|
||||
// they can be different if a player is frozen or using a
|
||||
// chainsaw.
|
||||
MODINPUT_OLDBUTTONS,
|
||||
MODINPUT_BUTTONS,
|
||||
MODINPUT_PITCH,
|
||||
MODINPUT_YAW,
|
||||
MODINPUT_ROLL,
|
||||
MODINPUT_FORWARDMOVE,
|
||||
MODINPUT_SIDEMOVE,
|
||||
MODINPUT_UPMOVE
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
BT_ATTACK = 1<<0, // Press "Fire".
|
||||
BT_USE = 1<<1, // Use button, to open doors, activate switches.
|
||||
BT_JUMP = 1<<2,
|
||||
BT_CROUCH = 1<<3,
|
||||
BT_TURN180 = 1<<4,
|
||||
BT_ALTATTACK = 1<<5, // Press your other "Fire".
|
||||
BT_RELOAD = 1<<6, // [XA] Reload key. Causes state jump in A_WeaponReady.
|
||||
BT_ZOOM = 1<<7, // [XA] Zoom key. Ditto.
|
||||
|
||||
// The rest are all ignored by the play simulation and are for scripts.
|
||||
BT_SPEED = 1<<8,
|
||||
BT_STRAFE = 1<<9,
|
||||
|
||||
BT_MOVERIGHT = 1<<10,
|
||||
BT_MOVELEFT = 1<<11,
|
||||
BT_BACK = 1<<12,
|
||||
BT_FORWARD = 1<<13,
|
||||
BT_RIGHT = 1<<14,
|
||||
BT_LEFT = 1<<15,
|
||||
BT_LOOKUP = 1<<16,
|
||||
BT_LOOKDOWN = 1<<17,
|
||||
BT_MOVEUP = 1<<18,
|
||||
BT_MOVEDOWN = 1<<19,
|
||||
BT_SHOWSCORES = 1<<20,
|
||||
|
||||
BT_USER1 = 1<<21,
|
||||
BT_USER2 = 1<<22,
|
||||
BT_USER3 = 1<<23,
|
||||
BT_USER4 = 1<<24,
|
||||
};
|
||||
|
|
|
@ -11,7 +11,7 @@ ACTOR Inventory native
|
|||
action native A_CustomPunch(int damage, bool norandom = false, int flags = CPF_USEAMMO, class<Actor> pufftype = "BulletPuff", float range = 0, float lifesteal = 0, int lifestealmax = 0, class<BasicArmorBonus> armorbonustype = "ArmorBonus", sound MeleeSound = "", sound MissSound = "");
|
||||
action native A_FireBullets(float/*angle*/ spread_xy, float/*angle*/ spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", int flags = 1, float range = 0);
|
||||
action native A_FireCustomMissile(class<Actor> missiletype, float angle = 0, bool useammo = true, float spawnofs_xy = 0, float spawnheight = 0, int flags = 0, float pitch = 0);
|
||||
action native A_RailAttack(int damage, int spawnofs_xy = 0, bool useammo = true, color color1 = "", color color2 = "", int flags = 0, float maxdiff = 0, class<Actor> pufftype = "BulletPuff", float/*angle*/ spread_xy = 0, float/*angle*/ spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270);
|
||||
action native A_RailAttack(int damage, int spawnofs_xy = 0, bool useammo = true, color color1 = "", color color2 = "", int flags = 0, float maxdiff = 0, class<Actor> pufftype = "BulletPuff", float/*angle*/ spread_xy = 0, float/*angle*/ spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270, int limit = 0);
|
||||
action native A_Light(int extralight);
|
||||
action native A_Light0();
|
||||
action native A_Light1();
|
||||
|
@ -48,8 +48,7 @@ ACTOR Inventory native
|
|||
action native A_RestoreSpecialDoomThing();
|
||||
action native A_RestoreSpecialThing1();
|
||||
action native A_RestoreSpecialThing2();
|
||||
action native A_WeaponOffset(float wx = 0, float wy = 32, int flags = 0);
|
||||
|
||||
|
||||
States
|
||||
{
|
||||
HideDoomish:
|
||||
|
|
|
@ -425,6 +425,11 @@ D0139194F7817BF06F3988DFC47DB38D // Whispers of Satan map29
|
|||
multiexit
|
||||
}
|
||||
|
||||
C98F79709BD7E0E4C19026AB9575EC6F // cc-cod.zip:codlev.wad map07
|
||||
{
|
||||
maskedmidtex
|
||||
}
|
||||
|
||||
D7F6E9F08C39A17026349A04F8C0B0BE // Return to Hadron, e1m9
|
||||
19D03FFC875589E21EDBB7AB74EF4AEF // Return to Hadron, e1m9, 2016.01.03 update
|
||||
{
|
||||
|
|
Binary file not shown.
|
@ -1,5 +1,16 @@
|
|||
// Must be sorted in identification order (easiest to recognize first!)
|
||||
|
||||
IWad
|
||||
{
|
||||
Name = "Delaweare"
|
||||
Autoname = "delaweare"
|
||||
Game = "Doom"
|
||||
Config = "Delaweare"
|
||||
Mapinfo = "mapinfo/doom2.txt"
|
||||
MustContain = "TITLEMAP", "ROVEA0", "GRLURD01", "SQOUI01"
|
||||
BannerColors = "00 00 00", "ff ff ff"
|
||||
}
|
||||
|
||||
IWad
|
||||
{
|
||||
Name = "The Adventures of Square"
|
||||
|
@ -393,4 +404,5 @@ Names
|
|||
"hacx.wad"
|
||||
"hacx2.wad"
|
||||
"square1.pk3"
|
||||
"delaweare.wad"
|
||||
}
|
||||
|
|
|
@ -108,5 +108,7 @@ CMPTMNU_SECTORSOUNDS = "Sector sounds use centre as source";
|
|||
OPTVAL_MAPDEFINEDCOLORSONLY = "Map defined colours only";
|
||||
C_GRAY = "\ccgrey";
|
||||
C_DARKGRAY = "\cudark grey";
|
||||
DSPLYMNU_MOVEBOB = "View bob amount while moving";
|
||||
DSPLYMNU_STILLBOB = "View bob amount while not moving";
|
||||
|
||||
OPTVAL_ANYFIXEDCOLORMAP = "Any fixed colourmap";
|
||||
|
|
|
@ -700,6 +700,8 @@ OptionMenu "VideoOptions"
|
|||
Option "$DSPLYMNU_NOMONSTERINTERPOLATION", "nomonsterinterpolation", "NoYes"
|
||||
Slider "$DSPLYMNU_MENUDIM", "dimamount", 0, 1.0, 0.05, 2
|
||||
ColorPicker "$DSPLYMNU_DIMCOLOR", "dimcolor"
|
||||
Slider "$DSPLYMNU_MOVEBOB", "movebob", 0, 1.0, 0.05, 2
|
||||
Slider "$DSPLYMNU_STILLBOB", "stillbob", 0, 1.0, 0.05, 2
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue