SVN r26 (trunk)

This commit is contained in:
Christoph Oelckers 2006-04-11 08:36:23 +00:00
parent cd3cebf340
commit e06ba32525
38 changed files with 389 additions and 761 deletions

View File

@ -1,4 +1,62 @@
April 11, 2006 (Changes by Graf Zahl)
- Fixed: It was possible to use things through closed walls when the wall
was further away than 64 map units.
- Added a check for MF3_BLOODLESSIMPACT to P_LineAttack so that bloodless
hitscan attacks can be created.
- Added a check to P_CheckSlopeWalk that prevents sliding when hanging over
a sloped dropoff.
- Fixed: The line id hash chains used signed shorts to link their elements.
This completely broke line manipulation for linedef indices >= 32768.
- Fixed: Changed PL_SKYFLAT from 0x8000 to 0x10000 because otherwise it
doesn't work with linedef indices >= 32768. Also expanded sector_t::sky
from WORD to int to make this work.
- Added the flag parser fix from GZDoom. It was still incorrect.
- Added an escape flag to sc_man. This was necessary to parse the frame names
correctly which can contain backslashes so they must be excluded from
converting \" to ".
- Fixed: The 'ELVIS' cheat code wasn't terminated with 255.
- Fixed: When an object without any death state dies it has to be destroyed.
- Added 'nofog' parameter to Thing_Move
- Added a check for Teleport_ZombieChanger to P_TranslateTeleportThings.
- Fixed: Dumpmap crashed when the loaded map has GL nodes because it tried
to access the linedef of a miniseg. Needless to say, the BSP that is
written in this case is completely broken but at least it doesn't crash
anymore.
- Fixed: z-momentum application in P_ZMovement was incompatible with
the original method. Unless MF2_FLOATBOB is set it must be done before
applying gravity to momz.
- Fixed: AActor::Massacre caused an infinite loop when it wasn't able to
hurt the actor.
- Fixed: Due to movement interpolation the viewsector could be incorrect
if the actual camera's position and the interpolated position were not
in the same sector.
- Fixed: Assigning an empty string to a 'string' object NULLed
the Chars pointer. This cannot be done because it makes the
string object invalid.
- Fixed: Default intermission handling for E1-E3 should only happen when
playing Doom 1 and Heretic.
- Fixed: 'Give all' cheat must not try to give an item of type 'All'.
- Fixed: In rare circumstances DBoundingBox::AddToBox could produce
incorrect results.
- Fixed: The node builder still used NO_INDEX for initializing non-existent
sidedefs.
- Added MaxStepHeight and MaxDropoffHeight actor properties to DECORATE.
- Added new code pointers from GZDoom: A_FireAssaultGun, A_FadeIn and
the target inventory functions. Also added changes to several other
code pointers.
- Fixed: The FlameThrowerParts were missing the IF_INVBAR flag.
- Added a third parameter to A_BFGSpray to customize the amount of damage.
- Added A_DualPainAttack code pointer submitted by Justin for GZDoom.
- Fixed: AFatShot must have a height of 8, not 32.
- Fixed: AFighterPLayer::DoHealingRadius initialized the armor item
incorrectly so it was ineffective.
- Fixed: Strife's Brass Key needs a DoomEdNum of 39.
- Removed all the obsolete code and variables from the keys. With the
LOCKDEFS lump the original key numbers were deleted anyway and the
NeedKey messages are taken from the lump now.
April 10, 2006 (Changes by Graf Zahl)
- Fixed: The Teleporter Beacon was missing the pickup message.
- Made the IronLich's projectiles bright. Using them in non-bright state
in dark sectors looks truly odd.
- Fixed: Using bot_observer cleared the FRIENDLY flag off the player.

View File

@ -6,21 +6,6 @@
#include "a_keys.h"
#include "gstrings.h"
// I don't know why I didn't keep this ordering the same as it used to be
enum
{
it_redcard = 1,
it_bluecard,
it_yellowcard,
it_redskull,
it_blueskull,
it_yellowskull,
red = it_redcard+128,
blue = it_bluecard+128,
yellow = it_yellowcard+128
};
IMPLEMENT_STATELESS_ACTOR (ADoomKey, Doom, -1, 0)
PROP_RadiusFixed (20)
PROP_HeightFixed (16)
@ -34,7 +19,6 @@ class ABlueCard : public ADoomKey
DECLARE_ACTOR (ABlueCard, ADoomKey)
public:
const char *PickupMessage ();
const char *NeedKeyMessage (bool remote, int keynum);
};
FState ABlueCard::States[] =
@ -45,8 +29,6 @@ FState ABlueCard::States[] =
IMPLEMENT_ACTOR (ABlueCard, Doom, 5, 85)
PROP_SpawnState (0)
PROP_Key_KeyNumber (it_bluecard)
PROP_Key_AltKeyNumber (blue)
PROP_Inventory_Icon ("STKEYS0")
END_DEFAULTS
@ -55,12 +37,6 @@ const char *ABlueCard::PickupMessage ()
return GStrings("GOTBLUECARD");
}
const char *ABlueCard::NeedKeyMessage (bool remote, int keynum)
{
return remote ? GStrings("PD_BLUEO") : keynum == it_bluecard ?
GStrings("PD_BLUEC") : GStrings("PD_BLUEK");
}
// Yellow key card ----------------------------------------------------------
class AYellowCard : public ADoomKey
@ -68,7 +44,6 @@ class AYellowCard : public ADoomKey
DECLARE_ACTOR (AYellowCard, ADoomKey)
public:
const char *PickupMessage ();
const char *NeedKeyMessage (bool remote, int keynum);
};
FState AYellowCard::States[] =
@ -79,8 +54,6 @@ FState AYellowCard::States[] =
IMPLEMENT_ACTOR (AYellowCard, Doom, 6, 87)
PROP_SpawnState (0)
PROP_Key_KeyNumber (it_yellowcard)
PROP_Key_AltKeyNumber (yellow)
PROP_Inventory_Icon ("STKEYS1")
END_DEFAULTS
@ -89,12 +62,6 @@ const char *AYellowCard::PickupMessage ()
return GStrings("GOTYELWCARD");
}
const char *AYellowCard::NeedKeyMessage (bool remote, int keynum)
{
return remote ? GStrings("PD_YELLOWO") : keynum == it_yellowcard ?
GStrings("PD_YELLOWC") : GStrings("PD_YELLOWK");
}
// Red key card -------------------------------------------------------------
class ARedCard : public ADoomKey
@ -113,8 +80,6 @@ FState ARedCard::States[] =
IMPLEMENT_ACTOR (ARedCard, Doom, 13, 86)
PROP_SpawnState (0)
PROP_Key_KeyNumber (it_redcard)
PROP_Key_AltKeyNumber (red)
PROP_Inventory_Icon ("STKEYS2")
END_DEFAULTS
@ -123,12 +88,6 @@ const char *ARedCard::PickupMessage ()
return GStrings("GOTREDCARD");
}
const char *ARedCard::NeedKeyMessage (bool remote, int keynum)
{
return remote ? GStrings("PD_REDO") : keynum == it_redcard ?
GStrings("PD_REDC") : GStrings("PD_REDK");
}
// Blue skull key -----------------------------------------------------------
class ABlueSkull : public ADoomKey
@ -147,8 +106,6 @@ FState ABlueSkull::States[] =
IMPLEMENT_ACTOR (ABlueSkull, Doom, 40, 90)
PROP_SpawnState (0)
PROP_Key_KeyNumber (it_blueskull)
PROP_Key_AltKeyNumber (blue)
PROP_Inventory_Icon ("STKEYS3")
END_DEFAULTS
@ -157,12 +114,6 @@ const char *ABlueSkull::PickupMessage ()
return GStrings("GOTBLUESKUL");
}
const char *ABlueSkull::NeedKeyMessage (bool remote, int keynum)
{
return remote ? GStrings("PD_BLUEO") : keynum == it_blueskull ?
GStrings("PD_BLUES") : GStrings("PD_BLUEK");
}
// Yellow skull key ---------------------------------------------------------
class AYellowSkull : public ADoomKey
@ -170,7 +121,6 @@ class AYellowSkull : public ADoomKey
DECLARE_ACTOR (AYellowSkull, ADoomKey)
public:
const char *PickupMessage ();
const char *NeedKeyMessage (bool remote, int keynum);
};
FState AYellowSkull::States[] =
@ -181,8 +131,6 @@ FState AYellowSkull::States[] =
IMPLEMENT_ACTOR (AYellowSkull, Doom, 39, 88)
PROP_SpawnState (0)
PROP_Key_KeyNumber (it_yellowskull)
PROP_Key_AltKeyNumber (yellow)
PROP_Inventory_Icon ("STKEYS4")
END_DEFAULTS
@ -191,12 +139,6 @@ const char *AYellowSkull::PickupMessage ()
return GStrings("GOTYELWSKUL");
}
const char *AYellowSkull::NeedKeyMessage (bool remote, int keynum)
{
return remote ? GStrings("PD_YELLOWO") : keynum == it_yellowskull ?
GStrings("PD_YELLOWS") : GStrings("PD_YELLOWK");
}
// Red skull key ------------------------------------------------------------
class ARedSkull : public ADoomKey
@ -204,7 +146,6 @@ class ARedSkull : public ADoomKey
DECLARE_ACTOR (ARedSkull, ADoomKey)
public:
const char *PickupMessage ();
const char *NeedKeyMessage (bool remote, int keynum);
};
FState ARedSkull::States[] =
@ -215,8 +156,6 @@ FState ARedSkull::States[] =
IMPLEMENT_ACTOR (ARedSkull, Doom, 38, 89)
PROP_SpawnState (0)
PROP_Key_KeyNumber (it_redskull)
PROP_Key_AltKeyNumber (red)
PROP_Inventory_Icon ("STKEYS5")
END_DEFAULTS
@ -225,9 +164,3 @@ const char *ARedSkull::PickupMessage ()
return GStrings("GOTREDSKUL");
}
const char *ARedSkull::NeedKeyMessage (bool remote, int keynum)
{
return remote ? GStrings("PD_REDO") : keynum == it_redskull ?
GStrings("PD_REDS") : GStrings("PD_REDK");
}

View File

@ -1351,14 +1351,18 @@ void A_BFGSpray (AActor *mo)
AActor *thingToHit;
const TypeInfo *spraytype = NULL;
int numrays = 40;
int damagecnt = 15;
int index = CheckIndex (2, NULL);
int index = CheckIndex (3, NULL);
if (index >= 0)
{
spraytype = TypeInfo::FindType ((const char *)StateParameters[index]);
numrays = EvalExpressionI (StateParameters[index+1], mo);
if (numrays <= 0)
numrays = 40;
damagecnt = EvalExpressionI (StateParameters[index+2], mo);
if (damagecnt <= 0)
damagecnt = 15;
}
if (spraytype == NULL)
{
@ -1384,7 +1388,7 @@ void A_BFGSpray (AActor *mo)
linetarget->z + (linetarget->height>>2));
damage = 0;
for (j = 0; j < 15; ++j)
for (j = 0; j < damagecnt; ++j)
damage += (pr_bfgspray() & 7) + 1;
thingToHit = linetarget;

View File

@ -134,7 +134,7 @@ FState AFatShot::States[] =
IMPLEMENT_ACTOR (AFatShot, Doom, -1, 153)
PROP_RadiusFixed (6)
PROP_HeightFixed (32)
PROP_HeightFixed (8)
PROP_SpeedFixed (20)
PROP_Damage (8)
PROP_Flags (MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY)
@ -252,6 +252,7 @@ void A_FatAttack3 (AActor *self)
}
}
int EvalExpressionI (int id, AActor *self);
//
// killough 9/98: a mushroom explosion effect, sorta :)
// Original idea: Linguica
@ -266,7 +267,7 @@ void A_Mushroom (AActor *actor)
if (index >= 0)
{
spawntype = TypeInfo::FindType((const char *)StateParameters[index]);
n = (int)StateParameters[index+1];
n = EvalExpressionI (StateParameters[index+1], actor);
if (n == 0)
n = actor->damage;
}

View File

@ -210,6 +210,16 @@ void A_PainAttack (AActor *self)
A_PainShootSkull (self, self->angle);
}
void A_DualPainAttack (AActor *self)
{
if (!self->target)
return;
A_FaceTarget (self);
A_PainShootSkull (self, self->angle + ANG45);
A_PainShootSkull (self, self->angle - ANG45);
}
void A_PainDie (AActor *self)
{
if (self->IsFriend (self->target))

View File

@ -1,392 +0,0 @@
#include "templates.h"
#include "actor.h"
#include "info.h"
#include "m_random.h"
#include "s_sound.h"
#include "p_local.h"
#include "p_enemy.h"
#include "gstrings.h"
static FRandom pr_foo ("ImpMissileRange");
static FRandom pr_imp ("ImpExplode");
static FRandom pr_impmeatk ("ImpMeAttack");
static FRandom pr_impmsatk ("ImpMsAttack");
static FRandom pr_impmsatk2 ("ImpMsAttack2");
void A_ImpExplode (AActor *);
void A_ImpMeAttack (AActor *);
void A_ImpMsAttack (AActor *);
void A_ImpMsAttack2 (AActor *);
void A_ImpDeath (AActor *);
void A_ImpXDeath1 (AActor *);
void A_ImpXDeath2 (AActor *);
// Heretic imp (as opposed to the Doom variety) -----------------------------
class AHereticImp : public AActor
{
DECLARE_ACTOR (AHereticImp, AActor)
public:
bool SuggestMissileAttack (fixed_t dist);
const char *GetObituary ();
const char *GetHitObituary ();
};
FState AHereticImp::States[] =
{
#define S_IMP_LOOK 0
S_NORMAL (IMPX, 'A', 10, A_Look , &States[S_IMP_LOOK+1]),
S_NORMAL (IMPX, 'B', 10, A_Look , &States[S_IMP_LOOK+2]),
S_NORMAL (IMPX, 'C', 10, A_Look , &States[S_IMP_LOOK+3]),
S_NORMAL (IMPX, 'B', 10, A_Look , &States[S_IMP_LOOK+0]),
#define S_IMP_FLY (S_IMP_LOOK+4)
S_NORMAL (IMPX, 'A', 3, A_Chase , &States[S_IMP_FLY+1]),
S_NORMAL (IMPX, 'A', 3, A_Chase , &States[S_IMP_FLY+2]),
S_NORMAL (IMPX, 'B', 3, A_Chase , &States[S_IMP_FLY+3]),
S_NORMAL (IMPX, 'B', 3, A_Chase , &States[S_IMP_FLY+4]),
S_NORMAL (IMPX, 'C', 3, A_Chase , &States[S_IMP_FLY+5]),
S_NORMAL (IMPX, 'C', 3, A_Chase , &States[S_IMP_FLY+6]),
S_NORMAL (IMPX, 'B', 3, A_Chase , &States[S_IMP_FLY+7]),
S_NORMAL (IMPX, 'B', 3, A_Chase , &States[S_IMP_FLY+0]),
#define S_IMP_MEATK (S_IMP_FLY+8)
S_NORMAL (IMPX, 'D', 6, A_FaceTarget , &States[S_IMP_MEATK+1]),
S_NORMAL (IMPX, 'E', 6, A_FaceTarget , &States[S_IMP_MEATK+2]),
S_NORMAL (IMPX, 'F', 6, A_ImpMeAttack , &States[S_IMP_FLY+0]),
#define S_IMP_MSATK1 (S_IMP_MEATK+3)
S_NORMAL (IMPX, 'A', 10, A_FaceTarget , &States[S_IMP_MSATK1+1]),
S_NORMAL (IMPX, 'B', 6, A_ImpMsAttack , &States[S_IMP_MSATK1+2]),
S_NORMAL (IMPX, 'C', 6, NULL , &States[S_IMP_MSATK1+3]),
S_NORMAL (IMPX, 'B', 6, NULL , &States[S_IMP_MSATK1+4]),
S_NORMAL (IMPX, 'A', 6, NULL , &States[S_IMP_MSATK1+5]),
S_NORMAL (IMPX, 'B', 6, NULL , &States[S_IMP_MSATK1+2]),
#define S_IMP_PAIN (S_IMP_MSATK1+6)
S_NORMAL (IMPX, 'G', 3, NULL , &States[S_IMP_PAIN+1]),
S_NORMAL (IMPX, 'G', 3, A_Pain , &States[S_IMP_FLY+0]),
#define S_IMP_DIE (S_IMP_PAIN+2)
S_NORMAL (IMPX, 'G', 4, A_ImpDeath , &States[S_IMP_DIE+1]),
S_NORMAL (IMPX, 'H', 5, NULL , &States[S_IMP_DIE+1]),
#define S_IMP_XDIE (S_IMP_DIE+2)
S_NORMAL (IMPX, 'S', 5, A_ImpXDeath1 , &States[S_IMP_XDIE+1]),
S_NORMAL (IMPX, 'T', 5, NULL , &States[S_IMP_XDIE+2]),
S_NORMAL (IMPX, 'U', 5, NULL , &States[S_IMP_XDIE+3]),
S_NORMAL (IMPX, 'V', 5, A_ImpXDeath2 , &States[S_IMP_XDIE+4]),
S_NORMAL (IMPX, 'W', 5, NULL , &States[S_IMP_XDIE+4]),
#define S_IMP_CRASH (S_IMP_XDIE+5)
S_NORMAL (IMPX, 'I', 7, A_ImpExplode , &States[S_IMP_CRASH+1]),
S_NORMAL (IMPX, 'J', 7, A_Scream , &States[S_IMP_CRASH+2]),
S_NORMAL (IMPX, 'K', 7, NULL , &States[S_IMP_CRASH+3]),
S_NORMAL (IMPX, 'L', -1, NULL , NULL),
#define S_IMP_XCRASH (S_IMP_CRASH+4)
S_NORMAL (IMPX, 'X', 7, NULL , &States[S_IMP_XCRASH+1]),
S_NORMAL (IMPX, 'Y', 7, NULL , &States[S_IMP_XCRASH+2]),
S_NORMAL (IMPX, 'Z', -1, NULL , NULL)
};
IMPLEMENT_ACTOR (AHereticImp, Heretic, 66, 5)
PROP_SpawnHealth (40)
PROP_RadiusFixed (16)
PROP_HeightFixed (36)
PROP_Mass (50)
PROP_SpeedFixed (10)
PROP_PainChance (200)
PROP_Flags (MF_SOLID|MF_SHOOTABLE|MF_FLOAT|MF_NOGRAVITY|MF_COUNTKILL)
PROP_Flags2 (MF2_SPAWNFLOAT|MF2_PASSMOBJ|MF2_PUSHWALL)
PROP_Flags3 (MF3_DONTOVERLAP)
PROP_SpawnState (S_IMP_LOOK)
PROP_SeeState (S_IMP_FLY)
PROP_PainState (S_IMP_PAIN)
PROP_MeleeState (S_IMP_MEATK)
PROP_MissileState (S_IMP_MSATK1)
PROP_CrashState (S_IMP_CRASH)
PROP_DeathState (S_IMP_DIE)
PROP_XDeathState (S_IMP_XDIE)
PROP_SeeSound ("himp/sight")
PROP_AttackSound ("himp/attack")
PROP_PainSound ("himp/pain")
PROP_DeathSound ("himp/death")
PROP_ActiveSound ("himp/active")
END_DEFAULTS
const char *AHereticImp::GetObituary ()
{
return GStrings(OB_HERETICIMP);
}
const char *AHereticImp::GetHitObituary ()
{
return GStrings(OB_HERETICIMPHIT);
}
// Heretic imp leader -------------------------------------------------------
class AHereticImpLeader : public AHereticImp
{
DECLARE_ACTOR (AHereticImpLeader, AHereticImp)
};
FState AHereticImpLeader::States[] =
{
#define S_IMP_MSATK2 0
S_NORMAL (IMPX, 'D', 6, A_FaceTarget , &States[S_IMP_MSATK2+1]),
S_NORMAL (IMPX, 'E', 6, A_FaceTarget , &States[S_IMP_MSATK2+2]),
S_NORMAL (IMPX, 'F', 6, A_ImpMsAttack2 , &AHereticImp::States[S_IMP_FLY]),
};
IMPLEMENT_ACTOR (AHereticImpLeader, Heretic, 5, 7)
PROP_SpawnHealth (80)
PROP_MeleeState (~0)
PROP_MissileState (S_IMP_MSATK2)
PROP_AttackSound ("himp/leaderattack")
END_DEFAULTS
// Heretic imp chunk 1 ------------------------------------------------------
class AHereticImpChunk1 : public AActor
{
DECLARE_ACTOR (AHereticImpChunk1, AActor)
};
FState AHereticImpChunk1::States[] =
{
S_NORMAL (IMPX, 'M', 5, NULL , &States[1]),
S_NORMAL (IMPX, 'N', 700, NULL , &States[2]),
S_NORMAL (IMPX, 'O', 700, NULL , NULL)
};
IMPLEMENT_ACTOR (AHereticImpChunk1, Heretic, -1, 0)
PROP_Mass (5)
PROP_Radius (4)
PROP_Flags (MF_NOBLOCKMAP)
PROP_SpawnState (0)
END_DEFAULTS
// Heretic imp chunk 2 ------------------------------------------------------
class AHereticImpChunk2 : public AActor
{
DECLARE_ACTOR (AHereticImpChunk2, AActor)
};
FState AHereticImpChunk2::States[] =
{
S_NORMAL (IMPX, 'P', 5, NULL , &States[1]),
S_NORMAL (IMPX, 'Q', 700, NULL , &States[2]),
S_NORMAL (IMPX, 'R', 700, NULL , NULL)
};
IMPLEMENT_ACTOR (AHereticImpChunk2, Heretic, -1, 0)
PROP_Mass (5)
PROP_Radius (4)
PROP_Flags (MF_NOBLOCKMAP)
PROP_SpawnState (0)
END_DEFAULTS
// Heretic imp ball ---------------------------------------------------------
class AHereticImpBall : public AActor
{
DECLARE_ACTOR (AHereticImpBall, AActor)
};
FState AHereticImpBall::States[] =
{
#define S_IMPFX 0
S_BRIGHT (FX10, 'A', 6, NULL , &States[S_IMPFX+1]),
S_BRIGHT (FX10, 'B', 6, NULL , &States[S_IMPFX+2]),
S_BRIGHT (FX10, 'C', 6, NULL , &States[S_IMPFX+0]),
#define S_IMPFXI (S_IMPFX+3)
S_BRIGHT (FX10, 'D', 5, NULL , &States[S_IMPFXI+1]),
S_BRIGHT (FX10, 'E', 5, NULL , &States[S_IMPFXI+2]),
S_BRIGHT (FX10, 'F', 5, NULL , &States[S_IMPFXI+3]),
S_BRIGHT (FX10, 'G', 5, NULL , NULL)
};
IMPLEMENT_ACTOR (AHereticImpBall, Heretic, -1, 10)
PROP_RadiusFixed (8)
PROP_HeightFixed (8)
PROP_SpeedFixed (10)
PROP_Damage (1)
PROP_Flags (MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY)
PROP_Flags2 (MF2_WINDTHRUST|MF2_NOTELEPORT)
PROP_RenderStyle (STYLE_Add)
PROP_SpawnState (S_IMPFX)
PROP_DeathState (S_IMPFXI)
END_DEFAULTS
AT_SPEED_SET (HereticImpBall, speed)
{
SimpleSpeedSetter (AHereticImpBall, 10*FRACUNIT, 20*FRACUNIT, speed);
}
bool AHereticImp::SuggestMissileAttack (fixed_t dist)
{ // Imps fly attack from far away
return pr_foo() >= MIN<int> (dist >> (FRACBITS + 1), 200);
}
//----------------------------------------------------------------------------
//
// PROC A_ImpExplode
//
//----------------------------------------------------------------------------
void A_ImpExplode (AActor *self)
{
AActor *chunk;
self->flags &= ~MF_NOGRAVITY;
chunk = Spawn<AHereticImpChunk1> (self->x, self->y, self->z);
chunk->momx = pr_imp.Random2 () << 10;
chunk->momy = pr_imp.Random2 () << 10;
chunk->momz = 9*FRACUNIT;
chunk = Spawn<AHereticImpChunk2> (self->x, self->y, self->z);
chunk->momx = pr_imp.Random2 () << 10;
chunk->momy = pr_imp.Random2 () << 10;
chunk->momz = 9*FRACUNIT;
if (self->special1 == 666)
{ // Extreme death crash
self->SetState (&AHereticImp::States[S_IMP_XCRASH]);
}
}
//----------------------------------------------------------------------------
//
// PROC A_ImpMeAttack
//
//----------------------------------------------------------------------------
void A_ImpMeAttack (AActor *self)
{
if (!self->target)
{
return;
}
S_SoundID (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
if (P_CheckMeleeRange (self))
{
int damage = 5+(pr_impmeatk()&7);
P_DamageMobj (self->target, self, self, damage, MOD_HIT);
P_TraceBleed (damage, self->target, self);
}
}
//----------------------------------------------------------------------------
//
// PROC A_ImpMsAttack
//
//----------------------------------------------------------------------------
void A_ImpMsAttack (AActor *self)
{
AActor *dest;
angle_t an;
int dist;
if (!self->target || pr_impmsatk() > 64)
{
self->SetState (self->SeeState);
return;
}
dest = self->target;
self->flags |= MF_SKULLFLY;
S_SoundID (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
A_FaceTarget (self);
an = self->angle >> ANGLETOFINESHIFT;
self->momx = FixedMul (12*FRACUNIT, finecosine[an]);
self->momy = FixedMul (12*FRACUNIT, finesine[an]);
dist = P_AproxDistance (dest->x - self->x, dest->y - self->y);
dist = dist/(12*FRACUNIT);
if (dist < 1)
{
dist = 1;
}
self->momz = (dest->z + (dest->height>>1) - self->z)/dist;
}
//----------------------------------------------------------------------------
//
// PROC A_ImpMsAttack2
//
// Fireball attack of the imp leader.
//
//----------------------------------------------------------------------------
void A_ImpMsAttack2 (AActor *self)
{
if (!self->target)
{
return;
}
S_SoundID (self, CHAN_WEAPON, self->AttackSound, 1, ATTN_NORM);
if (P_CheckMeleeRange (self))
{
int damage = 5+(pr_impmsatk2()&7);
P_DamageMobj (self->target, self, self, damage, MOD_HIT);
P_TraceBleed (damage, self->target, self);
return;
}
P_SpawnMissile (self, self->target, RUNTIME_CLASS(AHereticImpBall));
}
//----------------------------------------------------------------------------
//
// PROC A_ImpDeath
//
//----------------------------------------------------------------------------
void A_ImpDeath (AActor *self)
{
self->flags &= ~MF_SOLID;
self->flags2 |= MF2_FLOORCLIP;
if (self->z <= self->floorz)
{
//self->SetState (&AHereticImp::States[S_IMP_CRASH]);
}
}
//----------------------------------------------------------------------------
//
// PROC A_ImpXDeath1
//
//----------------------------------------------------------------------------
void A_ImpXDeath1 (AActor *self)
{
self->flags &= ~MF_SOLID;
self->flags |= MF_NOGRAVITY;
self->flags2 |= MF2_FLOORCLIP;
self->special1 = 666; // Flag the crash routine
}
//----------------------------------------------------------------------------
//
// PROC A_ImpXDeath2
//
//----------------------------------------------------------------------------
void A_ImpXDeath2 (AActor *self)
{
self->flags &= ~MF_NOGRAVITY;
if (self->z <= self->floorz)
{
self->SetState (&AHereticImp::States[S_IMP_CRASH]);
}
}

View File

@ -5,15 +5,6 @@
#include "p_local.h"
#include "a_keys.h"
// I don't know why I changed this from Heretic's numbering
// (which was yellow, green, blue).
enum
{
key_green = 1,
key_blue,
key_yellow,
};
IMPLEMENT_STATELESS_ACTOR (AHereticKey, Heretic, -1, 0)
PROP_Flags (MF_SPECIAL|MF_NOTDMATCH)
PROP_RadiusFixed (20)
@ -46,8 +37,6 @@ FState AKeyGreen::States[] =
IMPLEMENT_ACTOR (AKeyGreen, Heretic, 73, 86)
PROP_SpawnState (0)
PROP_Key_KeyNumber (key_green)
PROP_Key_AltKeyNumber (key_green+128)
END_DEFAULTS
const char *AKeyGreen::PickupMessage ()
@ -55,11 +44,6 @@ const char *AKeyGreen::PickupMessage ()
return GStrings("TXT_GOTGREENKEY");
}
const char *AKeyGreen::NeedKeyMessage (bool remote, int keynum)
{
return GStrings("TXT_NEEDGREENKEY");
}
// Blue key -----------------------------------------------------------------
class AKeyBlue : public AHereticKey
@ -67,7 +51,6 @@ class AKeyBlue : public AHereticKey
DECLARE_ACTOR (AKeyBlue, AHereticKey)
public:
const char *PickupMessage ();
const char *NeedKeyMessage (bool remote, int keynum);
};
FState AKeyBlue::States[] =
@ -86,8 +69,6 @@ FState AKeyBlue::States[] =
IMPLEMENT_ACTOR (AKeyBlue, Heretic, 79, 85)
PROP_SpawnState (0)
PROP_Key_KeyNumber (key_blue)
PROP_Key_AltKeyNumber (key_blue+128)
END_DEFAULTS
const char *AKeyBlue::PickupMessage ()
@ -95,11 +76,6 @@ const char *AKeyBlue::PickupMessage ()
return GStrings("TXT_GOTBLUEKEY");
}
const char *AKeyBlue::NeedKeyMessage (bool remote, int keynum)
{
return GStrings("TXT_NEEDBLUEKEY");
}
// Yellow key ---------------------------------------------------------------
class AKeyYellow : public AHereticKey
@ -107,7 +83,6 @@ class AKeyYellow : public AHereticKey
DECLARE_ACTOR (AKeyYellow, AHereticKey)
public:
const char *PickupMessage ();
const char *NeedKeyMessage (bool remote, int keynum);
};
FState AKeyYellow::States[] =
@ -125,8 +100,6 @@ FState AKeyYellow::States[] =
IMPLEMENT_ACTOR (AKeyYellow, Heretic, 80, 87)
PROP_SpawnState (0)
PROP_Key_KeyNumber (key_yellow)
PROP_Key_AltKeyNumber (key_yellow+128)
END_DEFAULTS
const char *AKeyYellow::PickupMessage ()
@ -134,11 +107,6 @@ const char *AKeyYellow::PickupMessage ()
return GStrings("TXT_GOTYELLOWKEY");
}
const char *AKeyYellow::NeedKeyMessage (bool remote, int keynum)
{
return GStrings("TXT_NEEDYELLOWKEY");
}
// --- Key gizmos -----------------------------------------------------------
void A_InitKeyGizmo (AActor *);

View File

@ -372,8 +372,8 @@ bool AFighterPlayer::DoHealingRadius (APlayerPawn *other)
for (int i = 0; i < 4; ++i)
{
AHexenArmor *armor = Spawn<AHexenArmor> (0,0,0);
armor->Amount = i;
armor->MaxAmount = 1;
armor->health = i;
armor->Amount = 1;
if (!armor->TryPickup (player->mo))
{
armor->Destroy ();

View File

@ -15,22 +15,10 @@ END_DEFAULTS
DECLARE_ACTOR (AKey##n1, AHexenKey) \
public: \
const char *PickupMessage () { return GStrings("TXT_KEY_" #name); } \
const char *NeedKeyMessage (bool remote, int keynum) { return MakeNeedKey("TXT_KEY_" #name); } \
}; \
FState AKey##n1::States[] = { S_NORMAL (KEY##num, 'A', -1, NULL, NULL) }; \
IMPLEMENT_ACTOR (AKey##n1, Hexen, ednum, spawn) PROP_SpawnState (0) \
PROP_Key_KeyNumber(0x##num) PROP_Inventory_Icon ("KEYSLOT" #num) END_DEFAULTS
static TArray<char> NeedString;
static const char *MakeNeedKey (const char *msgname)
{
const char *keyname = GStrings(msgname);
NeedString.Grow ((unsigned int)strlen(keyname) + 14);
sprintf (&NeedString[0], "YOU NEED THE %s", keyname);
return &NeedString[0];
}
PROP_Inventory_Icon ("KEYSLOT" #num) END_DEFAULTS
MAKEKEY (1, Steel, STEEL, 8030, 85)
MAKEKEY (2, Cave, CAVE, 8031, 86)

View File

@ -448,23 +448,6 @@ bool AKey::ShouldStay ()
return !!multiplayer;
}
//==========================================================================
//
// These 2 methods are practically obsolete... ;)
//
//==========================================================================
const char *AKey::NeedKeyMessage (bool remote, int keynum)
{
return "You don't have the key";
}
const char *AKey::NeedKeySound ()
{
return "misc/keytry";
}
//==========================================================================
//
// These functions can be used to get color information for

View File

@ -9,12 +9,7 @@ class AKey : public AInventory
public:
virtual bool HandlePickup (AInventory *item);
// A Key can match two different locks.
BYTE KeyNumber;
BYTE AltKeyNumber;
virtual const char *NeedKeyMessage (bool remote, int keynum);
virtual const char *NeedKeySound ();
protected:
virtual bool ShouldStay ();

View File

@ -28,7 +28,6 @@ IMPLEMENT_ACTOR (ABaseKey, Strife, 230, 0)
PROP_StrifeTeaserType (129)
PROP_StrifeTeaserType2 (132)
PROP_SpawnState (0)
PROP_Key_KeyNumber (1)
PROP_Inventory_Icon ("I_FUSL")
PROP_Tag ("Base_Key")
END_DEFAULTS
@ -57,7 +56,6 @@ IMPLEMENT_ACTOR (AGovsKey, Strife, -1, 0)
PROP_StrifeTeaserType (130)
PROP_StrifeTeaserType2 (133)
PROP_SpawnState (0)
PROP_Key_KeyNumber (2)
PROP_Inventory_Icon ("I_REBL")
PROP_Tag ("Govs_Key") // "Rebel_Key" in the Teaser
END_DEFAULTS
@ -74,7 +72,6 @@ class APasscard : public AStrifeKey
DECLARE_ACTOR (APasscard, AStrifeKey)
public:
const char *PickupMessage ();
const char *NeedKeyMessage (bool remote, int keynum);
};
FState APasscard::States[] =
@ -87,7 +84,6 @@ IMPLEMENT_ACTOR (APasscard, Strife, 185, 0)
PROP_StrifeTeaserType (131)
PROP_StrifeTeaserType2 (134)
PROP_SpawnState (0)
PROP_Key_KeyNumber (3)
PROP_Inventory_Icon ("I_TPAS")
PROP_Tag ("Passcard")
END_DEFAULTS
@ -97,12 +93,6 @@ const char *APasscard::PickupMessage ()
return "You picked up the Passcard.";
}
const char *APasscard::NeedKeyMessage (bool remote, int keynum)
{
return remote ? "You need a pass card"
: "You need a pass card to open this door";
}
// ID Badge -----------------------------------------------------------------
class AIDBadge : public AStrifeKey
@ -110,7 +100,6 @@ class AIDBadge : public AStrifeKey
DECLARE_ACTOR (AIDBadge, AStrifeKey)
public:
const char *PickupMessage ();
const char *NeedKeyMessage (bool remote, int keynum);
};
FState AIDBadge::States[] =
@ -123,7 +112,6 @@ IMPLEMENT_ACTOR (AIDBadge, Strife, 184, 0)
PROP_StrifeTeaserType (132)
PROP_StrifeTeaserType2 (135)
PROP_SpawnState (0)
PROP_Key_KeyNumber (4)
PROP_Inventory_Icon ("I_CRD1")
PROP_Tag ("ID_Badge")
END_DEFAULTS
@ -133,12 +121,6 @@ const char *AIDBadge::PickupMessage ()
return "You picked up the ID Badge.";
}
const char *AIDBadge::NeedKeyMessage (bool remote, int keynum)
{
return remote ? "You need an id badge" :
"You need an id badge to open this door";
}
// Prison Key ---------------------------------------------------------------
class APrisonKey : public AStrifeKey
@ -147,7 +129,6 @@ class APrisonKey : public AStrifeKey
public:
bool TryPickup (AActor *toucher);
const char *PickupMessage ();
const char *NeedKeyMessage (bool remote, int keynum);
};
FState APrisonKey::States[] =
@ -160,7 +141,6 @@ IMPLEMENT_ACTOR (APrisonKey, Strife, -1, 0)
PROP_StrifeTeaserType (133)
PROP_StrifeTeaserType2 (136)
PROP_SpawnState (0)
PROP_Key_KeyNumber (5)
PROP_Inventory_Icon ("I_PRIS")
PROP_Tag ("Prison_Key")
END_DEFAULTS
@ -180,11 +160,6 @@ const char *APrisonKey::PickupMessage ()
return "You picked up the Prsion Key.";
}
const char *APrisonKey::NeedKeyMessage (bool remote, int keynum)
{
return "You don't have the key to the prison";
}
// Severed Hand -------------------------------------------------------------
class ASeveredHand : public AStrifeKey
@ -193,7 +168,6 @@ class ASeveredHand : public AStrifeKey
public:
bool TryPickup (AActor *toucher);
const char *PickupMessage ();
const char *NeedKeyMessage (bool remote, int keynum);
};
FState ASeveredHand::States[] =
@ -206,7 +180,6 @@ IMPLEMENT_ACTOR (ASeveredHand, Strife, 91, 0)
PROP_StrifeTeaserType (134)
PROP_StrifeTeaserType2 (137)
PROP_SpawnState (0)
PROP_Key_KeyNumber (6)
PROP_Inventory_Icon ("I_HAND")
PROP_Tag ("Severed_Hand")
END_DEFAULTS
@ -226,11 +199,6 @@ const char *ASeveredHand::PickupMessage ()
return "You picked up the Severed Hand.";
}
const char *ASeveredHand::NeedKeyMessage (bool remote, int keynum)
{
return "Hand print not on file";
}
// Power1 Key ---------------------------------------------------------------
class APower1Key : public AStrifeKey
@ -250,7 +218,6 @@ IMPLEMENT_ACTOR (APower1Key, Strife, -1, 0)
PROP_StrifeTeaserType (135)
PROP_StrifeTeaserType2 (138)
PROP_SpawnState (0)
PROP_Key_KeyNumber (7)
PROP_Inventory_Icon ("I_PWR1")
PROP_Tag ("Power1_Key")
END_DEFAULTS
@ -279,7 +246,6 @@ IMPLEMENT_ACTOR (APower2Key, Strife, -1, 0)
PROP_StrifeTeaserType (136)
PROP_StrifeTeaserType2 (139)
PROP_SpawnState (0)
PROP_Key_KeyNumber (8)
PROP_Inventory_Icon ("I_PWR2")
PROP_Tag ("Power2_Key")
END_DEFAULTS
@ -308,7 +274,6 @@ IMPLEMENT_ACTOR (APower3Key, Strife, -1, 0)
PROP_StrifeTeaserType (137)
PROP_StrifeTeaserType2 (140)
PROP_SpawnState (0)
PROP_Key_KeyNumber (9)
PROP_Inventory_Icon ("I_PWR3")
PROP_Tag ("Power3_Key")
END_DEFAULTS
@ -325,7 +290,6 @@ class AGoldKey : public AStrifeKey
DECLARE_ACTOR (AGoldKey, AStrifeKey)
public:
const char *PickupMessage ();
const char *NeedKeyMessage (bool remote, int keynum);
};
FState AGoldKey::States[] =
@ -338,7 +302,6 @@ IMPLEMENT_ACTOR (AGoldKey, Strife, 40, 0)
PROP_StrifeTeaserType (138)
PROP_StrifeTeaserType2 (141)
PROP_SpawnState (0)
PROP_Key_KeyNumber (10)
PROP_Inventory_Icon ("I_KY1G")
PROP_Tag ("Gold_Key")
END_DEFAULTS
@ -348,11 +311,6 @@ const char *AGoldKey::PickupMessage ()
return "You picked up the Gold Key.";
}
const char *AGoldKey::NeedKeyMessage (bool remote, int keynum)
{
return "You need a gold key";
}
// ID Card ------------------------------------------------------------------
class AIDCard : public AStrifeKey
@ -360,7 +318,6 @@ class AIDCard : public AStrifeKey
DECLARE_ACTOR (AIDCard, AStrifeKey)
public:
const char *PickupMessage ();
const char *NeedKeyMessage (bool remote, int keynum);
};
FState AIDCard::States[] =
@ -373,7 +330,6 @@ IMPLEMENT_ACTOR (AIDCard, Strife, 13, 0)
PROP_StrifeTeaserType (139)
PROP_StrifeTeaserType2 (142)
PROP_SpawnState (0)
PROP_Key_KeyNumber (11)
PROP_Inventory_Icon ("I_CRD2")
PROP_Tag ("ID_Card")
END_DEFAULTS
@ -383,13 +339,6 @@ const char *AIDCard::PickupMessage ()
return "You picked up the ID Card.";
}
const char *AIDCard::NeedKeyMessage (bool remote, int keynum)
{
return remote ? "You need an id card"
: "You need an id card to open this door";
}
// Silver Key ---------------------------------------------------------------
class ASilverKey : public AStrifeKey
@ -397,7 +346,6 @@ class ASilverKey : public AStrifeKey
DECLARE_ACTOR (ASilverKey, AStrifeKey)
public:
const char *PickupMessage ();
const char *NeedKeyMessage (bool remote, int keynum);
};
FState ASilverKey::States[] =
@ -410,7 +358,6 @@ IMPLEMENT_ACTOR (ASilverKey, Strife, 38, 0)
PROP_StrifeTeaserType (140)
PROP_StrifeTeaserType2 (143)
PROP_SpawnState (0)
PROP_Key_KeyNumber (12)
PROP_Inventory_Icon ("I_KY2S")
PROP_Tag ("Silver_Key")
END_DEFAULTS
@ -420,11 +367,6 @@ const char *ASilverKey::PickupMessage ()
return "You picked up the Silver Key.";
}
const char *ASilverKey::NeedKeyMessage (bool remote, int keynum)
{
return "You need a silver key";
}
// Oracle Key ---------------------------------------------------------------
class AOracleKey : public AStrifeKey
@ -444,7 +386,6 @@ IMPLEMENT_ACTOR (AOracleKey, Strife, 61, 0)
PROP_StrifeTeaserType (141)
PROP_StrifeTeaserType2 (144)
PROP_SpawnState (0)
PROP_Key_KeyNumber (13)
PROP_Inventory_Icon ("I_ORAC")
PROP_Tag ("Oracle_Key")
END_DEFAULTS
@ -473,7 +414,6 @@ IMPLEMENT_ACTOR (AMilitaryID, Strife, -1, 0)
PROP_StrifeTeaserType (142)
PROP_StrifeTeaserType2 (145)
PROP_SpawnState (0)
PROP_Key_KeyNumber (14)
PROP_Inventory_Icon ("I_GYID")
PROP_Tag ("Military ID")
END_DEFAULTS
@ -502,7 +442,6 @@ IMPLEMENT_ACTOR (AOrderKey, Strife, 86, 0)
PROP_StrifeTeaserType (143)
PROP_StrifeTeaserType2 (146)
PROP_SpawnState (0)
PROP_Key_KeyNumber (15)
PROP_Inventory_Icon ("I_FUBR")
PROP_Tag ("Order_Key")
END_DEFAULTS
@ -531,7 +470,6 @@ IMPLEMENT_ACTOR (AWarehouseKey, Strife, 166, 0)
PROP_StrifeTeaserType (144)
PROP_StrifeTeaserType2 (147)
PROP_SpawnState (0)
PROP_Key_KeyNumber (16)
PROP_Inventory_Icon ("I_WARE")
PROP_Tag ("Warehouse_Key")
END_DEFAULTS
@ -548,7 +486,6 @@ class ABrassKey : public AStrifeKey
DECLARE_ACTOR (ABrassKey, AStrifeKey)
public:
const char *PickupMessage ();
const char *NeedKeyMessage (bool remote, int keynum);
};
FState ABrassKey::States[] =
@ -556,12 +493,11 @@ FState ABrassKey::States[] =
S_NORMAL (KY3B, 'A', -1, NULL, NULL)
};
IMPLEMENT_ACTOR (ABrassKey, Strife, -1, 0)
IMPLEMENT_ACTOR (ABrassKey, Strife, 39, 0)
PROP_StrifeType (149)
PROP_StrifeTeaserType (145)
PROP_StrifeTeaserType2 (148)
PROP_SpawnState (0)
PROP_Key_KeyNumber (17)
PROP_Inventory_Icon ("I_KY3B")
PROP_Tag ("Brass_Key")
END_DEFAULTS
@ -571,11 +507,6 @@ const char *ABrassKey::PickupMessage ()
return "You picked up the Brass Key.";
}
const char *ABrassKey::NeedKeyMessage (bool remote, int keynum)
{
return "You need a brass key";
}
// Red Crystal Key ----------------------------------------------------------
class ARedCrystalKey : public AStrifeKey
@ -595,7 +526,6 @@ IMPLEMENT_ACTOR (ARedCrystalKey, Strife, 192, 0)
PROP_StrifeTeaserType (146)
PROP_StrifeTeaserType2 (149)
PROP_SpawnState (0)
PROP_Key_KeyNumber (18)
PROP_Inventory_Icon ("I_RCRY")
PROP_Tag ("Red_Crystal_Key")
END_DEFAULTS
@ -624,7 +554,6 @@ IMPLEMENT_ACTOR (ABlueCrystalKey, Strife, 193, 0)
PROP_StrifeTeaserType (147)
PROP_StrifeTeaserType2 (150)
PROP_SpawnState (0)
PROP_Key_KeyNumber (19)
PROP_Inventory_Icon ("I_BCRY")
PROP_Tag ("Blue_Crystal_Key")
END_DEFAULTS
@ -653,7 +582,6 @@ IMPLEMENT_ACTOR (AChapelKey, Strife, 195, 0)
PROP_StrifeTeaserType (148)
PROP_StrifeTeaserType2 (151)
PROP_SpawnState (0)
PROP_Key_KeyNumber (20)
PROP_Inventory_Icon ("I_CHAP")
PROP_Tag ("Chapel_Key")
END_DEFAULTS
@ -683,7 +611,6 @@ IMPLEMENT_ACTOR (ACatacombKey, Strife, -1, 0)
PROP_StrifeTeaserType (149)
PROP_StrifeTeaserType2 (152)
PROP_SpawnState (0)
PROP_Key_KeyNumber (21)
PROP_Inventory_Icon ("I_TUNL")
PROP_Tag ("Catacomb_Key") // "Tunnel_Key" in the Teaser
END_DEFAULTS
@ -722,7 +649,6 @@ IMPLEMENT_ACTOR (ASecurityKey, Strife, -1, 0)
PROP_StrifeTeaserType (150)
PROP_StrifeTeaserType2 (153)
PROP_SpawnState (0)
PROP_Key_KeyNumber (22)
PROP_Inventory_Icon ("I_SECK")
PROP_Tag ("Security_Key")
END_DEFAULTS
@ -751,7 +677,6 @@ IMPLEMENT_ACTOR (ACoreKey, Strife, 236, 0)
PROP_StrifeTeaserType (151)
PROP_StrifeTeaserType2 (154)
PROP_SpawnState (0)
PROP_Key_KeyNumber (23)
PROP_Inventory_Icon ("I_GOID")
PROP_Tag ("Core_Key") // "New_Key1" in the Teaser
END_DEFAULTS
@ -780,7 +705,6 @@ IMPLEMENT_ACTOR (AMaulerKey, Strife, 233, 0)
PROP_StrifeTeaserType (152)
PROP_StrifeTeaserType2 (155)
PROP_SpawnState (0)
PROP_Key_KeyNumber (24)
PROP_Inventory_Icon ("I_BLTK")
PROP_Tag ("Mauler_Key") // "New_Key2" in the Teaser
END_DEFAULTS
@ -809,7 +733,6 @@ IMPLEMENT_ACTOR (AFactoryKey, Strife, 234, 0)
PROP_StrifeTeaserType (153)
PROP_StrifeTeaserType2 (156)
PROP_SpawnState (0)
PROP_Key_KeyNumber (25)
PROP_Inventory_Icon ("I_PROC")
PROP_Tag ("Factory_Key") // "New_Key3" in the Teaser
END_DEFAULTS
@ -838,7 +761,6 @@ IMPLEMENT_ACTOR (AMineKey, Strife, 235, 0)
PROP_StrifeTeaserType (154)
PROP_StrifeTeaserType2 (157)
PROP_SpawnState (0)
PROP_Key_KeyNumber (26)
PROP_Inventory_Icon ("I_MINE") // "New_Key4" in the Teaser
PROP_Tag ("MINE_KEY")
END_DEFAULTS
@ -867,7 +789,6 @@ IMPLEMENT_ACTOR (ANewKey5, Strife, -1, 0)
PROP_StrifeTeaserType (155)
PROP_StrifeTeaserType2 (158)
PROP_SpawnState (0)
PROP_Key_KeyNumber (27)
PROP_Inventory_Icon ("I_BLTK")
PROP_Tag ("New_Key5")
END_DEFAULTS
@ -898,7 +819,6 @@ IMPLEMENT_ACTOR (APrisonPass, Strife, -1, 0)
PROP_StrifeTeaserType (286)
PROP_StrifeTeaserType2 (303)
PROP_SpawnState (0)
PROP_Key_KeyNumber (50)
PROP_Inventory_Icon ("I_TOKN")
PROP_Tag ("Prison_pass")
END_DEFAULTS
@ -941,7 +861,6 @@ class AOraclePass : public AKey
public:
bool TryPickup (AActor *toucher);
const char *PickupMessage ();
const char *NeedKeyMessage (bool remote, int keynum);
};
FState AOraclePass::States[] =
@ -954,7 +873,6 @@ IMPLEMENT_ACTOR (AOraclePass, Strife, -1, 0)
PROP_StrifeTeaserType (292)
PROP_StrifeTeaserType2 (309)
PROP_SpawnState (0)
PROP_Key_KeyNumber (51)
PROP_Inventory_Icon ("I_OTOK")
PROP_Tag ("Oracle_Pass")
END_DEFAULTS
@ -974,7 +892,3 @@ const char *AOraclePass::PickupMessage ()
return "You picked up the Oracle Pass.";
}
const char *AOraclePass::NeedKeyMessage (bool remote, int keynum)
{
return "You need the Oracle Pass!";
}

