- scriptified Stalker and Sentinel.

This commit is contained in:
Christoph Oelckers 2016-11-28 19:56:16 +01:00
parent 360cbfba2a
commit dd5494d848
7 changed files with 139 additions and 197 deletions

View file

@ -861,8 +861,6 @@ set( NOT_COMPILED_SOURCE_FILES
sc_man_scanner.re
g_hexen/a_heresiarch.cpp
g_hexen/a_spike.cpp
g_strife/a_sentinel.cpp
g_strife/a_stalker.cpp
g_strife/a_strifeitems.cpp
g_strife/a_strifeweapons.cpp
g_strife/a_thingstoblowup.cpp

View file

@ -1,95 +0,0 @@
/*
#include "actor.h"
#include "p_enemy.h"
#include "a_action.h"
#include "p_local.h"
#include "m_random.h"
#include "vm.h"
*/
static FRandom pr_sentinelrefire ("SentinelRefire");
DEFINE_ACTION_FUNCTION(AActor, A_SentinelBob)
{
PARAM_SELF_PROLOGUE(AActor);
double minz, maxz;
if (self->flags & MF_INFLOAT)
{
self->Vel.Z = 0;
return 0;
}
if (self->threshold != 0)
return 0;
maxz = self->ceilingz - self->Height - 16;
minz = self->floorz + 96;
if (minz > maxz)
{
minz = maxz;
}
if (minz < self->Z())
{
self->Vel.Z -= 1;
}
else
{
self->Vel.Z += 1;
}
self->reactiontime = (minz >= self->Z()) ? 4 : 0;
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_SentinelAttack)
{
PARAM_SELF_PROLOGUE(AActor);
AActor *missile, *trail;
// [BB] Without a target the P_SpawnMissileZAimed call will crash.
if (!self->target)
{
return 0;
}
missile = P_SpawnMissileZAimed (self, self->Z() + 32, self->target, PClass::FindActor("SentinelFX2"));
if (missile != NULL && (missile->Vel.X != 0 || missile->Vel.Y != 0))
{
for (int i = 8; i > 1; --i)
{
trail = Spawn("SentinelFX1",
self->Vec3Angle(missile->radius*i, missile->Angles.Yaw, 32 + missile->Vel.Z / 4 * i), ALLOW_REPLACE);
if (trail != NULL)
{
trail->target = self;
trail->Vel = missile->Vel;
P_CheckMissileSpawn (trail, self->radius);
}
}
missile->AddZ(missile->Vel.Z / 4);
}
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_SentinelRefire)
{
PARAM_SELF_PROLOGUE(AActor);
A_FaceTarget (self);
if (pr_sentinelrefire() >= 30)
{
if (self->target == NULL ||
self->target->health <= 0 ||
!P_CheckSight (self, self->target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES) ||
P_HitFriend(self) ||
(self->MissileState == NULL && !self->CheckMeleeRange()) ||
pr_sentinelrefire() < 40)
{
self->SetState (self->SeeState);
}
}
return 0;
}

View file

@ -1,88 +0,0 @@
/*
#include "actor.h"
#include "m_random.h"
#include "a_action.h"
#include "p_local.h"
#include "p_enemy.h"
#include "s_sound.h"
#include "vm.h"
*/
static FRandom pr_stalker ("Stalker");
DEFINE_ACTION_FUNCTION(AActor, A_StalkerChaseDecide)
{
PARAM_SELF_PROLOGUE(AActor);
if (!(self->flags & MF_NOGRAVITY))
{
self->SetState (self->FindState("SeeFloor"));
}
else if (self->ceilingz > self->Top())
{
self->SetState (self->FindState("Drop"));
}
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_StalkerLookInit)
{
PARAM_SELF_PROLOGUE(AActor);
FState *state;
if (self->flags & MF_NOGRAVITY)
{
state = self->FindState("LookCeiling");
}
else
{
state = self->FindState("LookFloor");
}
if (self->state->NextState != state)
{
self->SetState (state);
}
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_StalkerDrop)
{
PARAM_SELF_PROLOGUE(AActor);
self->flags5 &= ~MF5_NOVERTICALMELEERANGE;
self->flags &= ~MF_NOGRAVITY;
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_StalkerAttack)
{
PARAM_SELF_PROLOGUE(AActor);
if (self->flags & MF_NOGRAVITY)
{
self->SetState (self->FindState("Drop"));
}
else if (self->target != NULL)
{
A_FaceTarget (self);
if (self->CheckMeleeRange ())
{
int damage = (pr_stalker() & 7) * 2 + 2;
int newdam = P_DamageMobj (self->target, self, self, damage, NAME_Melee);
P_TraceBleed (newdam > 0 ? newdam : damage, self->target, self);
}
}
return 0;
}
DEFINE_ACTION_FUNCTION(AActor, A_StalkerWalk)
{
PARAM_SELF_PROLOGUE(AActor);
S_Sound (self, CHAN_BODY, "stalker/walk", 1, ATTN_NORM);
A_Chase (stack, self);
return 0;
}

View file

@ -24,8 +24,6 @@
#include "vm.h"
// Include all the other Strife stuff here to reduce compile time
#include "a_sentinel.cpp"
#include "a_stalker.cpp"
#include "a_strifeitems.cpp"
#include "a_strifeweapons.cpp"
#include "a_thingstoblowup.cpp"

View file

@ -619,8 +619,6 @@ class Actor : Thinker native
native void A_Wander(int flags = 0);
native void A_Look2();
native void A_TossGib();
native void A_SentinelBob();
native void A_SentinelRefire();
native void A_SetShadow();
native void A_ClearShadow();
native void A_GetHurt();

View file

@ -28,8 +28,6 @@ class Sentinel : Actor
Obituary "$OB_SENTINEL";
}
native void A_SentinelAttack ();
States
{
Spawn:
@ -56,6 +54,34 @@ class Sentinel : Actor
SEWR J 5;
Stop;
}
void A_SentinelAttack ()
{
// [BB] Without a target the P_SpawnMissileZAimed call will crash.
if (!target)
{
return;
}
Actor missile = SpawnMissileZAimed (pos.z + 32, target, "SentinelFX2");
if (missile != NULL && (missile.Vel.X != 0 || missile.Vel.Y != 0))
{
for (int i = 8; i > 1; --i)
{
Actor trail = Spawn("SentinelFX1", Vec3Angle(missile.radius*i, missile.angle, 32 + missile.Vel.Z / 4 * i), ALLOW_REPLACE);
if (trail != NULL)
{
trail.target = self;
trail.Vel = missile.Vel;
trail.CheckMissileSpawn (radius);
}
}
missile.AddZ(missile.Vel.Z / 4);
}
}
}
// Sentinel FX 1 ------------------------------------------------------------
@ -102,3 +128,52 @@ class SentinelFX2 : SentinelFX1
}
}
extend class Actor
{
// These are used elsewhere, too.
void A_SentinelBob()
{
if (bInFloat)
{
Vel.Z = 0;
return;
}
if (threshold != 0)
return;
double maxz = ceilingz - Height - 16;
double minz = floorz + 96;
if (minz > maxz)
{
minz = maxz;
}
if (minz < pos.z)
{
Vel.Z -= 1;
}
else
{
Vel.Z += 1;
}
reactiontime = (minz >= pos.z) ? 4 : 0;
}
void A_SentinelRefire()
{
A_FaceTarget ();
if (random[SentinelRefire]() >= 30)
{
if (target == NULL ||
target.health <= 0 ||
!CheckSight (target, SF_SEEPASTBLOCKEVERYTHING|SF_SEEPASTSHOOTABLELINES) ||
HitFriend() ||
(MissileState == NULL && !CheckMeleeRange()) ||
random[SentinelRefire]() < 40)
{
SetState (SeeState);
}
}
}
}

