diff --git a/docs/rh-log.txt b/docs/rh-log.txt
index 4294b0dd9..b7d269fba 100644
--- a/docs/rh-log.txt
+++ b/docs/rh-log.txt
@@ -1,4 +1,28 @@
+April 16, 2006 (Changes by Graf Zahl)
+- Increased the limit for the sound DoorCloseLight in Hexen to 4 because
+ it got cut off in the polyobject crusher in MAP01.
+- Fixed: A player that has no body (as in the head popped off in Heretic
+ and Hexen) must not be resurrected.
+- Fixed: Repeatable switches that are being activated while the switch
+ animation was still running didn't react properly.
+- Fixed: Not all paths in P_LoadSegs freed the vertchanged array.
+- Fixed: With infinitely tall actors on P_CheckPosition must not
+ check for stepping on things.
+- Fixed: R_FakeFlat used the control sector's floor light level for
+ ceilings of deep water areas.
+- Fixed: Dormant floating monsters still adjusted their height to their
+ target.
+- Fixed: Invisible special things should never create terrain splashes.
+- Changed: The Demon no longer reduces the actual state durations for
+ fast mode. Now this is done by AActor::SetState and controlled by
+ actor flags.
+- Fixed: Friendly monsters are now completely excluded fron being counted
+ as kills.
+
April 15, 2006 (Changes by Graf Zahl)
+- Changed -warp for ExMy to use atoi to parse the parameters. This is
+ more robust than reading the characters directly.
+- Expanded thing and line args to 32 bit.
- Extended Makewad so it can write Zip files in addition to WAD files.
April 14, 2006 (Changes by Graf Zahl)
diff --git a/src/actor.h b/src/actor.h
index a7a435b7f..b8f726ce1 100644
--- a/src/actor.h
+++ b/src/actor.h
@@ -272,6 +272,9 @@ enum
MF4_EXTREMEDEATH = 0x20000000, // this projectile or weapon always gibs its victim
MF4_FRIGHTENED = 0x40000000, // Monster runs away from player
MF4_NOBOUNCESOUND = 0x80000000, // Strife's grenades don't make a bouncing sound.
+
+ MF5_FASTER = 0x00000001, // moves faster when DF_FAST_MONSTERS or nightmare is on.
+ MF5_FASTMELEE = 0x00000002, // has a faster melee attack when DF_FAST_MONSTERS or nightmare is on.
// --- mobj.renderflags ---
@@ -483,8 +486,8 @@ public:
// Called by RoughBlockCheck
virtual bool IsOkayToAttack (AActor *target);
- virtual void ChangeSpecial (byte special, byte data1, byte data2,
- byte data3, byte data4, byte data5);
+ virtual void ChangeSpecial (int special, int data1, int data2,
+ int data3, int data4, int data5);
// Plays the actor's ActiveSound if its voice isn't already making noise.
void PlayActiveSound ();
@@ -565,6 +568,12 @@ public:
// What species am I?
virtual const TypeInfo *GetSpecies();
+
+ // Check for monsters that count as kill but excludes all friendlies.
+ bool CountsAsKill() const
+ {
+ return (flags & MF_COUNTKILL) && !(flags & MF_FRIENDLY);
+ }
// info for drawing
// NOTE: The first member variable *must* be x.
@@ -600,6 +609,7 @@ public:
DWORD flags2; // Heretic flags
DWORD flags3; // [RH] Hexen/Heretic actor-dependant behavior made flaggable
DWORD flags4; // [RH] Even more flags!
+ DWORD flags5; // OMG! We need another one.
int special1; // Special info
int special2; // Special info
int health;
@@ -627,7 +637,7 @@ public:
fixed_t floorclip; // value to use for floor clipping
SWORD tid; // thing identifier
BYTE special; // special
- BYTE args[5]; // special arguments
+ int args[5]; // special arguments
AActor *inext, **iprev;// Links to other mobjs in same bucket
AActor *goal; // Monster's goal if not chasing anything
@@ -711,6 +721,8 @@ public:
void UnlinkFromWorld ();
void AdjustFloorClip ();
void SetOrigin (fixed_t x, fixed_t y, fixed_t z);
+ bool InStateSequence(FState * newstate, FState * basestate);
+ int GetTics(FState * newstate);
bool SetState (FState *newstate);
bool SetStateNF (FState *newstate);
bool UpdateWaterLevel (fixed_t oldz);
diff --git a/src/c_console.cpp b/src/c_console.cpp
index 97b0634dc..8f3047258 100644
--- a/src/c_console.cpp
+++ b/src/c_console.cpp
@@ -433,7 +433,6 @@ void C_AddNotifyString (int printlevel, const char *source)
REPLACELINE
} addtype = NEWLINE;
- char *work;
brokenlines_t *lines;
int i, len, width;
@@ -451,13 +450,12 @@ void C_AddNotifyString (int printlevel, const char *source)
width = con_scaletext > 1 ? DisplayWidth/2 : con_scaletext == 1 ? DisplayWidth / CleanXfac : DisplayWidth;
- if (addtype == APPENDLINE && NotifyStrings[NUMNOTIFIES-1].printlevel == printlevel
- && (work = (char *)malloc (strlen ((char *)NotifyStrings[NUMNOTIFIES-1].text)
- + strlen (source) + 1)) )
+ if (addtype == APPENDLINE && NotifyStrings[NUMNOTIFIES-1].printlevel == printlevel)
{
- sprintf (work, "%s%s", NotifyStrings[NUMNOTIFIES-1].text, source);
- lines = V_BreakLines (width, work);
- free (work);
+ string str;
+
+ str.Format("%s%s", NotifyStrings[NUMNOTIFIES-1].text, source);
+ lines = V_BreakLines (width, str.GetChars());
}
else
{
diff --git a/src/d_main.cpp b/src/d_main.cpp
index 3f923985e..f9cda830c 100644
--- a/src/d_main.cpp
+++ b/src/d_main.cpp
@@ -2143,8 +2143,8 @@ void D_DoomMain (void)
}
else
{
- ep = Args.GetArg(p+1)[0]-'0';
- map = p < Args.NumArgs() - 2 ? Args.GetArg(p+2)[0]-'0' : 10;
+ ep = atoi (Args.GetArg(p+1));
+ map = p < Args.NumArgs() - 2 ? atoi (Args.GetArg(p+2)) : 10;
if ((unsigned)map > 9)
{
map = ep;
diff --git a/src/g_doom/a_archvile.cpp b/src/g_doom/a_archvile.cpp
index 7ffb00f24..cbc8babb7 100644
--- a/src/g_doom/a_archvile.cpp
+++ b/src/g_doom/a_archvile.cpp
@@ -288,15 +288,16 @@ void A_VileChase (AActor *self)
corpsehit->target = NULL;
corpsehit->lastenemy = NULL;
- // You are the Archvile's minion now, so hate what it hates
- corpsehit->CopyFriendliness (self, false);
-
// [RH] If it's a monster, it gets to count as another kill
- if (corpsehit->flags & MF_COUNTKILL)
+ if (corpsehit->CountsAsKill())
{
level.total_monsters++;
}
+ // You are the Archvile's minion now, so hate what it hates
+ corpsehit->CopyFriendliness (self, false);
+
+
return;
}
}
diff --git a/src/g_doom/a_demon.cpp b/src/g_doom/a_demon.cpp
index b63c2aab0..b7035ffe4 100644
--- a/src/g_doom/a_demon.cpp
+++ b/src/g_doom/a_demon.cpp
@@ -68,6 +68,7 @@ IMPLEMENT_ACTOR (ADemon, Doom, 3002, 8)
PROP_Mass (400)
PROP_Flags (MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL)
PROP_Flags2 (MF2_MCROSS|MF2_PASSMOBJ|MF2_PUSHWALL|MF2_FLOORCLIP)
+ PROP_Flags5 (MF5_FASTER|MF5_FASTMELEE)
PROP_SpawnState (S_SARG_STND)
PROP_SeeState (S_SARG_RUN)
@@ -83,32 +84,6 @@ IMPLEMENT_ACTOR (ADemon, Doom, 3002, 8)
PROP_ActiveSound ("demon/active")
END_DEFAULTS
-static void SetTics (FState *state, int count)
-{
- state->Tics = (count+1) & 255;
- state->Misc1 = state->GetMisc1() | ((count+1)>>8);
- state->Frame = (state->Frame & ~SF_BIGTIC) | (count > 254 ? SF_BIGTIC : 0);
-}
-
-AT_SPEED_SET (Demon, speednow)
-{
- static bool isFast = false;
- int i;
-
- if (speednow == SPEED_Fast && !isFast)
- {
- isFast = true;
- for (i = S_SARG_RUN; i < S_SARG_PAIN; i++)
- SetTics (&ADemon::States[i], ADemon::States[i].GetTics() >> 1);
- }
- else if (speednow == SPEED_Normal && isFast)
- {
- isFast = false;
- for (i = S_SARG_RUN; i < S_SARG_PAIN; i++)
- SetTics (&ADemon::States[i], ADemon::States[i].GetTics() << 1);
- }
-}
-
class AStealthDemon : public ADemon
{
DECLARE_STATELESS_ACTOR (AStealthDemon, ADemon)
diff --git a/src/g_doom/doom_sbar.cpp b/src/g_doom/doom_sbar.cpp
index e6f66127b..1af51b79f 100644
--- a/src/g_doom/doom_sbar.cpp
+++ b/src/g_doom/doom_sbar.cpp
@@ -778,6 +778,7 @@ private:
int i;
angle_t badguyangle;
angle_t diffang;
+
if (FacePriority < 10)
{
@@ -804,6 +805,12 @@ private:
FaceIndex = CalcPainOffset() + ST_EVILGRINOFFSET;
}
}
+ else
+ {
+ // This happens when a weapon is added to the inventory
+ // by other means than being picked up.
+ bEvilGrin = false;
+ }
}
if (FacePriority < 8)
diff --git a/src/g_hexen/a_hexenspecialdecs.cpp b/src/g_hexen/a_hexenspecialdecs.cpp
index 1c4c56172..191a132d3 100644
--- a/src/g_hexen/a_hexenspecialdecs.cpp
+++ b/src/g_hexen/a_hexenspecialdecs.cpp
@@ -305,7 +305,7 @@ void A_PotteryExplode (AActor *actor)
}
}
S_Sound (mo, CHAN_BODY, "PotteryExplode", 1, ATTN_NORM);
- if (SpawnableThings[actor->args[0]])
+ if (actor->args[0]>=0 && actor->args[0]<=255 && SpawnableThings[actor->args[0]])
{ // Spawn an item
if (!(dmflags & DF_NO_MONSTERS)
|| !(GetDefaultByType (SpawnableThings[actor->args[0]])->flags3 & MF3_ISMONSTER))
@@ -1083,7 +1083,7 @@ void A_SoAExplode (AActor *actor)
mo->momy = pr_soaexplode.Random2()<<(FRACBITS-6);
}
}
- if (SpawnableThings[actor->args[0]])
+ if (actor->args[0]>=0 && actor->args[0]<=255 && SpawnableThings[actor->args[0]])
{ // Spawn an item
if (!(dmflags & DF_NO_MONSTERS)
|| !(GetDefaultByType (SpawnableThings[actor->args[0]])->flags3 & MF3_ISMONSTER))
diff --git a/src/g_shared/a_camera.cpp b/src/g_shared/a_camera.cpp
index b08b49248..e7863072e 100644
--- a/src/g_shared/a_camera.cpp
+++ b/src/g_shared/a_camera.cpp
@@ -81,6 +81,7 @@ protected:
IMPLEMENT_STATELESS_ACTOR (ASecurityCamera, Any, 9025, 0)
PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY)
+ PROP_Flags3 (MF3_DONTSPLASH)
PROP_RenderStyle (STYLE_None)
END_DEFAULTS
diff --git a/src/g_shared/a_hatetarget.cpp b/src/g_shared/a_hatetarget.cpp
index 710df7657..2c120ca66 100644
--- a/src/g_shared/a_hatetarget.cpp
+++ b/src/g_shared/a_hatetarget.cpp
@@ -55,6 +55,7 @@ IMPLEMENT_ACTOR (AHateTarget, Any, 9076, 0)
PROP_RadiusFixed (20)
PROP_HeightFixed (56)
PROP_Flags (MF_SHOOTABLE|MF_NOGRAVITY|MF_NOBLOOD)
+ PROP_Flags3 (MF3_DONTSPLASH)
PROP_SpawnState (0)
PROP_MassLong (INT_MAX)
END_DEFAULTS
diff --git a/src/g_shared/a_movingcamera.cpp b/src/g_shared/a_movingcamera.cpp
index 051117972..a0a268620 100644
--- a/src/g_shared/a_movingcamera.cpp
+++ b/src/g_shared/a_movingcamera.cpp
@@ -70,6 +70,7 @@ END_POINTERS
BEGIN_STATELESS_DEFAULTS (AInterpolationPoint, Any, 9070, 0)
PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY)
+ PROP_Flags3 (MF3_DONTSPLASH)
PROP_RenderStyle (STYLE_None)
END_DEFAULTS
@@ -142,6 +143,7 @@ public:
IMPLEMENT_STATELESS_ACTOR (AInterpolationSpecial, Any, 9075, 0)
PROP_Flags (MF_NOBLOCKMAP|MF_NOSECTOR)
+ PROP_Flags3 (MF3_DONTSPLASH)
END_DEFAULTS
/*
@@ -191,6 +193,7 @@ END_POINTERS
BEGIN_STATELESS_DEFAULTS (APathFollower, Any, 9071, 0)
PROP_Flags (MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY)
+ PROP_Flags3 (MF3_DONTSPLASH)
END_DEFAULTS
void APathFollower::Serialize (FArchive &arc)
diff --git a/src/g_shared/a_secrettrigger.cpp b/src/g_shared/a_secrettrigger.cpp
index a474b06bb..a7e40208e 100644
--- a/src/g_shared/a_secrettrigger.cpp
+++ b/src/g_shared/a_secrettrigger.cpp
@@ -51,6 +51,7 @@ public:
IMPLEMENT_STATELESS_ACTOR (ASecretTrigger, Any, 9046, 0)
PROP_Flags (MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY)
+ PROP_Flags3 (MF3_DONTSPLASH)
END_DEFAULTS
void ASecretTrigger::PostBeginPlay ()
diff --git a/src/g_shared/a_sectoraction.cpp b/src/g_shared/a_sectoraction.cpp
index af5878ae4..2adddcbb6 100644
--- a/src/g_shared/a_sectoraction.cpp
+++ b/src/g_shared/a_sectoraction.cpp
@@ -39,6 +39,7 @@
IMPLEMENT_STATELESS_ACTOR (ASectorAction, Any, -1, 0)
PROP_Flags (MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY)
+ PROP_Flags3 (MF3_DONTSPLASH)
END_DEFAULTS
void ASectorAction::Destroy ()
diff --git a/src/g_shared/a_sharedmisc.cpp b/src/g_shared/a_sharedmisc.cpp
index 1f367a550..214b0d1b4 100644
--- a/src/g_shared/a_sharedmisc.cpp
+++ b/src/g_shared/a_sharedmisc.cpp
@@ -14,6 +14,7 @@ IMPLEMENT_ACTOR (AUnknown, Any, -1, 0)
PROP_RadiusFixed (32)
PROP_HeightFixed (56)
PROP_Flags (MF_NOGRAVITY|MF_NOBLOCKMAP)
+ PROP_Flags3 (MF3_DONTSPLASH)
PROP_SpawnState (0)
END_DEFAULTS
@@ -24,7 +25,8 @@ IMPLEMENT_STATELESS_ACTOR (APatrolPoint, Any, 9024, 0)
PROP_RadiusFixed (8)
PROP_HeightFixed (8)
PROP_Mass (10)
- PROP_Flags (MF_NOBLOCKMAP)
+ PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY)
+ PROP_Flags3 (MF3_DONTSPLASH)
PROP_RenderStyle (STYLE_None)
END_DEFAULTS
@@ -34,7 +36,8 @@ IMPLEMENT_STATELESS_ACTOR (APatrolSpecial, Any, 9047, 0)
PROP_RadiusFixed (8)
PROP_HeightFixed (8)
PROP_Mass (10)
- PROP_Flags (MF_NOBLOCKMAP)
+ PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY)
+ PROP_Flags3 (MF3_DONTSPLASH)
PROP_RenderStyle (STYLE_None)
END_DEFAULTS
@@ -114,12 +117,14 @@ void ABlood::SetDamage (int damage)
IMPLEMENT_STATELESS_ACTOR (AMapSpot, Any, 9001, 0)
PROP_Flags (MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY)
PROP_RenderStyle (STYLE_None)
+ PROP_Flags3 (MF3_DONTSPLASH)
END_DEFAULTS
// Map spot with gravity ---------------------------------------------------
IMPLEMENT_STATELESS_ACTOR (AMapSpotGravity, Any, 9013, 0)
PROP_Flags (0)
+ PROP_Flags3(MF3_DONTSPLASH)
END_DEFAULTS
// Bloody gibs -------------------------------------------------------------
diff --git a/src/g_shared/a_skies.cpp b/src/g_shared/a_skies.cpp
index 1e22fb8dd..a754fde90 100644
--- a/src/g_shared/a_skies.cpp
+++ b/src/g_shared/a_skies.cpp
@@ -40,6 +40,7 @@
IMPLEMENT_STATELESS_ACTOR (ASkyViewpoint, Any, 9080, 0)
PROP_Flags (MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY)
+ PROP_Flags3 (MF3_DONTSPLASH)
END_DEFAULTS
// If this actor has no TID, make it the default sky box
@@ -90,6 +91,7 @@ public:
IMPLEMENT_STATELESS_ACTOR (ASkyPicker, Any, 9081, 0)
PROP_Flags (MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY)
+ PROP_Flags3 (MF3_DONTSPLASH)
END_DEFAULTS
void ASkyPicker::PostBeginPlay ()
diff --git a/src/g_shared/a_soundenvironment.cpp b/src/g_shared/a_soundenvironment.cpp
index 70415a9e6..2273ec2c1 100644
--- a/src/g_shared/a_soundenvironment.cpp
+++ b/src/g_shared/a_soundenvironment.cpp
@@ -48,6 +48,7 @@ public:
IMPLEMENT_STATELESS_ACTOR (ASoundEnvironment, Any, 9048, 0)
PROP_Flags (MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY)
+ PROP_Flags3 (MF3_DONTSPLASH)
END_DEFAULTS
void ASoundEnvironment::PostBeginPlay ()
diff --git a/src/g_shared/a_waterzone.cpp b/src/g_shared/a_waterzone.cpp
index d7118ed5c..9e234f76b 100644
--- a/src/g_shared/a_waterzone.cpp
+++ b/src/g_shared/a_waterzone.cpp
@@ -44,6 +44,7 @@ public:
IMPLEMENT_STATELESS_ACTOR (AWaterZone, Any, 9045, 0)
PROP_Flags (MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOGRAVITY)
+ PROP_Flags3 (MF3_DONTSPLASH)
END_DEFAULTS
void AWaterZone::PostBeginPlay ()
diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp
index e093412e7..5fc4d8791 100644
--- a/src/g_shared/a_weapons.cpp
+++ b/src/g_shared/a_weapons.cpp
@@ -103,6 +103,9 @@ bool AWeapon::Use (bool pickup)
{
AWeapon *useweap = this;
+ // Powered up weapons cannot be used directly.
+ if (WeaponFlags & WIF_POWERED_UP) return false;
+
// If the player is powered-up, use the alternate version of the
// weapon, if one exists.
if (SisterWeapon != NULL &&
diff --git a/src/info.h b/src/info.h
index a906ac351..ada25291a 100644
--- a/src/info.h
+++ b/src/info.h
@@ -257,14 +257,17 @@ enum
ADEF_Flags2, // "
ADEF_Flags3, // "
ADEF_Flags4, // "
+ ADEF_Flags5, // "
ADEF_FlagsSet, // Or these flags with previous
ADEF_Flags2Set, // "
ADEF_Flags3Set, // "
ADEF_Flags4Set, // "
+ ADEF_Flags5Set, // "
ADEF_FlagsClear, // Clear these flags from previous
ADEF_Flags2Clear, // "
ADEF_Flags3Clear, // "
ADEF_Flags4Clear, // "
+ ADEF_Flags5Clear, // "
ADEF_Alpha,
ADEF_RenderStyle,
ADEF_RenderFlags,
diff --git a/src/infodefaults.cpp b/src/infodefaults.cpp
index 130121d8d..07a75327b 100644
--- a/src/infodefaults.cpp
+++ b/src/infodefaults.cpp
@@ -194,14 +194,17 @@ static void ApplyActorDefault (int defnum, const char *datastr, int dataint)
case ADEF_Flags2: actor->flags2 = dataint; break;
case ADEF_Flags3: actor->flags3 = dataint; break;
case ADEF_Flags4: actor->flags4 = dataint; break;
+ case ADEF_Flags5: actor->flags5 = dataint; break;
case ADEF_FlagsSet: actor->flags |= dataint; break;
case ADEF_Flags2Set: actor->flags2 |= dataint; break;
case ADEF_Flags3Set: actor->flags3 |= dataint; break;
case ADEF_Flags4Set: actor->flags4 |= dataint; break;
+ case ADEF_Flags5Set: actor->flags5 |= dataint; break;
case ADEF_FlagsClear: actor->flags &= ~dataint; break;
case ADEF_Flags2Clear: actor->flags2 &= ~dataint; break;
case ADEF_Flags3Clear: actor->flags3 &= ~dataint; break;
case ADEF_Flags4Clear: actor->flags4 &= ~dataint; break;
+ case ADEF_Flags5Clear: actor->flags5 &= ~dataint; break;
case ADEF_Alpha: actor->alpha = dataint; break;
case ADEF_RenderStyle: actor->RenderStyle = dataint; break;
case ADEF_RenderFlags: actor->renderflags = dataint; break;
diff --git a/src/infomacros.h b/src/infomacros.h
index c2589658c..cb38e9869 100644
--- a/src/infomacros.h
+++ b/src/infomacros.h
@@ -237,14 +237,17 @@ public:
#define PROP_Flags2(x) ADD_LONG_PROP(ADEF_Flags2,x)
#define PROP_Flags3(x) ADD_LONG_PROP(ADEF_Flags3,x)
#define PROP_Flags4(x) ADD_LONG_PROP(ADEF_Flags4,x)
+#define PROP_Flags5(x) ADD_LONG_PROP(ADEF_Flags5,x)
#define PROP_FlagsSet(x) ADD_LONG_PROP(ADEF_FlagsSet,x)
#define PROP_Flags2Set(x) ADD_LONG_PROP(ADEF_Flags2Set,x)
#define PROP_Flags3Set(x) ADD_LONG_PROP(ADEF_Flags3Set,x)
#define PROP_Flags4Set(x) ADD_LONG_PROP(ADEF_Flags4Set,x)
+#define PROP_Flags5Set(x) ADD_LONG_PROP(ADEF_Flags5Set,x)
#define PROP_FlagsClear(x) ADD_LONG_PROP(ADEF_FlagsClear,x)
#define PROP_Flags2Clear(x) ADD_LONG_PROP(ADEF_Flags2Clear,x)
#define PROP_Flags3Clear(x) ADD_LONG_PROP(ADEF_Flags3Clear,x)
#define PROP_Flags4Clear(x) ADD_LONG_PROP(ADEF_Flags4Clear,x)
+#define PROP_Flags5Clear(x) ADD_LONG_PROP(ADEF_Flags5Clear,x)
#define PROP_Alpha(x) ADD_LONG_PROP(ADEF_Alpha,x)
#define PROP_RenderStyle(x) ADD_BYTE_PROP(ADEF_RenderStyle,x)
#define PROP_RenderFlags(x) ADD_WORD_PROP(ADEF_RenderFlags,x)
diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp
index 1c71c5e0b..ab54e623c 100644
--- a/src/m_cheat.cpp
+++ b/src/m_cheat.cpp
@@ -272,24 +272,31 @@ void cht_DoCheat (player_t *player, int cheat)
case CHT_RESSURECT:
if (player->playerstate != PST_LIVE && player->mo != NULL)
{
- player->playerstate = PST_LIVE;
- if (player->mo->tracer != NULL)
+ if (player->mo->IsKindOf(RUNTIME_CLASS(APlayerChunk)))
{
- APlayerPawn * pmo = player->mo;
- player->mo = (APlayerPawn*)player->mo->tracer;
- pmo->Destroy();
- player->mo->player=player;
- player->mo->renderflags &= ~RF_INVISIBLE;
- player->morphTics = 0;
+ Printf("Unable to resurrect. Player is no longer connected to its body.\n");
+ }
+ 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 = player->defaultviewheight;
+ player->mo->flags = player->mo->GetDefault()->flags;
+ player->mo->height = player->mo->GetDefault()->height;
+ player->mo->SetState (player->mo->SpawnState);
+ player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players));
+ player->mo->GiveDefaultInventory();
+ P_SetPsprite(player, ps_weapon, player->ReadyWeapon->UpState);
}
- player->health = player->mo->health = player->mo->GetDefault()->health;
- player->viewheight = player->defaultviewheight;
- player->mo->flags = player->mo->GetDefault()->flags;
- player->mo->height = player->mo->GetDefault()->height;
- player->mo->SetState (player->mo->SpawnState);
- player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players));
- player->mo->GiveDefaultInventory();
- P_SetPsprite(player, ps_weapon, player->ReadyWeapon->UpState);
}
break;
diff --git a/src/p_acs.cpp b/src/p_acs.cpp
index b4b11ddec..bbfcbb6bc 100644
--- a/src/p_acs.cpp
+++ b/src/p_acs.cpp
@@ -1770,7 +1770,7 @@ int DLevelScript::DoSpawn (int type, fixed_t x, fixed_t y, fixed_t z, int tid, i
{
// If this is a monster, subtract it from the total monster
// count, because it already added to it during spawning.
- if (actor->flags & MF_COUNTKILL)
+ if (actor->CountsAsKill())
{
level.total_monsters--;
}
diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp
index c34dcf6d2..91aacd9f7 100644
--- a/src/p_interaction.cpp
+++ b/src/p_interaction.cpp
@@ -411,7 +411,7 @@ void AActor::Die (AActor *source, AActor *inflictor)
if (source && source->player)
{
- if (flags & MF_COUNTKILL)
+ if (CountsAsKill())
{ // count for intermission
source->player->killcount++;
level.killed_monsters++;
@@ -553,7 +553,7 @@ void AActor::Die (AActor *source, AActor *inflictor)
}
}
}
- else if (!multiplayer && (flags & MF_COUNTKILL))
+ else if (!multiplayer && CountsAsKill())
{
// count all monster deaths,
// even those caused by other monsters
diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp
index 0bbed8f22..c6f55e290 100644
--- a/src/p_lnspec.cpp
+++ b/src/p_lnspec.cpp
@@ -1032,8 +1032,8 @@ FUNC(LS_Thing_Remove)
// Don't remove live players.
if (actor->player == NULL || actor != actor->player->mo)
{
- // be friendly to the level statistics! ;)
- if (actor->flags&MF_COUNTKILL && actor->health > 0) level.total_monsters--;
+ // be friendly to the level statistics. ;)
+ if (actor->CountsAsKill() && actor->health > 0) level.total_monsters--;
if (actor->flags&MF_COUNTITEM) level.total_items--;
actor->Destroy ();
}
diff --git a/src/p_map.cpp b/src/p_map.cpp
index 15743c1bc..5ed31893a 100644
--- a/src/p_map.cpp
+++ b/src/p_map.cpp
@@ -1307,7 +1307,7 @@ BOOL P_CheckPosition (AActor *thing, fixed_t x, fixed_t y)
// other things in the blocks and see if we hit something that is
// definitely blocking. Otherwise, we need to check the lines, or we
// could end up stuck inside a wall.
- if (BlockingMobj == NULL)
+ if (BlockingMobj == NULL || (compatflags & COMPATF_NO_PASSMOBJ))
{ // Thing slammed into something; don't let it move now.
thing->height = realheight;
return false;
diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp
index 72ee365ac..f0614cc69 100644
--- a/src/p_mobj.cpp
+++ b/src/p_mobj.cpp
@@ -274,6 +274,7 @@ void AActor::Serialize (FArchive &arc)
<< flags2
<< flags3
<< flags4
+ << flags5
<< special1
<< special2
<< health
@@ -442,6 +443,59 @@ AActor &AActor::operator= (const AActor &other)
return *this;
}
+//==========================================================================
+//
+// AActor::InStateSequence
+//
+// Checks whether the current state is in a contiguous sequence that
+// starts with basestate
+//
+//==========================================================================
+
+bool AActor::InStateSequence(FState * newstate, FState * basestate)
+{
+ if (basestate == NULL) return false;
+
+ FState * thisstate = basestate;
+ do
+ {
+ if (newstate == thisstate) return true;
+ basestate = thisstate;
+ thisstate = thisstate->GetNextState();
+ }
+ while (thisstate == basestate+1);
+ return false;
+}
+
+//==========================================================================
+//
+// AActor::GetTics
+//
+// Get the actual duration of the next state
+// This is a more generalized attempt to make the Demon faster in
+// nightmare mode. Actually changing the states' durations has to
+// be considered highly problematic.
+//
+//==========================================================================
+
+int AActor::GetTics(FState * newstate)
+{
+ int tics = newstate->GetTics();
+
+ if (gameskill == sk_nightmare || (dmflags & DF_FAST_MONSTERS))
+ {
+ if (flags5 & MF5_FASTER)
+ {
+ if (InStateSequence(newstate, SeeState)) return tics - (tics>>1);
+ }
+ if (flags5 & MF5_FASTMELEE)
+ {
+ if (InStateSequence(newstate, MeleeState)) return tics - (tics>>1);
+ }
+ }
+ return tics;
+}
+
//==========================================================================
//
// AActor::SetState
@@ -473,7 +527,7 @@ bool AActor::SetState (FState *newstate)
prevsprite = -1;
}
state = newstate;
- tics = newstate->GetTics();
+ tics = GetTics(newstate);
renderflags = (renderflags & ~RF_FULLBRIGHT) | newstate->GetFullbright();
newsprite = newstate->sprite.index;
if (newsprite != 1)
@@ -552,7 +606,7 @@ bool AActor::SetStateNF (FState *newstate)
prevsprite = -1;
}
state = newstate;
- tics = newstate->GetTics();
+ tics = GetTics(newstate);
renderflags = (renderflags & ~RF_FULLBRIGHT) | newstate->GetFullbright();
newsprite = newstate->sprite.index;
if (newsprite != 1)
@@ -788,6 +842,7 @@ bool AActor::GiveAmmo (const TypeInfo *type, int amount)
void AActor::CopyFriendliness (const AActor *other, bool changeTarget)
{
+ level.total_monsters -= CountsAsKill();
TIDtoHate = other->TIDtoHate;
LastLook = other->LastLook;
flags = (flags & ~MF_FRIENDLY) | (other->flags & MF_FRIENDLY);
@@ -798,6 +853,7 @@ void AActor::CopyFriendliness (const AActor *other, bool changeTarget)
{
target = other->target;
}
+ level.total_monsters += CountsAsKill();
}
//============================================================================
@@ -1759,7 +1815,7 @@ void P_ZMovement (AActor *mo)
//
// adjust height
//
- if ((mo->flags & MF_FLOAT) && mo->target)
+ if ((mo->flags & MF_FLOAT) && !(mo->flags2 & MF2_DORMANT) && mo->target)
{ // float down towards target if too close
if (!(mo->flags & MF_SKULLFLY) && !(mo->flags & MF_INFLOAT))
{
@@ -2068,8 +2124,8 @@ void P_NightmareRespawn (AActor *mobj)
// something is occupying its position?
if (!P_TestMobjLocation (mo))
{
- //[GrafZahl] MF_COUNTKILL still needs to be checked here!
- if (mo->flags & MF_COUNTKILL) level.total_monsters--;
+ //[GrafZahl] MF_COUNTKILL still needs to be checked here.
+ if (mo->CountsAsKill()) level.total_monsters--;
mo->Destroy ();
return; // no respawn
}
@@ -2316,8 +2372,8 @@ bool AActor::IsOkayToAttack (AActor *link)
return false;
}
-void AActor::ChangeSpecial (byte special, byte data1, byte data2,
- byte data3, byte data4, byte data5)
+void AActor::ChangeSpecial (int special, int data1, int data2,
+ int data3, int data4, int data5)
{
this->special = special;
args[0] = data1;
@@ -3048,7 +3104,7 @@ AActor *AActor::StaticSpawn (const TypeInfo *type, fixed_t ix, fixed_t iy, fixed
}
}
// [RH] Count monsters whenever they are spawned.
- if (actor->flags & MF_COUNTKILL)
+ if (actor->CountsAsKill())
{
level.total_monsters++;
}
@@ -3087,7 +3143,6 @@ void AActor::HandleSpawnFlags ()
if (SpawnFlags & MTF_FRIENDLY)
{
flags |= MF_FRIENDLY;
- // Friendlies don't count as kills!
if (flags & MF_COUNTKILL)
{
flags &= ~MF_COUNTKILL;
@@ -3728,7 +3783,7 @@ void P_SpawnMapThing (mapthing2_t *mthing, int position)
// [RH] Set the thing's special
mobj->special = mthing->special;
- memcpy (mobj->args, mthing->args, sizeof(mobj->args));
+ for(int j=0;j<5;j++) mobj->args[j]=mthing->args[j];
// [RH] Add ThingID to mobj and link it in with the others
mobj->tid = mthing->thingid;
diff --git a/src/p_setup.cpp b/src/p_setup.cpp
index adeab8487..932ebb510 100644
--- a/src/p_setup.cpp
+++ b/src/p_setup.cpp
@@ -553,6 +553,7 @@ void P_LoadSegs (int lump)
Printf ("This map has no segs.\n");
delete[] subsectors;
delete[] nodes;
+ delete[] vertchanged;
ForceNodeBuild = true;
return;
}
@@ -700,7 +701,6 @@ void P_LoadSegs (int lump)
delete[] subsectors;
delete[] nodes;
ForceNodeBuild = true;
- return;
}
delete[] vertchanged; // phares 10/4/98
diff --git a/src/p_switch.cpp b/src/p_switch.cpp
index dc83dadb7..dfcef3184 100644
--- a/src/p_switch.cpp
+++ b/src/p_switch.cpp
@@ -428,7 +428,7 @@ static WORD AddSwitchDef (FSwitchDef *def)
// Start a button counting down till it turns off.
// [RH] Rewritten to remove MAXBUTTONS limit.
//
-static void P_StartButton (side_t *side, DActiveButton::EWhere w, int switchnum,
+static bool P_StartButton (side_t *side, DActiveButton::EWhere w, int switchnum,
fixed_t x, fixed_t y, bool useagain)
{
DActiveButton *button;
@@ -438,10 +438,14 @@ static void P_StartButton (side_t *side, DActiveButton::EWhere w, int switchnum,
while ( (button = iterator.Next ()) )
{
if (button->m_Side == side)
- return;
+ {
+ button->m_Timer=1; // force advancing to the next frame
+ return false;
+ }
}
new DActiveButton (side, w, switchnum, x, y, useagain);
+ return true;
}
static int TryFindSwitch (SWORD texture)
@@ -527,13 +531,16 @@ bool P_ChangeSwitchTexture (side_t *side, int useAgain, byte special, bool *ques
// button just activated, either).
fixed_t pt[3];
line_t *line = &lines[side->linenum];
+ bool playsound;
pt[0] = line->v1->x + (line->dx >> 1);
pt[1] = line->v1->y + (line->dy >> 1);
- S_SoundID (pt, CHAN_VOICE|CHAN_LISTENERZ|CHAN_IMMOBILE, sound, 1, ATTN_STATIC);
*texture = SwitchList[i]->u.Textures[SwitchList[i]->NumFrames*2];
if (useAgain || SwitchList[i]->NumFrames > 1)
- P_StartButton (side, where, i, pt[0], pt[1], !!useAgain);
+ playsound = P_StartButton (side, where, i, pt[0], pt[1], !!useAgain);
+ else
+ playsound = true;
+ if (playsound) S_SoundID (pt, CHAN_VOICE|CHAN_LISTENERZ|CHAN_IMMOBILE, sound, 1, ATTN_STATIC);
if (quest != NULL)
{
*quest = SwitchList[i]->QuestPanel;
diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp
index a2371a320..814501b94 100644
--- a/src/p_teleport.cpp
+++ b/src/p_teleport.cpp
@@ -116,6 +116,7 @@ void ATeleportFog::PostBeginPlay ()
IMPLEMENT_STATELESS_ACTOR (ATeleportDest, Any, 14, 0)
PROP_Flags (MF_NOBLOCKMAP|MF_NOSECTOR)
+ PROP_Flags3(MF3_DONTSPLASH)
END_DEFAULTS
// Teleport dest that can spawn above floor
diff --git a/src/p_things.cpp b/src/p_things.cpp
index 9b29c77b3..e65d3a088 100644
--- a/src/p_things.cpp
+++ b/src/p_things.cpp
@@ -93,7 +93,7 @@ bool P_Thing_Spawn (int tid, int type, angle_t angle, bool fog, int newtid)
{
// If this is a monster, subtract it from the total monster
// count, because it already added to it during spawning.
- if (mobj->flags & MF_COUNTKILL)
+ if (mobj->CountsAsKill())
{
level.total_monsters--;
}
@@ -337,7 +337,7 @@ nolead:
{
// If this is a monster, subtract it from the total monster
// count, because it already added to it during spawning.
- if (mobj->flags & MF_COUNTKILL)
+ if (mobj->CountsAsKill())
{
level.total_monsters--;
}
diff --git a/src/p_xlat.cpp b/src/p_xlat.cpp
index 34d0a0f01..1ede6095a 100644
--- a/src/p_xlat.cpp
+++ b/src/p_xlat.cpp
@@ -268,8 +268,8 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld)
ld->special = *tlate++;
for (;;)
{
- short *destp;
- short flagtemp;
+ int *destp;
+ int flagtemp;
BYTE op = *tlate++;
BYTE dest;
BYTE val = 0; // quiet, GCC
@@ -291,7 +291,7 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld)
}
else
{
- flagtemp = short((flags >> 9) & 0x3f);
+ flagtemp = ((flags >> 9) & 0x3f);
destp = &flagtemp;
}
lsize = op >> 4;
diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp
index 6b193a414..ab989bb03 100644
--- a/src/r_bsp.cpp
+++ b/src/r_bsp.cpp
@@ -385,7 +385,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec,
if (ceilinglightlevel != NULL)
{
- *ceilinglightlevel = GetFloorLight (s);
+ *ceilinglightlevel = GetCeilingLight (s);
}
}
FakeSide = FAKED_BelowFloor;
@@ -504,7 +504,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec,
if (ceilinglightlevel != NULL)
{
- *ceilinglightlevel = GetFloorLight (s);
+ *ceilinglightlevel = GetCeilingLight (s);
}
}
FakeSide = FAKED_BelowFloor;
diff --git a/src/r_defs.h b/src/r_defs.h
index 599d318b6..cb6af375d 100644
--- a/src/r_defs.h
+++ b/src/r_defs.h
@@ -428,9 +428,7 @@ struct line_s
byte special; // [RH] specials are only one byte (like Hexen)
byte alpha; // <--- translucency (0-255/255=opaque)
short id; // <--- same as tag or set with Line_SetIdentification
- short args[5]; // <--- hexen-style arguments
- // note that these are shorts in order to support
- // the tag parameter from DOOM.
+ int args[5]; // <--- hexen-style arguments (expanded to ZDoom's full width)
int firstid, nextid;
DWORD sidenum[2]; // sidenum[1] will be 0xffffffff if one sided
fixed_t bbox[4]; // bounding box, for the extent of the LineDef.
diff --git a/src/thingdef_codeptr.cpp b/src/thingdef_codeptr.cpp
index 9047422ab..68ab45d03 100644
--- a/src/thingdef_codeptr.cpp
+++ b/src/thingdef_codeptr.cpp
@@ -1101,7 +1101,7 @@ void A_SpawnItem(AActor * self)
if (!P_TestMobjLocation(mo))
{
// The monster is blocked so don't spawn it at all!
- if (mo->flags&MF_COUNTKILL) level.total_monsters--;
+ if (mo->CountsAsKill()) level.total_monsters--;
mo->Destroy();
StateCall.Result=false; // for an inventory iten's use state
return;
diff --git a/wadsrc/sndinfo.txt b/wadsrc/sndinfo.txt
index c7ef7e197..20adf2f55 100644
--- a/wadsrc/sndinfo.txt
+++ b/wadsrc/sndinfo.txt
@@ -943,6 +943,8 @@ $alias menu/dismiss PlatformStop
$alias menu/choose DoorCloseLight
$alias menu/clear PlatformStop
+$limit DoorCloseLight 4
+
$endif // ifhexen
//===========================================================================
diff --git a/zdoom.vcproj b/zdoom.vcproj
index c6dd1a80c..d403d8066 100644
--- a/zdoom.vcproj
+++ b/zdoom.vcproj
@@ -1775,6 +1775,9 @@
+
+