mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-10 14:51:46 +00:00
- Changed: The decision whether blood splatter sprites are spawned is no
longer determined by game. Instead there's a new flag, MF5_BLOODSPLATTER which is deciding what to do. To keep backwards compatibility this flag is unset for projectiles in Doom and Strife and set for them in Heretic and Hexen. The same applies to DECORATE but of course the flag can be manipulated here. - BLODxx sprites are now globally renamed to BLUDxx when not playing Doom. This allows using the same states in every game, including the Raven-specific blood actors. - Gave the bullet puff and the axe blood masses of 5 so that the make small splashes. - Added A_Light(value) code pointer for DECORATE to generalize the weapon light effect. - Added 'noskillmenu' option to MAPINFO episode definitions. This is for WADs that want to implement a skill selection level. - Added APROP_ChaseGoal and APROP_Frightened actor properties for ACS. - Added MF5_CHASEGOAL flag that makes monsters to go after their goal even if they have a valid target. - Fixed some issues with the changes to P_NewChaseDir I made to include MBF's dropoff logic. - Added a PowerFrightener powerup class. It seemed like such a waste to have this cool feature but no means to use it in a decent fashion. - Fixed: S_Init and S_ParseSndInfo should call atterm only once but not each time they are called. SVN r112 (trunk)
This commit is contained in:
parent
8fcf93d65a
commit
bb617dfbfd
26 changed files with 231 additions and 59 deletions
|
@ -1,3 +1,29 @@
|
|||
May 13, 2006 (Changes by Graf Zahl)
|
||||
- Changed: The decision whether blood splatter sprites are spawned is no
|
||||
longer determined by game. Instead there's a new flag, MF5_BLOODSPLATTER
|
||||
which is deciding what to do. To keep backwards compatibility this flag
|
||||
is unset for projectiles in Doom and Strife and set for them in Heretic
|
||||
and Hexen. The same applies to DECORATE but of course the flag can be
|
||||
manipulated here.
|
||||
- BLODxx sprites are now globally renamed to BLUDxx when not playing Doom.
|
||||
This allows using the same states in every game, including the
|
||||
Raven-specific blood actors.
|
||||
- Gave the bullet puff and the axe blood masses of 5 so that the make small
|
||||
splashes.
|
||||
- Added A_Light(value) code pointer for DECORATE to generalize the weapon
|
||||
light effect.
|
||||
- Added 'noskillmenu' option to MAPINFO episode definitions. This is for
|
||||
WADs that want to implement a skill selection level.
|
||||
- Added APROP_ChaseGoal and APROP_Frightened actor properties for ACS.
|
||||
- Added MF5_CHASEGOAL flag that makes monsters to go after their goal even
|
||||
if they have a valid target.
|
||||
- Fixed some issues with the changes to P_NewChaseDir I made to include
|
||||
MBF's dropoff logic.
|
||||
- Added a PowerFrightener powerup class. It seemed like such a waste to
|
||||
have this cool feature but no means to use it in a decent fashion.
|
||||
- Fixed: S_Init and S_ParseSndInfo should call atterm only once but not
|
||||
each time they are called.
|
||||
|
||||
May 11, 2006
|
||||
- Merged a lot of these static destructor-only structs into regular
|
||||
functions added to the exit chain with atterm so that they can be called
|
||||
|
|
|
@ -277,9 +277,11 @@ enum
|
|||
MF5_FASTMELEE = 0x00000002, // has a faster melee attack when DF_FAST_MONSTERS or nightmare is on.
|
||||
MF5_NODROPOFF = 0x00000004, // cannot drop off under any circumstances.
|
||||
MF5_BOUNCEONACTORS = 0x00000008, // bouncing missile doesn't explode when it hits an actor
|
||||
MF5_EXPLODEONWATER = 0x00000010, // bouncing missile explpdes when hitting a water surface
|
||||
MF5_AVOIDINGDROPOFF = 0x00000020, // Used to move monsters away fro dropoffs
|
||||
MF5_EXPLODEONWATER = 0x00000010, // bouncing missile explodes when hitting a water surface
|
||||
MF5_AVOIDINGDROPOFF = 0x00000020, // Used to move monsters away from dropoffs
|
||||
MF5_NODAMAGE = 0x00000040, // Actor can be shot and reacts to being shot but takes no damage
|
||||
MF5_CHASEGOAL = 0x00000080, // Walks to goal instead of target if a valid goal is set.
|
||||
MF5_BLOODSPLATTER = 0x00000100, // Blood splatter like in Raven's games.
|
||||
|
||||
// --- mobj.renderflags ---
|
||||
|
||||
|
|
|
@ -110,6 +110,7 @@ IMPLEMENT_ACTOR (ABulletPuff, Doom, -1, 131)
|
|||
|
||||
PROP_SpawnState (0)
|
||||
PROP_MeleeState (2)
|
||||
PROP_Mass(5)
|
||||
END_DEFAULTS
|
||||
|
||||
void ABulletPuff::BeginPlay ()
|
||||
|
|
|
@ -373,6 +373,7 @@ FState AGoldWand::States[] =
|
|||
};
|
||||
|
||||
IMPLEMENT_ACTOR (AGoldWand, Heretic, -1, 0)
|
||||
PROP_Flags5 (MF5_BLOODSPLATTER)
|
||||
PROP_Weapon_SelectionOrder (2000)
|
||||
PROP_Weapon_AmmoUse1 (USE_GWND_AMMO_1)
|
||||
PROP_Weapon_AmmoGive1 (25)
|
||||
|
@ -1696,6 +1697,7 @@ FState AGauntlets::States[] =
|
|||
|
||||
IMPLEMENT_ACTOR (AGauntlets, Heretic, 2005, 32)
|
||||
PROP_Flags (MF_SPECIAL)
|
||||
PROP_Flags5 (MF5_BLOODSPLATTER)
|
||||
PROP_SpawnState (S_WGNT)
|
||||
|
||||
PROP_Weapon_SelectionOrder (2300)
|
||||
|
@ -1989,6 +1991,7 @@ FState ABlaster::States[] =
|
|||
|
||||
IMPLEMENT_ACTOR (ABlaster, Heretic, 53, 28)
|
||||
PROP_Flags (MF_SPECIAL)
|
||||
PROP_Flags5 (MF5_BLOODSPLATTER)
|
||||
PROP_SpawnState (S_BLSR)
|
||||
|
||||
PROP_Weapon_SelectionOrder (500)
|
||||
|
|
|
@ -58,6 +58,7 @@ FState ACWeapMace::States[] =
|
|||
|
||||
IMPLEMENT_ACTOR (ACWeapMace, Hexen, -1, 0)
|
||||
PROP_Weapon_SelectionOrder (3500)
|
||||
PROP_Flags5 (MF5_BLOODSPLATTER)
|
||||
PROP_Weapon_Flags (WIF_BOT_MELEE)
|
||||
PROP_Weapon_UpState (S_CMACEUP)
|
||||
PROP_Weapon_DownState (S_CMACEDOWN)
|
||||
|
|
|
@ -220,6 +220,7 @@ FState AAxeBlood::States[] =
|
|||
};
|
||||
|
||||
IMPLEMENT_ACTOR (AAxeBlood, Hexen, -1, 0)
|
||||
PROP_Mass (5)
|
||||
PROP_RadiusFixed (2)
|
||||
PROP_HeightFixed (4)
|
||||
PROP_Flags (MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DROPOFF)
|
||||
|
|
|
@ -65,6 +65,7 @@ FState AFWeapHammer::States[] =
|
|||
|
||||
IMPLEMENT_ACTOR (AFWeapHammer, Hexen, 123, 28)
|
||||
PROP_Flags (MF_SPECIAL)
|
||||
PROP_Flags5 (MF5_BLOODSPLATTER)
|
||||
PROP_SpawnState (S_HAMM)
|
||||
|
||||
PROP_Weapon_SelectionOrder (900)
|
||||
|
|
|
@ -208,6 +208,7 @@ FState AFWeapFist::States[] =
|
|||
};
|
||||
|
||||
IMPLEMENT_ACTOR (AFWeapFist, Hexen, -1, 0)
|
||||
PROP_Flags5 (MF5_BLOODSPLATTER)
|
||||
PROP_Weapon_SelectionOrder (3400)
|
||||
PROP_Weapon_Flags (WIF_BOT_MELEE)
|
||||
PROP_Weapon_UpState (S_PUNCHUP)
|
||||
|
|
|
@ -62,6 +62,7 @@ FState AMWeapFrost::States[] =
|
|||
|
||||
IMPLEMENT_ACTOR (AMWeapFrost, Hexen, 53, 36)
|
||||
PROP_Flags (MF_SPECIAL)
|
||||
PROP_Flags5 (MF5_BLOODSPLATTER)
|
||||
PROP_SpawnState (S_COS1)
|
||||
|
||||
PROP_Weapon_SelectionOrder (1700)
|
||||
|
|
|
@ -982,6 +982,7 @@ static void ParseMapInfoLower (MapInfoHandler *handlers,
|
|||
// name "Episode name as text"
|
||||
// picname "Picture to display the episode name"
|
||||
// key "Shortcut key for the menu"
|
||||
// noskillmenu
|
||||
// remove
|
||||
|
||||
static void ParseEpisodeInfo ()
|
||||
|
@ -993,6 +994,7 @@ static void ParseEpisodeInfo ()
|
|||
bool remove = false;
|
||||
char key = 0;
|
||||
bool addedgfx = false;
|
||||
bool noskill = false;
|
||||
|
||||
// Get map name
|
||||
SC_MustGetString ();
|
||||
|
@ -1032,6 +1034,10 @@ static void ParseEpisodeInfo ()
|
|||
SC_MustGetString ();
|
||||
key = sc_String[0];
|
||||
}
|
||||
else if (SC_Compare("noskillmenu"))
|
||||
{
|
||||
noskill = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_UnGet ();
|
||||
|
@ -1059,6 +1065,8 @@ static void ParseEpisodeInfo ()
|
|||
sizeof(EpisodeMaps[0])*(EpiDef.numitems - i - 1));
|
||||
memmove (&EpisodeMenu[i], &EpisodeMenu[i+1],
|
||||
sizeof(EpisodeMenu[0])*(EpiDef.numitems - i - 1));
|
||||
memmove (&EpisodeNoSkill[i], &EpisodeNoSkill[i+1],
|
||||
sizeof(EpisodeNoSkill[0])*(EpiDef.numitems - i - 1));
|
||||
}
|
||||
EpiDef.numitems--;
|
||||
}
|
||||
|
@ -1090,6 +1098,7 @@ static void ParseEpisodeInfo ()
|
|||
EpisodeMenu[i].name = pic;
|
||||
EpisodeMenu[i].alphaKey = tolower(key);
|
||||
EpisodeMenu[i].fulltext = !picisgfx;
|
||||
EpisodeNoSkill[i] = noskill;
|
||||
strncpy (EpisodeMaps[i], map, 8);
|
||||
|
||||
if (picisgfx)
|
||||
|
|
|
@ -1073,6 +1073,40 @@ void APowerTargeter::PositionAccuracy ()
|
|||
player->psprites[ps_targetright].sx = (160-3)*FRACUNIT + ((100 - player->accuracy) << FRACBITS);
|
||||
}
|
||||
|
||||
// Frightener Powerup --------------------------------
|
||||
|
||||
IMPLEMENT_STATELESS_ACTOR (APowerFrightener, Any, -1, 0)
|
||||
PROP_Powerup_EffectTics (60*TICRATE)
|
||||
END_DEFAULTS
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerFrightener :: InitEffect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerFrightener::InitEffect ()
|
||||
{
|
||||
if (Owner->player == NULL)
|
||||
return;
|
||||
|
||||
Owner->player->cheats |= CF_FRIGHTENING;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// APowerFrightener :: EndEffect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void APowerFrightener::EndEffect ()
|
||||
{
|
||||
if (Owner->player == NULL)
|
||||
return;
|
||||
|
||||
Owner->player->cheats &= ~CF_FRIGHTENING;
|
||||
}
|
||||
|
||||
// Scanner powerup ----------------------------------------------------------
|
||||
|
||||
IMPLEMENT_STATELESS_ACTOR (APowerScanner, Any, -1, 0)
|
||||
|
|
|
@ -185,6 +185,15 @@ protected:
|
|||
void Travelled ();
|
||||
};
|
||||
|
||||
class APowerFrightener : public APowerup
|
||||
{
|
||||
DECLARE_STATELESS_ACTOR (APowerFrightener, APowerup)
|
||||
protected:
|
||||
void InitEffect ();
|
||||
void EndEffect ();
|
||||
};
|
||||
|
||||
|
||||
class player_s;
|
||||
|
||||
#endif //__A_ARTIFACTS_H__
|
||||
|
|
|
@ -50,12 +50,7 @@ FState ABlood::States[] =
|
|||
S_NORMAL (BLUD, 'B', 8, NULL , &States[S_DBLOOD+2]),
|
||||
S_NORMAL (BLUD, 'A', 8, NULL , NULL),
|
||||
|
||||
#define S_HBLOOD (S_DBLOOD+3)
|
||||
S_NORMAL (BLOD, 'C', 8, NULL , &States[S_HBLOOD+1]),
|
||||
S_NORMAL (BLOD, 'B', 8, NULL , &States[S_HBLOOD+2]),
|
||||
S_NORMAL (BLOD, 'A', 8, NULL , NULL),
|
||||
|
||||
#define S_SBLOOD (S_HBLOOD+3)
|
||||
#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]),
|
||||
|
@ -68,16 +63,10 @@ FState ABlood::States[] =
|
|||
IMPLEMENT_ACTOR (ABlood, Any, -1, 130)
|
||||
PROP_Flags (MF_NOBLOCKMAP)
|
||||
PROP_Flags2 (MF2_NOTELEPORT)
|
||||
PROP_SpawnState(S_DBLOOD)
|
||||
PROP_Mass (5)
|
||||
END_DEFAULTS
|
||||
|
||||
AT_GAME_SET (Blood)
|
||||
{
|
||||
ABlood *def = GetDefault<ABlood>();
|
||||
|
||||
def->SpawnState = &ABlood::States[gameinfo.gametype == GAME_Doom ? S_DBLOOD : S_HBLOOD];
|
||||
}
|
||||
|
||||
void ABlood::SetDamage (int damage)
|
||||
{
|
||||
if (gameinfo.gametype == GAME_Doom)
|
||||
|
@ -99,15 +88,15 @@ void ABlood::SetDamage (int damage)
|
|||
}
|
||||
else if (damage >= 10)
|
||||
{
|
||||
SetState (&States[S_HBLOOD]);
|
||||
SetState (&States[S_DBLOOD]);
|
||||
}
|
||||
else if (damage >= 7)
|
||||
{
|
||||
SetState (&States[S_HBLOOD+1]);
|
||||
SetState (&States[S_DBLOOD+1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetState (&States[S_HBLOOD+2]);
|
||||
SetState (&States[S_DBLOOD+2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -372,4 +372,9 @@ void FActorInfo::ApplyDefaults (BYTE *defaults)
|
|||
{
|
||||
((AActor *)defaults)->flags3 |= MF3_ISMONSTER;
|
||||
}
|
||||
// Any default projectile in Raven's games produces blood splatter
|
||||
if (gameinfo.gametype & GAME_Raven && ((AActor *)defaults)->flags & MF_MISSILE)
|
||||
{
|
||||
((AActor *)defaults)->flags5 |= MF5_BLOODSPLATTER;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -313,6 +313,7 @@ oldmenuitem_t EpisodeMenu[MAX_EPISODES] =
|
|||
};
|
||||
|
||||
char EpisodeMaps[MAX_EPISODES][8];
|
||||
bool EpisodeNoSkill[MAX_EPISODES];
|
||||
|
||||
oldmenu_t EpiDef =
|
||||
{
|
||||
|
@ -1500,7 +1501,11 @@ void M_NewGame(int choice)
|
|||
{
|
||||
if (EpiDef.numitems <= 1)
|
||||
{
|
||||
if (gameinfo.gametype & (GAME_Doom|GAME_Strife))
|
||||
if (EpisodeNoSkill[0])
|
||||
{
|
||||
M_ChooseSkill(2);
|
||||
}
|
||||
else if (gameinfo.gametype & (GAME_Doom|GAME_Strife))
|
||||
{
|
||||
M_SetupNextMenu (&NewDef);
|
||||
}
|
||||
|
@ -1621,6 +1626,12 @@ void M_Episode (int choice)
|
|||
return;
|
||||
}
|
||||
|
||||
if (EpisodeNoSkill[choice])
|
||||
{
|
||||
M_ChooseSkill(2);
|
||||
return;
|
||||
}
|
||||
|
||||
epi = choice;
|
||||
if (gameinfo.gametype & (GAME_Doom|GAME_Strife))
|
||||
M_SetupNextMenu (&NewDef);
|
||||
|
@ -1685,10 +1696,14 @@ static void SCClass (int option)
|
|||
{
|
||||
M_SetupNextMenu (&EpiDef);
|
||||
}
|
||||
else
|
||||
else if (!EpisodeNoSkill[0])
|
||||
{
|
||||
M_SetupNextMenu (&HexenSkillMenu);
|
||||
}
|
||||
else
|
||||
{
|
||||
M_ChooseSkill(2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -222,6 +222,7 @@ extern int CurrentItem;
|
|||
#define MAX_EPISODES 8
|
||||
|
||||
extern oldmenuitem_t EpisodeMenu[MAX_EPISODES];
|
||||
extern bool EpisodeNoSkill[MAX_EPISODES];
|
||||
extern char EpisodeMaps[MAX_EPISODES][8];
|
||||
extern oldmenu_t EpiDef;
|
||||
|
||||
|
|
|
@ -1913,6 +1913,8 @@ void DLevelScript::DoSetFont (int fontnum)
|
|||
#define APROP_Ambush 10
|
||||
#define APROP_Invulnerable 11
|
||||
#define APROP_JumpZ 12 // [GRB]
|
||||
#define APROP_ChaseGoal 13
|
||||
#define APROP_Frightened 14
|
||||
#define APROP_SeeSound 5 // Sounds can only be set, not gotten
|
||||
#define APROP_AttackSound 6
|
||||
#define APROP_PainSound 7
|
||||
|
@ -1960,6 +1962,8 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
|
|||
case APROP_Invulnerable:if (value) actor->flags2 |= MF2_INVULNERABLE; else actor->flags2 &= ~MF2_INVULNERABLE; break;
|
||||
case APROP_JumpZ: if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn)))
|
||||
static_cast<APlayerPawn *>(actor)->JumpZ = value; break; // [GRB]
|
||||
case APROP_ChaseGoal: if (value) actor->flags5 |= MF5_CHASEGOAL; else actor->flags5 &= ~MF5_CHASEGOAL; break;
|
||||
case APROP_Frightened: if (value) actor->flags4 |= MF4_FRIGHTENED; else actor->flags4 &= ~MF4_FRIGHTENED; break;
|
||||
case APROP_SeeSound: actor->SeeSound = S_FindSound (FBehavior::StaticLookupString (value)); break;
|
||||
case APROP_AttackSound: actor->AttackSound = S_FindSound (FBehavior::StaticLookupString (value)); break;
|
||||
case APROP_PainSound: actor->PainSound = S_FindSound (FBehavior::StaticLookupString (value)); break;
|
||||
|
@ -1997,6 +2001,8 @@ int DLevelScript::GetActorProperty (int tid, int property)
|
|||
case APROP_Alpha: return actor->alpha;
|
||||
case APROP_RenderStyle: return actor->RenderStyle;
|
||||
case APROP_Ambush: return !!(actor->flags & MF_AMBUSH);
|
||||
case APROP_ChaseGoal: return !!(actor->flags5 & MF5_CHASEGOAL);
|
||||
case APROP_Frightened: return !!(actor->flags4 & MF4_FRIGHTENED);
|
||||
case APROP_JumpZ: if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn)))
|
||||
{
|
||||
return static_cast<APlayerPawn *>(actor)->JumpZ; // [GRB]
|
||||
|
|
|
@ -89,6 +89,7 @@ dirtype_t diags[4] =
|
|||
fixed_t xspeed[8] = {FRACUNIT,46341,0,-46341,-FRACUNIT,-46341,0,46341};
|
||||
fixed_t yspeed[8] = {0,46341,FRACUNIT,46341,0,-46341,-FRACUNIT,-46341};
|
||||
|
||||
void P_RandomChaseDir (AActor *actor);
|
||||
|
||||
|
||||
//
|
||||
|
@ -576,22 +577,9 @@ void P_DoNewChaseDir (AActor *actor, fixed_t deltax, fixed_t deltay)
|
|||
int tdir;
|
||||
dirtype_t olddir, turnaround;
|
||||
|
||||
if (actor->target == NULL)
|
||||
I_Error ("P_NewChaseDir: called with no target");
|
||||
|
||||
olddir = (dirtype_t)actor->movedir;
|
||||
turnaround = opposite[olddir];
|
||||
|
||||
|
||||
// [RH] Make monsters run away from frightening players
|
||||
if ((actor->target->player != NULL &&
|
||||
(actor->target->player->cheats & CF_FRIGHTENING)) ||
|
||||
actor->flags4 & MF4_FRIGHTENED)
|
||||
{
|
||||
deltax = -deltax;
|
||||
deltay = -deltay;
|
||||
}
|
||||
|
||||
if (deltax>10*FRACUNIT)
|
||||
d[1]= DI_EAST;
|
||||
else if (deltax<-10*FRACUNIT)
|
||||
|
@ -702,6 +690,7 @@ void P_DoNewChaseDir (AActor *actor, fixed_t deltax, fixed_t deltay)
|
|||
|
||||
struct avoiddropoff_t
|
||||
{
|
||||
AActor * thing;
|
||||
fixed_t deltax;
|
||||
fixed_t deltay;
|
||||
fixed_t floorx;
|
||||
|
@ -724,13 +713,13 @@ static BOOL PIT_AvoidDropoff(line_t *line)
|
|||
angle_t angle;
|
||||
|
||||
// The monster must contact one of the two floors,
|
||||
// and the other must be a tall dropoff (more than 24).
|
||||
// and the other must be a tall dropoff.
|
||||
|
||||
if (back == a.floorz && front < a.floorz - FRACUNIT*24)
|
||||
if (back == a.floorz && front < a.floorz - a.thing->MaxDropOffHeight)
|
||||
{
|
||||
angle = R_PointToAngle2(0,0,line->dx,line->dy); // front side dropoff
|
||||
}
|
||||
else if (front == a.floorz && back < a.floorz - FRACUNIT*24)
|
||||
else if (front == a.floorz && back < a.floorz - a.thing->MaxDropOffHeight)
|
||||
{
|
||||
angle = R_PointToAngle2(line->dx,line->dy,0,0); // back side dropoff
|
||||
}
|
||||
|
@ -754,8 +743,33 @@ static BOOL PIT_AvoidDropoff(line_t *line)
|
|||
|
||||
void P_NewChaseDir(AActor * actor)
|
||||
{
|
||||
fixed_t deltax = actor->target->x - actor->x;
|
||||
fixed_t deltay = actor->target->y - actor->y;
|
||||
fixed_t deltax;
|
||||
fixed_t deltay;
|
||||
|
||||
if ((actor->flags5&MF5_CHASEGOAL || actor->goal == actor->target) && actor->goal!=NULL)
|
||||
{
|
||||
deltax = actor->goal->x - actor->x;
|
||||
deltay = actor->goal->y - actor->y;
|
||||
}
|
||||
else if (actor->target != NULL)
|
||||
{
|
||||
deltax = actor->target->x - actor->x;
|
||||
deltay = actor->target->y - actor->y;
|
||||
|
||||
if ((actor->target->player != NULL && (actor->target->player->cheats & CF_FRIGHTENING)) ||
|
||||
(actor->flags4 & MF4_FRIGHTENED))
|
||||
{
|
||||
deltax = -deltax;
|
||||
deltay = -deltay;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't abort if this happens.
|
||||
Printf ("P_NewChaseDir: called with no target\n");
|
||||
P_RandomChaseDir(actor);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to move away from a dropoff
|
||||
if (actor->floorz - actor->dropoffz > actor->MaxDropOffHeight &&
|
||||
|
@ -763,6 +777,7 @@ void P_NewChaseDir(AActor * actor)
|
|||
!(actor->flags2 & MF2_ONMOBJ) &&
|
||||
!(actor->flags & MF_FLOAT) && !(compatflags & COMPATF_DROPOFF))
|
||||
{
|
||||
a.thing = actor;
|
||||
a.deltax = a.deltay = 0;
|
||||
a.floorx = actor->x;
|
||||
a.floory = actor->y;
|
||||
|
@ -1510,6 +1525,8 @@ void A_Look (AActor *actor)
|
|||
actor->special = 0;
|
||||
actor->goal = iterator.Next ();
|
||||
actor->reactiontime = actor->args[2] * TICRATE + level.maptime;
|
||||
if (actor->args[3] == 0) actor->flags5 &=~ MF5_CHASEGOAL;
|
||||
else actor->flags5 |= MF5_CHASEGOAL;
|
||||
}
|
||||
|
||||
actor->threshold = 0; // any shot will wake up
|
||||
|
@ -1859,9 +1876,14 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
|
|||
}
|
||||
|
||||
// [RH] Don't attack if just moving toward goal
|
||||
if (actor->target == actor->goal)
|
||||
if (actor->target == actor->goal || (actor->flags5&MF5_CHASEGOAL && actor->goal != NULL))
|
||||
{
|
||||
if (actor->CheckMeleeRange ())
|
||||
AActor * savedtarget = actor->target;
|
||||
actor->target = actor->goal;
|
||||
bool result = actor->CheckMeleeRange();
|
||||
actor->target = savedtarget;
|
||||
|
||||
if (result)
|
||||
{
|
||||
// reached the goal
|
||||
TActorIterator<APatrolPoint> iterator (actor->goal->args[0]);
|
||||
|
@ -1877,27 +1899,31 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi
|
|||
}
|
||||
|
||||
angle_t lastgoalang = actor->goal->angle;
|
||||
actor->goal = iterator.Next ();
|
||||
if (actor->goal != NULL)
|
||||
int delay;
|
||||
AActor * newgoal = iterator.Next ();
|
||||
if (newgoal != NULL && actor->goal == actor->target)
|
||||
{
|
||||
actor->reactiontime = actor->goal->args[1] * TICRATE + level.maptime;
|
||||
delay = newgoal->args[1];
|
||||
actor->reactiontime = delay * TICRATE + level.maptime;
|
||||
}
|
||||
else
|
||||
{
|
||||
delay = 0;
|
||||
actor->reactiontime = actor->GetDefault()->reactiontime;
|
||||
actor->angle = lastgoalang; // Look in direction of last goal
|
||||
}
|
||||
actor->target = NULL;
|
||||
if (actor->target == actor->goal) actor->target = NULL;
|
||||
actor->flags |= MF_JUSTATTACKED;
|
||||
if (actor->goal != NULL && actor->goal->args[1] != 0)
|
||||
if (newgoal != NULL && delay != 0)
|
||||
{
|
||||
actor->flags4 |= MF4_INCOMBAT;
|
||||
actor->SetState (actor->SpawnState);
|
||||
}
|
||||
actor->flags &= ~MF_INCHASE;
|
||||
actor->goal = newgoal;
|
||||
return;
|
||||
}
|
||||
goto nomissile;
|
||||
if (actor->goal == actor->target) goto nomissile;
|
||||
}
|
||||
|
||||
// Strafe (Hexen's class bosses)
|
||||
|
|
|
@ -1310,7 +1310,7 @@ FUNC(LS_Thing_SpawnFacing)
|
|||
}
|
||||
|
||||
FUNC(LS_Thing_SetGoal)
|
||||
// Thing_SetGoal (tid, goal, delay)
|
||||
// Thing_SetGoal (tid, goal, delay, chasegoal)
|
||||
{
|
||||
TActorIterator<AActor> selfiterator (arg0);
|
||||
TActorIterator<APatrolPoint> goaliterator (arg1);
|
||||
|
@ -1324,10 +1324,14 @@ FUNC(LS_Thing_SetGoal)
|
|||
if (self->flags & MF_SHOOTABLE)
|
||||
{
|
||||
self->goal = goal;
|
||||
if (!self->target)
|
||||
if (arg3 == 0) self->flags5 &=~ MF5_CHASEGOAL;
|
||||
else self->flags |= MF5_CHASEGOAL;
|
||||
if (self->target == NULL)
|
||||
{
|
||||
self->reactiontime = arg2 * TICRATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
|
|
@ -1049,7 +1049,7 @@ BOOL PIT_CheckThing (AActor *thing)
|
|||
if (damage > 0)
|
||||
{
|
||||
P_DamageMobj (thing, tmthing, tmthing->target, damage, tmthing->DamageType);
|
||||
if (gameinfo.gametype != GAME_Doom &&
|
||||
if ((tmthing->flags5 & MF5_BLOODSPLATTER) &&
|
||||
!(thing->flags & MF_NOBLOOD) &&
|
||||
!(thing->flags2 & MF2_REFLECTIVE) &&
|
||||
!(thing->flags2 & (MF2_INVULNERABLE|MF2_DORMANT)) &&
|
||||
|
@ -2746,9 +2746,11 @@ void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
|
|||
}
|
||||
else
|
||||
{
|
||||
bool axeBlood;
|
||||
bool bloodsplatter = (t1->flags5 & MF5_BLOODSPLATTER) ||
|
||||
(t1->player != NULL && t1->player->ReadyWeapon != NULL &&
|
||||
(t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD));
|
||||
|
||||
axeBlood = (t1->player != NULL &&
|
||||
bool axeBlood = (t1->player != NULL &&
|
||||
t1->player->ReadyWeapon != NULL &&
|
||||
(t1->player->ReadyWeapon->WeaponFlags & WIF_AXEBLOOD));
|
||||
|
||||
|
@ -2767,7 +2769,7 @@ void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
|
|||
}
|
||||
if (!(GetDefaultByType(pufftype)->flags3&MF3_BLOODLESSIMPACT))
|
||||
{
|
||||
if ((gameinfo.gametype & (GAME_DoomStrife)) && !axeBlood &&
|
||||
if (!bloodsplatter && !axeBlood &&
|
||||
!(trace.Actor->flags & MF_NOBLOOD) &&
|
||||
!(trace.Actor->flags2 & (MF2_INVULNERABLE|MF2_DORMANT)))
|
||||
{
|
||||
|
@ -2776,7 +2778,7 @@ void P_LineAttack (AActor *t1, angle_t angle, fixed_t distance,
|
|||
|
||||
if (damage)
|
||||
{
|
||||
if ((gameinfo.gametype&GAME_Raven) || axeBlood)
|
||||
if (bloodsplatter || axeBlood)
|
||||
{
|
||||
if (!(trace.Actor->flags&MF_NOBLOOD) &&
|
||||
!(trace.Actor->flags2&(MF2_INVULNERABLE|MF2_DORMANT)))
|
||||
|
|
|
@ -3925,12 +3925,12 @@ class ABloodSplatter : public AActor
|
|||
FState ABloodSplatter::States[] =
|
||||
{
|
||||
#define S_BLOODSPLATTER 0
|
||||
S_NORMAL (BLOD, 'C', 8, NULL, &States[S_BLOODSPLATTER+1]),
|
||||
S_NORMAL (BLOD, 'B', 8, NULL, &States[S_BLOODSPLATTER+2]),
|
||||
S_NORMAL (BLOD, 'A', 8, NULL, NULL),
|
||||
S_NORMAL (BLUD, 'C', 8, NULL, &States[S_BLOODSPLATTER+1]),
|
||||
S_NORMAL (BLUD, 'B', 8, NULL, &States[S_BLOODSPLATTER+2]),
|
||||
S_NORMAL (BLUD, 'A', 8, NULL, NULL),
|
||||
|
||||
#define S_BLOODSPLATTERX (S_BLOODSPLATTER+3)
|
||||
S_NORMAL (BLOD, 'A', 6, NULL, NULL)
|
||||
S_NORMAL (BLUD, 'A', 6, NULL, NULL)
|
||||
};
|
||||
|
||||
IMPLEMENT_ACTOR (ABloodSplatter, Raven, -1, 0)
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "p_effect.h"
|
||||
#include "a_doomglobal.h"
|
||||
#include "templates.h"
|
||||
#include "thingdef.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -743,6 +744,16 @@ void A_Light2 (AActor *actor)
|
|||
}
|
||||
}
|
||||
|
||||
void A_Light (AActor *actor)
|
||||
{
|
||||
int index=CheckIndex(1, &CallingState);
|
||||
|
||||
if (actor->player != NULL && index > 0)
|
||||
{
|
||||
actor->player->extralight = clamp<int>(EvalExpressionI (StateParameters[index], actor), 0, 20);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// PROC P_SetupPsprites
|
||||
|
|
|
@ -591,9 +591,14 @@ static void S_ClearSoundData()
|
|||
|
||||
void S_ParseSndInfo ()
|
||||
{
|
||||
static bool termdone=false;
|
||||
int lump;
|
||||
|
||||
if (!termdone)
|
||||
{
|
||||
termdone=true;
|
||||
atterm (S_ClearSoundData);
|
||||
}
|
||||
S_ClearSoundData(); // remove old sound data first!
|
||||
|
||||
CurrentPitchMask = 0;
|
||||
|
|
|
@ -279,11 +279,16 @@ void S_AddLocalSndInfo(int lump);
|
|||
|
||||
void S_Init ()
|
||||
{
|
||||
static bool termdone=false;
|
||||
int i;
|
||||
int curvelump;
|
||||
|
||||
Printf ("S_Init\n");
|
||||
if (!termdone)
|
||||
{
|
||||
termdone=true;
|
||||
atterm (S_Shutdown);
|
||||
}
|
||||
|
||||
// remove old data (S_Init can be called multiple times!)
|
||||
LastLocalSndInfo = LastLocalSndSeq = "";
|
||||
|
|
|
@ -215,6 +215,7 @@ static flagdef ActorFlags[]=
|
|||
DEFINE_FLAG(MF5, BOUNCEONACTORS, AActor, flags5),
|
||||
DEFINE_FLAG(MF5, EXPLODEONWATER, AActor, flags5),
|
||||
DEFINE_FLAG(MF5, NODAMAGE, AActor, flags5),
|
||||
DEFINE_FLAG(MF5, BLOODSPLATTER, AActor, flags5),
|
||||
|
||||
// Effect flags
|
||||
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),
|
||||
|
@ -496,6 +497,7 @@ ACTOR(TakeFromTarget)
|
|||
ACTOR(JumpIfInTargetInventory)
|
||||
ACTOR(CountdownArg)
|
||||
ACTOR(CustomMeleeAttack)
|
||||
ACTOR(Light)
|
||||
|
||||
|
||||
#include "d_dehackedactions.h"
|
||||
|
@ -622,6 +624,7 @@ AFuncDesc AFTable[]=
|
|||
|
||||
// Only selected original weapon functions will be available.
|
||||
// All the attack pointers are somewhat tricky due to the way the flash state is handled
|
||||
FUNC(A_Light, "X")
|
||||
FUNC(A_Light0, NULL)
|
||||
FUNC(A_Light1, NULL)
|
||||
FUNC(A_Light2, NULL)
|
||||
|
@ -2962,6 +2965,7 @@ static void ActorProjectile (AActor *defaults, Baggage &bag)
|
|||
// sets the standard flags for a projectile
|
||||
defaults->flags|=MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DROPOFF|MF_MISSILE;
|
||||
defaults->flags2|=MF2_IMPACT|MF2_PCROSS|MF2_NOTELEPORT;
|
||||
if (gameinfo.gametype&GAME_Raven) defaults->flags5|=MF5_BLOODSPLATTER;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -1310,6 +1310,16 @@ void FWadCollection::RenameSprites (int startlump)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When not playing Doom rename all BLOD sprites to BLUD so that
|
||||
// the same blood states can be used everywhere
|
||||
if (gameinfo.gametype != GAME_Doom)
|
||||
{
|
||||
if (*(DWORD *)LumpInfo[i].name == MAKE_ID('B', 'L', 'O', 'D'))
|
||||
{
|
||||
*(DWORD *)LumpInfo[i].name = MAKE_ID('B', 'L', 'U', 'D');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue