mirror of
https://github.com/ZDoom/gzdoom-last-svn.git
synced 2025-05-30 00:41:19 +00:00
* Updated to ZDoom 4251:
- Added bounce states. Set the BOUNCE_UseBounceState flag to use them (+USEBOUNCESTATE via DECORATE). - Added a big-endian fix for actor flag fields that aren't four bytes wide. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1565 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
parent
4cb2cf4b45
commit
e164627296
10 changed files with 155 additions and 34 deletions
|
@ -414,6 +414,7 @@ enum EBounceFlags
|
|||
// for them that are not present in ZDoom, so it is necessary to identify it properly.
|
||||
BOUNCE_MBF = 1<<12, // This in itself is not a valid mode, but replaces MBF's MF_BOUNCE flag.
|
||||
BOUNCE_AutoOffFloorOnly = 1<<13, // like BOUNCE_AutoOff, but only on floors
|
||||
BOUNCE_UseBounceState = 1<<14, // Use Bounce[.*] states
|
||||
|
||||
BOUNCE_TypeMask = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors | BOUNCE_AutoOff | BOUNCE_HereticType | BOUNCE_MBF,
|
||||
|
||||
|
@ -1006,6 +1007,11 @@ public:
|
|||
return GetClass()->ActorInfo->FindState(2, names, exact);
|
||||
}
|
||||
|
||||
FState *FindState(int numnames, FName *names, bool exact = false) const
|
||||
{
|
||||
return GetClass()->ActorInfo->FindState(numnames, names, exact);
|
||||
}
|
||||
|
||||
bool HasSpecialDeathStates () const;
|
||||
|
||||
TArray<TObjPtr<AActor> > dynamiclights;
|
||||
|
|
|
@ -181,6 +181,13 @@ xx(Idle)
|
|||
xx(GenericFreezeDeath)
|
||||
xx(GenericCrush)
|
||||
|
||||
// Bounce state names
|
||||
xx(Bounce)
|
||||
xx(Wall)
|
||||
xx(Floor)
|
||||
xx(Ceiling)
|
||||
xx(Creature)
|
||||
|
||||
// Compatible death names for the decorate parser.
|
||||
xx(XDeath)
|
||||
xx(Burn)
|
||||
|
|
|
@ -2869,6 +2869,14 @@ bool FSlide::BounceWall (AActor *mo)
|
|||
}
|
||||
mo->velx = FixedMul(movelen, finecosine[deltaangle]);
|
||||
mo->vely = FixedMul(movelen, finesine[deltaangle]);
|
||||
if (mo->BounceFlags & BOUNCE_UseBounceState)
|
||||
{
|
||||
FState *bouncestate = mo->FindState(NAME_Bounce, NAME_Wall);
|
||||
if (bouncestate != NULL)
|
||||
{
|
||||
mo->SetState(bouncestate);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2906,6 +2914,22 @@ bool P_BounceActor (AActor *mo, AActor *BlockingMobj, bool ontop)
|
|||
mo->velx = FixedMul (speed, finecosine[angle]);
|
||||
mo->vely = FixedMul (speed, finesine[angle]);
|
||||
mo->PlayBounceSound(true);
|
||||
if (mo->BounceFlags & BOUNCE_UseBounceState)
|
||||
{
|
||||
FName names[] = { NAME_Bounce, NAME_Actor, NAME_Creature };
|
||||
FState *bouncestate;
|
||||
int count = 2;
|
||||
|
||||
if ((BlockingMobj->flags & MF_SHOOTABLE) && !(BlockingMobj->flags & MF_NOBLOOD))
|
||||
{
|
||||
count = 3;
|
||||
}
|
||||
bouncestate = mo->FindState(count, names);
|
||||
if (bouncestate != NULL)
|
||||
{
|
||||
mo->SetState(bouncestate);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1383,6 +1383,22 @@ bool AActor::FloorBounceMissile (secplane_t &plane)
|
|||
}
|
||||
|
||||
PlayBounceSound(true);
|
||||
|
||||
// Set bounce state
|
||||
if (BounceFlags & BOUNCE_UseBounceState)
|
||||
{
|
||||
FName names[2];
|
||||
FState *bouncestate;
|
||||
|
||||
names[0] = NAME_Bounce;
|
||||
names[1] = plane.c < 0 ? NAME_Ceiling : NAME_Floor;
|
||||
bouncestate = FindState(2, names);
|
||||
if (bouncestate != NULL)
|
||||
{
|
||||
SetState(bouncestate);
|
||||
}
|
||||
}
|
||||
|
||||
if (BounceFlags & BOUNCE_MBF) // Bring it to rest below a certain speed
|
||||
{
|
||||
if (abs(velz) < (fixed_t)(Mass * GetGravity() / 64))
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
// This file was automatically generated by the
|
||||
// updaterevision tool. Do not edit by hand.
|
||||
|
||||
#define ZD_SVN_REVISION_STRING "4249"
|
||||
#define ZD_SVN_REVISION_NUMBER 4249
|
||||
#define ZD_SVN_REVISION_STRING "4251"
|
||||
#define ZD_SVN_REVISION_NUMBER 4251
|
||||
|
|
|
@ -22,12 +22,15 @@ struct FFlagDef
|
|||
unsigned int flagbit;
|
||||
const char *name;
|
||||
int structoffset;
|
||||
int fieldsize;
|
||||
};
|
||||
|
||||
FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2);
|
||||
void HandleDeprecatedFlags(AActor *defaults, FActorInfo *info, bool set, int index);
|
||||
bool CheckDeprecatedFlags(AActor *actor, FActorInfo *info, int index);
|
||||
bool CheckDeprecatedFlags(const AActor *actor, FActorInfo *info, int index);
|
||||
const char *GetFlagName(unsigned int flagnum, int flagoffset);
|
||||
void ModActorFlag(AActor *actor, FFlagDef *fd, bool set);
|
||||
INTBOOL CheckActorFlag(const AActor *actor, FFlagDef *fd);
|
||||
|
||||
#define FLAG_NAME(flagnum, flagvar) GetFlagName(flagnum, myoffsetof(AActor, flagvar))
|
||||
|
||||
|
|
|
@ -3629,14 +3629,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeFlag)
|
|||
bool linkchange = flagp == &self->flags && (fd->flagbit == MF_NOBLOCKMAP || fd->flagbit == MF_NOSECTOR);
|
||||
|
||||
if (linkchange) self->UnlinkFromWorld();
|
||||
if (expression)
|
||||
{
|
||||
*flagp |= fd->flagbit;
|
||||
}
|
||||
else
|
||||
{
|
||||
*flagp &= ~fd->flagbit;
|
||||
}
|
||||
ModActorFlag(self, fd, expression);
|
||||
if (linkchange) self->LinkToWorld();
|
||||
}
|
||||
kill_after = self->CountsAsKill();
|
||||
|
@ -3721,13 +3714,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckFlag)
|
|||
|
||||
if (fd != NULL)
|
||||
{
|
||||
if (fd->structoffset == -1)
|
||||
{
|
||||
if (CheckDeprecatedFlags(owner, cls->ActorInfo, fd->flagbit)) {
|
||||
ACTION_JUMP(jumpto);
|
||||
}
|
||||
}
|
||||
else if ( fd->flagbit & *(DWORD*)(((char*)owner) + fd->structoffset))
|
||||
if (CheckActorFlag(owner, fd))
|
||||
{
|
||||
ACTION_JUMP(jumpto);
|
||||
}
|
||||
|
|
|
@ -55,10 +55,10 @@ static TArray<FVariableInfo*> variables;
|
|||
//==========================================================================
|
||||
|
||||
// [RH] Keep GCC quiet by not using offsetof on Actor types.
|
||||
#define DEFINE_FLAG(prefix, name, type, variable) { prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1 }
|
||||
#define DEFINE_FLAG2(symbol, name, type, variable) { symbol, #name, (int)(size_t)&((type*)1)->variable - 1 }
|
||||
#define DEFINE_DEPRECATED_FLAG(name) { DEPF_##name, #name, -1 }
|
||||
#define DEFINE_DUMMY_FLAG(name) { DEPF_UNUSED, #name, -1 }
|
||||
#define DEFINE_FLAG(prefix, name, type, variable) { prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable) }
|
||||
#define DEFINE_FLAG2(symbol, name, type, variable) { symbol, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable) }
|
||||
#define DEFINE_DEPRECATED_FLAG(name) { DEPF_##name, #name, -1, 0 }
|
||||
#define DEFINE_DUMMY_FLAG(name) { DEPF_UNUSED, #name, -1, 0 }
|
||||
|
||||
static FFlagDef ActorFlags[]=
|
||||
{
|
||||
|
@ -255,6 +255,7 @@ static FFlagDef ActorFlags[]=
|
|||
DEFINE_FLAG2(BOUNCE_ExplodeOnWater, EXPLODEONWATER, AActor, BounceFlags),
|
||||
DEFINE_FLAG2(BOUNCE_MBF, MBFBOUNCER, AActor, BounceFlags),
|
||||
DEFINE_FLAG2(BOUNCE_AutoOffFloorOnly, BOUNCEAUTOOFFFLOORONLY, AActor, BounceFlags),
|
||||
DEFINE_FLAG2(BOUNCE_UseBounceState, USEBOUNCESTATE, AActor, BounceFlags),
|
||||
|
||||
// Deprecated flags. Handling must be performed in HandleDeprecatedFlags
|
||||
DEFINE_DEPRECATED_FLAG(FIREDAMAGE),
|
||||
|
|
|
@ -441,15 +441,7 @@ void HandleActorFlag(FScanner &sc, Baggage &bag, const char *part1, const char *
|
|||
}
|
||||
else
|
||||
{
|
||||
DWORD * flagvar = (DWORD*) ((char*)defaults + fd->structoffset);
|
||||
if (mod == '+')
|
||||
{
|
||||
*flagvar |= fd->flagbit;
|
||||
}
|
||||
else
|
||||
{
|
||||
*flagvar &= ~fd->flagbit;
|
||||
}
|
||||
ModActorFlag(defaults, fd, mod == '+');
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -95,6 +95,91 @@ static const PClass *FindClassTentative(const char *name, const char *ancestor)
|
|||
return cls;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets or clears a flag, taking field width into account.
|
||||
//
|
||||
//==========================================================================
|
||||
void ModActorFlag(AActor *actor, FFlagDef *fd, bool set)
|
||||
{
|
||||
// Little-Endian machines only need one case, because all field sizes
|
||||
// start at the same address. (Unless the machine has unaligned access
|
||||
// exceptions, in which case you'll need multiple cases for it too.)
|
||||
#ifdef __BIG_ENDIAN__
|
||||
if (fd->fieldsize == 4)
|
||||
#endif
|
||||
{
|
||||
DWORD *flagvar = (DWORD *)((char *)actor + fd->structoffset);
|
||||
if (set)
|
||||
{
|
||||
*flagvar |= fd->flagbit;
|
||||
}
|
||||
else
|
||||
{
|
||||
*flagvar &= ~fd->flagbit;
|
||||
}
|
||||
}
|
||||
#ifdef __BIG_ENDIAN__
|
||||
else if (fd->fieldsize == 2)
|
||||
{
|
||||
WORD *flagvar = (WORD *)((char *)actor + fd->structoffset);
|
||||
if (set)
|
||||
{
|
||||
*flagvar |= fd->flagbit;
|
||||
}
|
||||
else
|
||||
{
|
||||
*flagvar &= ~fd->flagbit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(fd->fieldsize == 1);
|
||||
BYTE *flagvar = (BYTE *)((char *)actor + fd->structoffset);
|
||||
if (set)
|
||||
{
|
||||
*flagvar |= fd->flagbit;
|
||||
}
|
||||
else
|
||||
{
|
||||
*flagvar &= ~fd->flagbit;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Returns whether an actor flag is true or not.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
INTBOOL CheckActorFlag(const AActor *owner, FFlagDef *fd)
|
||||
{
|
||||
if (fd->structoffset == -1)
|
||||
{
|
||||
return CheckDeprecatedFlags(owner, owner->GetClass()->ActorInfo, fd->flagbit);
|
||||
}
|
||||
else
|
||||
#ifdef __BIG_ENDIAN__
|
||||
if (fd->fieldsize == 4)
|
||||
#endif
|
||||
{
|
||||
return fd->flagbit & *(DWORD *)(((char*)owner) + fd->structoffset);
|
||||
}
|
||||
#ifdef __BID_ENDIAN__
|
||||
else if (fd->fieldsize == 2)
|
||||
{
|
||||
return fd->flagbit & *(WORD *)(((char*)owner) + fd->structoffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(fd->fieldsize == 1);
|
||||
return fd->flagbit & *(BYTE *)(((char*)owner) + fd->structoffset);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// HandleDeprecatedFlags
|
||||
|
@ -170,7 +255,7 @@ void HandleDeprecatedFlags(AActor *defaults, FActorInfo *info, bool set, int ind
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
bool CheckDeprecatedFlags(AActor *actor, FActorInfo *info, int index)
|
||||
bool CheckDeprecatedFlags(const AActor *actor, FActorInfo *info, int index)
|
||||
{
|
||||
// A deprecated flag is false if
|
||||
// a) it hasn't been added here
|
||||
|
@ -211,11 +296,11 @@ bool CheckDeprecatedFlags(AActor *actor, FActorInfo *info, int index)
|
|||
return (actor->BounceFlags & (BOUNCE_TypeMask|BOUNCE_UseSeeSound)) == BOUNCE_DoomCompat;
|
||||
|
||||
case DEPF_PICKUPFLASH:
|
||||
return static_cast<AInventory*>(actor)->PickupFlash == PClass::FindClass("PickupFlash");
|
||||
return static_cast<const AInventory*>(actor)->PickupFlash == PClass::FindClass("PickupFlash");
|
||||
// A pure name lookup may or may not be more efficient, but I know no static identifier for PickupFlash.
|
||||
|
||||
case DEPF_INTERHUBSTRIP:
|
||||
return !(static_cast<AInventory*>(actor)->InterHubAmount);
|
||||
return !(static_cast<const AInventory*>(actor)->InterHubAmount);
|
||||
}
|
||||
|
||||
return false; // Any entirely unknown flag is not set
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue