- Fixed: The StrifePlayer couldn't obtain his default inventory because

APlayerPawn::GiveDefaultInventory gave him some HexenArmor even though
  he doesn't need it.
- Added custom blood type properties to DECORATE.
- Converted Blood to DECORATE and made some minor changes to the code
  in preparation for custom blood types.
- Converted the bot helper things to DECORATE.
- Added damage type specific crash states.


SVN r395 (trunk)
This commit is contained in:
Christoph Oelckers 2006-11-29 10:03:35 +00:00
parent 4467cd6563
commit 0ba809234e
20 changed files with 337 additions and 215 deletions

View file

@ -1,8 +1,19 @@
November 28, 2006 (Changes by Graf Zahl)
- Fixed: The StrifePlayer couldn't obtain his default inventory because
APlayerPawn::GiveDefaultInventory gave him some HexenArmor even though
he doesn't need it.
- Added custom blood type properties to DECORATE.
- Converted Blood to DECORATE and made some minor changes to the code
in preparation for custom blood types.
- Converted the bot helper things to DECORATE.
- Added damage type specific crash states.
November 28, 2006
- Started adding action function declarations to objects.
- Added integer constant declarations to objects.
- Added a simple symbol table to PClass.
>>>>>>> .r394
November 27, 2006 (Changes by Graf Zahl)
- Changed: When playing a shareware game no external WADs are loaded at all,
not even zvox.wad or the skins directory.
@ -3072,7 +3083,7 @@ February 10, 2005
as fast as their Doom counterparts.
- Fixed: Strife auto-uses the best ammo first, not the worst. I got confused because
in Strife ARM1 is the best armor, but in Doom it's ARM2 that is best.
- Fixed: Strife does not double ammo at it's highest skill level.
- Fixed: Strife does not double ammo at its highest skill level.
- New: Using Degnin Ore will drop it, similar to the Teleporter Beacon.
- Fixed: In nightmare skill, every actor is spawned with a reactiontime of 0. This
make's Strife's HE Grenades explode immediately, because they use their reactiontime
@ -4793,7 +4804,7 @@ January 2, 2004
nearest integer when determining TexelLength instead of always round down.
- Fixed: Using an empty string with HUDMSG_TYPEON caused a crash.
- Fixed: A buried wraith could enter its pain state while rising from the
ground and not properly finish raising, so it's bottom portion would remain
ground and not properly finish raising, so its bottom portion would remain
clipped for the rest of its existance.
- Fixed: Using a switch to start a script on another map would not make the
switch switch.
@ -5110,7 +5121,7 @@ November 1, 2003
- Changed the sector soundorg calculation so that it can't overflow.
October 31, 2003
- Added Strife's Reaver. Aside from it's unknown flag, it should be fully
- Added Strife's Reaver. Aside from its unknown flag, it should be fully
functional.
- Added Strife's dagger-wielding fist. It has a chance of doing 0 damage,
which seems odd.
@ -7633,7 +7644,7 @@ August 3, 2002
July 31, 2002
- Fixed some stuff with local doors already performing a ceiling action.
In particular, if the ceiling was moving but not as a door, it's thinker
In particular, if the ceiling was moving but not as a door, its thinker
would be replaced with a door thinker instead of being left alone.
- Wallrunning seems to be gone. I don't know when it disappeared. I
certainly set out trying to fix it.
@ -9579,7 +9590,7 @@ April 20, 2001
April 17, 2001
- Fixed: It was possible to stand at the very edge of a steep slope and not
fall off of it. It is still possible to "balance" by running away from the
edge, but I think that will take more time to fix than it's work (especially
edge, but I think that will take more time to fix than it's worth (especially
if I really do go ahead and rewrite the level geometry collision detection.)
- Added in-air friction that depends on aircontrol: The greater aircontrol is,
the more friction affects things. Only affects players.
@ -11247,7 +11258,7 @@ February 12, 2000
to find the following causes of the problem: 1. When monsters went up
steps, they didn't check to make sure there was nothing in the way above
them. 2. When P_CheckOnmobj() found a monster's move to be blocked, the
monster could still float down inside the head of it's blocker, causing
monster could still float down inside the head of its blocker, causing
the blocking monster to get stuck until it floated up again.
February 9, 2000
@ -11765,7 +11776,7 @@ July 7, 1999
removed the use of short ints.
July 6, 1999
- Restored Cmd_Exec to it's 1.17c version. I'm not sure what I was trying to
- Restored Cmd_Exec to its 1.17c version. I'm not sure what I was trying to
accomplish with the changes I made, but they broke it under certain
situations.
@ -13679,7 +13690,7 @@ May 19, 1998
starting with ';'.
- Changed the default config file to zdoom.cfg and added the -config
parameter to choose alternate ones. (Blargh! Doom Legacy decided to
use config.cfg as it's default config file, when I've been using it
use config.cfg as its default config file, when I've been using it
all along!)
May 18, 1998