View File

@ -1035,6 +1035,7 @@ IMPLEMENT_ACTOR (AFlameThrowerParts, Strife, -1, 0)
PROP_StrifeType (191)
PROP_StrifeTeaserType (185)
PROP_StrifeTeaserType2 (189)
PROP_Inventory_FlagsSet (IF_INVBAR)
PROP_Inventory_Icon ("I_BFLM")
PROP_Tag ("flame_thrower_parts")
END_DEFAULTS

View File

@ -43,12 +43,12 @@ void DBoundingBox::AddToBox (fixed_t x, fixed_t y)
{
if (x < m_Box[BOXLEFT])
m_Box[BOXLEFT] = x;
else if (x > m_Box[BOXRIGHT])
if (x > m_Box[BOXRIGHT])
m_Box[BOXRIGHT] = x;
if (y < m_Box[BOXBOTTOM])
m_Box[BOXBOTTOM] = y;
else if (y > m_Box[BOXTOP])
if (y > m_Box[BOXTOP])
m_Box[BOXTOP] = y;
}

View File

@ -633,6 +633,9 @@ void cht_Give (player_t *player, char *name, int amount)
return;
}
if (giveall)
return;
type = TypeInfo::IFindType (name);
if (type == NULL || !type->IsDescendantOf (RUNTIME_CLASS(AInventory)))
{

View File

@ -244,7 +244,7 @@ DWORD FNodeBuilder::AddMiniseg (int v1, int v2, DWORD partner, DWORD seg1, DWORD
FPrivSeg *seg = &Segs[seg1];
FPrivSeg newseg;
newseg.sidedef = NO_INDEX;
newseg.sidedef = NO_SIDE;
newseg.linedef = -1;
newseg.loopnum = 0;
newseg.next = DWORD_MAX;

View File

@ -143,11 +143,8 @@ void FNodeBuilder::MakeSegsFromSides ()
share1 = NULL;
if (Level.Lines[i].sidenum[0] != NO_SIDE)
{
DWORD backside;
seg.linedef = i;
seg.sidedef = Level.Lines[i].sidenum[0];
backside = Level.Lines[i].sidenum[1];
seg.frontsector = Level.Lines[i].frontsector;
seg.backsector = Level.Lines[i].backsector;
seg.v1 = (int)(size_t)Level.Lines[i].v1;
@ -173,11 +170,8 @@ void FNodeBuilder::MakeSegsFromSides ()
if (Level.Lines[i].sidenum[1] != NO_SIDE)
{
DWORD backside;
seg.linedef = i;
seg.sidedef = Level.Lines[i].sidenum[1];
backside = Level.Lines[i].sidenum[0];
seg.frontsector = Level.Lines[i].backsector;
seg.backsector = Level.Lines[i].frontsector;
seg.v1 = (int)(size_t)Level.Lines[i].v2;

View File

@ -675,6 +675,10 @@ void AActor::Die (AActor *source, AActor *inflictor)
{
SetState (IDeathState);
}
else
{
Destroy();
}
}
}

View File

@ -1324,9 +1324,9 @@ FUNC(LS_Thing_SetGoal)
}
FUNC(LS_Thing_Move) // [BC]
// Thing_Move (tid, mapspot)
// Thing_Move (tid, mapspot, nofog)
{
return P_Thing_Move (arg0, arg1);
return P_Thing_Move (arg0, arg1, arg2 ? false : true);
}
FUNC(LS_Thing_SetTranslation)

View File

@ -131,7 +131,7 @@ bool P_Thing_Spawn (int tid, int type, angle_t angle, bool fog, int newtid);
bool P_Thing_Projectile (int tid, int type, angle_t angle,
fixed_t speed, fixed_t vspeed, int dest, AActor *forcedest, int gravity, int newtid,
bool leadTarget);
bool P_Thing_Move (int tid, int mapspot);
bool P_Thing_Move (int tid, int mapspot, bool fog);
//
// P_ENEMY

View File

@ -1293,6 +1293,8 @@ BOOL P_CheckPosition (AActor *thing, fixed_t x, fixed_t y)
{ // [RH] Fake taller height to catch stepping up into things.
thing->height = realheight + thing->MaxStepHeight;
}
stepthing = NULL;
for (bx = xl; bx <= xh; bx++)
{
for (by = yl; by <= yh; by++)
@ -1300,7 +1302,6 @@ BOOL P_CheckPosition (AActor *thing, fixed_t x, fixed_t y)
AActor *robin = NULL;
do
{
stepthing = NULL;
if (!P_BlockThingsIterator (bx, by, PIT_CheckThing, checkpbt, robin))
{ // [RH] If a thing can be stepped up on, we need to continue checking
// other things in the blocks and see if we hit something that is
@ -2212,6 +2213,8 @@ bool P_CheckSlopeWalk (AActor *actor, fixed_t &xmove, fixed_t &ymove)
if (actor->floorsector != actor->Sector)
{
// this additional check prevents sliding on sloped dropoffs
if (planezhere>actor->floorz+4*FRACUNIT)
return false;
}
@ -2734,36 +2737,38 @@ void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
{
puff = P_SpawnPuff (pufftype, hitx, hity, hitz, angle - ANG180, 2, true);
}
if ((gameinfo.gametype & (GAME_DoomStrife)) &&
!axeBlood &&
!(trace.Actor->flags & MF_NOBLOOD) &&
!(trace.Actor->flags2 & (MF2_INVULNERABLE|MF2_DORMANT)))
if (!(GetDefaultByType(pufftype)->flags3&MF3_BLOODLESSIMPACT))
{
P_SpawnBlood (hitx, hity, hitz, angle - ANG180, damage, trace.Actor);
}
if (damage)
{
if ((gameinfo.gametype & GAME_Raven) || axeBlood)
if ((gameinfo.gametype & (GAME_DoomStrife)) && !axeBlood &&
!(trace.Actor->flags & MF_NOBLOOD) &&
!(trace.Actor->flags2 & (MF2_INVULNERABLE|MF2_DORMANT)))
{
if (!(trace.Actor->flags&MF_NOBLOOD) &&
!(trace.Actor->flags2&(MF2_INVULNERABLE|MF2_DORMANT)))
P_SpawnBlood (hitx, hity, hitz, angle - ANG180, damage, trace.Actor);
}
if (damage)
{
if ((gameinfo.gametype&GAME_Raven) || axeBlood)
{
if (axeBlood)
if (!(trace.Actor->flags&MF_NOBLOOD) &&
!(trace.Actor->flags2&(MF2_INVULNERABLE|MF2_DORMANT)))
{
P_BloodSplatter2 (hitx, hity, hitz, trace.Actor);
}
if (pr_lineattack() < 192)
{
P_BloodSplatter (hitx, hity, hitz, trace.Actor);
if (axeBlood)
{
P_BloodSplatter2 (hitx, hity, hitz, trace.Actor);
}
if (pr_lineattack() < 192)
{
P_BloodSplatter (hitx, hity, hitz, trace.Actor);
}
}
}
// [RH] Stick blood to walls
P_TraceBleed (damage, trace.X, trace.Y, trace.Z,
trace.Actor, srcangle, srcpitch);
}
P_DamageMobj (trace.Actor, puff ? puff : t1, t1, damage, damageType);
// [RH] Stick blood to walls
P_TraceBleed (damage, trace.X, trace.Y, trace.Z,
trace.Actor, srcangle, srcpitch);
}
if (damage) P_DamageMobj (trace.Actor, puff ? puff : t1, t1, damage, damageType);
}
if (trace.CrossedWater)
{
@ -3089,6 +3094,7 @@ BOOL PTR_UseTraverse (intercept_t *in)
// [RH] Check for things to talk with or use a puzzle item on
if (!in->isaline)
{
if (usething==in->d.thing) return true;
// Check thing
// Check for puzzle item use
@ -3124,7 +3130,9 @@ BOOL PTR_UseTraverse (intercept_t *in)
// lines further than 64 units away.
if (in->frac > FRACUNIT/2)
{
return true;
P_LineOpening (in->d.line, trace.x + FixedMul (trace.dx, in->frac),
trace.y + FixedMul (trace.dy, in->frac));
return openrange>0;
}
if (in->d.line->special == 0 || (GET_SPAC(in->d.line->flags) != SPAC_USETHROUGH &&
@ -3191,17 +3199,16 @@ blocked:
BOOL PTR_NoWayTraverse (intercept_t *in)
{
line_t *ld = in->d.line; // This linedef
line_t *ld = in->d.line;
return ld->special || !( // Ignore specials
ld->flags & (ML_BLOCKING|ML_BLOCKEVERYTHING) || ( // Always blocking
P_LineOpening(ld, trace.x + FixedMul (trace.dx, in->frac),
trace.y + FixedMul (trace.dy, in->frac)), // Find openings
openrange <= 0 || // No opening
openbottom > usething->z+usething->MaxStepHeight || // Too high it blocks
opentop < usething->z+usething->height // Too low it blocks
)
);
// [GrafZahl] de-obfuscated. Was I the only one who was unable to makes sense out of
// this convoluted mess?
if (ld->special) return true;
if (ld->flags&(ML_BLOCKING|ML_BLOCKEVERYTHING)) return false;
P_LineOpening(ld, trace.x+FixedMul(trace.dx, in->frac),trace.y+FixedMul(trace.dy, in->frac));
return openrange >0 &&
openbottom <= usething->z + usething->MaxStepHeight &&
opentop >= usething->z + usething->height;
}
/*
@ -3814,14 +3821,6 @@ void P_DoCrunch (AActor *thing)
// crunch dropped items
if (thing->flags & MF_DROPPED)
{
// [GrafZahl] Just a quick fix to prevent items in a player's inventory from being crushed
// I still think this should be taken care of by the inventory system, not a special check here.
if (!thing->IsKindOf(RUNTIME_CLASS(AInventory)) || !static_cast<AInventory*>(thing)->Owner)
thing->Destroy ();
return; // keep checking
}
if (thing->flags & MF_DROPPED)
{
thing->Destroy ();
return; // keep checking

View File

@ -917,15 +917,18 @@ void AActor::Touch (AActor *toucher)
bool AActor::Massacre ()
{
int prevhealth;
if (health > 0)
{
flags |= MF_SHOOTABLE;
flags2 &= ~(MF2_DORMANT|MF2_INVULNERABLE);
do
{
prevhealth = health;
P_DamageMobj (this, NULL, NULL, 1000000, MOD_MASSACRE);
}
while (health > 0);
while (health != prevhealth && health > 0); //abort if the actor wasn't hurt.
return true;
}
return false;
@ -1266,8 +1269,16 @@ void P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
// it gets blocked.
if (mo->player != NULL && (compatflags & COMPATF_WALLRUN) || (mo->waterlevel >= 2))
{
xmove = mo->momx = clamp (mo->momx, -maxmove, maxmove);
ymove = mo->momy = clamp (mo->momy, -maxmove, maxmove);
// try to preserve the direction instead of clamping x and y independently.
xmove = clamp (mo->momx, -maxmove, maxmove);
ymove = clamp (mo->momy, -maxmove, maxmove);
fixed_t xfac = FixedDiv(xmove, mo->momx);
fixed_t yfac = FixedDiv(ymove, mo->momy);
fixed_t fac = MIN(xfac, yfac);
xmove = mo->momx = FixedMul(mo->momx, fac);
ymove = mo->momy = FixedMul(mo->momy, fac);
}
else
{
@ -1725,6 +1736,9 @@ void P_ZMovement (AActor *mo)
mo->player->viewheight -= mo->floorz - mo->z;
mo->player->deltaviewheight = (VIEWHEIGHT - mo->player->viewheight)>>3;
}
if (!(mo->flags2&MF2_FLOATBOB)) mo->z += mo->momz;
//
// apply gravity
//
@ -1753,10 +1767,12 @@ void P_ZMovement (AActor *mo)
}
}
}
if (mo->flags2&MF2_FLOATBOB) mo->z += mo->momz;
//
// adjust height
//
mo->z += mo->momz;
if ((mo->flags & MF_FLOAT) && mo->target)
{ // float down towards target if too close
if (!(mo->flags & MF_SKULLFLY) && !(mo->flags & MF_INFLOAT))

View File

@ -114,7 +114,7 @@ bool P_Thing_Spawn (int tid, int type, angle_t angle, bool fog, int newtid)
// [BC] Added
// [RH] Fixed
bool P_Thing_Move (int tid, int mapspot)
bool P_Thing_Move (int tid, int mapspot, bool fog)
{
FActorIterator iterator1 (tid);
FActorIterator iterator2 (mapspot);
@ -134,8 +134,11 @@ bool P_Thing_Move (int tid, int mapspot)
source->SetOrigin (target->x, target->y, target->z);
if (P_TestMobjLocation (source))
{
Spawn<ATeleportFog> (target->x, target->y, target->z + TELEFOGHEIGHT);
Spawn<ATeleportFog> (oldx, oldy, oldz + TELEFOGHEIGHT);
if (fog)
{
Spawn<ATeleportFog> (target->x, target->y, target->z + TELEFOGHEIGHT);
Spawn<ATeleportFog> (oldx, oldy, oldz + TELEFOGHEIGHT);
}
return true;
}
else

View File

@ -172,12 +172,15 @@ static int WriteSEGS (FILE *file)
ms.offset = 0; // unused by ZDoom, so just leave it 0
for (int i = 0; i < numsegs; ++i)
{
ms.v1 = LittleShort(short(segs[i].v1 - vertexes));
ms.v2 = LittleShort(short(segs[i].v2 - vertexes));
ms.linedef = LittleShort(short(segs[i].linedef - lines));
ms.side = LittleShort(segs[i].sidedef - sides == segs[i].linedef->sidenum[0] ? 0 : 1);
ms.angle = LittleShort(short(R_PointToAngle2 (segs[i].v1->x, segs[i].v1->y, segs[i].v2->x, segs[i].v2->y)>>16));
fwrite (&ms, sizeof(ms), 1, file);
if (segs[i].linedef!=NULL)
{
ms.v1 = LittleShort(short(segs[i].v1 - vertexes));
ms.v2 = LittleShort(short(segs[i].v2 - vertexes));
ms.linedef = LittleShort(short(segs[i].linedef - lines));
ms.side = LittleShort(segs[i].sidedef - sides == segs[i].linedef->sidenum[0] ? 0 : 1);
ms.angle = LittleShort(short(R_PointToAngle2 (segs[i].v1->x, segs[i].v1->y, segs[i].v2->x, segs[i].v2->y)>>16));
fwrite (&ms, sizeof(ms), 1, file);
}
}
return numsegs * sizeof(ms);
}

View File

@ -400,6 +400,13 @@ void P_TranslateTeleportThings ()
lines[i].args[0] = 1;
}
}
else if (lines[i].special == Teleport_ZombieChanger)
{
if (lines[i].args[2] == 0)
{
lines[i].args[0] = 1;
}
}
}
}
}

View File

@ -308,7 +308,7 @@ struct sector_t
short tag;
int nexttag,firsttag; // killough 1/30/98: improves searches for tags.
WORD sky;
int sky;
short seqType; // this sector's sound sequence
fixed_t soundorg[3]; // origin for any sounds played by the sector
@ -429,7 +429,7 @@ struct line_s
short args[5]; // <--- hexen-style arguments
// note that these are shorts in order to support
// the tag parameter from DOOM.
short firstid, nextid;
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.
slopetype_t slopetype; // To aid move clipping.

View File

@ -862,6 +862,9 @@ void R_InterpolateView (player_t *player, fixed_t frac, InterpolationViewer *ivi
viewpitch = iview->oviewpitch + FixedMul (frac, iview->nviewpitch - iview->oviewpitch);
viewangle = iview->oviewangle + FixedMul (frac, iview->nviewangle - iview->oviewangle);
}
// Due to interpolation this is not necessarily the same as the sector the camera is in.
viewsector = R_PointInSubsector(viewx, viewy)->sector;
}
//==========================================================================

View File

@ -63,7 +63,7 @@ typedef struct visplane_s visplane_t;
// killough 10/98: special mask indicates sky flat comes from sidedef
#define PL_SKYFLAT (0x8000)
#define PL_SKYFLAT 0x10000
// Visplane related.
extern ptrdiff_t lastopening; // type short

View File

@ -1480,7 +1480,9 @@ void R_DrawPlayerSprites (void)
(players[consoleplayer].cheats & CF_CHASECAM))
return;
sec = R_FakeFlat (camera->Sector, &tempsec, &floorlight,
// This used to use camera->Sector but due to interpolation that can be incorrect
// when the interpolated viewpoint is in a different sector than the camera.
sec = R_FakeFlat (viewsector, &tempsec, &floorlight,
&ceilinglight, false);
// [RH] set foggy flag

View File

@ -74,6 +74,7 @@ static bool FreeScript = false;
static char *SavedScriptPtr;
static int SavedScriptLine;
static bool CMode;
static bool Escape=true;
// CODE --------------------------------------------------------------------
@ -242,13 +243,18 @@ void SC_SetCMode (bool cmode)
CMode = cmode;
}
void SC_SetEscape (bool esc)
{
Escape = esc;
}
//==========================================================================
//
// SC_GetString
//
//==========================================================================
BOOL SC_GetString (void)
BOOL SC_GetString ()
{
char *text;
BOOL foundToken;
@ -326,9 +332,18 @@ BOOL SC_GetString (void)
if (*ScriptPtr == ASCII_QUOTE)
{ // Quoted string
ScriptPtr++;
while (*ScriptPtr != ASCII_QUOTE || *(ScriptPtr - 1) == '\\')
while (*ScriptPtr != ASCII_QUOTE)
{
*text++ = *ScriptPtr++;
// Hack alert: Do not allow escaped quotation marks when parsing DECORATE!
if (*ScriptPtr=='\\' && ScriptPtr[1]=='"' && Escape)
{
*text++ = '"';
ScriptPtr+=2;
}
else
{
*text++ = *ScriptPtr++;
}
if (ScriptPtr == ScriptEndPtr
|| text == &sc_String[MAX_STRING_SIZE-1])
{
@ -373,6 +388,9 @@ BOOL SC_GetString (void)
if (strchr (stopchars, *ScriptPtr))
{
*text++ = *ScriptPtr++;
// [GRB] Allow 2-char operators
if (CMode && strchr ("&=|<>", *ScriptPtr))
*text++ = *ScriptPtr++;
}
else
{

View File

@ -7,6 +7,7 @@ void SC_OpenMem (const char *name, char *buffer, int size);
void SC_OpenLumpNum (int lump, const char *name);
void SC_Close (void);
void SC_SetCMode (bool cmode);
void SC_SetEscape (bool esc);
void SC_SavePos (void);
void SC_RestorePos (void);
BOOL SC_GetString (void);

View File

@ -138,7 +138,7 @@ static BYTE CheatOmnipotent[] = { 'o','m','n','i','p','o','t','e','n','t',255 };
static BYTE CheatJimmy[] = { 'j','i','m','m','y',255 };
static BYTE CheatBoomstix[] = { 'b','o','o','m','s','t','i','x',255 };
static BYTE CheatStoneCold[] = { 's','t','o','n','e','c','o','l','d',255 };
static BYTE CheatElvis[] = { 'e','l','v','i','s' };
static BYTE CheatElvis[] = { 'e','l','v','i','s',255 };
static BYTE CheatTopo[] = { 't','o','p','o',255 };
static cheatseq_t DoomCheats[] =

View File

@ -225,9 +225,6 @@ void FStringTable::LoadLanguage (int lumpnum, DWORD code, bool exactMatch, int p
continue;
}
if (SC_Compare ("C2TEXT"))
skip = skip;
string strName (sc_String);
SC_MustGetStringName ("=");
SC_MustGetString ();

View File

@ -434,6 +434,7 @@ ACTOR(KlaxonBlare)
ACTOR(20e10)
ACTOR(Countdown)
ACTOR(AlertMonsters)
ACTOR(FireAssaultGun)
ACTOR(PlaySound)
ACTOR(PlayWeaponSound)
ACTOR(LoopActiveSound)
@ -462,6 +463,7 @@ ACTOR(Recoil)
ACTOR(SelectWeapon)
ACTOR(Print)
ACTOR(SetTranslucent)
ACTOR(FadeIn)
ACTOR(FadeOut)
ACTOR(SpawnDebris)
ACTOR(SetSolid)
@ -480,6 +482,10 @@ ACTOR(SetUserVar)
ACTOR(SetUserVarRandom)
ACTOR(KillMaster)
ACTOR(KillChildren)
ACTOR(DualPainAttack)
ACTOR(GiveToTarget)
ACTOR(TakeFromTarget)
ACTOR(JumpIfInTargetInventory)
#include "d_dehackedactions.h"
@ -491,7 +497,7 @@ AFuncDesc AFTable[]=
// most of the functions available in Dehacked
FUNC(A_MonsterRail, NULL)
FUNC(A_BFGSpray, "mx")
FUNC(A_BFGSpray, "mxx")
FUNC(A_Pain, NULL)
FUNC(A_NoBlocking, NULL)
FUNC(A_XScream, NULL)
@ -531,6 +537,7 @@ AFuncDesc AFTable[]=
FUNC(A_Hoof, NULL)
FUNC(A_CyberAttack, NULL)
FUNC(A_PainAttack, "m")
FUNC(A_DualPainAttack, "m")
FUNC(A_PainDie, "m")
FUNC(A_KeenDie, NULL)
FUNC(A_BrainPain, NULL)
@ -565,8 +572,6 @@ AFuncDesc AFTable[]=
FUNC(A_UnsetSolid, NULL)
FUNC(A_SetFloat, NULL)
FUNC(A_UnsetFloat, NULL)
FUNC(A_BishopMissileWeave, NULL)
FUNC(A_CStaffMissileSlither, NULL)
// For better chainsaw attacks
FUNC(A_M_Saw, NULL)
@ -601,6 +606,7 @@ AFuncDesc AFTable[]=
FUNC(A_KlaxonBlare, NULL)
FUNC(A_Countdown, NULL)
FUNC(A_AlertMonsters, NULL)
FUNC(A_FireAssaultGun, NULL)
{"A_CheckTerrain", A_20e10, NULL }, // This needs a better name!
// Only selected original weapon functions will be available.
@ -626,26 +632,27 @@ AFuncDesc AFTable[]=
FUNC(A_StopSound, NULL )
FUNC(A_SeekerMissile, "XX" )
FUNC(A_Jump, "XL" )
FUNC(A_CustomMissile, "MXXxxxx" )
FUNC(A_CustomMissile, "MXXxxx" )
FUNC(A_CustomBulletAttack, "XXXXmx" )
FUNC(A_CustomRailgun, "Xxccxxx" )
FUNC(A_CustomRailgun, "Xxccyyx" )
FUNC(A_JumpIfHealthLower, "XL" )
FUNC(A_JumpIfCloser, "XL" )
FUNC(A_JumpIfInventory, "MXL" )
FUNC(A_GiveInventory, "Mx" )
FUNC(A_TakeInventory, "Mx" )
FUNC(A_SpawnItem, "Mxxx" )
FUNC(A_ThrowGrenade, "Mxxxx" )
FUNC(A_SpawnItem, "Mxxy" )
FUNC(A_ThrowGrenade, "Mxxxy" )
FUNC(A_SelectWeapon, "M")
FUNC(A_Print, "T")
FUNC(A_SetTranslucent, "Xx")
FUNC(A_FadeIn, "x")
FUNC(A_FadeOut, "x")
FUNC(A_SpawnDebris, "M")
FUNC(A_CheckSight, "L")
FUNC(A_ExtChase, "XXxx")
FUNC(A_ExtChase, "XXyx")
FUNC(A_Jiggle, "XX")
FUNC(A_DropInventory, "M")
FUNC(A_SetBlend, "CXX")
FUNC(A_SetBlend, "DXXd")
FUNC(A_ChangeFlag, "TX")
FUNC(A_JumpIf, "XL")
FUNC(A_KillMaster, NULL)
@ -654,11 +661,14 @@ AFuncDesc AFTable[]=
// Weapon only functions
FUNC(A_JumpIfNoAmmo, "L" )
FUNC(A_CustomPunch, "Xxxmx" )
FUNC(A_FireBullets, "XXXXmxx" )
FUNC(A_FireCustomMissile, "Mxxxx" )
FUNC(A_RailAttack, "Xxxccxx" )
FUNC(A_CustomPunch, "Xxymx" )
FUNC(A_FireBullets, "XXXXmyx" )
FUNC(A_FireCustomMissile, "Mxyxx" )
FUNC(A_RailAttack, "Xxyccyx" )
FUNC(A_Recoil, "X")
FUNC(A_JumpIfInTargetInventory, "MXL" )
FUNC(A_GiveToTarget, "Mx" )
FUNC(A_TakeFromTarget, "Mx" )
};
//==========================================================================
@ -1037,8 +1047,11 @@ typedef ActorProps (*ActorPropHandler) (register const char *str, register unsig
static const ActorProps *is_actorprop (const char *str);
//int ParseExpression ();
int ParseExpression (bool _not)
{
SC_MustGetNumber();
return _not? !sc_Number : sc_Number;
}
//==========================================================================
//
@ -1311,7 +1324,7 @@ bool DoSpecialFunctions(FState & state, bool multistate, int * statecount, Bagga
{
for (i = 0; i < 5;)
{
StateParameters[paramindex+i+1]=SC_GetNumber();//ParseExpression ();
StateParameters[paramindex+i+1]=ParseExpression (false);
i++;
if (!TestCom()) break;
}
@ -1495,7 +1508,9 @@ static int ProcessStates(FActorInfo * actor, AActor * defaults, Baggage &bag)
char * statestrp;
strncpy(statestring, sc_String, 255);
SC_MustGetString();
SC_SetEscape(false);
SC_MustGetString(); // this can read the frame string so escape characters have to be disabled
SC_SetEscape(true);
if (SC_Compare (":"))
{
@ -1523,7 +1538,9 @@ static int ProcessStates(FActorInfo * actor, AActor * defaults, Baggage &bag)
memcpy(state.sprite.name, statestring, 4);
state.Misc1=state.Misc2=0;
SC_MustGetString();
SC_SetEscape(false);
SC_MustGetString(); // This reads the frame string so escape characters have to be disabled
SC_SetEscape(true);
strncpy(statestring, sc_String + 1, 255);
statestrp = statestring;
state.Frame=(*sc_String&223)-'A';
@ -1681,11 +1698,21 @@ static int ProcessStates(FActorInfo * actor, AActor * defaults, Baggage &bag)
}
break;
case 'D':
case 'd':
SC_MustGetString ();
v = V_GetColor (NULL, sc_String);
((PalEntry *)&v)->a = 255;
break;
case 'X':
case 'x':
//v = ParseExpression ();
SC_MustGetNumber ();
v = sc_Number;
v = ParseExpression (false);
break;
case 'Y':
case 'y':
v = ParseExpression (true);
break;
}
StateParameters[paramindex++]=v;
@ -1947,7 +1974,7 @@ void ParseActorProperties (Baggage &bag)
string propname = sc_String;
if (sc_String[0] != '-' && sc_String[1] != '+')
if (sc_String[0]!='-' && sc_String[0]!='+')
{
if (SC_CheckString ("."))
{
@ -2669,6 +2696,24 @@ static void ActorDecal (AActor *defaults, Baggage &bag)
defaults->DecalGenerator = (FDecalBase *) ((size_t)DecalNames.Push(copystring(sc_String))+1);
}
//==========================================================================
//
//==========================================================================
static void ActorMaxStepHeight (AActor *defaults, Baggage &bag)
{
SC_MustGetNumber ();
defaults->MaxStepHeight=sc_Number;
}
//==========================================================================
//
//==========================================================================
static void ActorMaxDropoffHeight (AActor *defaults, Baggage &bag)
{
SC_MustGetNumber ();
defaults->MaxDropOffHeight=sc_Number;
}
//==========================================================================
//
//==========================================================================
@ -3215,6 +3260,8 @@ static const ActorProps props[] =
{ "inventory.respawntics", (apf)InventoryRespawntics, RUNTIME_CLASS(AInventory) },
{ "inventory.usesound", (apf)InventoryUsesound, RUNTIME_CLASS(AInventory) },
{ "mass", ActorMass, RUNTIME_CLASS(AActor) },
{ "maxdropoffheight", ActorMaxDropoffHeight, RUNTIME_CLASS(AActor) },
{ "maxstepheight", ActorMaxStepHeight, RUNTIME_CLASS(AActor) },
{ "melee", ActorMeleeState, RUNTIME_CLASS(AActor) },
{ "meleedamage", ActorMeleeDamage, RUNTIME_CLASS(AActor) },
{ "meleerange", ActorMeleeRange, RUNTIME_CLASS(AActor) },

View File

@ -409,11 +409,11 @@ void A_JumpIfCloser(AActor * self)
// State jump function
//
//==========================================================================
void A_JumpIfInventory(AActor * self)
void DoJumpIfInventory(AActor * self, AActor * owner)
{
FState * CallingState;
int index=CheckIndex(3, &CallingState);
if (index<0) return;
if (index<0 || owner == NULL) return;
const char * ItemType=(const char *)StateParameters[index];
int ItemAmount = EvalExpressionI (StateParameters[index+1], self);
@ -422,7 +422,7 @@ void A_JumpIfInventory(AActor * self)
if (!Type) return;
AInventory * Item=self->FindInventory(Type);
AInventory * Item=owner->FindInventory(Type);
if (Item)
{
@ -431,6 +431,15 @@ void A_JumpIfInventory(AActor * self)
}
}
void A_JumpIfInventory(AActor * self)
{
DoJumpIfInventory(self, self);
}
void A_JumpIfInTargetInventory(AActor * self)
{
DoJumpIfInventory(self, self->target);
}
//==========================================================================
//
@ -484,6 +493,19 @@ void A_CallSpecial(AActor * self)
EvalExpressionI (StateParameters[index+5], self));
}
//==========================================================================
//
// Checks whether this actor is a missile
// Unfortunately this was buggy in older versions of the code and many
// released DECORATE monsters rely on this bug so it can only be fixed
// with an optional flag
//
//==========================================================================
inline static bool isMissile(AActor * self, bool precise=true)
{
return self->flags&MF_MISSILE || (precise && self->GetDefault()->flags&MF_MISSILE);
}
//==========================================================================
//
// The ultimate code pointer: Fully customizable missiles!
@ -491,7 +513,7 @@ void A_CallSpecial(AActor * self)
//==========================================================================
void A_CustomMissile(AActor * self)
{
int index=CheckIndex(7);
int index=CheckIndex(6);
if (index<0) return;
const char * MissileName=(const char*)StateParameters[index];
@ -500,7 +522,6 @@ void A_CustomMissile(AActor * self)
angle_t Angle=EvalExpressionF (StateParameters[index+3], self) * ANGLE_1;
int aimmode=EvalExpressionI (StateParameters[index+4], self);
angle_t pitch=EvalExpressionF (StateParameters[index+5], self) * ANGLE_1;
BOOL realtarget = EvalExpressionI (StateParameters[index+6], self);
AActor * targ;
AActor * missile;
@ -515,7 +536,7 @@ void A_CustomMissile(AActor * self)
fixed_t y = Spawnofs_XY * finesine[ang];
fixed_t z = SpawnHeight-32*FRACUNIT;
switch (aimmode)
switch (aimmode&3)
{
case 0:
// same adjustment as above (in all 3 directions this time) - for better aiming!
@ -568,10 +589,10 @@ void A_CustomMissile(AActor * self)
// handle projectile shooting projectiles - track the
// links back to a real owner
if (self->flags&MF_MISSILE)
if (isMissile(self, !!(aimmode&4)))
{
AActor * owner=self ;//->target;
while (owner->flags&MF_MISSILE && owner->target) owner=owner->target;
while (isMissile(owner, !!(aimmode&4)) && owner->target) owner=owner->target;
targ=owner;
missile->target=owner;
// automatic handling of seeker missiles
@ -931,14 +952,14 @@ void A_CustomRailgun (AActor *actor)
//===========================================================================
//
// A_GiveInventory
// DoGiveInventory
//
//===========================================================================
void A_GiveInventory(AActor * self)
static void DoGiveInventory(AActor * self, AActor * receiver)
{
int index=CheckIndex(2);
if (index<0) return;
if (index<0 || receiver == NULL) return;
const char * item =(const char*)StateParameters[index];
int amount=EvalExpressionI (StateParameters[index+1], self);
@ -962,7 +983,7 @@ void A_GiveInventory(AActor * self)
item->flags&=~MF_COUNTITEM;
level.total_items--;
}
if (!item->TryPickup (self))
if (!item->TryPickup (receiver))
{
item->Destroy ();
StateCall.Result = false;
@ -972,16 +993,26 @@ void A_GiveInventory(AActor * self)
else StateCall.Result = false;
}
void A_GiveInventory(AActor * self)
{
DoGiveInventory(self, self);
}
void A_GiveToTarget(AActor * self)
{
DoGiveInventory(self, self->target);
}
//===========================================================================
//
// A_GiveInventory
// A_TakeInventory
//
//===========================================================================
void A_TakeInventory(AActor * self)
void DoTakeInventory(AActor * self, AActor * receiver)
{
int index=CheckIndex(2);
if (index<0) return;
if (index<0 || receiver == NULL) return;
const char * item =(const char*)StateParameters[index];
int amount=EvalExpressionI (StateParameters[index+1], self);
@ -991,7 +1022,7 @@ void A_TakeInventory(AActor * self)
StateCall.Result=false;
if (mi)
{
AInventory * inv = self->FindInventory(mi);
AInventory * inv = receiver->FindInventory(mi);
if (inv && !inv->IsKindOf(RUNTIME_CLASS(AHexenArmor)))
{
@ -1006,6 +1037,15 @@ void A_TakeInventory(AActor * self)
}
}
void A_TakeInventory(AActor * self)
{
DoTakeInventory(self, self);
}
void A_TakeFromTarget(AActor * self)
{
DoTakeInventory(self, self->target);
}
//===========================================================================
//
@ -1056,7 +1096,7 @@ void A_SpawnItem(AActor * self)
{
AActor * originator = self;
while (originator && originator->flags&MF_MISSILE) originator = originator->target;
while (originator && isMissile(originator)) originator = originator->target;
if (mo->flags3&MF3_ISMONSTER)
{
@ -1072,8 +1112,8 @@ void A_SpawnItem(AActor * self)
{
if (originator->flags3&MF3_ISMONSTER)
{
// If this is a monster, transfer all friendliness information
mo->CopyFriendliness (originator, true);
// If this is a monster transfer all friendliness information
mo->CopyFriendliness(originator, true);
if (useammo) mo->master = originator; // don't let it attack you (optional)!
}
else if (originator->player)
@ -1148,7 +1188,11 @@ void A_ThrowGrenade(AActor * self)
bo->momx += self->momx>>1;
bo->momy += self->momy>>1;
bo->target= self;
bo->tics -= pr_grenade()&3;
if (bo->flags4&MF4_RANDOMIZE)
{
bo->tics -= pr_grenade()&3;
if (bo->tics<1) bo->tics=1;
}
P_CheckMissileSpawn (bo);
StateCall.Result=true;
}
@ -1241,6 +1285,26 @@ void A_SetTranslucent(AActor * self)
self->RenderStyle=mode;
}
//===========================================================================
//
// A_FadeIn
//
// Fades the actor in
//
//===========================================================================
void A_FadeIn(AActor * self)
{
int index=CheckIndex(1, NULL);
if (index<0) return;
fixed_t reduce = EvalExpressionF (StateParameters[index], self) * FRACUNIT;
if (reduce == 0) reduce = FRACUNIT/10;
if (self->RenderStyle==STYLE_Normal) self->RenderStyle=STYLE_Translucent;
self->alpha += reduce;
//if (self->alpha<=0) self->Destroy();
}
//===========================================================================
//
// A_FadeOut
@ -1384,28 +1448,23 @@ void A_DropInventory(AActor * self)
void A_SetBlend(AActor * self)
{
int index=CheckIndex(3);
int colorn = StateParameters[index];
PalEntry color;
if (!colorn)
return;
else if (colorn == -1)
color.r = color.g = color.b = 255;
else
color = GPalette.BaseColors[colorn];
fixed_t alpha = EvalExpressionF (StateParameters[index+1], self) * FRACUNIT;
PalEntry color = StateParameters[index];
float alpha = clamp<float> (EvalExpressionF (StateParameters[index+1], self), 0, 1);
int tics = EvalExpressionI (StateParameters[index+2], self);
PalEntry color2 = StateParameters[index+3];
if (!color2.a)
color2 = color;
new DFlashFader(color.r/255.0f, color.g/255.0f, color.b/255.0f, alpha/(float)FRACUNIT,
color.r/255.0f, color.g/255.0f, color.b/255.0f, 0, tics, self);
new DFlashFader(color.r/255.0f, color.g/255.0f, color.b/255.0f, alpha,
color2.r/255.0f, color2.g/255.0f, color2.b/255.0f, 0,
(float)tics/TICRATE, self);
}
//===========================================================================
//
// A_JUmpIf
// A_JumpIf
//
//===========================================================================
void A_JumpIf(AActor * self)

View File

@ -296,6 +296,8 @@ char *V_GetColorStringByName (const char *name)
int c[3], step;
size_t namelen;
if (Wads.GetNumLumps()==0) return NULL;
rgblump = Wads.CheckNumForName ("X11R6RGB");
if (rgblump == -1)
{

View File

@ -56,7 +56,7 @@ typedef enum
} stateenum_t;
CVAR (Bool, wi_percents, true, CVAR_ARCHIVE)
CVAR (Bool, wi_totaltime, false, CVAR_ARCHIVE) // Something that can be added later.
CVAR (Bool, wi_showtotaltime, true, CVAR_ARCHIVE)
void WI_loadData ();
@ -328,11 +328,15 @@ void WI_LoadBackground(bool isenterpic)
// Not if the exit pic is user defined!
if (level.info->exitpic[0]!=0) return;
// not if the last level is not from the first 3 episodes
if (!IsExMy(wbs->current)) return;
// E1-E3 need special treatment when playing Doom 1.
if (gamemode!=commercial)
{
// not if the last level is not from the first 3 episodes
if (!IsExMy(wbs->current)) return;
// not if the next level is one of the first 3 episodes
if (IsExMy(wbs->next)) return;
// not if the next level is one of the first 3 episodes
if (IsExMy(wbs->next)) return;
}
}
lumpname = "INTERPIC";
}
@ -1753,6 +1757,7 @@ void WI_updateStats ()
if (cnt_time >= plrs[me].stime / TICRATE)
{
cnt_total_time = wbs->totaltime / TICRATE;
S_Sound (CHAN_VOICE, NEXTSTAGE, 1, ATTN_NONE);
sp_state++;
}
@ -1801,7 +1806,7 @@ void WI_drawStats (void)
screen->DrawTexture (timepic, SP_TIMEX, SP_TIMEY, DTA_Clean, true, TAG_DONE);
WI_drawTime (160 - SP_TIMEX, SP_TIMEY, cnt_time);
if (wi_totaltime)
if (wi_showtotaltime)
{
WI_drawTime (160 - SP_TIMEX, SP_TIMEY + lh, cnt_total_time, true); // no 'sucks' for total time ever!
}
@ -1845,7 +1850,7 @@ void WI_drawStats (void)
screen->DrawText (CR_UNTRANSLATED, 85, 160, "TIME",
DTA_Clean, true, DTA_Shadow, true, TAG_DONE);
WI_drawTime (249, 160, cnt_time);
if (wi_totaltime)
if (wi_showtotaltime)
{
WI_drawTime (249, 180, cnt_total_time);
}

View File

@ -122,11 +122,13 @@ string &string::operator = (const char *copyStr)
else
{
size_t len = strlen (copyStr);
/*
if (len == 0)
{
Chars = NULL;
}
else
*/
{
Chars = Pond.Alloc (this, len);
StrCopy (Chars, copyStr, len);