From 3c9b55d1db437404752bea2be3fde461ce557861 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 6 May 2006 03:25:12 +0000 Subject: [PATCH] SVN r81 (trunk) --- docs/rh-log.txt | 8 + src/g_doom/a_cacodemon.cpp | 32 ---- src/g_doom/a_demon.cpp | 32 ---- src/g_doom/a_doomimp.cpp | 33 ---- src/g_doom/a_doomplayer.cpp | 42 ----- src/g_doom/a_lostsoul.cpp | 40 ---- src/g_doom/a_possessed.cpp | 70 ------- src/info.cpp | 88 ++++++--- src/info.h | 3 + src/r_bsp.cpp | 2 +- src/thingdef.cpp | 271 +++++++++++++++++++++------- wadsrc/decorate/decorate.txt | 1 + wadsrc/decorate/doom/deadthings.txt | 123 +++++++++++++ wadsrc/wadsrc.vcproj | 3 + wadsrc/zdoom.lst | 1 + 15 files changed, 400 insertions(+), 349 deletions(-) create mode 100644 wadsrc/decorate/doom/deadthings.txt diff --git a/docs/rh-log.txt b/docs/rh-log.txt index f212cccb1..3ef2785a4 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,6 +1,14 @@ May 5, 2006 +- Added "DropItem None" as a way for inherited actors to avoid dropping items if + their superclass normally does. This is only needed if somebody dehacks + DeadZombieMan or DeadShotgunGuy. +- Moved Doom's dead body actors into DECORATE so that I can finish and verify the + implementation of "States { StateLabel: goto SomeOtherLabel }" constructs. The + alternate method of overriding inherited states is now deprecated, since it's + incompatible with the coming custom state labels. - Changed TAG_MORE to pass a va_list pointer instead of a va_list because it's a non-POD type when targeting several non-ix86 targets with GCC. Hopefully this works. + (Guess it didn't. Boohoo.) May 4, 2006 - Rewrote FName to use only POD types for its static data so that it can be used diff --git a/src/g_doom/a_cacodemon.cpp b/src/g_doom/a_cacodemon.cpp index 31fb63d05..29367b965 100644 --- a/src/g_doom/a_cacodemon.cpp +++ b/src/g_doom/a_cacodemon.cpp @@ -149,35 +149,3 @@ void A_HeadAttack (AActor *self) // launch a missile P_SpawnMissile (self, self->target, RUNTIME_CLASS(ACacodemonBall)); } - -// Dead cacodemon ---------------------------------------------------------- - -class ADeadCacodemon : public ACacodemon -{ - DECLARE_STATELESS_ACTOR (ADeadCacodemon, ACacodemon) -}; - -IMPLEMENT_STATELESS_ACTOR (ADeadCacodemon, Doom, 22, 0) - PROP_SpawnState (S_HEAD_DIE+5) - - // Undo all the changes to default Actor properties that ACacodemon made - PROP_SpawnHealth (1000) - PROP_RadiusFixed (20) - PROP_HeightFixed (16) - PROP_Mass (100) - PROP_SpeedFixed (0) - PROP_PainChance (0) - PROP_Flags (0) - PROP_Flags2 (0) - PROP_Flags3 (0) - PROP_SeeState (255) - PROP_PainState (255) - PROP_MissileState (255) - PROP_DeathState (255) - PROP_RaiseState (255) - PROP_SeeSound ("") - PROP_PainSound ("") - PROP_DeathSound ("") - PROP_ActiveSound ("") - PROP_AttackSound ("") -END_DEFAULTS diff --git a/src/g_doom/a_demon.cpp b/src/g_doom/a_demon.cpp index b7035ffe4..b45dc0062 100644 --- a/src/g_doom/a_demon.cpp +++ b/src/g_doom/a_demon.cpp @@ -130,35 +130,3 @@ void A_SargAttack (AActor *self) P_TraceBleed (damage, self->target, self); } } - -// Dead demon -------------------------------------------------------------- - -class ADeadDemon : public ADemon -{ - DECLARE_STATELESS_ACTOR (ADeadDemon, ADemon) -}; - -IMPLEMENT_STATELESS_ACTOR (ADeadDemon, Doom, 21, 0) - PROP_SpawnState (S_SARG_DIE+5) - - // Undo all the changes to default Actor properties that ADemon made - PROP_SpawnHealth (1000) - PROP_RadiusFixed (20) - PROP_HeightFixed (16) - PROP_Mass (100) - PROP_SpeedFixed (0) - PROP_PainChance (0) - PROP_Flags (0) - PROP_Flags2 (0) - PROP_Flags3 (0) - PROP_SeeState (255) - PROP_PainState (255) - PROP_MissileState (255) - PROP_DeathState (255) - PROP_RaiseState (255) - PROP_SeeSound ("") - PROP_PainSound ("") - PROP_DeathSound ("") - PROP_ActiveSound ("") - PROP_AttackSound ("") -END_DEFAULTS diff --git a/src/g_doom/a_doomimp.cpp b/src/g_doom/a_doomimp.cpp index 21b34bbb5..530bf927a 100644 --- a/src/g_doom/a_doomimp.cpp +++ b/src/g_doom/a_doomimp.cpp @@ -168,36 +168,3 @@ void A_TroopAttack (AActor *self) // launch a missile P_SpawnMissile (self, self->target, RUNTIME_CLASS(ADoomImpBall)); } - -// Dead imp ---------------------------------------------------------------- - -class ADeadDoomImp : public ADoomImp -{ - DECLARE_STATELESS_ACTOR (ADeadDoomImp, ADoomImp) -}; - -IMPLEMENT_STATELESS_ACTOR (ADeadDoomImp, Doom, 20, 0) - PROP_SpawnState (S_TROO_DIE+4) - - // Undo all the changes to default Actor properties that ADoomImp made - PROP_SpawnHealth (1000) - PROP_RadiusFixed (20) - PROP_HeightFixed (16) - PROP_Mass (100) - PROP_SpeedFixed (0) - PROP_PainChance (0) - PROP_Flags (0) - PROP_Flags2 (0) - PROP_Flags3 (0) - PROP_SeeState (255) - PROP_PainState (255) - PROP_MissileState (255) - PROP_DeathState (255) - PROP_XDeathState (255) - PROP_RaiseState (255) - PROP_SeeSound ("") - PROP_PainSound ("") - PROP_DeathSound ("") - PROP_ActiveSound ("") - PROP_AttackSound ("") -END_DEFAULTS diff --git a/src/g_doom/a_doomplayer.cpp b/src/g_doom/a_doomplayer.cpp index 1bc256141..e58acfa16 100644 --- a/src/g_doom/a_doomplayer.cpp +++ b/src/g_doom/a_doomplayer.cpp @@ -207,45 +207,3 @@ void A_DoomSkinCheck2 (AActor *actor) actor->SetState (&ADoomPlayer::States[S_HTIC_XDIE]); } } - -// Dead marine ------------------------------------------------------------- - -class ADeadMarine : public AActor -{ - DECLARE_ACTOR (ADeadMarine, AActor) -}; - -FState ADeadMarine::States[] = -{ - S_NORMAL (PLAY, 'N', -1, NULL , NULL) -}; - -IMPLEMENT_ACTOR (ADeadMarine, Doom, 15, 0) - PROP_SpawnState (0) -END_DEFAULTS - -// Gibbed marine ----------------------------------------------------------- - -class AGibbedMarine : public AActor -{ - DECLARE_ACTOR (AGibbedMarine, AActor) -}; - -FState AGibbedMarine::States[] = -{ - S_NORMAL (PLAY, 'W', -1, NULL , NULL) -}; - -IMPLEMENT_ACTOR (AGibbedMarine, Doom, 10, 145) - PROP_SpawnState (0) -END_DEFAULTS - -// Gibbed marine (extra copy) ---------------------------------------------- - -class AGibbedMarineExtra : public AGibbedMarine -{ - DECLARE_STATELESS_ACTOR (AGibbedMarineExtra, AGibbedMarine) -}; - -IMPLEMENT_STATELESS_ACTOR (AGibbedMarineExtra, Doom, 12, 0) -END_DEFAULTS diff --git a/src/g_doom/a_lostsoul.cpp b/src/g_doom/a_lostsoul.cpp index 95fb595e8..dce9d8cbe 100644 --- a/src/g_doom/a_lostsoul.cpp +++ b/src/g_doom/a_lostsoul.cpp @@ -104,46 +104,6 @@ void A_SkullAttack (AActor *self) self->momz = (dest->z+(dest->height>>1) - self->z) / dist; } -// Dead lost soul ---------------------------------------------------------- - -/* [RH] Considering that the lost soul removes itself when it dies, there - * really wasn't much point in id including this thing, but they did anyway. - * (There was probably a time when it stayed around after death, and this is - * a holdover from that.) - */ - -class ADeadLostSoul : public ALostSoul -{ - DECLARE_STATELESS_ACTOR (ADeadLostSoul, ALostSoul) -}; - -IMPLEMENT_STATELESS_ACTOR (ADeadLostSoul, Doom, 23, 0) - PROP_SpawnState (S_SKULL_DIE+5) - - // Undo all the changes to default Actor properties that ALostSoul made - PROP_SpawnHealth (1000) - PROP_RadiusFixed (20) - PROP_HeightFixed (16) - PROP_Mass (100) - PROP_SpeedFixed (0) - PROP_Damage (0) - PROP_PainChance (0) - PROP_Flags (0) - PROP_Flags2 (0) - PROP_Flags3 (0) - PROP_Flags4 (0) - PROP_RenderStyle (STYLE_Normal) - PROP_SeeState (255) - PROP_PainState (255) - PROP_MissileState (255) - PROP_DeathState (255) - PROP_RaiseState (255) - PROP_PainSound ("") - PROP_DeathSound ("") - PROP_ActiveSound ("") - PROP_AttackSound ("") -END_DEFAULTS - //========================================================================== // // CVAR transsouls diff --git a/src/g_doom/a_possessed.cpp b/src/g_doom/a_possessed.cpp index 94bea8993..4a9ac9f2e 100644 --- a/src/g_doom/a_possessed.cpp +++ b/src/g_doom/a_possessed.cpp @@ -143,41 +143,6 @@ void A_PosAttack (AActor *self) P_LineAttack (self, angle, MISSILERANGE, slope, damage, MOD_UNKNOWN, RUNTIME_CLASS(ABulletPuff)); } -// Dead zombie man --------------------------------------------------------- - -class ADeadZombieMan : public AZombieMan -{ - DECLARE_STATELESS_ACTOR (ADeadZombieMan, AZombieMan) -public: - void NoBlockingSet () {} -}; - -IMPLEMENT_STATELESS_ACTOR (ADeadZombieMan, Doom, 18, 0) - PROP_SpawnState (S_POSS_DIE+4) - - // Undo all the changes to default Actor properties that AZombieMan made - PROP_SpawnHealth (1000) - PROP_RadiusFixed (20) - PROP_HeightFixed (16) - PROP_Mass (100) - PROP_SpeedFixed (0) - PROP_PainChance (0) - PROP_Flags (0) - PROP_Flags2 (0) - PROP_Flags3 (0) - PROP_SeeState (255) - PROP_PainState (255) - PROP_MissileState (255) - PROP_DeathState (255) - PROP_XDeathState (255) - PROP_RaiseState (255) - PROP_SeeSound ("") - PROP_PainSound ("") - PROP_DeathSound ("") - PROP_ActiveSound ("") - PROP_AttackSound ("") -END_DEFAULTS - // Shotgun guy ------------------------------------------------------------- class AShotgunGuy : public AActor @@ -321,41 +286,6 @@ void A_SPosAttack (AActor *self) A_SPosAttack2 (self); } -// Dead shotgun guy -------------------------------------------------------- - -class ADeadShotgunGuy : public AShotgunGuy -{ - DECLARE_STATELESS_ACTOR (ADeadShotgunGuy, AShotgunGuy) -public: - void NoBlockingSet () {} -}; - -IMPLEMENT_STATELESS_ACTOR (ADeadShotgunGuy, Doom, 19, 0) - PROP_SpawnState (S_SPOS_DIE+4) - - // Undo all the changes to default Actor properties that AShotgunGuy made - PROP_SpawnHealth (1000) - PROP_RadiusFixed (20) - PROP_HeightFixed (16) - PROP_Mass (100) - PROP_SpeedFixed (0) - PROP_PainChance (0) - PROP_Flags (0) - PROP_Flags2 (0) - PROP_Flags3 (0) - PROP_SeeState (255) - PROP_PainState (255) - PROP_MissileState (255) - PROP_DeathState (255) - PROP_XDeathState (255) - PROP_RaiseState (255) - PROP_SeeSound ("") - PROP_PainSound ("") - PROP_DeathSound ("") - PROP_ActiveSound ("") - PROP_AttackSound ("") -END_DEFAULTS - // Chaingun guy ------------------------------------------------------------ class AChaingunGuy : public AActor diff --git a/src/info.cpp b/src/info.cpp index 3cd092e84..eadb3df45 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -66,6 +66,8 @@ extern void LoadDecorations (void (*process)(FState *, int)); FArchive &operator<< (FArchive &arc, FState *&state) { + const TypeInfo *info; + if (arc.IsStoring ()) { if (state == NULL) @@ -75,41 +77,17 @@ FArchive &operator<< (FArchive &arc, FState *&state) return arc; } - FActorInfo *info = RUNTIME_CLASS(AActor)->ActorInfo; + info = FState::StaticFindStateOwner (state); - if (state >= info->OwnedStates && - state < info->OwnedStates + info->NumOwnedStates) + if (info != NULL) { - arc.UserWriteClass (RUNTIME_CLASS(AActor)); - arc.WriteCount ((DWORD)(state - info->OwnedStates)); - return arc; + arc.UserWriteClass (info); + arc.WriteCount ((DWORD)(state - info->ActorInfo->OwnedStates)); } - - TAutoSegIterator reg; - while (++reg != NULL) + else { - if (state >= reg->OwnedStates && - state < reg->OwnedStates + reg->NumOwnedStates) - { - arc.UserWriteClass (reg->Class); - arc.WriteCount ((DWORD)(state - reg->OwnedStates)); - return arc; - } + I_Error ("Cannot find owner for state %p\n", state); } - - for (unsigned int i = 0; i < TypeInfo::m_RuntimeActors.Size(); ++i) - { - FActorInfo *info = TypeInfo::m_RuntimeActors[i]->ActorInfo; - if (state >= info->OwnedStates && - state < info->OwnedStates + info->NumOwnedStates) - { - arc.UserWriteClass (info->Class); - arc.WriteCount ((DWORD)(state - info->OwnedStates)); - return arc; - } - } - - I_Error ("Cannot find owner for state %p\n", state); } else { @@ -134,6 +112,56 @@ FArchive &operator<< (FArchive &arc, FState *&state) return arc; } +// Find the actor that a state belongs to. +const TypeInfo *FState::StaticFindStateOwner (const FState *state) +{ + const FActorInfo *info = RUNTIME_CLASS(AActor)->ActorInfo; + + if (state >= info->OwnedStates && + state < info->OwnedStates + info->NumOwnedStates) + { + return RUNTIME_CLASS(AActor); + } + + TAutoSegIterator reg; + while (++reg != NULL) + { + if (state >= reg->OwnedStates && + state < reg->OwnedStates + reg->NumOwnedStates) + { + return reg->Class; + } + } + + for (unsigned int i = 0; i < TypeInfo::m_RuntimeActors.Size(); ++i) + { + info = TypeInfo::m_RuntimeActors[i]->ActorInfo; + if (state >= info->OwnedStates && + state < info->OwnedStates + info->NumOwnedStates) + { + return info->Class; + } + } + + return NULL; +} + +// Find the actor that a state belongs to, but restrict the search to +// the specified type and its ancestors. +const TypeInfo *FState::StaticFindStateOwner (const FState *state, const FActorInfo *info) +{ + while (info != NULL) + { + if (state >= info->OwnedStates && + state < info->OwnedStates + info->NumOwnedStates) + { + return info->Class; + } + info = info->Class->ParentType->ActorInfo; + } + return NULL; +} + // Change sprite names to indices static void ProcessStates (FState *states, int numstates) { diff --git a/src/info.h b/src/info.h index 02cb5a3f0..bc8638df0 100644 --- a/src/info.h +++ b/src/info.h @@ -161,6 +161,9 @@ struct FState { Frame = (Frame & (SF_FULLBRIGHT|SF_BIGTIC)) | (frame-'A'); } + + static const TypeInfo *StaticFindStateOwner (const FState *state); + static const TypeInfo *StaticFindStateOwner (const FState *state, const FActorInfo *info); }; // A truly awful hack to get to the state that called an action function diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 8bfc1782b..5a94b2696 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -78,7 +78,7 @@ fixed_t rw_frontcz1, rw_frontcz2; fixed_t rw_frontfz1, rw_frontfz2; -unsigned int MaxDrawSegs; +size_t MaxDrawSegs; drawseg_t *drawsegs; drawseg_t* firstdrawseg; drawseg_t* ds_p; diff --git a/src/thingdef.cpp b/src/thingdef.cpp index 3734831c5..65d50fbc4 100644 --- a/src/thingdef.cpp +++ b/src/thingdef.cpp @@ -65,6 +65,7 @@ #include "a_hexenglobal.h" #include "a_weaponpiece.h" #include "p_conversation.h" +#include "v_text.h" #include "thingdef.h" @@ -74,7 +75,7 @@ extern TArray Decorations; // allow decal specifications in DECORATE. Decals are loaded after DECORATE so the names must be stored here. TArray DecalNames; // all state parameters -TArray StateParameters; +TArray StateParameters; //========================================================================== // @@ -989,8 +990,11 @@ void A_NoBlocking (AActor *actor) while (di != NULL) { - const TypeInfo *ti = TypeInfo::FindType(di->Name); - if (ti) P_DropItem (actor, ti, di->amount, di->probability); + if (stricmp (di->Name, "None") != 0) + { + const TypeInfo *ti = TypeInfo::FindType(di->Name); + if (ti) P_DropItem (actor, ti, di->amount, di->probability); + } di = di->Next; } } @@ -1422,7 +1426,7 @@ static int ProcessStates(FActorInfo * actor, AActor * defaults, Baggage &bag) FState * laststate = NULL; intptr_t lastlabel = -1; FState ** stp; - int minrequiredstate = 0; + int minrequiredstate = -1; statestring[255] = 0; @@ -1433,8 +1437,14 @@ static int ProcessStates(FActorInfo * actor, AActor * defaults, Baggage &bag) SC_MustGetString(); if (SC_Compare("GOTO")) { - SC_MustGetString(); +do_goto: SC_MustGetString(); strncpy (statestring, sc_String, 255); + if (SC_CheckString (".")) + { + SC_MustGetString (); + strcat (statestring, "."); + strcat (statestring, sc_String); + } if (SC_CheckString ("+")) { SC_MustGetNumber (); @@ -1493,6 +1503,7 @@ static int ProcessStates(FActorInfo * actor, AActor * defaults, Baggage &bag) if (SC_Compare (":")) { + laststate = NULL; do { lastlabel = count; @@ -1501,10 +1512,13 @@ static int ProcessStates(FActorInfo * actor, AActor * defaults, Baggage &bag) else SC_ScriptError("Unknown state label %s", statestring); SC_MustGetString (); + if (SC_Compare ("Goto")) + { + goto do_goto; + } strncpy(statestring, sc_String, 255); SC_MustGetString (); } while (SC_Compare (":")); - laststate = NULL; // continue; } @@ -1745,6 +1759,88 @@ endofstate: return count; } +//========================================================================== +// +// ResolveGotoLabel +// +//========================================================================== + +static FState *ResolveGotoLabel (AActor *actor, const TypeInfo *type, char *name) +{ + FState **stp, *state; + char *namestart = name; + char *label, *offset, *pt; + int v; + + // Check for classname + if ((pt = strchr (name, '.')) != NULL) + { + const char *classname = name; + *pt = '\0'; + name = pt + 1; + + // The classname may either be "Super" to identify this class's immediate + // superclass, or it may the name of any class that this one derives from. + if (stricmp (classname, "Super") == 0) + { + type = type->ParentType; + actor = GetDefaultByType (type); + } + else + { + const TypeInfo *stype = TypeInfo::IFindType (classname); + if (stype == NULL) + { + SC_ScriptError ("%s is an unknown class.", classname); + } + if (!stype->IsDescendantOf (RUNTIME_CLASS(AActor))) + { + SC_ScriptError ("%s is not an actor class, so it has no states.", stype->Name+1); + } + if (!stype->IsAncestorOf (type)) + { + SC_ScriptError ("%s is not derived from %s so cannot access its states.", + type->Name+1, stype->Name+1); + } + if (type != stype) + { + type = stype; + actor = GetDefaultByType (type); + } + } + } + label = name; + // Check for offset + offset = NULL; + if ((pt = strchr (name, '+')) != NULL) + { + *pt = '\0'; + offset = pt + 1; + } + v = offset ? strtol (offset, NULL, 0) : 0; + + // Calculate the state's address. + stp = FindState (actor, type, label); + state = NULL; + if (stp != NULL) + { + if (*stp != NULL) + { + state = *stp + v; + } + else if (v != 0) + { + SC_ScriptError ("Attempt to get invalid state from actor %s.", type->Name+1); + } + } + else + { + SC_ScriptError("Unknown state label %s", label); + } + free(namestart); // free the allocated string buffer + return state; +} + //========================================================================== // // FixStatePointers @@ -1776,14 +1872,15 @@ static void FixStatePointers (FActorInfo *actor, FState **start, FState **stop) // //========================================================================== -static void FixStatePointersAgain (FActorInfo *actor, FState **start, FState **stop) +static void FixStatePointersAgain (FActorInfo *actor, AActor *defaults, FState **start, FState **stop) { FState **stp; for (stp = start; stp <= stop; ++stp) { - if (*stp != NULL && (*stp < actor->OwnedStates || *stp >= actor->OwnedStates + actor->NumOwnedStates)) - { // It doesn't point into this actor's own states, so it must be a label string. Resolve it. + if (*stp != NULL && FState::StaticFindStateOwner (*stp, actor) == NULL) + { // It's not a valid state, so it must be a label string. Resolve it. + *stp = ResolveGotoLabel (defaults, actor->Class, (char *)*stp); } } } @@ -1796,82 +1893,79 @@ static void FixStatePointersAgain (FActorInfo *actor, FState **start, FState **s //========================================================================== static int FinishStates (FActorInfo *actor, AActor *defaults, Baggage &bag) { - FState **stp; int count = StateArray.Size(); - FState * realstates=new FState[count]; + FState *realstates = new FState[count]; int i; int currange; - memcpy(realstates,&StateArray[0],count*sizeof(FState)); - actor->OwnedStates=realstates; - actor->NumOwnedStates=count; - - // adjust the state pointers - // In the case new states are added these must be adjusted, too! - FixStatePointers (actor, &defaults->SpawnState, &defaults->GreetingsState); - if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(AWeapon))) + if (count > 0) { - AWeapon * weapon=(AWeapon*)defaults; + memcpy(realstates, &StateArray[0], count*sizeof(FState)); + actor->OwnedStates = realstates; + actor->NumOwnedStates = count; - FixStatePointers (actor, &weapon->UpState, &weapon->FlashState); - } - if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ACustomInventory))) - { - ACustomInventory * item=(ACustomInventory*)defaults; - - FixStatePointers (actor, &item->UseState, &item->DropState); - } - - for(i = currange = 0; i < count; i++) - { - // resolve labels and jumps - switch((ptrdiff_t)realstates[i].NextState) + // adjust the state pointers + // In the case new states are added these must be adjusted, too! + FixStatePointers (actor, &defaults->SpawnState, &defaults->GreetingsState); + if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(AWeapon))) { - case 0: // next - realstates[i].NextState=(iUpState, &weapon->FlashState); + } + if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ACustomInventory))) + { + ACustomInventory *item = (ACustomInventory*)defaults; - case -2: // wait - realstates[i].NextState=&realstates[i]; - break; + FixStatePointers (actor, &item->UseState, &item->DropState); + } - default: // loop - if ((size_t)realstates[i].NextState < 0x10000) + for(i = currange = 0; i < count; i++) + { + // resolve labels and jumps + switch((ptrdiff_t)realstates[i].NextState) { - realstates[i].NextState=&realstates[(size_t)realstates[i].NextState-1]; - } - else // goto - { - char *label = strtok ((char*)realstates[i].NextState, "+"); - char *labelpt = label; - char *offset = strtok (NULL, "+"); - int v = offset ? strtol (offset, NULL, 0) : 0; + case 0: // next + realstates[i].NextState = (i < count-1 ? &realstates[i+1] : &realstates[0]); + break; - stp = FindState (defaults, bag.Info->Class, label); - if (stp) + case -1: // stop + realstates[i].NextState = NULL; + break; + + case -2: // wait + realstates[i].NextState = &realstates[i]; + break; + + default: // loop + if ((size_t)realstates[i].NextState < 0x10000) { - if (*stp) realstates[i].NextState=*stp+v; - else - { - realstates[i].NextState=NULL; - if (v) - { - SC_ScriptError("Attempt to get invalid state from actor %s\n", actor->Class->Name); - return 0; - } - } + realstates[i].NextState = &realstates[(size_t)realstates[i].NextState-1]; + } + else // goto + { + realstates[i].NextState = ResolveGotoLabel (defaults, bag.Info->Class, (char *)realstates[i].NextState); } - else - SC_ScriptError("Unknown state label %s", label); - free(labelpt); // free the allocated string buffer } } } StateArray.Clear (); + + // Fix state pointers that are gotos + FixStatePointersAgain (actor, defaults, &defaults->SpawnState, &defaults->GreetingsState); + if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(AWeapon))) + { + AWeapon *weapon = (AWeapon*)defaults; + + FixStatePointersAgain (actor, defaults, &weapon->UpState, &weapon->FlashState); + } + if (bag.Info->Class->IsDescendantOf(RUNTIME_CLASS(ACustomInventory))) + { + ACustomInventory *item = (ACustomInventory*)defaults; + + FixStatePointersAgain (actor, defaults, &item->UseState, &item->DropState); + } + return count; } @@ -2063,6 +2157,29 @@ void ProcessActor(void (*process)(FState *, int)) SC_SetCMode (false); } +//========================================================================== +// +// StatePropertyIsDeprecated +// +// Deprecated means it will be removed in a future version. +// +//========================================================================== + +static void StatePropertyIsDeprecated (const char *actorname, const char *prop) +{ + static bool warned = false; + + Printf (TEXTCOLOR_YELLOW "In actor %s, the %s property is deprecated.\n", + actorname, prop); + if (!warned) + { + warned = true; + Printf (TEXTCOLOR_YELLOW "Instead of \"%s \", add this to the actor's States block:\n" + TEXTCOLOR_YELLOW " %s:\n" + TEXTCOLOR_YELLOW " Goto \n", prop, prop); + } +} + //========================================================================== // // Property parsers @@ -2336,6 +2453,7 @@ static void ActorDropItem (AActor *defaults, Baggage &bag) //========================================================================== static void ActorSpawnState (AActor *defaults, Baggage &bag) { + StatePropertyIsDeprecated (bag.Info->Class->Name+1, "Spawn"); defaults->SpawnState=CheckState (bag.CurrentState, bag.Info->Class); } @@ -2344,6 +2462,7 @@ static void ActorSpawnState (AActor *defaults, Baggage &bag) //========================================================================== static void ActorSeeState (AActor *defaults, Baggage &bag) { + StatePropertyIsDeprecated (bag.Info->Class->Name+1, "See"); defaults->SeeState=CheckState (bag.CurrentState, bag.Info->Class); } @@ -2352,6 +2471,7 @@ static void ActorSeeState (AActor *defaults, Baggage &bag) //========================================================================== static void ActorMeleeState (AActor *defaults, Baggage &bag) { + StatePropertyIsDeprecated (bag.Info->Class->Name+1, "Melee"); defaults->MeleeState=CheckState (bag.CurrentState, bag.Info->Class); } @@ -2360,6 +2480,7 @@ static void ActorMeleeState (AActor *defaults, Baggage &bag) //========================================================================== static void ActorMissileState (AActor *defaults, Baggage &bag) { + StatePropertyIsDeprecated (bag.Info->Class->Name+1, "Missile"); defaults->MissileState=CheckState (bag.CurrentState, bag.Info->Class); } @@ -2368,6 +2489,7 @@ static void ActorMissileState (AActor *defaults, Baggage &bag) //========================================================================== static void ActorPainState (AActor *defaults, Baggage &bag) { + StatePropertyIsDeprecated (bag.Info->Class->Name+1, "Pain"); defaults->PainState=CheckState (bag.CurrentState, bag.Info->Class); } @@ -2376,6 +2498,7 @@ static void ActorPainState (AActor *defaults, Baggage &bag) //========================================================================== static void ActorDeathState (AActor *defaults, Baggage &bag) { + StatePropertyIsDeprecated (bag.Info->Class->Name+1, "Death"); defaults->DeathState=CheckState (bag.CurrentState, bag.Info->Class); } @@ -2384,6 +2507,7 @@ static void ActorDeathState (AActor *defaults, Baggage &bag) //========================================================================== static void ActorXDeathState (AActor *defaults, Baggage &bag) { + StatePropertyIsDeprecated (bag.Info->Class->Name+1, "XDeath"); defaults->XDeathState=CheckState (bag.CurrentState, bag.Info->Class); } @@ -2392,6 +2516,7 @@ static void ActorXDeathState (AActor *defaults, Baggage &bag) //========================================================================== static void ActorBurnState (AActor *defaults, Baggage &bag) { + StatePropertyIsDeprecated (bag.Info->Class->Name+1, "Burn"); defaults->BDeathState=CheckState (bag.CurrentState, bag.Info->Class); } @@ -2400,6 +2525,7 @@ static void ActorBurnState (AActor *defaults, Baggage &bag) //========================================================================== static void ActorIceState (AActor *defaults, Baggage &bag) { + StatePropertyIsDeprecated (bag.Info->Class->Name+1, "Ice"); defaults->IDeathState=CheckState (bag.CurrentState, bag.Info->Class); } @@ -2408,6 +2534,7 @@ static void ActorIceState (AActor *defaults, Baggage &bag) //========================================================================== static void ActorRaiseState (AActor *defaults, Baggage &bag) { + StatePropertyIsDeprecated (bag.Info->Class->Name+1, "Raise"); defaults->RaiseState=CheckState (bag.CurrentState, bag.Info->Class); } @@ -2416,6 +2543,7 @@ static void ActorRaiseState (AActor *defaults, Baggage &bag) //========================================================================== static void ActorCrashState (AActor *defaults, Baggage &bag) { + StatePropertyIsDeprecated (bag.Info->Class->Name+1, "Crash"); defaults->CrashState=CheckState (bag.CurrentState, bag.Info->Class); } @@ -2424,6 +2552,7 @@ static void ActorCrashState (AActor *defaults, Baggage &bag) //========================================================================== static void ActorCrushState (AActor *defaults, Baggage &bag) { + StatePropertyIsDeprecated (bag.Info->Class->Name+1, "Crush"); defaults->CrushState=CheckState (bag.CurrentState, bag.Info->Class); } @@ -2432,6 +2561,7 @@ static void ActorCrushState (AActor *defaults, Baggage &bag) //========================================================================== static void ActorWoundState (AActor *defaults, Baggage &bag) { + StatePropertyIsDeprecated (bag.Info->Class->Name+1, "Wound"); defaults->WoundState=CheckState (bag.CurrentState, bag.Info->Class); } @@ -2440,6 +2570,7 @@ static void ActorWoundState (AActor *defaults, Baggage &bag) //========================================================================== static void ActorDisintegrateState (AActor *defaults, Baggage &bag) { + StatePropertyIsDeprecated (bag.Info->Class->Name+1, "Disintegrate"); defaults->EDeathState=CheckState (bag.CurrentState, bag.Info->Class); } @@ -2448,6 +2579,7 @@ static void ActorDisintegrateState (AActor *defaults, Baggage &bag) //========================================================================== static void ActorHealState (AActor *defaults, Baggage &bag) { + StatePropertyIsDeprecated (bag.Info->Class->Name+1, "Heal"); defaults->HealState=CheckState (bag.CurrentState, bag.Info->Class); } @@ -2456,6 +2588,7 @@ static void ActorHealState (AActor *defaults, Baggage &bag) //========================================================================== static void ActorYesState (AActor *defaults, Baggage &bag) { + StatePropertyIsDeprecated (bag.Info->Class->Name+1, "Yes"); defaults->YesState=CheckState (bag.CurrentState, bag.Info->Class); } @@ -2464,6 +2597,7 @@ static void ActorYesState (AActor *defaults, Baggage &bag) //========================================================================== static void ActorNoState (AActor *defaults, Baggage &bag) { + StatePropertyIsDeprecated (bag.Info->Class->Name+1, "No"); defaults->NoState=CheckState (bag.CurrentState, bag.Info->Class); } @@ -2472,6 +2606,7 @@ static void ActorNoState (AActor *defaults, Baggage &bag) //========================================================================== static void ActorGreetingsState (AActor *defaults, Baggage &bag) { + StatePropertyIsDeprecated (bag.Info->Class->Name+1, "Greetings"); defaults->GreetingsState=CheckState (bag.CurrentState, bag.Info->Class); } @@ -3492,5 +3627,3 @@ void FinishThingdef() } } } - - diff --git a/wadsrc/decorate/decorate.txt b/wadsrc/decorate/decorate.txt index a4b997a2d..4ee7eee48 100644 --- a/wadsrc/decorate/decorate.txt +++ b/wadsrc/decorate/decorate.txt @@ -1,6 +1,7 @@ #include "actors/shared/debris.txt" #include "actors/shared/splashes.txt" +#include "actors/doom/deadthings.txt" #include "actors/doom/doomarmor.txt" #include "actors/doom/doomartifacts.txt" #include "actors/doom/doomkeys.txt" diff --git a/wadsrc/decorate/doom/deadthings.txt b/wadsrc/decorate/doom/deadthings.txt new file mode 100644 index 000000000..435be5d43 --- /dev/null +++ b/wadsrc/decorate/doom/deadthings.txt @@ -0,0 +1,123 @@ +// Gibbed marine ----------------------------------------------------------- + +actor GibbedMarine 10 +{ + Game Doom + States + { + Spawn: + PLAY W -1 + Stop + } +} + +// Gibbed marine (extra copy) ---------------------------------------------- + +actor GibbedMarineExtra : GibbedMarine 12 +{ + Game Doom +} + +// Dead marine ------------------------------------------------------------- + +actor DeadMarine 15 +{ + Game Doom + States + { + Spawn: + PLAY N -1 + Stop + } +} + +/* If it wasn't for Dehacked compatibility, the rest of these would be + * better defined as single frame states. But since Doom reused the + * dead state from the original monsters, we need to do the same. + */ + +// Dead zombie man --------------------------------------------------------- + +actor DeadZombieMan : ZombieMan 18 +{ + Game Doom + DropItem None + Skip_Super + States + { + Spawn: + Goto Super.Death+4 + } +} + +// Dead shotgun guy -------------------------------------------------------- + +actor DeadShotgunGuy : ShotgunGuy 19 +{ + Game Doom + DropItem None + Skip_Super + States + { + Spawn: + Goto Super.Death+4 + } +}; + +// Dead imp ---------------------------------------------------------------- + +actor DeadDoomImp : DoomImp 20 +{ + Game Doom + Skip_Super + States + { + Spawn: + Goto Super.Death+4 + } +} + +// Dead demon -------------------------------------------------------------- + +actor DeadDemon : Demon 21 +{ + Game Doom + Skip_Super + States + { + Spawn: + Goto Super.Death+5 + } +} + +// Dead cacodemon ---------------------------------------------------------- + +actor DeadCacodemon : Cacodemon 22 +{ + Game Doom + Skip_Super + States + { + Spawn: + Goto Super.Death+5 + } +} + +// Dead lost soul ---------------------------------------------------------- + +/* [RH] Considering that the lost soul removes itself when it dies, there + * really wasn't much point in id including this thing, but they did anyway. + * (There was probably a time when it stayed around after death, and this is + * a holdover from that.) + */ + +actor DeadLostSoul : LostSoul 23 +{ + Game Doom + Skip_Super + States + { + Spawn: + Goto Super.Death+5 + } +} diff --git a/wadsrc/wadsrc.vcproj b/wadsrc/wadsrc.vcproj index e5566e5aa..781e005e3 100644 --- a/wadsrc/wadsrc.vcproj +++ b/wadsrc/wadsrc.vcproj @@ -238,6 +238,9 @@ + + diff --git a/wadsrc/zdoom.lst b/wadsrc/zdoom.lst index 8d0062f8f..8724a6d3e 100644 --- a/wadsrc/zdoom.lst +++ b/wadsrc/zdoom.lst @@ -187,6 +187,7 @@ decorate.txt decorate/decorate.txt actors/shared/debris.txt decorate/shared/debris.txt actors/shared/splashes.txt decorate/shared/splashes.txt +actors/doom/deadthings.txt decorate/doom/deadthings.txt actors/doom/doomarmor.txt decorate/doom/doomarmor.txt actors/doom/doomartifacts.txt decorate/doom/doomartifacts.txt actors/doom/doomkeys.txt decorate/doom/doomkeys.txt