From 5ac0789e6e11d79ddcbd9c9dc00c2d5bd8ffbd43 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 31 Jul 2006 10:22:53 +0000 Subject: [PATCH] - Added a type check to Spawn(actorname,...) to allow it to print a meaningful message instead of the nondescript 'Tried to spawn a class-less actor'. - Converted AGlassJunk to DECORATE and made the spawn function a little more flexible so that replacing the shard is easier. - Converted ABloodSplatter to DECORATE. - Removed A_Jiggle because it never worked properly. - Changed DECORATE parser to allow commas between arguments for multi- argument properties. For all newly added properties this format will become mandatory but for backwards compatibility it is optional for old ones. - Added a check for negative indices to TAutoGrowArray::SetVal to prevent passing an index of -1 from crashing the game. - Fixed: Morphing must clear the weapon's flash sprite. - Fixed: Resurrecting a morphed player caused a crash. - Fixed: Random sounds that recursively refer to themselves caused a stack overflow. Now they print a warning and get ignored. SVN r277 (trunk) --- docs/rh-log.txt | 19 +++++++++ src/actor.h | 5 +-- src/g_heretic/a_chicken.cpp | 5 +++ src/g_hexen/a_pig.cpp | 1 + src/m_cheat.cpp | 20 ++++----- src/p_lnspec.cpp | 39 +----------------- src/p_mobj.cpp | 40 +++++------------- src/s_advsound.cpp | 5 +++ src/tarray.h | 2 + src/thingdef.cpp | 52 ++++++++++++++++++++---- src/thingdef_codeptr.cpp | 24 ----------- wadsrc/decorate/decorate.txt | 1 + wadsrc/decorate/raven/ravenartifacts.txt | 2 +- wadsrc/decorate/shared/blood.txt | 25 ++++++++++++ wadsrc/decorate/shared/debris.txt | 28 +++++++++++++ wadsrc/zdoom.lst | 1 + 16 files changed, 156 insertions(+), 113 deletions(-) create mode 100644 wadsrc/decorate/shared/blood.txt diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 1abb7c0ec..171ba3a02 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,22 @@ +July 31, 2006 (Changes by Graf Zahl) +- Added a type check to Spawn(actorname,...) to allow it to print a + meaningful message instead of the nondescript + 'Tried to spawn a class-less actor'. +- Converted AGlassJunk to DECORATE and made the spawn function a little + more flexible so that replacing the shard is easier. +- Converted ABloodSplatter to DECORATE. +- Removed A_Jiggle because it never worked properly. +- Changed DECORATE parser to allow commas between arguments for multi- + argument properties. For all newly added properties this format will + become mandatory but for backwards compatibility it is optional for + old ones. +- Added a check for negative indices to TAutoGrowArray::SetVal to prevent + passing an index of -1 from crashing the game. +- Fixed: Morphing must clear the weapon's flash sprite. +- Fixed: Resurrecting a morphed player caused a crash. +- Fixed: Random sounds that recursively refer to themselves caused a stack + overflow. Now they print a warning and get ignored. + July 30, 2006 (Changes by Graf Zahl) - Added Grubber's GetPlayerInfo ACS function. - Fixed: Starting a game without skill menu always started the first episode. diff --git a/src/actor.h b/src/actor.h index 9b2eb00a4..1d915ee21 100644 --- a/src/actor.h +++ b/src/actor.h @@ -800,10 +800,7 @@ inline AActor *Spawn (const PClass *type, fixed_t x, fixed_t y, fixed_t z, repla return AActor::StaticSpawn (type, x, y, z, allowreplacement); } -inline AActor *Spawn (const char *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement) -{ - return AActor::StaticSpawn (PClass::FindClass(type), x, y, z, allowreplacement); -} +AActor *Spawn (const char *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement); template inline T *Spawn (fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement) diff --git a/src/g_heretic/a_chicken.cpp b/src/g_heretic/a_chicken.cpp index 6339eba2e..77d785807 100644 --- a/src/g_heretic/a_chicken.cpp +++ b/src/g_heretic/a_chicken.cpp @@ -212,6 +212,11 @@ void AChickenPlayer::ActivateMorphWeapon () { P_SetPsprite (player, ps_weapon, player->ReadyWeapon->GetReadyState()); } + else + { + P_SetPsprite (player, ps_weapon, NULL); + } + P_SetPsprite (player, ps_flash, NULL); } // Chicken (non-player) ----------------------------------------------------- diff --git a/src/g_hexen/a_pig.cpp b/src/g_hexen/a_pig.cpp index 826ea151f..1f5a140f5 100644 --- a/src/g_hexen/a_pig.cpp +++ b/src/g_hexen/a_pig.cpp @@ -194,6 +194,7 @@ void APigPlayer::ActivateMorphWeapon () { P_SetPsprite (player, ps_weapon, NULL); } + P_SetPsprite (player, ps_flash, NULL); } // Pig (non-player) --------------------------------------------------------- diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index ce542d7d2..97cc216f2 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -279,15 +279,6 @@ void cht_DoCheat (player_t *player, int cheat) else { player->playerstate = PST_LIVE; - if (player->mo->tracer != NULL) - { - APlayerPawn * pmo = player->mo; - player->mo = (APlayerPawn*)player->mo->tracer; - pmo->Destroy(); - player->mo->player=player; - player->mo->renderflags &= ~RF_INVISIBLE; - player->morphTics = 0; - } player->health = player->mo->health = player->mo->GetDefault()->health; player->viewheight = ((APlayerPawn *)player->mo->GetDefault())->ViewHeight; player->mo->flags = player->mo->GetDefault()->flags; @@ -296,7 +287,16 @@ void cht_DoCheat (player_t *player, int cheat) player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players)); player->mo->DamageType = MOD_UNKNOWN; // player->mo->GiveDefaultInventory(); - P_SetPsprite(player, ps_weapon, player->ReadyWeapon->UpState); + if (player->ReadyWeapon != NULL) + { + P_SetPsprite(player, ps_weapon, player->ReadyWeapon->UpState); + } + + if (player->morphTics > 0) + { + P_UndoPlayerMorph(player); + } + } } break; diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 8a74c9d07..312dd8544 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2523,41 +2523,6 @@ FUNC(LS_ClearForceField) return rtn; } -class AGlassJunk : public AActor -{ - DECLARE_ACTOR (AGlassJunk, AActor); -}; - -// [RH] Slowly fade the shards away instead of abruptly removing them. -void A_GlassAway (AActor *self) -{ - self->alpha -= FRACUNIT/32; - if (self->alpha <= 0) - { - self->Destroy (); - } -} - -FState AGlassJunk::States[] = -{ - // Are the first three frames used anywhere? - S_NORMAL (SHAR, 'A', 128, NULL, &States[6]), - S_NORMAL (SHAR, 'B', 128, NULL, &States[6]), - S_NORMAL (SHAR, 'C', 128, NULL, &States[6]), - S_NORMAL (SHAR, 'D', 128, NULL, &States[6]), - S_NORMAL (SHAR, 'E', 128, NULL, &States[6]), - S_NORMAL (SHAR, 'F', 128, NULL, &States[6]), - - S_NORMAL (----, 'A', 1, A_GlassAway, &States[6]) -}; - -IMPLEMENT_ACTOR (AGlassJunk, Any, -1, 0) - PROP_SpawnState (0) - PROP_Flags (MF_NOCLIP | MF_NOBLOCKMAP | MF_STRIFEx8000000) - PROP_RenderStyle (STYLE_Translucent) - PROP_Alpha (HX_SHADOW) -END_DEFAULTS - FUNC(LS_GlassBreak) // GlassBreak (bNoJunk) { @@ -2591,10 +2556,10 @@ FUNC(LS_GlassBreak) for (int i = 0; i < 7; ++i) { - glass = Spawn (x, y, ONFLOORZ, ALLOW_REPLACE); + glass = Spawn("GlassJunk", x, y, ONFLOORZ, ALLOW_REPLACE); glass->z += 24 * FRACUNIT; - glass->SetState (&AGlassJunk::States[3 + pr_glass() % 3]); + glass->SetState (glass->SpawnState + (pr_glass() % glass->health)); an = pr_glass() << (32-8); glass->angle = an; an >>= ANGLETOFINESHIFT; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index c0bf8463a..4cd78d6e7 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3150,6 +3150,16 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t return actor; } +AActor *Spawn (const char *type, fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement) +{ + const PClass *cls = PClass::FindClass(type); + if (cls == NULL) + { + I_Error("Attempt to spawn actor of unknown type '%s'\n", type); + } + return AActor::StaticSpawn (cls, x, y, z, allowreplacement); +} + void AActor::LevelSpawned () { if (tics > 0 && !(flags4 & MF4_SYNCHRONIZED)) @@ -3906,34 +3916,6 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc P_DrawSplash2 (40, x, y, z, dir, 2, bloodcolor); } -// Blood splatter ----------------------------------------------------------- - -class ABloodSplatter : public AActor -{ - DECLARE_ACTOR (ABloodSplatter, AActor) -}; - -FState ABloodSplatter::States[] = -{ -#define S_BLOODSPLATTER 0 - S_NORMAL (BLUD, 'C', 8, NULL, &States[S_BLOODSPLATTER+1]), - S_NORMAL (BLUD, 'B', 8, NULL, &States[S_BLOODSPLATTER+2]), - S_NORMAL (BLUD, 'A', 8, NULL, NULL), - -#define S_BLOODSPLATTERX (S_BLOODSPLATTER+3) - S_NORMAL (BLUD, 'A', 6, NULL, NULL) -}; - -IMPLEMENT_ACTOR (ABloodSplatter, Raven, -1, 0) - PROP_SpawnState (S_BLOODSPLATTER) - PROP_DeathState (S_BLOODSPLATTERX) - PROP_RadiusFixed (2) - PROP_HeightFixed (4) - PROP_Flags (MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF) - PROP_Flags2 (MF2_NOTELEPORT|MF2_CANNOTPUSH) - PROP_Mass (5) -END_DEFAULTS - //--------------------------------------------------------------------------- // // PROC P_BloodSplatter @@ -3948,7 +3930,7 @@ void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator) { AActor *mo; - mo = Spawn (x, y, z, ALLOW_REPLACE); + mo = Spawn("BloodSplatter", x, y, z, ALLOW_REPLACE); mo->target = originator; mo->momx = pr_splatter.Random2 () << 10; mo->momy = pr_splatter.Random2 () << 10; diff --git a/src/s_advsound.cpp b/src/s_advsound.cpp index 8000f43fb..ede1cb907 100644 --- a/src/s_advsound.cpp +++ b/src/s_advsound.cpp @@ -966,6 +966,11 @@ static void S_AddSNDINFO (int lump) while (SC_GetString () && !SC_Compare ("}")) { WORD sfxto = S_FindSoundTentative (sc_String); + if (sfxto == random.SfxHead) + { + Printf("Definition of random sound '%s' refers to itself recursively.", sc_String); + continue; + } list.Push (sfxto); } if (list.Size() == 1) diff --git a/src/tarray.h b/src/tarray.h index 0cd10a203..3037cf78d 100644 --- a/src/tarray.h +++ b/src/tarray.h @@ -288,6 +288,8 @@ public: } void SetVal (unsigned int index, T val) { + if ((int)index < 0) return; // These always result in an out of memory condition. + if (index >= this->Size()) { this->Resize (index + 1); diff --git a/src/thingdef.cpp b/src/thingdef.cpp index 4711e9c8f..9deb90f80 100644 --- a/src/thingdef.cpp +++ b/src/thingdef.cpp @@ -485,7 +485,6 @@ ACTOR(BishopMissileWeave) ACTOR(CStaffMissileSlither) ACTOR(CheckSight) ACTOR(ExtChase) -ACTOR(Jiggle) ACTOR(DropInventory) ACTOR(SetBlend) ACTOR(JumpIf) @@ -675,7 +674,6 @@ AFuncDesc AFTable[]= FUNC(A_SpawnDebris, "M") FUNC(A_CheckSight, "L") FUNC(A_ExtChase, "XXyx") - FUNC(A_Jiggle, "XX") FUNC(A_DropInventory, "M") FUNC(A_SetBlend, "CXXc") FUNC(A_ChangeFlag, "TX") @@ -2034,7 +2032,36 @@ static FState *CheckState(int statenum, PClass *type) } +//========================================================================== +// +// Checks for a numeric parameter which may or may not be preceded by a comma +// +//========================================================================== +static bool CheckNumParm() +{ + if (SC_CheckString(",")) + { + SC_MustGetNumber(); + return true; + } + else + { + return !!SC_CheckNumber(); + } +} +static bool CheckFloatParm() +{ + if (SC_CheckString(",")) + { + SC_MustGetFloat(); + return true; + } + else + { + return !!SC_CheckFloat(); + } +} //========================================================================== // @@ -2464,6 +2491,8 @@ static void ActorActiveSound (AActor *defaults, Baggage &bag) //========================================================================== static void ActorDropItem (AActor *defaults, Baggage &bag) { + bool res; + // create a linked list of dropitems if (!bag.DropItemSet) { @@ -2477,10 +2506,11 @@ static void ActorDropItem (AActor *defaults, Baggage &bag) di->Name=sc_String; di->probability=255; di->amount=-1; - if (SC_CheckNumber()) + + if (CheckNumParm()) { di->probability=sc_Number; - if (SC_CheckNumber()) + if (CheckNumParm()) { di->amount=sc_Number; } @@ -2817,8 +2847,10 @@ static void ActorBloodColor (AActor *defaults, Baggage &bag) { SC_MustGetNumber(); r=clamp(sc_Number, 0, 255); + SC_CheckString(","); SC_MustGetNumber(); g=clamp(sc_Number, 0, 255); + SC_CheckString(","); SC_MustGetNumber(); b=clamp(sc_Number, 0, 255); } @@ -3159,7 +3191,7 @@ static void InventoryPickupmsg (AInventory *defaults, Baggage &bag) SC_MustGetString(); int game = SC_MatchString(games); - if (game!=-1) + if (game!=-1 && SC_CheckString(",")) { SC_MustGetString(); if (!(gameinfo.gametype&gamemode[game])) return; @@ -3368,8 +3400,10 @@ static void PowerupColor (APowerupGiver *defaults, Baggage &bag) if (SC_CheckNumber()) { r=clamp(sc_Number, 0, 255); + SC_CheckString(","); SC_MustGetNumber(); g=clamp(sc_Number, 0, 255); + SC_CheckString(","); SC_MustGetNumber(); b=clamp(sc_Number, 0, 255); } @@ -3393,6 +3427,7 @@ static void PowerupColor (APowerupGiver *defaults, Baggage &bag) g=GPART(c); b=BPART(c); } + SC_CheckString(","); SC_MustGetFloat(); alpha=int(sc_Float*255); alpha=clamp(alpha, 0, 255); @@ -3470,6 +3505,7 @@ static void PlayerColorRange (APlayerPawn *defaults, Baggage &bag) SC_MustGetNumber (); start = sc_Number; + SC_CheckString(","); SC_MustGetNumber (); end = sc_Number; @@ -3525,7 +3561,7 @@ static void PlayerForwardMove (APlayerPawn *defaults, Baggage &bag) { SC_MustGetFloat (); defaults->ForwardMove1 = defaults->ForwardMove2 = FLOAT2FIXED (sc_Float); - if (SC_CheckFloat ()) + if (CheckFloatParm ()) defaults->ForwardMove2 = FLOAT2FIXED (sc_Float); } @@ -3536,7 +3572,7 @@ static void PlayerSideMove (APlayerPawn *defaults, Baggage &bag) { SC_MustGetFloat (); defaults->SideMove1 = defaults->SideMove2 = FLOAT2FIXED (sc_Float); - if (SC_CheckFloat ()) + if (CheckFloatParm ()) defaults->SideMove2 = FLOAT2FIXED (sc_Float); } @@ -3596,7 +3632,7 @@ static void PlayerStartItem (APlayerPawn *defaults, Baggage &bag) di->Name = sc_String; di->probability=255; di->amount=0; - if (SC_CheckNumber()) + if (CheckNumParm()) { di->amount=sc_Number; } diff --git a/src/thingdef_codeptr.cpp b/src/thingdef_codeptr.cpp index 12bb820a9..68c56dae9 100644 --- a/src/thingdef_codeptr.cpp +++ b/src/thingdef_codeptr.cpp @@ -77,7 +77,6 @@ static FRandom pr_cwpunch ("CustomWpPunch"); static FRandom pr_grenade ("ThrowGrenade"); static FRandom pr_crailgun ("CustomRailgun"); static FRandom pr_spawndebris ("SpawnDebris"); -static FRandom pr_jiggle ("Jiggle"); static FRandom pr_burst ("Burst"); @@ -1471,29 +1470,6 @@ void A_ExtChase(AActor * self) } -//=========================================================================== -// -// Weapon jiggling -// -//=========================================================================== -void A_Jiggle(AActor * self) -{ - int index=CheckIndex(2, &CallingState); - if (index<0) return; - int xmax = EvalExpressionI (StateParameters[index], self); - int ymax = EvalExpressionI (StateParameters[index+1], self); - - if (self->player) - { - int rand_x = (pr_jiggle()%(xmax*2))-xmax; - int rand_y = (pr_jiggle()%(ymax*2))-ymax; - self->player->psprites[0].sx += rand_x; - self->player->psprites[0].sy += rand_y; - self->player->psprites[1].sx += rand_x; - self->player->psprites[1].sy += rand_y; - } -} - //=========================================================================== // // Inventory drop diff --git a/wadsrc/decorate/decorate.txt b/wadsrc/decorate/decorate.txt index d8c7060d5..8c8e35f71 100644 --- a/wadsrc/decorate/decorate.txt +++ b/wadsrc/decorate/decorate.txt @@ -1,3 +1,4 @@ +#include "actors/shared/blood.txt" #include "actors/shared/debris.txt" #include "actors/shared/splashes.txt" diff --git a/wadsrc/decorate/raven/ravenartifacts.txt b/wadsrc/decorate/raven/ravenartifacts.txt index 05190bb6d..6729869fb 100644 --- a/wadsrc/decorate/raven/ravenartifacts.txt +++ b/wadsrc/decorate/raven/ravenartifacts.txt @@ -77,7 +77,7 @@ ACTOR ArtiInvulnerability : PowerupGiver 84 Inventory.RespawnTics 4230 Inventory.Icon ARTIINVU Inventory.PickupMessage "$TXT_ARTIINVULNERABILITY" - Inventory.PickupMessage Hexen "$TXT_ARTIINVULNERABILITY2" + Inventory.PickupMessage Hexen, "$TXT_ARTIINVULNERABILITY2" Powerup.Type Invulnerable States { diff --git a/wadsrc/decorate/shared/blood.txt b/wadsrc/decorate/shared/blood.txt new file mode 100644 index 000000000..1a2767327 --- /dev/null +++ b/wadsrc/decorate/shared/blood.txt @@ -0,0 +1,25 @@ +// Blood splatter ----------------------------------------------------------- + +ACTOR BloodSplatter +{ + Game Raven + Radius 2 + Height 4 + +NOBLOCKMAP + +MISSILE + +DROPOFF + +NOTELEPORT + +CANNOTPUSH + Mass 5 + States + { + Spawn: + BLUD CBA 8 + Stop + Death: + BLUD A 6 + Stop + } +} + + \ No newline at end of file diff --git a/wadsrc/decorate/shared/debris.txt b/wadsrc/decorate/shared/debris.txt index b696a03a8..12a5a9658 100644 --- a/wadsrc/decorate/shared/debris.txt +++ b/wadsrc/decorate/shared/debris.txt @@ -370,3 +370,31 @@ ACTOR SGShard0 : GlassShard } } +ACTOR GlassJunk +{ + +NOCLIP + +NOBLOCKMAP + RenderStyle Translucent + Alpha 0.4 + Health 3 // Number of different shards + States + { + // Are the first three frames used anywhere? + SHAR A 128 + Goto Death + SHAR B 128 + Goto Death + SHAR C 128 + Goto Death + Spawn: + SHAR D 128 + Goto Death + SHAR E 128 + Goto Death + SHAR F 128 + Goto Death + Death: + "----" A 1 A_FadeOut(0.03) + Wait + } +} diff --git a/wadsrc/zdoom.lst b/wadsrc/zdoom.lst index 683661b50..494f2020a 100644 --- a/wadsrc/zdoom.lst +++ b/wadsrc/zdoom.lst @@ -236,6 +236,7 @@ acs/strfhelp.o strfhelp.o decorate.txt decorate/decorate.txt +actors/shared/blood.txt decorate/shared/blood.txt actors/shared/debris.txt decorate/shared/debris.txt actors/shared/splashes.txt decorate/shared/splashes.txt