View file

@ -28,12 +28,6 @@ class Stalker : Actor
HitObituary "$OB_STALKER";
}
native void A_StalkerLookInit ();
native void A_StalkerChaseDecide ();
native void A_StalkerWalk ();
native void A_StalkerDrop ();
native void A_StalkerAttack ();
States
{
Spawn:
@ -76,4 +70,66 @@ class Stalker : Actor
STLK "XYZ[" 4 Bright;
Stop;
}
void A_StalkerChaseDecide ()
{
if (!bNoGravity)
{
SetStateLabel("SeeFloor");
}
else if (ceilingz > pos.z + height)
{
SetStateLabel("Drop");
}
}
void A_StalkerLookInit ()
{
State st;
if (!bNoGravity)
{
st = FindState("LookCeiling");
}
else
{
st = FindState("LookFloor");
}
if (st.NextState != st)
{
SetState (st);
}
}
void A_StalkerDrop ()
{
bNoVerticalMeleeRange = false;
bNoGravity = false;
}
void A_StalkerAttack ()
{
if (bNoGravity)
{
SetStateLabel("Drop");
}
else if (target != null)
{
A_FaceTarget ();
if (CheckMeleeRange ())
{
int damage = (random[Stalker]() & 7) * 2 + 2;
int newdam = target.DamageMobj (self, self, damage, 'Melee');
target.TraceBleed (newdam > 0 ? newdam : damage, self);
}
}
}
void A_StalkerWalk ()
{
A_PlaySound ("stalker/walk", CHAN_BODY);
A_Chase ();
}
}