- Fixed: The pointer cleanup code must also check a sector's sky box pointers.

- Fixed: Right after teleporting P_SlideMove could cause player movement.
  Added a check for reactiontime to prevent that.
- Fixed: PainChances and Damagefactors were never freed.
- Added option to A_Chase that prevents the monster from moving.
- Fixed: The stained glass shards were missing the HEXENBOUNCE flag.
- Added some NULL pointer checks to AActor::GiveAmmo.
- Fixed: The FSwordMissile was missing the special damage handling that
  reduces damage when hitting a player.

SVN r555 (trunk)
This commit is contained in:
Christoph Oelckers 2007-10-29 20:27:40 +00:00
parent 3b477d7022
commit b15767c26f
17 changed files with 149 additions and 54 deletions

View file

@ -1,4 +1,20 @@
October 28, 2007 (Changes by Graf Zahl)
- Fixed: The pointer cleanup code must also check a sector's sky box pointers.
October 27, 2007 (Changes by Graf Zahl)
- Fixed: Right after teleporting P_SlideMove could cause player movement.
Added a check for reactiontime to prevent that.
- Fixed: PainChances and Damagefactors were never freed.
- Added option to A_Chase that prevents the monster from moving.
October 20, 2007 (Changes by Graf Zahl)
- Added some NULL pointer checks to AActor::GiveAmmo.
- Fixed: The FSwordMissile was missing the special damage handling that
reduces damage when hitting a player.
October 19, 2007 (Changes by Graf Zahl) October 19, 2007 (Changes by Graf Zahl)
- Fixed: APlayerPawn::UpdateWaterLevel must check if the actor is still
connected to a player.
- Fixed: POwered up weapons with a different ready state than their base - Fixed: POwered up weapons with a different ready state than their base
weapon didn't change back when the powerup expired. weapon didn't change back when the powerup expired.
- Fixed: The powered up version of Heretic's Gauntlets missed the proper - Fixed: The powered up version of Heretic's Gauntlets missed the proper

View file

@ -74,21 +74,21 @@ CCMD (removebots)
Net_WriteByte (DEM_KILLBOTS); Net_WriteByte (DEM_KILLBOTS);
} }
extern bool CheckCheatmode ();
CCMD (freeze) CCMD (freeze)
{ {
if (!netgame) if (CheckCheatmode ())
{ return;
if (bglobal.freeze)
{ if (netgame && consoleplayer != Net_Arbitrator)
bglobal.freeze = false; {
Printf ("Freeze mode off\n"); Printf ("Only player %d can use freeze mode\n", Net_Arbitrator + 1);
} return;
else }
{
bglobal.freeze = true; Net_WriteByte (DEM_GENERICCHEAT);
Printf ("Freeze mode on\n"); Net_WriteByte (CHT_FREEZE);
}
}
} }
CCMD (listbots) CCMD (listbots)

View file

@ -188,6 +188,7 @@ enum ECheatCommand
CHT_LEGO, CHT_LEGO,
CHT_RESSURECT, // [GRB] CHT_RESSURECT, // [GRB]
CHT_CLEARFROZENPROPS, CHT_CLEARFROZENPROPS,
CHT_FREEZE,
}; };
void StartChunk (int id, BYTE **stream); void StartChunk (int id, BYTE **stream);

View file

@ -46,6 +46,7 @@
#include "i_system.h" #include "i_system.h"
#include "r_state.h" #include "r_state.h"
#include "stats.h" #include "stats.h"
#include "a_sharedglobal.h"
#include "autosegs.h" #include "autosegs.h"
@ -507,6 +508,14 @@ void DObject::PointerSubstitution (DObject *old, DObject *notOld)
{ {
sectors[i].SoundTarget = static_cast<AActor *>(notOld); sectors[i].SoundTarget = static_cast<AActor *>(notOld);
} }
if (sectors[i].CeilingSkyBox == old)
{
sectors[i].CeilingSkyBox = static_cast<ASkyViewpoint *>(notOld);
}
if (sectors[i].FloorSkyBox == old)
{
sectors[i].FloorSkyBox = static_cast<ASkyViewpoint *>(notOld);
}
} }
} }
} }

