- Update scripting branch to trunk.

SVN r3758 (scripting)
This commit is contained in:
Randy Heit 2012-07-14 03:04:41 +00:00
commit 562cf04db2
614 changed files with 63691 additions and 31256 deletions

View file

@ -44,6 +44,7 @@
#include "thingdef/thingdef.h"
#include "d_dehacked.h"
#include "g_level.h"
#include "teaminfo.h"
#include "gi.h"
@ -114,7 +115,7 @@ void P_RandomChaseDir (AActor *actor);
// sound blocking lines cut off traversal.
//----------------------------------------------------------------------------
void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soundblocks)
void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soundblocks, AActor *emitter, fixed_t maxdist)
{
int i;
line_t* check;
@ -135,7 +136,8 @@ void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soun
// [RH] Set this in the actors in the sector instead of the sector itself.
for (actor = sec->thinglist; actor != NULL; actor = actor->snext)
{
if (actor != soundtarget && (!splash || !(actor->flags4 & MF4_NOSPLASHALERT)))
if (actor != soundtarget && (!splash || !(actor->flags4 & MF4_NOSPLASHALERT)) &&
(!maxdist || (P_AproxDistance(actor->x - emitter->x, actor->y - emitter->y) <= maxdist)))
{
actor->LastHeard = soundtarget;
}
@ -178,11 +180,11 @@ void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soun
if (check->flags & ML_SOUNDBLOCK)
{
if (!soundblocks)
P_RecursiveSound (other, soundtarget, splash, 1);
P_RecursiveSound (other, soundtarget, splash, 1, emitter, maxdist);
}
else
{
P_RecursiveSound (other, soundtarget, splash, soundblocks);
P_RecursiveSound (other, soundtarget, splash, soundblocks, emitter, maxdist);
}
}
}
@ -198,7 +200,7 @@ void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soun
//
//----------------------------------------------------------------------------
void P_NoiseAlert (AActor *target, AActor *emitter, bool splash)
void P_NoiseAlert (AActor *target, AActor *emitter, bool splash, fixed_t maxdist)
{
if (emitter == NULL)
return;
@ -207,7 +209,7 @@ void P_NoiseAlert (AActor *target, AActor *emitter, bool splash)
return;
validcount++;
P_RecursiveSound (emitter->Sector, target, splash, 0);
P_RecursiveSound (emitter->Sector, target, splash, 0, emitter, maxdist);
}
@ -308,7 +310,7 @@ bool P_CheckMissileRange (AActor *actor)
{
fixed_t dist;
if (!P_CheckSight (actor, actor->target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES))
if (!P_CheckSight (actor, actor->target, SF_SEEPASTBLOCKEVERYTHING))
return false;
if (actor->flags & MF_JUSTHIT)
@ -427,20 +429,14 @@ bool P_Move (AActor *actor)
return false;
}
// [RH] Instead of yanking non-floating monsters to the ground,
// let gravity drop them down, unless they're moving down a step.
// [RH] Walking actors that are not on the ground cannot walk. We don't
// want to yank them to the ground here as Doom did, since that makes
// it difficult to thrust them vertically in a reasonable manner.
// [GZ] Let jumping actors jump.
if (!((actor->flags & MF_NOGRAVITY) || (actor->flags6 & MF6_CANJUMP))
&& actor->z > actor->floorz && !(actor->flags2 & MF2_ONMOBJ))
{
if (actor->z > actor->floorz + actor->MaxStepHeight)
{
return false;
}
else
{
actor->z = actor->floorz;
}
return false;
}
if ((unsigned)actor->movedir >= 8)
@ -537,6 +533,26 @@ bool P_Move (AActor *actor)
actor->vely += FixedMul (deltay, movefactor);
}
// [RH] If a walking monster is no longer on the floor, move it down
// to the floor if it is within MaxStepHeight, presuming that it is
// actually walking down a step.
if (try_ok &&
!((actor->flags & MF_NOGRAVITY) || (actor->flags6 & MF6_CANJUMP))
&& actor->z > actor->floorz && !(actor->flags2 & MF2_ONMOBJ))
{
if (actor->z <= actor->floorz + actor->MaxStepHeight)
{
fixed_t savedz = actor->z;
actor->z = actor->floorz;
// Make sure that there isn't some other actor between us and
// the floor we could get stuck in. The old code did not do this.
if (!P_TestMobjZ(actor))
{
actor->z = savedz;
}
}
}
if (!try_ok)
{
if (((actor->flags6 & MF6_CANJUMP)||(actor->flags & MF_FLOAT)) && tm.floatok)
@ -1111,7 +1127,7 @@ bool P_IsVisible(AActor *lookee, AActor *other, INTBOOL allaround, FLookExParams
else
{
mindist = maxdist = 0;
fov = allaround? 0 : ANGLE_180;
fov = allaround ? 0 : ANGLE_180;
}
fixed_t dist = P_AproxDistance (other->x - lookee->x, other->y - lookee->y);
@ -1136,7 +1152,7 @@ bool P_IsVisible(AActor *lookee, AActor *other, INTBOOL allaround, FLookExParams
}
// P_CheckSight is by far the most expensive operation in here so let's do it last.
return P_CheckSight(lookee, other, SF_SEEPASTBLOCKEVERYTHING);
return P_CheckSight(lookee, other, SF_SEEPASTSHOOTABLELINES);
}
//---------------------------------------------------------------------------
@ -1403,9 +1419,7 @@ AActor *LookForEnemiesInBlock (AActor *lookee, int index, void *extparam)
other = NULL;
if (link->flags & MF_FRIENDLY)
{
if (deathmatch &&
lookee->FriendPlayer != 0 && link->FriendPlayer != 0 &&
lookee->FriendPlayer != link->FriendPlayer)
if (!lookee->IsFriend(link))
{
// This is somebody else's friend, so go after it
other = link;
@ -1567,7 +1581,7 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params)
}
#endif
// [SP] If you don't see any enemies in deathmatch, look for players (but only when friend to a specific player.)
if (actor->FriendPlayer == 0) return result;
if (actor->FriendPlayer == 0 && (!teamplay || actor->DesignatedTeam == TEAM_NONE)) return result;
if (result || !deathmatch) return true;
@ -1650,25 +1664,28 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params)
// We're going to ignore our master, but go after his enemies.
if ( actor->flags & MF_FRIENDLY )
{
if ( actor->FriendPlayer == 0 )
continue; // I have no friends, I will ignore players.
if ( actor->FriendPlayer == player->mo->FriendPlayer )
continue; // This is my master.
if ( actor->IsFriend(player->mo) )
continue;
}
if ((player->mo->flags & MF_SHADOW && !(i_compatflags & COMPATF_INVISIBILITY)) ||
player->mo->flags3 & MF3_GHOST)
// [RC] Well, let's let special monsters with this flag active be able to see
// the player then, eh?
if(!(actor->flags & MF6_SEEINVISIBLE))
{
if ((P_AproxDistance (player->mo->x - actor->x,
player->mo->y - actor->y) > 2*MELEERANGE)
&& P_AproxDistance (player->mo->velx, player->mo->vely)
< 5*FRACUNIT)
{ // Player is sneaking - can't detect
return false;
}
if (pr_lookforplayers() < 225)
{ // Player isn't sneaking, but still didn't detect
return false;
if ((player->mo->flags & MF_SHADOW && !(i_compatflags & COMPATF_INVISIBILITY)) ||
player->mo->flags3 & MF3_GHOST)
{
if ((P_AproxDistance (player->mo->x - actor->x,
player->mo->y - actor->y) > 2*MELEERANGE)
&& P_AproxDistance (player->mo->velx, player->mo->vely)
< 5*FRACUNIT)
{ // Player is sneaking - can't detect
return false;
}
if (pr_lookforplayers() < 225)
{ // Player isn't sneaking, but still didn't detect
return false;
}
}
}
@ -1818,11 +1835,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LookEx)
PARAM_FIXED_OPT (minseedist) { minseedist = 0; }
PARAM_FIXED_OPT (maxseedist) { maxseedist = 0; }
PARAM_FIXED_OPT (maxheardist) { maxheardist = 0; }
PARAM_ANGLE_OPT (fov) { fov = 0; }
PARAM_FLOAT_OPT (fov_f) { fov_f = 0; }
PARAM_STATE_OPT (seestate) { seestate = NULL; }
AActor *targ = NULL; // Shuts up gcc
fixed_t dist;
angle_t fov = (fov_f == 0) ? ANGLE_180 : angle_t(fov_f * ANGLE_90 / 90);
FLookExParams params = { fov, minseedist, maxseedist, maxheardist, flags, seestate };
if (self->flags5 & MF5_INCONVERSATION)
@ -1995,6 +2013,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LookEx)
// [KS] *** End additions by me ***
//==========================================================================
//
// A_ClearLastHeard
//
//==========================================================================
DEFINE_ACTION_FUNCTION(AActor, A_ClearLastHeard)
{
PARAM_ACTION_PROLOGUE;
self->LastHeard = NULL;
return 0;
}
//==========================================================================
//
// A_Wander
@ -2162,10 +2193,13 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele
if (nightmarefast && G_SkillProperty(SKILLP_FastMonsters))
{ // Monsters move faster in nightmare mode
actor->tics -= actor->tics / 2;
if (actor->tics < 3)
if (actor->tics > 3)
{
actor->tics = 3;
actor->tics -= actor->tics / 2;
if (actor->tics < 3)
{
actor->tics = 3;
}
}
}
@ -2291,7 +2325,7 @@ void A_DoChase (VMFrameStack *stack, AActor *actor, bool fastchase, FState *mele
// as the goal.
while ( (spec = specit.Next()) )
{
LineSpecials[spec->special] (NULL, actor, false, spec->args[0],
P_ExecuteSpecial(spec->special, NULL, actor, false, spec->args[0],
spec->args[1], spec->args[2], spec->args[3], spec->args[4]);
}
@ -2510,6 +2544,25 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates)
if ( abs(corpsehit-> x - viletryx) > maxdist ||
abs(corpsehit-> y - viletryy) > maxdist )
continue; // not actually touching
#ifdef _3DFLOORS
// Let's check if there are floors in between the archvile and its target
sector_t *vilesec = self->Sector;
sector_t *corpsec = corpsehit->Sector;
// We only need to test if at least one of the sectors has a 3D floor.
sector_t *testsec = vilesec->e->XFloor.ffloors.Size() ? vilesec :
(vilesec != corpsec && corpsec->e->XFloor.ffloors.Size()) ? corpsec : NULL;
if (testsec)
{
fixed_t zdist1, zdist2;
if (P_Find3DFloor(testsec, corpsehit->x, corpsehit->y, corpsehit->z, false, true, zdist1)
!= P_Find3DFloor(testsec, self->x, self->y, self->z, false, true, zdist2))
{
// Not on same floor
if (vilesec == corpsec || abs(zdist1 - self->z) > self->height)
continue;
}
}
#endif
corpsehit->velx = corpsehit->vely = 0;
// [RH] Check against real height and radius
@ -2645,7 +2698,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Chase)
}
else // this is the old default A_Chase
{
A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, !!(gameinfo.gametype & GAME_Raven), false);
A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false);
}
return 0;
}
@ -2661,7 +2714,9 @@ DEFINE_ACTION_FUNCTION(AActor, A_VileChase)
{
PARAM_ACTION_PROLOGUE;
if (!P_CheckForResurrection(self, true))
A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, !!(gameinfo.gametype & GAME_Raven), false);
{
A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false);
}
return 0;
}
@ -2683,17 +2738,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ExtChase)
// for internal use
void A_Chase(VMFrameStack *stack, AActor *self)
{
A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, !!(gameinfo.gametype & GAME_Raven), false);
A_DoChase(stack, self, false, self->MeleeState, self->MissileState, true, gameinfo.nightmarefast, false);
}
//=============================================================================
//
// A_FaceTarget
// A_FaceMaster
// A_FaceTracer
//
//=============================================================================
void A_FaceTarget (AActor *self, angle_t max_turn)
void A_Face (AActor *self, AActor *other, angle_t max_turn, angle_t max_pitch)
{
if (!self->target)
if (!other)
return;
// [RH] Andy Baker's stealth monsters
@ -2704,15 +2761,15 @@ void A_FaceTarget (AActor *self, angle_t max_turn)
self->flags &= ~MF_AMBUSH;
angle_t target_angle = R_PointToAngle2 (self->x, self->y, self->target->x, self->target->y);
angle_t other_angle = R_PointToAngle2 (self->x, self->y, other->x, other->y);
// 0 means no limit. Also, if we turn in a single step anyways, no need to go through the algorithms.
// It also means that there is no need to check for going past the target.
if (max_turn && (max_turn < (angle_t)abs(self->angle - target_angle)))
// It also means that there is no need to check for going past the other.
if (max_turn && (max_turn < (angle_t)abs(self->angle - other_angle)))
{
if (self->angle > target_angle)
if (self->angle > other_angle)
{
if (self->angle - target_angle < ANGLE_180)
if (self->angle - other_angle < ANGLE_180)
{
self->angle -= max_turn;
}
@ -2723,7 +2780,7 @@ void A_FaceTarget (AActor *self, angle_t max_turn)
}
else
{
if (target_angle - self->angle < ANGLE_180)
if (other_angle - self->angle < ANGLE_180)
{
self->angle += max_turn;
}
@ -2735,22 +2792,90 @@ void A_FaceTarget (AActor *self, angle_t max_turn)
}
else
{
self->angle = target_angle;
self->angle = other_angle;
}
// [DH] Now set pitch. In order to maintain compatibility, this can be
// disabled and is so by default.
if (max_pitch <= ANGLE_180)
{
// [DH] Don't need to do proper fixed->double conversion, since the
// result is only used in a ratio.
double dist_x = self->target->x - self->x;
double dist_y = self->target->y - self->y;
double dist_z = self->target->z - self->z;
double dist = sqrt(dist_x*dist_x + dist_y*dist_y + dist_z*dist_z);
int other_pitch = (int)rad2bam(asin(dist_z / dist));
if (max_pitch != 0)
{
if (self->pitch > other_pitch)
{
max_pitch = MIN(max_pitch, unsigned(self->pitch - other_pitch));
self->pitch -= max_pitch;
}
else
{
max_pitch = MIN(max_pitch, unsigned(other_pitch - self->pitch));
self->pitch += max_pitch;
}
}
else
{
self->pitch = other_pitch;
}
}
// This will never work well if the turn angle is limited.
if (max_turn == 0 && (self->angle == target_angle) && self->target->flags & MF_SHADOW)
if (max_turn == 0 && (self->angle == other_angle) && other->flags & MF_SHADOW && !(self->flags6 & MF6_SEEINVISIBLE) )
{
self->angle += pr_facetarget.Random2() << 21;
}
}
void A_FaceTarget (AActor *self, angle_t max_turn, angle_t max_pitch)
{
A_Face(self, self->target, max_turn, max_pitch);
}
void A_FaceMaster (AActor *self, angle_t max_turn, angle_t max_pitch)
{
A_Face(self, self->master, max_turn, max_pitch);
}
void A_FaceTracer (AActor *self, angle_t max_turn, angle_t max_pitch)
{
A_Face(self, self->tracer, max_turn, max_pitch);
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceTarget)
{
PARAM_ACTION_PROLOGUE;
PARAM_ANGLE_OPT(max_turn) { max_turn = 0; }
PARAM_ANGLE_OPT(max_pitch) { max_pitch = 270; }
A_FaceTarget(self);
A_FaceTarget(self, max_turn, max_pitch);
return 0;
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceMaster)
{
PARAM_ACTION_PROLOGUE;
PARAM_ANGLE_OPT(max_turn) { max_turn = 0; }
PARAM_ANGLE_OPT(max_pitch) { max_pitch = 270; }
A_FaceMaster(self, max_turn, max_pitch);
return 0;
}
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceTracer)
{
PARAM_ACTION_PROLOGUE;
PARAM_ANGLE_OPT(max_turn) { max_turn = 0; }
PARAM_ANGLE_OPT(max_pitch) { max_pitch = 270; }
A_FaceTracer(self, max_turn, max_pitch);
return 0;
}
@ -2800,10 +2925,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_MonsterRail)
self->target->x - self->target->velx * 3,
self->target->y - self->target->vely * 3);
if (self->target->flags & MF_SHADOW)
{
if (self->target->flags & MF_SHADOW && !(self->flags6 & MF6_SEEINVISIBLE))
{
self->angle += pr_railface.Random2() << 21;
}
}
P_RailAttack (self, self->GetMissileDamage (0, 1), 0);
self->pitch = saved_pitch;
@ -3145,7 +3270,7 @@ void A_BossDeath(AActor *self)
}
checked = true;
LineSpecials[sa->Action](NULL, self, false,
P_ExecuteSpecial(sa->Action, NULL, self, false,
sa->Args[0], sa->Args[1], sa->Args[2], sa->Args[3], sa->Args[4]);
}
}