View file

@ -173,6 +173,7 @@ enum
MF2_THRUGHOST = 0x00004000, // missile will pass through ghosts [RH] was 8
MF2_BOSS = 0x00008000, // mobj is a major boss
MF2_DONTTRANSLATE = 0x00010000, // Don't apply palette translations
MF2_NODMGTHRUST = 0x00020000, // does not thrust target when damaging
MF2_TELESTOMP = 0x00040000, // mobj can stomp another
MF2_FLOATBOB = 0x00080000, // use float bobbing z movement
@ -419,6 +420,9 @@ enum
AMETA_RDFactor, // Radius damage factor
AMETA_CameraHeight, // Height of camera when used as such
AMETA_HowlSound, // Sound being played when electrocuted or poisoned
AMETA_BloodType, // Blood replacement type
AMETA_BloodType2, // Bloodsplatter replacement type
AMETA_BloodType3, // AxeBlood replacement type
};
// Map Object definition.
@ -589,6 +593,9 @@ public:
// What species am I?
virtual const PClass *GetSpecies();
// Enter the crash state
void Crash();
// Check for monsters that count as kill but excludes all friendlies.
bool CountsAsKill() const
{

View file

@ -446,15 +446,6 @@ AActor *DCajunMaster::Find_enemy (AActor *bot)
}
class ACajunBodyNode : public AActor
{
DECLARE_STATELESS_ACTOR (ACajunBodyNode, AActor)
};
IMPLEMENT_STATELESS_ACTOR (ACajunBodyNode, Any, -1, 0)
PROP_Flags (MF_NOSECTOR | MF_NOGRAVITY)
PROP_RenderFlags (RF_INVISIBLE)
END_DEFAULTS
//Creates a temporary mobj (invisible) at the given location.
void DCajunMaster::SetBodyAt (fixed_t x, fixed_t y, fixed_t z, int hostnum)
@ -464,14 +455,14 @@ void DCajunMaster::SetBodyAt (fixed_t x, fixed_t y, fixed_t z, int hostnum)
if (body1)
body1->SetOrigin (x, y, z);
else
body1 = Spawn<ACajunBodyNode> (x, y, z, NO_REPLACE);
body1 = Spawn ("ACajunBodyNode", x, y, z, NO_REPLACE);
}
else if (hostnum == 2)
{
if (body2)
body2->SetOrigin (x, y, z);
else
body2 = Spawn<ACajunBodyNode> (x, y, z, NO_REPLACE);
body2 = Spawn ("ACajunBodyNode", x, y, z, NO_REPLACE);
}
}
@ -483,23 +474,11 @@ void DCajunMaster::SetBodyAt (fixed_t x, fixed_t y, fixed_t z, int hostnum)
//This function assumes actor->player->angle
//has been set an is the main aiming angle.
class ACajunTrace : public AActor
{
DECLARE_STATELESS_ACTOR (ACajunTrace, AActor)
};
IMPLEMENT_STATELESS_ACTOR (ACajunTrace, Any, -1, 0)
PROP_SpeedFixed (12)
PROP_RadiusFixed (6)
PROP_HeightFixed (8)
PROP_Flags (MF_NOBLOCKMAP|MF_DROPOFF|MF_MISSILE|MF_NOGRAVITY)
PROP_Flags2 (MF2_NOTELEPORT)
END_DEFAULTS
//Emulates missile travel. Returns distance travelled.
fixed_t DCajunMaster::FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd)
{
AActor *th = Spawn<ACajunTrace> (source->x, source->y, source->z + 4*8*FRACUNIT, NO_REPLACE);
AActor *th = Spawn ("CajunTrace", source->x, source->y, source->z + 4*8*FRACUNIT, NO_REPLACE);
th->target = source; // where it came from

View file

@ -188,7 +188,7 @@ void A_DripBlood (AActor *actor)
x = actor->x + (pr_dripblood.Random2 () << 11);
y = actor->y + (pr_dripblood.Random2 () << 11);
mo = Spawn<ABlood> (x, y, actor->z, ALLOW_REPLACE);
mo = Spawn ("Blood", x, y, actor->z, ALLOW_REPLACE);
mo->momx = pr_dripblood.Random2 () << 10;
mo->momy = pr_dripblood.Random2 () << 10;
mo->flags2 |= MF2_LOGRAV;

View file

@ -15,7 +15,6 @@
#define AXERANGE ((fixed_t)(2.25*MELEERANGE))
static FRandom pr_atk ("FAxeAtk");
static FRandom pr_splat ("FAxeSplatter");
void A_FAxeCheckReady (AActor *actor);
void A_FAxeCheckUp (AActor *actor);
@ -192,34 +191,6 @@ IMPLEMENT_ACTOR (AAxePuffGlow, Hexen, -1, 0)
PROP_SpawnState (0)
END_DEFAULTS
// Axe Blood ----------------------------------------------------------------
class AAxeBlood : public AActor
{
DECLARE_ACTOR (AAxeBlood, AActor)
};
FState AAxeBlood::States[] =
{
S_NORMAL (FAXE, 'F', 3, NULL , &States[1]),
S_NORMAL (FAXE, 'G', 3, NULL , &States[2]),
S_NORMAL (FAXE, 'H', 3, NULL , &States[3]),
S_NORMAL (FAXE, 'I', 3, NULL , &States[4]),
S_NORMAL (FAXE, 'J', 3, NULL , &States[5]),
S_NORMAL (FAXE, 'K', 3, NULL , NULL),
};
IMPLEMENT_ACTOR (AAxeBlood, Hexen, -1, 0)
PROP_Mass (5)
PROP_RadiusFixed (2)
PROP_HeightFixed (4)
PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DROPOFF)
PROP_Flags2 (MF2_NOTELEPORT|MF2_CANNOTPUSH)
PROP_SpawnState (0)
PROP_DeathState (5)
END_DEFAULTS
//============================================================================
//
// A_FAxeCheckReady
@ -431,34 +402,3 @@ axedone:
return;
}
//===========================================================================
//
// P_BloodSplatter2
//
//===========================================================================
void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
{
PalEntry bloodcolor = (PalEntry)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodColor);
if (cl_bloodtype <= 1)
{
AActor *mo;
x += ((pr_splat()-128)<<11);
y += ((pr_splat()-128)<<11);
mo = Spawn<AAxeBlood> (x, y, z, ALLOW_REPLACE);
mo->target = originator;
// colorize the blood!
if (bloodcolor != 0)
{
mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
}
}
if (cl_bloodtype >= 1)
{
P_DrawSplash2 (100, x, y, z, R_PointToAngle2 (0, 0, originator->x - x, originator->y - y), 2, bloodcolor);
}
}

View file

@ -33,13 +33,6 @@ class APatrolSpecial : public AActor
DECLARE_STATELESS_ACTOR (APatrolSpecial, AActor)
};
class ABlood : public AActor
{
DECLARE_ACTOR (ABlood, AActor)
public:
void SetDamage (int damage);
};
class AMapSpot : public AActor
{
DECLARE_STATELESS_ACTOR (AMapSpot, AActor)

View file

@ -41,66 +41,6 @@ IMPLEMENT_STATELESS_ACTOR (APatrolSpecial, Any, 9047, 0)
PROP_RenderStyle (STYLE_None)
END_DEFAULTS
// Blood sprite - adjusts itself for each game -----------------------------
FState ABlood::States[] =
{
#define S_DBLOOD 0
S_NORMAL (BLUD, 'C', 8, NULL , &States[S_DBLOOD+1]),
S_NORMAL (BLUD, 'B', 8, NULL , &States[S_DBLOOD+2]),
S_NORMAL (BLUD, 'A', 8, NULL , NULL),
#define S_SBLOOD (S_DBLOOD+3)
S_NORMAL (SPRY, 'A', 3, NULL , &States[S_SBLOOD+1]),
S_NORMAL (SPRY, 'B', 3, NULL , &States[S_SBLOOD+2]),
S_NORMAL (SPRY, 'C', 3, NULL , &States[S_SBLOOD+3]),
S_NORMAL (SPRY, 'D', 3, NULL , &States[S_SBLOOD+4]),
S_NORMAL (SPRY, 'E', 3, NULL , &States[S_SBLOOD+5]),
S_NORMAL (SPRY, 'F', 3, NULL , &States[S_SBLOOD+6]),
S_NORMAL (SPRY, 'G', 2, NULL , NULL),
};
IMPLEMENT_ACTOR (ABlood, Any, -1, 130)
PROP_Flags (MF_NOBLOCKMAP)
PROP_Flags2 (MF2_NOTELEPORT)
PROP_SpawnState(S_DBLOOD)
PROP_Mass (5)
END_DEFAULTS
void ABlood::SetDamage (int damage)
{
if (gameinfo.gametype == GAME_Doom)
{
if (damage <= 12 && damage >= 9)
{
SetState (SpawnState + 1);
}
else if (damage < 9)
{
SetState (SpawnState + 2);
}
}
else if (gameinfo.gametype == GAME_Strife)
{
if (damage > 13)
{
SetState (&States[S_SBLOOD]);
}
else if (damage >= 10)
{
SetState (&States[S_DBLOOD]);
}
else if (damage >= 7)
{
SetState (&States[S_DBLOOD+1]);
}
else
{
SetState (&States[S_DBLOOD+2]);
}
}
}
// Map spot ----------------------------------------------------------------
IMPLEMENT_STATELESS_ACTOR (AMapSpot, Any, 9001, 0)

View file

@ -7,6 +7,17 @@ xx(Actor)
xx(Untranslated)
xx(Doom)
xx(Heretic)
xx(Hexen)
xx(Strife)
// blood spawning
xx(Blood)
xx(BloodSplatter)
xx(AxeBlood)
xx(Spray)
// Invulnerability types
xx(Ghost)
xx(Reflective)

View file

@ -641,9 +641,11 @@ void AActor::Die (AActor *source, AActor *inflictor)
if ((health<gibhealth || flags4 & MF4_EXTREMEDEATH) && !(flags4 & MF4_NOEXTREMEDEATH))
{ // Extreme death
diestate = FindState (2, NAME_Death, NAME_Extreme);
diestate = GetClass()->ActorInfo->FindStateExact (2, NAME_Death, NAME_Extreme);
// if a non-player mark as extremely dead for the crash state.
if (diestate != NULL && player == NULL && health >= gibhealth) health = gibhealth-1;
}
else
if (diestate == NULL)
{ // Normal death
diestate = FindState (NAME_Death);
}

View file

@ -305,7 +305,7 @@ void P_TraceBleed (int damage, fixed_t x, fixed_t y, fixed_t z, AActor *target,
void P_TraceBleed (int damage, AActor *target, angle_t angle, int pitch);
void P_TraceBleed (int damage, AActor *target, AActor *missile); // missile version
void P_TraceBleed (int damage, AActor *target); // random direction version
void P_RailAttack (AActor *source, int damage, int offset, int color1 = 0, int color2 = 0, float maxdiff = 0, bool silent = false); // [RH] Shoot a railgun
void P_RailAttack (AActor *source, int damage, int offset, int color1 = 0, int color2 = 0, float maxdiff = 0, bool silent = false, FName puff = NAME_BulletPuff); // [RH] Shoot a railgun
bool P_HitFloor (AActor *thing);
bool P_HitWater (AActor *thing, sector_t *sec);
bool P_CheckMissileSpawn (AActor *missile);

View file

@ -3010,7 +3010,7 @@ static bool ProcessRailHit (FTraceResults &res)
return true;
}
void P_RailAttack (AActor *source, int damage, int offset, int color1, int color2, float maxdiff, bool silent)
void P_RailAttack (AActor *source, int damage, int offset, int color1, int color2, float maxdiff, bool silent, FName puff)
{
fixed_t vx, vy, vz;
angle_t angle, pitch;
@ -3080,11 +3080,11 @@ void P_RailAttack (AActor *source, int damage, int offset, int color1, int color
}
if (trace.CrossedWater)
{
AActor *puff = Spawn ("BulletPuff", 0, 0, 0, ALLOW_REPLACE);
if (puff != NULL)
AActor *thepuff = Spawn ("BulletPuff", 0, 0, 0, ALLOW_REPLACE);
if (thepuff != NULL)
{
SpawnDeepSplash (source, trace, puff, vx, vy, vz);
puff->Destroy ();
SpawnDeepSplash (source, trace, thepuff, vx, vy, vz);
thepuff->Destroy ();
}
}
@ -3102,7 +3102,8 @@ void P_RailAttack (AActor *source, int damage, int offset, int color1, int color
if ((RailHits[i].HitActor->flags & MF_NOBLOOD) ||
(RailHits[i].HitActor->flags2 & (MF2_DORMANT|MF2_INVULNERABLE)))
{
P_SpawnPuff (PClass::FindClass(NAME_BulletPuff), x, y, z, source->angle - ANG180, 1, true);
const PClass *puffclass = PClass::FindClass(puff);
if (puffclass != NULL) P_SpawnPuff (puffclass, x, y, z, source->angle - ANG180, 1, true);
}
else
{
@ -3939,18 +3940,22 @@ void P_DoCrunch (AActor *thing)
(!(thing->flags2&(MF2_INVULNERABLE|MF2_DORMANT))))
{
PalEntry bloodcolor = (PalEntry)thing->GetClass()->Meta.GetMetaInt(AMETA_BloodColor);
const PClass *bloodcls = PClass::FindClass((ENamedName)thing->GetClass()->Meta.GetMetaInt(AMETA_BloodType, NAME_Blood));
P_TraceBleed (crushchange, thing);
if (cl_bloodtype <= 1)
if (cl_bloodtype <= 1 && bloodcls != NULL)
{
AActor *mo;
mo = Spawn<ABlood> (thing->x, thing->y,
mo = Spawn (bloodcls, thing->x, thing->y,
thing->z + thing->height/2, ALLOW_REPLACE);
mo->momx = pr_crunch.Random2 () << 12;
mo->momy = pr_crunch.Random2 () << 12;
if (bloodcolor!=0) mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
if (bloodcolor != 0 && !(mo->flags2 & MF2_DONTTRANSLATE))
{
mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
}
}
if (cl_bloodtype >= 1)
{

View file

@ -92,6 +92,7 @@ static FRandom pr_spawnpuff ("SpawnPuff");
static FRandom pr_spawnblood ("SpawnBlood");
static FRandom pr_splatter ("BloodSplatter");
static FRandom pr_takedamage ("TakeDamage");
static FRandom pr_splat ("FAxeSplatter");
static FRandom pr_ripperblood ("RipperBlood");
static FRandom pr_chunk ("Chunk");
static FRandom pr_checkmissilespawn ("CheckMissileSpawn");
@ -1973,14 +1974,7 @@ void P_ZMovement (AActor *mo)
{ // The skull slammed into something
mo->momz = -mo->momz;
}
if ((mo->flags & MF_CORPSE) &&
!(mo->flags3 & MF3_CRASHED) &&
mo->DamageType != NAME_Ice)
{
FState * crashstate = mo->FindState(NAME_Crash);
if (crashstate != NULL) mo->SetState(crashstate);
mo->flags3 |= MF3_CRASHED;
}
mo->Crash();
}
}
@ -2847,14 +2841,7 @@ void AActor::Tick ()
}
flags2 |= MF2_ONMOBJ;
momz = 0;
if ((flags & MF_CORPSE) &&
!(flags3 & MF3_CRASHED) &&
DamageType != NAME_Ice)
{
FState * crashstate = FindState(NAME_Crash);
if (crashstate != NULL) SetState(crashstate);
flags3 |= MF3_CRASHED;
}
Crash();
}
}
else
@ -2867,14 +2854,7 @@ void AActor::Tick ()
}
else if (z <= floorz)
{
if ((flags & MF_CORPSE) &&
!(flags3 & MF3_CRASHED) &&
DamageType != NAME_Ice)
{
FState * crashstate = FindState(NAME_Crash);
if (crashstate != NULL) SetState(crashstate);
flags3 |= MF3_CRASHED;
}
Crash();
}
if (UpdateWaterLevel (oldz))
@ -3948,18 +3928,22 @@ AActor *P_SpawnPuff (const PClass *pufftype, fixed_t x, fixed_t y, fixed_t z, an
//---------------------------------------------------------------------------
//
// P_SpawnBlood
//
//---------------------------------------------------------------------------
void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AActor *originator)
{
ABlood *th;
AActor *th;
PalEntry bloodcolor = (PalEntry)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodColor);
const PClass *bloodcls = PClass::FindClass((ENamedName)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodType, NAME_Blood));
if (cl_bloodtype <= 1)
if (bloodcls!=NULL && cl_bloodtype <= 1)
{
z += pr_spawnblood.Random2 () << 10;
th = Spawn<ABlood> (x, y, z, ALLOW_REPLACE);
th = Spawn (bloodcls, x, y, z, ALLOW_REPLACE);
th->momz = FRACUNIT*2;
th->angle = dir;
if (gameinfo.gametype == GAME_Doom)
@ -3969,12 +3953,33 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc
if (th->tics < 1)
th->tics = 1;
}
// colorize the blood!
if (bloodcolor != 0)
// colorize the blood
if (bloodcolor != 0 && !(th->flags2 & MF2_DONTTRANSLATE))
{
th->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
}
th->SetDamage (damage);
// Moved out of the blood actor so that replacing blood is easier
if (gameinfo.gametype & GAME_DoomStrife)
{
if (gameinfo.gametype == GAME_Strife)
{
if (damage > 13)
{
FState *state = th->FindState(NAME_Spray);
if (state != NULL) th->SetState (state);
}
else damage+=2;
}
if (damage <= 12 && damage >= 9)
{
th->SetState (th->SpawnState + 1);
}
else if (damage < 9)
{
th->SetState (th->SpawnState + 2);
}
}
}
if (cl_bloodtype >= 1)
@ -3990,19 +3995,23 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc
void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
{
PalEntry bloodcolor = (PalEntry)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodColor);
const PClass *bloodcls = PClass::FindClass((ENamedName)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodType2, NAME_BloodSplatter));
if (cl_bloodtype <= 1)
if (bloodcls!=NULL && cl_bloodtype <= 1)
{
AActor *mo;
mo = Spawn("BloodSplatter", x, y, z, ALLOW_REPLACE);
mo = Spawn(bloodcls, x, y, z, ALLOW_REPLACE);
mo->target = originator;
mo->momx = pr_splatter.Random2 () << 10;
mo->momy = pr_splatter.Random2 () << 10;
mo->momz = 3*FRACUNIT;
// colorize the blood!
if (bloodcolor!=0) mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
if (bloodcolor!=0 && !(mo->flags2 & MF2_DONTTRANSLATE))
{
mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
}
}
if (cl_bloodtype >= 1)
{
@ -4010,6 +4019,39 @@ void P_BloodSplatter (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
}
}
//===========================================================================
//
// P_BloodSplatter2
//
//===========================================================================
void P_BloodSplatter2 (fixed_t x, fixed_t y, fixed_t z, AActor *originator)
{
PalEntry bloodcolor = (PalEntry)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodColor);
const PClass *bloodcls = PClass::FindClass((ENamedName)originator->GetClass()->Meta.GetMetaInt(AMETA_BloodType3, NAME_AxeBlood));
if (bloodcls!=NULL && cl_bloodtype <= 1)
{
AActor *mo;
x += ((pr_splat()-128)<<11);
y += ((pr_splat()-128)<<11);
mo = Spawn (bloodcls, x, y, z, ALLOW_REPLACE);
mo->target = originator;
// colorize the blood!
if (bloodcolor != 0 && !(mo->flags2 & MF2_DONTTRANSLATE))
{
mo->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
}
}
if (cl_bloodtype >= 1)
{
P_DrawSplash2 (100, x, y, z, R_PointToAngle2 (0, 0, originator->x - x, originator->y - y), 2, bloodcolor);
}
}
//---------------------------------------------------------------------------
//
// PROC P_RipperBlood
@ -4020,14 +4062,15 @@ void P_RipperBlood (AActor *mo, AActor *bleeder)
{
fixed_t x, y, z;
PalEntry bloodcolor = (PalEntry)bleeder->GetClass()->Meta.GetMetaInt(AMETA_BloodColor);
const PClass *bloodcls = PClass::FindClass((ENamedName)bleeder->GetClass()->Meta.GetMetaInt(AMETA_BloodType, NAME_Blood));
x = mo->x + (pr_ripperblood.Random2 () << 12);
y = mo->y + (pr_ripperblood.Random2 () << 12);
z = mo->z + (pr_ripperblood.Random2 () << 12);
if (cl_bloodtype <= 1)
if (bloodcls!=NULL && cl_bloodtype <= 1)
{
AActor *th;
th = Spawn<ABlood> (x, y, z, ALLOW_REPLACE);
th = Spawn (bloodcls, x, y, z, ALLOW_REPLACE);
if (gameinfo.gametype == GAME_Heretic)
th->flags |= MF_NOGRAVITY;
th->momx = mo->momx >> 1;
@ -4035,7 +4078,10 @@ void P_RipperBlood (AActor *mo, AActor *bleeder)
th->tics += pr_ripperblood () & 3;
// colorize the blood!
if (bloodcolor!=0) th->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
if (bloodcolor!=0 && !(th->flags2 & MF2_DONTTRANSLATE))
{
th->Translation = TRANSLATION(TRANSLATION_Blood, bloodcolor.a);
}
}
if (cl_bloodtype >= 1)
{
@ -4694,6 +4740,39 @@ int AActor::TakeSpecialDamage (AActor *inflictor, AActor *source, int damage, FN
return (death == NULL) ? -1 : damage;
}
void AActor::Crash()
{
if ((flags & MF_CORPSE) &&
!(flags3 & MF3_CRASHED) &&
!(flags & MF_ICECORPSE))
{
FState * crashstate=NULL;
if (DamageType != NAME_None)
{
crashstate = GetClass()->ActorInfo->FindStateExact(2, NAME_Crash, DamageType);
}
if (crashstate == NULL)
{
int gibhealth = -abs(GetClass()->Meta.GetMetaInt (AMETA_GibHealth,
gameinfo.gametype == GAME_Doom ? -GetDefault()->health : -GetDefault()->health/2));
if (health<gibhealth)
{ // Extreme death
crashstate = FindState (2, NAME_Crash, NAME_Extreme);
}
else
{ // Normal death
crashstate = FindState (NAME_Crash);
}
}
if (crashstate != NULL) SetState(crashstate);
// Set MF3_CRASHED regardless of the presence of a crash state
// so this code doesn't have to be executed repeatedly.
flags3 |= MF3_CRASHED;
}
}
FArchive &operator<< (FArchive &arc, FSoundIndex &snd)
{
if (arc.IsStoring ())

View file

@ -141,6 +141,67 @@ IMPLEMENT_STATELESS_ACTOR (ATeleportDest3, Any, 9043, 0)
PROP_FlagsClear (MF_NOGRAVITY)
END_DEFAULTS
//==========================================================================
//
// P_SpawnTeleportFog
//
// The beginning of customizable teleport fog
// (not active yet)
//
//==========================================================================
void P_SpawnTeleportFog(fixed_t x, fixed_t y, fixed_t z, int spawnid)
{
const PClass *fog=NULL;
if (spawnid > 0 && spawnid < MAX_SPAWNABLES && SpawnableThings[spawnid] != NULL)
{
fog = SpawnableThings[spawnid];
}
/* if (fog != NULL && level.info->teleportfog != NAME_None)
{
fog = PClass::FindClass(level.info->teleportfog);
}
*/
if (fog == NULL)
{
AActor *mo = Spawn ("TeleportFog", x, y, z + TELEFOGHEIGHT, ALLOW_REPLACE);
if (mo != NULL)
{
FState * state = NULL;
switch(gameinfo.gametype)
{
default:
case GAME_Doom:
state = mo->FindState(NAME_Doom);
break;
case GAME_Heretic:
state = mo->FindState(NAME_Heretic);
break;
case GAME_Hexen:
state = mo->FindState(NAME_Hexen);
break;
case GAME_Strife:
state = mo->FindState(NAME_Strife);
break;
}
if (state == NULL) state = mo->SpawnState; // allow execution of code pointers in the spawn state
mo->SetState(state);
}
}
else
{
AActor *mo = Spawn (fog, x, y, z, ALLOW_REPLACE);
if (mo != NULL) mo->SetState(mo->SpawnState);
}
}
//
// TELEPORTATION
//

View file

@ -915,7 +915,7 @@ void APlayerPawn::GiveDefaultInventory ()
}
fixed_t hx[5];
bool ishx;
bool ishx=false;
for(int i=0;i<5;i++)
{

View file

@ -144,6 +144,7 @@ static flagdef ActorFlags[]=
DEFINE_FLAG(MF2, THRUGHOST, AActor, flags2),
DEFINE_FLAG(MF2, BOSS, AActor, flags2),
DEFINE_FLAG2(MF2_NODMGTHRUST, NODAMAGETHRUST, AActor, flags2),
DEFINE_FLAG(MF2, DONTTRANSLATE, AActor, flags2),
DEFINE_FLAG(MF2, TELESTOMP, AActor, flags2),
DEFINE_FLAG(MF2, FLOATBOB, AActor, flags2),
DEFINE_FLAG(MF2, HEXENBOUNCE, AActor, flags2),
@ -693,7 +694,7 @@ AFuncDesc AFTable[]=
FUNC(A_Jump, "XL+" )
FUNC(A_CustomMissile, "MXXxxx" )
FUNC(A_CustomBulletAttack, "XXXXmx" )
FUNC(A_CustomRailgun, "Xxccxxx" )
FUNC(A_CustomRailgun, "Xxccxxxm" )
FUNC(A_JumpIfHealthLower, "XL" )
FUNC(A_JumpIfCloser, "XL" )
FUNC(A_JumpIfInventory, "MXL" )
@ -725,7 +726,7 @@ AFuncDesc AFTable[]=
FUNC(A_CustomPunch, "Xxymx" )
FUNC(A_FireBullets, "XXXXmyx" )
FUNC(A_FireCustomMissile, "Mxyxxx" )
FUNC(A_RailAttack, "Xxyccxx" )
FUNC(A_RailAttack, "Xxyccxxm" )
FUNC(A_Recoil, "X")
FUNC(A_JumpIfInTargetInventory, "MXL" )
FUNC(A_GiveToTarget, "Mx" )
@ -3347,6 +3348,33 @@ static void ActorBloodColor (AActor *defaults, Baggage &bag)
}
//==========================================================================
//
//==========================================================================
static void ActorBloodType (AActor *defaults, Baggage &bag)
{
SC_MustGetString();
FName blood = sc_String;
// normal blood
bag.Info->Class->Meta.SetMetaInt (AMETA_BloodType, blood);
if (SC_CheckString(","))
{
SC_MustGetString();
blood = sc_String;
}
// blood splatter
bag.Info->Class->Meta.SetMetaInt (AMETA_BloodType2, blood);
if (SC_CheckString(","))
{
SC_MustGetString();
blood = sc_String;
}
// axe blood
bag.Info->Class->Meta.SetMetaInt (AMETA_BloodType3, blood);
}
//==========================================================================
//
//==========================================================================
@ -4258,6 +4286,7 @@ static const ActorProps props[] =
{ "armor.savepercent", (apf)ArmorSavePercent, RUNTIME_CLASS(AActor) },
{ "attacksound", ActorAttackSound, RUNTIME_CLASS(AActor) },
{ "bloodcolor", ActorBloodColor, RUNTIME_CLASS(AActor) },
{ "bloodtype", ActorBloodType, RUNTIME_CLASS(AActor) },
{ "bouncecount", ActorBounceCount, RUNTIME_CLASS(AActor) },
{ "bouncefactor", ActorBounceFactor, RUNTIME_CLASS(AActor) },
{ "burn", ActorBurnState, RUNTIME_CLASS(AActor) },

View file

@ -1117,6 +1117,7 @@ void A_RailAttack (AActor * self)
int Color2=StateParameters[index+4];
bool Silent=!!EvalExpressionI (StateParameters[index+5], self);
float MaxDiff=EvalExpressionF (StateParameters[index+6], self);
ENamedName PuffTypeName=(ENamedName)StateParameters[index+7];
AWeapon * weapon=self->player->ReadyWeapon;
@ -1126,7 +1127,7 @@ void A_RailAttack (AActor * self)
if (!weapon->DepleteAmmo(weapon->bAltFire, true)) return; // out of ammo
}
P_RailAttack (self, Damage, Spawnofs_XY, Color1, Color2, MaxDiff, Silent);
P_RailAttack (self, Damage, Spawnofs_XY, Color1, Color2, MaxDiff, Silent, PuffTypeName);
}
//==========================================================================
@ -1150,6 +1151,7 @@ void A_CustomRailgun (AActor *actor)
bool Silent=!!EvalExpressionI (StateParameters[index+4], actor);
bool aim=!!EvalExpressionI (StateParameters[index+5], actor);
float MaxDiff=EvalExpressionF (StateParameters[index+6], actor);
ENamedName PuffTypeName=(ENamedName)StateParameters[index+7];
// [RH] Andy Baker's stealth monsters
if (actor->flags & MF_STEALTH)
@ -1183,7 +1185,7 @@ void A_CustomRailgun (AActor *actor)
}
}
P_RailAttack (actor, Damage, Spawnofs_XY, Color1, Color2, MaxDiff, Silent);
P_RailAttack (actor, Damage, Spawnofs_XY, Color1, Color2, MaxDiff, Silent, PuffTypeName);
}
//===========================================================================
@ -1298,7 +1300,7 @@ static void InitSpawnedItem(AActor *self, AActor *mo, INTBOOL transfer_translati
{
AActor * originator = self;
if (transfer_translation)
if (transfer_translation && !(mo->flags2 & MF2_DONTTRANSLATE))
{
mo->Translation = self->Translation;
}

View file

@ -1,3 +1,4 @@
#include "actors/shared/botstuff.txt"
#include "actors/shared/blood.txt"
#include "actors/shared/debris.txt"
#include "actors/shared/splashes.txt"

View file

@ -1,8 +1,28 @@
// Blood sprite ------------------------------------------------------------
ACTOR Blood
{
SpawnID 130
Mass 5
+NOBLOCKMAP
+NOTELEPORT
States
{
Spawn:
BLUD CBA 8
Stop
Spray:
SPRY ABCDEF 3
SPRY G 2
Stop
}
}
// Blood splatter -----------------------------------------------------------
ACTOR BloodSplatter
{
Game Raven
Radius 2
Height 4
+NOBLOCKMAP
@ -22,4 +42,26 @@ ACTOR BloodSplatter
}
}
// Axe Blood ----------------------------------------------------------------
ACTOR AxeBlood
{
Radius 2
Height 4
+NOBLOCKMAP
+NOGRAVITY
+DROPOFF
+NOTELEPORT
+CANNOTPUSH
Mass 5
States
{
Spawn:
FAXE FGHIJ 3
Death:
FAXE G 3
Stop
}
}

View file

@ -0,0 +1,19 @@
ACTOR CajunBodyNode
{
+NOSECTOR
+NOGRAVITY
+INVISIBLE
}
ACTOR CajunTrace
{
Speed 12
Radius 6
Height 8
+NOBLOCKMAP
+DROPOFF
+MISSILE
+NOGRAVITY
+NOTELEPORT
}

View file

@ -241,6 +241,7 @@ textcolors.txt textcolors.txt
decorate.txt decorate/decorate.txt
actors/shared/botstuff.txt decorate/shared/botstuff.txt
actors/shared/blood.txt decorate/shared/blood.txt
actors/shared/debris.txt decorate/shared/debris.txt
actors/shared/splashes.txt decorate/shared/splashes.txt