View file

@ -96,6 +96,16 @@ void PClass::StaticFreeData (PClass *type)
delete[] type->ActorInfo->OwnedStates; delete[] type->ActorInfo->OwnedStates;
type->ActorInfo->OwnedStates = NULL; type->ActorInfo->OwnedStates = NULL;
} }
if (type->ActorInfo->DamageFactors != NULL)
{
delete type->ActorInfo->DamageFactors;
type->ActorInfo->DamageFactors = NULL;
}
if (type->ActorInfo->PainChances != NULL)
{
delete type->ActorInfo->PainChances;
type->ActorInfo->PainChances = NULL;
}
delete type->ActorInfo; delete type->ActorInfo;
type->ActorInfo = NULL; type->ActorInfo = NULL;
} }

View file

@ -370,7 +370,7 @@ CCMD (invuse)
{ {
if (players[consoleplayer].inventorytics == 0 || gameinfo.gametype == GAME_Strife) if (players[consoleplayer].inventorytics == 0 || gameinfo.gametype == GAME_Strife)
{ {
SendItemUse = players[consoleplayer].mo->InvSel; if (players[consoleplayer].mo) SendItemUse = players[consoleplayer].mo->InvSel;
} }
players[consoleplayer].inventorytics = 0; players[consoleplayer].inventorytics = 0;
} }
@ -385,7 +385,7 @@ CCMD (use)
CCMD (invdrop) CCMD (invdrop)
{ {
SendItemDrop = players[consoleplayer].mo->InvSel; if (players[consoleplayer].mo) SendItemDrop = players[consoleplayer].mo->InvSel;
} }
CCMD (drop) CCMD (drop)

View file

@ -213,6 +213,7 @@ class AFSwordMissile : public AActor
DECLARE_ACTOR (AFSwordMissile, AActor) DECLARE_ACTOR (AFSwordMissile, AActor)
public: public:
void GetExplodeParms (int &damage, int &dist, bool &hurtSource); void GetExplodeParms (int &damage, int &dist, bool &hurtSource);
int DoSpecialDamage(AActor *victim, AActor *source, int damage);
}; };
FState AFSwordMissile::States[] = FState AFSwordMissile::States[] =
@ -257,6 +258,16 @@ void AFSwordMissile::GetExplodeParms (int &damage, int &dist, bool &hurtSource)
hurtSource = false; hurtSource = false;
} }
int AFSwordMissile::DoSpecialDamage(AActor *victim, AActor *source, int damage)
{
if (victim->player)
{
damage -= damage >> 2;
}
return damage;
}
// Fighter Sword Flame ------------------------------------------------------ // Fighter Sword Flame ------------------------------------------------------
class AFSwordFlame : public AActor class AFSwordFlame : public AActor

View file

@ -14,7 +14,7 @@ static FRandom pr_serpentmeattack ("SerpentMeAttack");
static FRandom pr_serpentgibs ("SerpentGibs"); static FRandom pr_serpentgibs ("SerpentGibs");
static FRandom pr_delaygib ("DelayGib"); static FRandom pr_delaygib ("DelayGib");
void A_DoChase(AActor * actor, bool fastchase, FState * meleestate, FState * missilestate, bool playactive, bool nightmarefast); void A_DoChase(AActor * actor, bool fastchase, FState * meleestate, FState * missilestate, bool playactive, bool nightmarefast,bool dontmove);
void A_SerpentChase (AActor *); void A_SerpentChase (AActor *);
void A_SerpentHumpDecide (AActor *); void A_SerpentHumpDecide (AActor *);
@ -403,7 +403,7 @@ void A_SerpentHide (AActor *actor)
void A_SerpentChase (AActor *actor) void A_SerpentChase (AActor *actor)
{ {
A_DoChase (actor, false, actor->MeleeState, NULL, false, true); A_DoChase (actor, false, actor->MeleeState, NULL, false, true, false);
} }
//============================================================================ //============================================================================
@ -501,7 +501,7 @@ void A_SerpentDiveSound (AActor *actor)
void A_SerpentWalk (AActor *actor) void A_SerpentWalk (AActor *actor)
{ {
A_DoChase (actor, false, &ASerpent::States[S_SERPENT_ATK1], NULL, true, true); A_DoChase (actor, false, &ASerpent::States[S_SERPENT_ATK1], NULL, true, true, false);
} }
//============================================================================ //============================================================================

View file

@ -399,6 +399,19 @@ void cht_DoCheat (player_t *player, int cheat)
player->cheats &= ~(CF_FROZEN|CF_TOTALLYFROZEN); player->cheats &= ~(CF_FROZEN|CF_TOTALLYFROZEN);
msg = "Frozen player properties turned off"; msg = "Frozen player properties turned off";
break; break;
case CHT_FREEZE:
if (bglobal.freeze)
{
bglobal.freeze = false;
msg = "Freeze mode off\n";
}
else
{
bglobal.freeze = true;
msg = "Freeze mode on\n";
}
break;
} }
if (!*msg) // [SO] Don't print blank lines! if (!*msg) // [SO] Don't print blank lines!

View file

@ -693,13 +693,29 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len)
Arrays = NULL; Arrays = NULL;
ArrayStore = NULL; ArrayStore = NULL;
Chunks = NULL; Chunks = NULL;
Data = NULL;
Format = ACS_Unknown; Format = ACS_Unknown;
LumpNum = lumpnum; LumpNum = lumpnum;
memset (MapVarStore, 0, sizeof(MapVarStore)); memset (MapVarStore, 0, sizeof(MapVarStore));
ModuleName[0] = 0; ModuleName[0] = 0;
// Now that everything is set up, record this module as being among the loaded modules.
// We need to do this before resolving any imports, because an import might (indirectly)
// need to resolve exports in this module. The only things that can be exported are
// functions and map variables, which must already be present if they're exported, so
// this is okay.
// This must be done first for 2 reasons:
// 1. If not, corrupt modules cause memory leaks
// 2. Corrupt modules won't be reported when a level is being loaded if this function quits before
// adding it to the list.
LibraryID = StaticModules.Push (this) << 16;
if (fr == NULL) len = Wads.LumpLength (lumpnum); if (fr == NULL) len = Wads.LumpLength (lumpnum);
// Any behaviors smaller than 32 bytes cannot possibly contain anything useful. // Any behaviors smaller than 32 bytes cannot possibly contain anything useful.
// (16 bytes for a completely empty behavior + 12 bytes for one script header // (16 bytes for a completely empty behavior + 12 bytes for one script header
// + 4 bytes for PCD_TERMINATE for an old-style object. A new-style object // + 4 bytes for PCD_TERMINATE for an old-style object. A new-style object
@ -802,7 +818,7 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len)
{ {
MapVars[i] = &MapVarStore[i]; MapVars[i] = &MapVarStore[i];
} }
LibraryID = StaticModules.Push (this) << 16; //LibraryID = StaticModules.Push (this) << 16;
} }
else else
{ {
@ -885,13 +901,6 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len)
} }
} }
// Now that everything is set up, record this module as being among the loaded modules.
// We need to do this before resolving any imports, because an import might (indirectly)
// need to resolve exports in this module. The only things that can be exported are
// functions and map variables, which must already be present if they're exported, so
// this is okay.
LibraryID = StaticModules.Push (this) << 16;
// Tag the library ID to any map variables that are initialized with strings // Tag the library ID to any map variables that are initialized with strings
if (LibraryID != 0) if (LibraryID != 0)
{ {
@ -941,7 +950,7 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len)
{ {
module = StaticLoadModule (lump); module = StaticLoadModule (lump);
} }
Imports.Push (module); if (module != NULL) Imports.Push (module);
do ; while (parse[++i]); do ; while (parse[++i]);
} }
++i; ++i;

View file

@ -1766,7 +1766,7 @@ nosee:
//============================================================================= //=============================================================================
#define CLASS_BOSS_STRAFE_RANGE 64*10*FRACUNIT #define CLASS_BOSS_STRAFE_RANGE 64*10*FRACUNIT
void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missilestate, bool playactive, bool nightmarefast) void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missilestate, bool playactive, bool nightmarefast, bool dontmove)
{ {
int delta; int delta;
@ -1879,7 +1879,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
A_Look (actor); A_Look (actor);
if (actor->target == NULL) if (actor->target == NULL)
{ {
A_Wander (actor); if (!dontmove) A_Wander (actor);
actor->flags &= ~MF_INCHASE; actor->flags &= ~MF_INCHASE;
return; return;
} }
@ -1961,7 +1961,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
// it can be just as easily handled by a simple flag so the monsters // it can be just as easily handled by a simple flag so the monsters
// can take advantage of all the other enhancements of A_Chase. // can take advantage of all the other enhancements of A_Chase.
if (fastchase) if (fastchase && !dontmove)
{ {
if (actor->special2 > 0) if (actor->special2 > 0)
{ {
@ -2057,7 +2057,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
// //
// class bosses don't do this when strafing // class bosses don't do this when strafing
if (!fastchase || !actor->special2) if ((!fastchase || !actor->special2) && !dontmove)
{ {
// CANTLEAVEFLOORPIC handling was completely missing in the non-serpent functions. // CANTLEAVEFLOORPIC handling was completely missing in the non-serpent functions.
fixed_t oldX = actor->x; fixed_t oldX = actor->x;
@ -2274,7 +2274,8 @@ enum ChaseFlags
CHF_FASTCHASE = 1, CHF_FASTCHASE = 1,
CHF_NOPLAYACTIVE = 2, CHF_NOPLAYACTIVE = 2,
CHF_NIGHTMAREFAST = 4, CHF_NIGHTMAREFAST = 4,
CHF_RESURRECT = 8 CHF_RESURRECT = 8,
CHF_DONTMOVE = 16,
}; };
void A_Chase (AActor *actor) void A_Chase (AActor *actor)
@ -2289,23 +2290,23 @@ void A_Chase (AActor *actor)
FState *missile = StateParameters[index+1]==0? NULL : P_GetState(actor, CallingState, StateParameters[index+1]); FState *missile = StateParameters[index+1]==0? NULL : P_GetState(actor, CallingState, StateParameters[index+1]);
A_DoChase(actor, !!(flags&CHF_FASTCHASE), melee, missile, !(flags&CHF_NOPLAYACTIVE), A_DoChase(actor, !!(flags&CHF_FASTCHASE), melee, missile, !(flags&CHF_NOPLAYACTIVE),
!!(flags&CHF_NIGHTMAREFAST)); !!(flags&CHF_NIGHTMAREFAST), !!(flags&CHF_DONTMOVE));
} }
else // this is the old default A_Chase else // this is the old default A_Chase
{ {
A_DoChase (actor, false, actor->MeleeState, actor->MissileState, true, !!(gameinfo.gametype & GAME_Raven)); A_DoChase (actor, false, actor->MeleeState, actor->MissileState, true, !!(gameinfo.gametype & GAME_Raven), false);
} }
} }
void A_FastChase (AActor *actor) void A_FastChase (AActor *actor)
{ {
A_DoChase (actor, true, actor->MeleeState, actor->MissileState, true, true); A_DoChase (actor, true, actor->MeleeState, actor->MissileState, true, true, false);
} }
void A_VileChase (AActor *actor) void A_VileChase (AActor *actor)
{ {
if (!P_CheckForResurrection(actor, true)) if (!P_CheckForResurrection(actor, true))
A_DoChase (actor, false, actor->MeleeState, actor->MissileState, true, !!(gameinfo.gametype & GAME_Raven)); A_DoChase (actor, false, actor->MeleeState, actor->MissileState, true, !!(gameinfo.gametype & GAME_Raven), false);
} }
void A_ExtChase(AActor * self) void A_ExtChase(AActor * self)
@ -2318,7 +2319,7 @@ void A_ExtChase(AActor * self)
EvalExpressionI (StateParameters[index], self) ? self->MeleeState:NULL, EvalExpressionI (StateParameters[index], self) ? self->MeleeState:NULL,
EvalExpressionI (StateParameters[index+1], self) ? self->MissileState:NULL, EvalExpressionI (StateParameters[index+1], self) ? self->MissileState:NULL,
EvalExpressionN (StateParameters[index+2], self), EvalExpressionN (StateParameters[index+2], self),
!!EvalExpressionI (StateParameters[index+3], self)); !!EvalExpressionI (StateParameters[index+3], self), false);
} }
//============================================================================= //=============================================================================

View file

@ -2151,6 +2151,9 @@ void P_SlideMove (AActor *mo, fixed_t tryx, fixed_t tryy, int numsteps)
slidemo = mo; slidemo = mo;
hitcount = 3; hitcount = 3;
if (mo->player && mo->reactiontime > 0)
return; // player coming right out of a teleporter.
retry: retry:
if (!--hitcount) if (!--hitcount)

View file

@ -838,15 +838,22 @@ AInventory *AActor::GiveInventoryType (const PClass *type)
bool AActor::GiveAmmo (const PClass *type, int amount) bool AActor::GiveAmmo (const PClass *type, int amount)
{ {
AInventory *item = static_cast<AInventory *>(Spawn (type, 0, 0, 0, NO_REPLACE)); if (type != NULL)
item->Amount = amount;
item->flags |= MF_DROPPED;
if (!item->TryPickup (this))
{ {
item->Destroy (); AInventory *item = static_cast<AInventory *>(Spawn (type, 0, 0, 0, NO_REPLACE));
return false; if (item)
{
item->Amount = amount;
item->flags |= MF_DROPPED;
if (!item->TryPickup (this))
{
item->Destroy ();
return false;
}
return true;
}
} }
return true; return false;
} }
//============================================================================ //============================================================================

View file

@ -844,17 +844,20 @@ bool APlayerPawn::UpdateWaterLevel (fixed_t oldz, bool splash)
{ {
int oldlevel = waterlevel; int oldlevel = waterlevel;
bool retval = Super::UpdateWaterLevel (oldz, splash); bool retval = Super::UpdateWaterLevel (oldz, splash);
if (oldlevel < 3 && waterlevel == 3) if (player != NULL)
{ // Our head just went under. {
S_Sound (this, CHAN_VOICE, "*dive", 1, ATTN_NORM); if (oldlevel < 3 && waterlevel == 3)
} { // Our head just went under.
else if (oldlevel == 3 && waterlevel < 3) S_Sound (this, CHAN_VOICE, "*dive", 1, ATTN_NORM);
{ // Our head just came up. }
if (player->air_finished > level.time) else if (oldlevel == 3 && waterlevel < 3)
{ // We hadn't run out of air yet. { // Our head just came up.
S_Sound (this, CHAN_VOICE, "*surface", 1, ATTN_NORM); if (player->air_finished > level.time)
{ // We hadn't run out of air yet.
S_Sound (this, CHAN_VOICE, "*surface", 1, ATTN_NORM);
}
// If we were running out of air, then ResetAirSupply() will play *gasp.
} }
// If we were running out of air, then ResetAirSupply() will play *gasp.
} }
return retval; return retval;
} }

View file

@ -1964,6 +1964,7 @@ void A_Burst (AActor *actor)
mo->momy = pr_burst.Random2 () << (FRACBITS-7); mo->momy = pr_burst.Random2 () << (FRACBITS-7);
mo->RenderStyle = actor->RenderStyle; mo->RenderStyle = actor->RenderStyle;
mo->alpha = actor->alpha; mo->alpha = actor->alpha;
mo->CopyFriendliness(actor, true);
} }
} }

View file

@ -19,4 +19,5 @@ const int CHF_FASTCHASE = 1;
const int CHF_NOPLAYACTIVE = 2; const int CHF_NOPLAYACTIVE = 2;
const int CHF_NIGHTMAREFAST = 4; const int CHF_NIGHTMAREFAST = 4;
const int CHF_RESURRECT = 8; const int CHF_RESURRECT = 8;
const int CHF_DONTMOVE = 16;

View file

@ -178,6 +178,7 @@ ACTOR SGShard1 : GlassShard
Projectile Projectile
-ACTIVATEMCROSS -ACTIVATEMCROSS
-ACTIVATEIMPACT -ACTIVATEIMPACT
+HEXENBOUNCE
BounceFactor 0.3 BounceFactor 0.3
States States
{ {
@ -198,6 +199,7 @@ ACTOR SGShard2 : GlassShard
Projectile Projectile
-ACTIVATEMCROSS -ACTIVATEMCROSS
-ACTIVATEIMPACT -ACTIVATEIMPACT
+HEXENBOUNCE
BounceFactor 0.3 BounceFactor 0.3
States States
{ {
@ -218,6 +220,7 @@ ACTOR SGShard3 : GlassShard
Projectile Projectile
-ACTIVATEMCROSS -ACTIVATEMCROSS
-ACTIVATEIMPACT -ACTIVATEIMPACT
+HEXENBOUNCE
BounceFactor 0.3 BounceFactor 0.3
States States
{ {
@ -238,6 +241,7 @@ ACTOR SGShard4 : GlassShard
Projectile Projectile
-ACTIVATEMCROSS -ACTIVATEMCROSS
-ACTIVATEIMPACT -ACTIVATEIMPACT
+HEXENBOUNCE
BounceFactor 0.3 BounceFactor 0.3
States States
{ {
@ -258,6 +262,7 @@ ACTOR SGShard5 : GlassShard
Projectile Projectile
-ACTIVATEMCROSS -ACTIVATEMCROSS
-ACTIVATEIMPACT -ACTIVATEIMPACT
+HEXENBOUNCE
BounceFactor 0.3 BounceFactor 0.3
States States
{ {
@ -278,6 +283,7 @@ ACTOR SGShard6 : GlassShard
Projectile Projectile
-ACTIVATEMCROSS -ACTIVATEMCROSS
-ACTIVATEIMPACT -ACTIVATEIMPACT
+HEXENBOUNCE
BounceFactor 0.3 BounceFactor 0.3
States States
{ {
@ -298,6 +304,7 @@ ACTOR SGShard7 : GlassShard
Projectile Projectile
-ACTIVATEMCROSS -ACTIVATEMCROSS
-ACTIVATEIMPACT -ACTIVATEIMPACT
+HEXENBOUNCE
BounceFactor 0.3 BounceFactor 0.3
States States
{ {
@ -318,6 +325,7 @@ ACTOR SGShard8 : GlassShard
Projectile Projectile
-ACTIVATEMCROSS -ACTIVATEMCROSS
-ACTIVATEIMPACT -ACTIVATEIMPACT
+HEXENBOUNCE
BounceFactor 0.3 BounceFactor 0.3
States States
{ {
@ -338,6 +346,7 @@ ACTOR SGShard9 : GlassShard
Projectile Projectile
-ACTIVATEMCROSS -ACTIVATEMCROSS
-ACTIVATEIMPACT -ACTIVATEIMPACT
+HEXENBOUNCE
BounceFactor 0.3 BounceFactor 0.3
States States
{ {
@ -358,6 +367,7 @@ ACTOR SGShard0 : GlassShard
Projectile Projectile
-ACTIVATEMCROSS -ACTIVATEMCROSS
-ACTIVATEIMPACT -ACTIVATEIMPACT
+HEXENBOUNCE
BounceFactor 0.3 BounceFactor 0.3
States States
{ {