mirror of
https://github.com/ZDoom/gzdoom-last-svn.git
synced 2025-05-30 00:41:19 +00:00
* Updated to ZDoom 4242:
- Be consistent with whitespace tabs. - Stylistic changes. - Fixed: A_RemoveSiblings and [A_RaiseSiblings] did not check that the caller had a master to deduce siblings from. - Fixed: WeaponGiver did not give half ammo when dropped. - Fixed: The constructor for single-lump fonts did not initialize the Cursor field. - Added a NODELAY state flag. This is only valid for a state immediately following a Spawn label. When set, the actor will run this state during its first tick. This means Spawn states may now run an action function if you set this flag. Note that this action function is executed during the actor's first tick, which is not the same as when it is spawned. - Fixed: r4226 [ported in r1557] had bad copy-paste angles for Demon2's XDeath. - A_KillSiblings and A_DamageSiblings didn't check for a valid master. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@1560 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
parent
3b47329254
commit
8d0af5b32d
12 changed files with 179 additions and 91 deletions
|
@ -448,7 +448,7 @@ int DThinker::TickThinkers (FThinkerList *list, FThinkerList *dest)
|
|||
NextToThink = node->NextThinker;
|
||||
if (node->ObjectFlags & OF_JustSpawned)
|
||||
{
|
||||
node->ObjectFlags &= ~OF_JustSpawned;
|
||||
// Leave OF_JustSpawn set until after Tick() so the ticker can check it.
|
||||
if (dest != NULL)
|
||||
{ // Move thinker from this list to the destination list
|
||||
node->Remove();
|
||||
|
@ -463,7 +463,8 @@ int DThinker::TickThinkers (FThinkerList *list, FThinkerList *dest)
|
|||
|
||||
if (!(node->ObjectFlags & OF_EuthanizeMe))
|
||||
{ // Only tick thinkers not scheduled for destruction
|
||||
node->Tick ();
|
||||
node->Tick();
|
||||
node->ObjectFlags &= ~OF_JustSpawned;
|
||||
GC::CheckGC();
|
||||
}
|
||||
node = NextToThink;
|
||||
|
|
|
@ -730,10 +730,41 @@ bool AWeaponGiver::TryPickup(AActor *&toucher)
|
|||
master = weap = static_cast<AWeapon*>(Spawn(di->Name, 0, 0, 0, NO_REPLACE));
|
||||
if (weap != NULL)
|
||||
{
|
||||
fixed_t dropammofactor;
|
||||
weap->ItemFlags &= ~IF_ALWAYSPICKUP; // use the flag of this item only.
|
||||
weap->flags = (weap->flags & ~MF_DROPPED) | (this->flags & MF_DROPPED);
|
||||
if (AmmoGive1 >= 0) weap->AmmoGive1 = AmmoGive1;
|
||||
if (AmmoGive2 >= 0) weap->AmmoGive2 = AmmoGive2;
|
||||
|
||||
// If we're not overriding the ammo given amounts, then apply dropped
|
||||
// item modifications if needed.
|
||||
if (weap->flags & MF_DROPPED)
|
||||
{
|
||||
dropammofactor = G_SkillProperty(SKILLP_DropAmmoFactor);
|
||||
if (dropammofactor < 0)
|
||||
{
|
||||
dropammofactor = FRACUNIT/2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dropammofactor = FRACUNIT;
|
||||
}
|
||||
|
||||
if (AmmoGive1 < 0)
|
||||
{
|
||||
weap->AmmoGive1 = FixedMul(weap->AmmoGive1, dropammofactor);
|
||||
}
|
||||
else
|
||||
{
|
||||
weap->AmmoGive1 = AmmoGive1;
|
||||
}
|
||||
if (AmmoGive2 < 0)
|
||||
{
|
||||
weap->AmmoGive2 = FixedMul(weap->AmmoGive2, dropammofactor);
|
||||
}
|
||||
else
|
||||
{
|
||||
weap->AmmoGive2 = AmmoGive2;
|
||||
}
|
||||
weap->BecomeItem();
|
||||
}
|
||||
else return false;
|
||||
|
|
|
@ -75,6 +75,7 @@ struct FState
|
|||
BYTE Fullbright:1; // State is fullbright
|
||||
BYTE SameFrame:1; // Ignore Frame (except when spawning actor)
|
||||
BYTE Fast:1;
|
||||
BYTE NoDelay:1; // Spawn states executes its action normally
|
||||
int ParameterIndex;
|
||||
|
||||
inline int GetFrame() const
|
||||
|
@ -109,6 +110,10 @@ struct FState
|
|||
{
|
||||
return NextState;
|
||||
}
|
||||
inline bool GetNoDelay() const
|
||||
{
|
||||
return NoDelay;
|
||||
}
|
||||
inline void SetFrame(BYTE frame)
|
||||
{
|
||||
Frame = frame - 'A';
|
||||
|
|
|
@ -3023,14 +3023,14 @@ void ModifyDropAmount(AInventory *inv, int dropamount)
|
|||
{
|
||||
// Half ammo when dropped by bad guys.
|
||||
inv->Amount = inv->GetClass()->Meta.GetMetaInt (AIMETA_DropAmount, MAX(1, FixedMul(inv->Amount, dropammofactor)));
|
||||
inv->ItemFlags|=flagmask;
|
||||
inv->ItemFlags |= flagmask;
|
||||
}
|
||||
else if (inv->IsKindOf (RUNTIME_CLASS(AWeapon)))
|
||||
{
|
||||
// The same goes for ammo from a weapon.
|
||||
static_cast<AWeapon *>(inv)->AmmoGive1 = FixedMul(static_cast<AWeapon *>(inv)->AmmoGive1, dropammofactor);
|
||||
static_cast<AWeapon *>(inv)->AmmoGive2 = FixedMul(static_cast<AWeapon *>(inv)->AmmoGive2, dropammofactor);
|
||||
inv->ItemFlags|=flagmask;
|
||||
inv->ItemFlags |= flagmask;
|
||||
}
|
||||
else if (inv->IsKindOf (RUNTIME_CLASS(ADehackedPickup)))
|
||||
{
|
||||
|
|
|
@ -3496,22 +3496,35 @@ void AActor::Tick ()
|
|||
}
|
||||
|
||||
// cycle through states, calling action functions at transitions
|
||||
assert (state != NULL);
|
||||
if (ObjectFlags & OF_JustSpawned && state->GetNoDelay())
|
||||
{
|
||||
// For immediately spawned objects with the NoDelay flag set for their
|
||||
// Spawn state, explicitly set the current state so that it calls its
|
||||
// action and chains 0-tic states.
|
||||
int starttics = tics;
|
||||
SetState(state);
|
||||
// If the initial state had a duration of 0 tics, let the next state run
|
||||
// normally. Otherwise, increment tics by 1 so that we don't double up ticks.
|
||||
if (starttics > 0 && tics >= 0)
|
||||
{
|
||||
tics++;
|
||||
}
|
||||
}
|
||||
if (tics != -1)
|
||||
{
|
||||
// [RH] Use tics <= 0 instead of == 0 so that spawnstates
|
||||
// of 0 tics work as expected.
|
||||
if (tics <= 0)
|
||||
{
|
||||
assert (state != NULL);
|
||||
if (state == NULL)
|
||||
{
|
||||
Destroy();
|
||||
return;
|
||||
}
|
||||
if (!SetState (state->GetNextState()))
|
||||
if (!SetState(state->GetNextState()))
|
||||
return; // freed itself
|
||||
}
|
||||
|
||||
tics--;
|
||||
}
|
||||
else
|
||||
|
@ -3983,13 +3996,6 @@ void AActor::PostBeginPlay ()
|
|||
Renderer->StateChanged(this);
|
||||
}
|
||||
PrevAngle = angle;
|
||||
|
||||
// [BL] Run zero-delay spawn states now so that we don't create a tic later
|
||||
if(tics == 0 && state)
|
||||
{
|
||||
if (!SetState (state->GetNextState()))
|
||||
return; // freed itself
|
||||
}
|
||||
}
|
||||
|
||||
void AActor::MarkPrecacheSounds() const
|
||||
|
|
|
@ -334,8 +334,8 @@ FStateDefine *FStateDefinitions::FindStateLabelInList(TArray<FStateDefine> & lis
|
|||
if (create)
|
||||
{
|
||||
FStateDefine def;
|
||||
def.Label=name;
|
||||
def.State=NULL;
|
||||
def.Label = name;
|
||||
def.State = NULL;
|
||||
def.DefineFlags = SDF_NEXT;
|
||||
return &list[list.Push(def)];
|
||||
}
|
||||
|
@ -351,12 +351,11 @@ FStateDefine *FStateDefinitions::FindStateLabelInList(TArray<FStateDefine> & lis
|
|||
|
||||
FStateDefine * FStateDefinitions::FindStateAddress(const char *name)
|
||||
{
|
||||
FStateDefine * statedef=NULL;
|
||||
|
||||
FStateDefine *statedef = NULL;
|
||||
TArray<FName> &namelist = MakeStateNameList(name);
|
||||
TArray<FStateDefine> *statelist = &StateLabels;
|
||||
|
||||
TArray<FStateDefine> * statelist = &StateLabels;
|
||||
for(unsigned i=0;i<namelist.Size();i++)
|
||||
for(unsigned i = 0; i < namelist.Size(); i++)
|
||||
{
|
||||
statedef = FindStateLabelInList(*statelist, namelist[i], true);
|
||||
statelist = &statedef->Children;
|
||||
|
@ -379,7 +378,7 @@ void FStateDefinitions::SetStateLabel (const char *statename, FState *state, BYT
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// Adds a new state to the curremt list
|
||||
// Adds a new state to the current list
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
@ -393,6 +392,24 @@ void FStateDefinitions::AddStateLabel (const char *statename)
|
|||
lastlabel = index;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Returns the index a state label points to. May only be called before
|
||||
// installing states.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FStateDefinitions::GetStateLabelIndex (FName statename)
|
||||
{
|
||||
FStateDefine *std = FindStateLabelInList(StateLabels, statename, false);
|
||||
if (std == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
assert((size_t)std->State <= StateArray.Size() + 1);
|
||||
return (int)((ptrdiff_t)std->State - 1);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Finds the state associated with the given name
|
||||
|
@ -863,6 +880,9 @@ bool FStateDefinitions::AddStates(FState *state, const char *framechars)
|
|||
state->Frame = frame;
|
||||
state->SameFrame = noframe;
|
||||
StateArray.Push(*state);
|
||||
|
||||
// NODELAY flag is not carried past the first state
|
||||
state->NoDelay = false;
|
||||
}
|
||||
laststate = &StateArray[StateArray.Size() - 1];
|
||||
laststatebeforelabel = laststate;
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
// This file was automatically generated by the
|
||||
// updaterevision tool. Do not edit by hand.
|
||||
|
||||
#define ZD_SVN_REVISION_STRING "4234"
|
||||
#define ZD_SVN_REVISION_NUMBER 4234
|
||||
#define ZD_SVN_REVISION_STRING "4242"
|
||||
#define ZD_SVN_REVISION_NUMBER 4242
|
||||
|
|
|
@ -91,6 +91,7 @@ public:
|
|||
|
||||
void SetStateLabel (const char * statename, FState * state, BYTE defflags = SDF_STATE);
|
||||
void AddStateLabel (const char * statename);
|
||||
int GetStateLabelIndex (FName statename);
|
||||
void InstallStates(FActorInfo *info, AActor *defaults);
|
||||
int FinishStates (FActorInfo *actor, AActor *defaults);
|
||||
|
||||
|
|
|
@ -2608,11 +2608,14 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_KillSiblings)
|
|||
TThinkerIterator<AActor> it;
|
||||
AActor *mo;
|
||||
|
||||
while ( (mo = it.Next()) )
|
||||
if (self->master != NULL)
|
||||
{
|
||||
if (mo->master == self->master && mo != self)
|
||||
while ( (mo = it.Next()) )
|
||||
{
|
||||
P_DamageMobj(mo, self, self, mo->health, damagetype, DMG_NO_ARMOR | DMG_NO_FACTOR);
|
||||
if (mo->master == self->master && mo != self)
|
||||
{
|
||||
P_DamageMobj(mo, self, self, mo->health, damagetype, DMG_NO_ARMOR | DMG_NO_FACTOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3501,18 +3504,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_DamageSiblings)
|
|||
ACTION_PARAM_INT(amount, 0);
|
||||
ACTION_PARAM_NAME(DamageType, 1);
|
||||
|
||||
while ( (mo = it.Next()) )
|
||||
if (self->master != NULL)
|
||||
{
|
||||
if (mo->master == self->master && mo != self)
|
||||
while ( (mo = it.Next()) )
|
||||
{
|
||||
if (amount > 0)
|
||||
if (mo->master == self->master && mo != self)
|
||||
{
|
||||
P_DamageMobj(mo, self, self, amount, DamageType, DMG_NO_ARMOR);
|
||||
}
|
||||
else if (amount < 0)
|
||||
{
|
||||
amount = -amount;
|
||||
P_GiveBody(mo, amount);
|
||||
if (amount > 0)
|
||||
{
|
||||
P_DamageMobj(mo, self, self, amount, DamageType, DMG_NO_ARMOR);
|
||||
}
|
||||
else if (amount < 0)
|
||||
{
|
||||
amount = -amount;
|
||||
P_GiveBody(mo, amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3741,10 +3747,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckFlag)
|
|||
//===========================================================================
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_RemoveMaster)
|
||||
{
|
||||
if (self->master != NULL)
|
||||
{
|
||||
P_RemoveThing(self->master);
|
||||
}
|
||||
if (self->master != NULL)
|
||||
{
|
||||
P_RemoveThing(self->master);
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -3754,18 +3760,18 @@ DEFINE_ACTION_FUNCTION(AActor, A_RemoveMaster)
|
|||
//===========================================================================
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveChildren)
|
||||
{
|
||||
TThinkerIterator<AActor> it;
|
||||
AActor * mo;
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_BOOL(removeall,0);
|
||||
TThinkerIterator<AActor> it;
|
||||
AActor *mo;
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_BOOL(removeall,0);
|
||||
|
||||
while ( (mo = it.Next()) )
|
||||
{
|
||||
if ( ( mo->master == self ) && ( ( mo->health <= 0 ) || removeall) )
|
||||
{
|
||||
P_RemoveThing(mo);
|
||||
}
|
||||
}
|
||||
while ((mo = it.Next()) != NULL)
|
||||
{
|
||||
if (mo->master == self && (mo->health <= 0 || removeall))
|
||||
{
|
||||
P_RemoveThing(mo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -3775,18 +3781,21 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveChildren)
|
|||
//===========================================================================
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveSiblings)
|
||||
{
|
||||
TThinkerIterator<AActor> it;
|
||||
AActor * mo;
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_BOOL(removeall,0);
|
||||
TThinkerIterator<AActor> it;
|
||||
AActor *mo;
|
||||
ACTION_PARAM_START(1);
|
||||
ACTION_PARAM_BOOL(removeall,0);
|
||||
|
||||
while ( (mo = it.Next()) )
|
||||
{
|
||||
if ( ( mo->master == self->master ) && ( mo != self ) && ( ( mo->health <= 0 ) || removeall) )
|
||||
{
|
||||
P_RemoveThing(mo);
|
||||
}
|
||||
}
|
||||
if (self->master != NULL)
|
||||
{
|
||||
while ((mo = it.Next()) != NULL)
|
||||
{
|
||||
if (mo->master == self->master && mo != self && (mo->health <= 0 || removeall))
|
||||
{
|
||||
P_RemoveThing(mo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -3796,10 +3805,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RemoveSiblings)
|
|||
//===========================================================================
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_RaiseMaster)
|
||||
{
|
||||
if (self->master != NULL)
|
||||
{
|
||||
P_Thing_Raise(self->master);
|
||||
}
|
||||
if (self->master != NULL)
|
||||
{
|
||||
P_Thing_Raise(self->master);
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -3809,16 +3818,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_RaiseMaster)
|
|||
//===========================================================================
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_RaiseChildren)
|
||||
{
|
||||
TThinkerIterator<AActor> it;
|
||||
AActor * mo;
|
||||
TThinkerIterator<AActor> it;
|
||||
AActor *mo;
|
||||
|
||||
while ((mo = it.Next()))
|
||||
{
|
||||
if ( mo->master == self )
|
||||
{
|
||||
P_Thing_Raise(mo);
|
||||
}
|
||||
}
|
||||
while ((mo = it.Next()) != NULL)
|
||||
{
|
||||
if (mo->master == self)
|
||||
{
|
||||
P_Thing_Raise(mo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
@ -3828,16 +3837,19 @@ DEFINE_ACTION_FUNCTION(AActor, A_RaiseChildren)
|
|||
//===========================================================================
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_RaiseSiblings)
|
||||
{
|
||||
TThinkerIterator<AActor> it;
|
||||
AActor * mo;
|
||||
TThinkerIterator<AActor> it;
|
||||
AActor *mo;
|
||||
|
||||
while ( (mo = it.Next()) )
|
||||
{
|
||||
if ( ( mo->master == self->master ) && ( mo != self ) )
|
||||
{
|
||||
P_Thing_Raise(mo);
|
||||
}
|
||||
}
|
||||
if (self->master != NULL)
|
||||
{
|
||||
while ((mo = it.Next()) != NULL)
|
||||
{
|
||||
if (mo->master == self->master && mo != self)
|
||||
{
|
||||
P_Thing_Raise(mo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -275,6 +275,18 @@ do_stop:
|
|||
state.Fast = true;
|
||||
continue;
|
||||
}
|
||||
if (sc.Compare("NODELAY"))
|
||||
{
|
||||
if (bag.statedef.GetStateLabelIndex(NAME_Spawn) == bag.statedef.GetStateCount())
|
||||
{
|
||||
state.NoDelay = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptMessage("NODELAY may only be used immediately after Spawn:");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (sc.Compare("OFFSET"))
|
||||
{
|
||||
// specify a weapon offset
|
||||
|
@ -338,8 +350,7 @@ do_stop:
|
|||
int paramindex = PrepareStateParameters(&state, numparams, bag.Info->Class);
|
||||
int paramstart = paramindex;
|
||||
bool varargs = params[numparams - 1] == '+';
|
||||
int varargcount=0;
|
||||
|
||||
int varargcount = 0;
|
||||
|
||||
if (varargs)
|
||||
{
|
||||
|
|
|
@ -908,6 +908,7 @@ FFont::FFont (int lump)
|
|||
Chars = NULL;
|
||||
PatchRemap = NULL;
|
||||
Name = NULL;
|
||||
Cursor = '_';
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -250,10 +250,10 @@ ACTOR Demon2 : Demon1 8080
|
|||
XDeath:
|
||||
DEM2 H 6
|
||||
DEM2 I 0 A_SpawnItemEx("Demon2Chunk1", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle+90), frandom[DemonChunks](1,4.984375)*sin(Angle+90), 8, 90, ChunkFlags)
|
||||
DEM2 I 0 A_SpawnItemEx("Demon2Chunk2", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle-90), frandom[DemonChunks](1,4.984375)*sin(Angle-90), 8, 90, ChunkFlags)
|
||||
DEM2 I 0 A_SpawnItemEx("Demon2Chunk3", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle-90), frandom[DemonChunks](1,4.984375)*sin(Angle-90), 8, 90, ChunkFlags)
|
||||
DEM2 I 0 A_SpawnItemEx("Demon2Chunk4", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle-90), frandom[DemonChunks](1,4.984375)*sin(Angle-90), 8, 90, ChunkFlags)
|
||||
DEM2 I 6 A_SpawnItemEx("Demon2Chunk5", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle-90), frandom[DemonChunks](1,4.984375)*sin(Angle-90), 8, 90, ChunkFlags)
|
||||
DEM2 I 0 A_SpawnItemEx("Demon2Chunk2", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle-90), frandom[DemonChunks](1,4.984375)*sin(Angle-90), 8, 270, ChunkFlags)
|
||||
DEM2 I 0 A_SpawnItemEx("Demon2Chunk3", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle-90), frandom[DemonChunks](1,4.984375)*sin(Angle-90), 8, 270, ChunkFlags)
|
||||
DEM2 I 0 A_SpawnItemEx("Demon2Chunk4", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle-90), frandom[DemonChunks](1,4.984375)*sin(Angle-90), 8, 270, ChunkFlags)
|
||||
DEM2 I 6 A_SpawnItemEx("Demon2Chunk5", 0,0,45, frandom[DemonChunks](1,4.984375)*cos(Angle-90), frandom[DemonChunks](1,4.984375)*sin(Angle-90), 8, 270, ChunkFlags)
|
||||
Goto Death+2
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue