- 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
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue