mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 20:21:26 +00:00
- 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)
This commit is contained in:
parent
f94cdaf782
commit
5ac0789e6e
16 changed files with 156 additions and 113 deletions
|
@ -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.
|
||||
|
|
|
@ -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<class T>
|
||||
inline T *Spawn (fixed_t x, fixed_t y, fixed_t z, replace_t allowreplacement)
|
||||
|
|
|
@ -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) -----------------------------------------------------
|
||||
|
|
|
@ -194,6 +194,7 @@ void APigPlayer::ActivateMorphWeapon ()
|
|||
{
|
||||
P_SetPsprite (player, ps_weapon, NULL);
|
||||
}
|
||||
P_SetPsprite (player, ps_flash, NULL);
|
||||
}
|
||||
|
||||
// Pig (non-player) ---------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<AGlassJunk> (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;
|
||||
|
|
|
@ -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<ABloodSplatter> (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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<int>(sc_Number, 0, 255);
|
||||
SC_CheckString(",");
|
||||
SC_MustGetNumber();
|
||||
g=clamp<int>(sc_Number, 0, 255);
|
||||
SC_CheckString(",");
|
||||
SC_MustGetNumber();
|
||||
b=clamp<int>(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<int>(sc_Number, 0, 255);
|
||||
SC_CheckString(",");
|
||||
SC_MustGetNumber();
|
||||
g=clamp<int>(sc_Number, 0, 255);
|
||||
SC_CheckString(",");
|
||||
SC_MustGetNumber();
|
||||
b=clamp<int>(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<int>(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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "actors/shared/blood.txt"
|
||||
#include "actors/shared/debris.txt"
|
||||
#include "actors/shared/splashes.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
|
||||
{
|
||||
|
|
25
wadsrc/decorate/shared/blood.txt
Normal file
25
wadsrc/decorate/shared/blood.txt
Normal file
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue