More work on scripted_sequences.

This commit is contained in:
Marco Cawthorne 2020-03-29 11:21:26 +02:00
parent 9442a597fa
commit f07600f194
6 changed files with 149 additions and 75 deletions

View file

@ -16,8 +16,8 @@
/* High Dynamic Range - Iris Adaption */ /* High Dynamic Range - Iris Adaption */
var float g_flHDRIrisMinValue = 0.0; var float g_flHDRIrisMinValue = 0.0;
var float g_flHDRIrisMaxValue = 1.75; var float g_flHDRIrisMaxValue = 2.0;
var float g_flHDRIrisMultiplier = 1.25; var float g_flHDRIrisMultiplier = 1.0;
var float g_flHDRIrisFadeUp = 0.1; var float g_flHDRIrisFadeUp = 0.1;
var float g_flHDRIrisFadeDown = 0.5; var float g_flHDRIrisFadeDown = 0.5;

View file

@ -32,8 +32,13 @@ enum {
MONSTER_IDLE, MONSTER_IDLE,
MONSTER_WALK, MONSTER_WALK,
MONSTER_RUN, MONSTER_RUN,
MONSTER_DEAD, MONSTER_DEAD
MONSTER_INSEQUENCE };
enum {
SEQUENCESTATE_NONE,
SEQUENCESTATE_ACTIVE,
SEQUENCESTATE_ENDING
}; };
enumflags { enumflags {
@ -59,6 +64,9 @@ class CBaseMonster:CBaseEntity
vector base_mins; vector base_mins;
vector base_maxs; vector base_maxs;
int base_health; int base_health;
int m_iSequenceState;
float m_flSequenceEnd;
float m_flSequenceSpeed; float m_flSequenceSpeed;
/* pathfinding */ /* pathfinding */
@ -79,6 +87,7 @@ class CBaseMonster:CBaseEntity
virtual void(int) Death; virtual void(int) Death;
virtual void() Physics; virtual void() Physics;
virtual void() IdleNoise; virtual void() IdleNoise;
virtual void() FreeState;
virtual void() Gib; virtual void() Gib;
virtual void(string) Sound; virtual void(string) Sound;
virtual float(entity, float) SendEntity; virtual float(entity, float) SendEntity;
@ -154,6 +163,22 @@ void CBaseMonster::ClearRoute(void)
} }
} }
void CBaseMonster::FreeState(void)
{
m_flSequenceEnd = 0;
m_iSequenceState = SEQUENCESTATE_NONE;
/* trigger when required */
if (m_strRouteEnded) {
for (entity t = world; (t = find(t, CBaseTrigger::m_strTargetName, m_strRouteEnded));) {
CBaseTrigger trigger = (CBaseTrigger)t;
if (trigger.Trigger != __NULL__) {
trigger.Trigger();
}
}
}
}
void CBaseMonster::CheckRoute(void) void CBaseMonster::CheckRoute(void)
{ {
float flDist; float flDist;
@ -165,20 +190,21 @@ void CBaseMonster::CheckRoute(void)
flDist = floor( vlen( m_pRoute[m_iCurNode].dest - origin ) ); flDist = floor( vlen( m_pRoute[m_iCurNode].dest - origin ) );
if ( flDist < 64 ) { if ( flDist < 64 ) {
print(sprintf("CBaseMonster::CheckNode: %s reached node\n", this.netname)); print(sprintf("^2CBaseMonster::CheckRoute^7: %s reached node\n", this.netname));
m_iCurNode--; m_iCurNode--;
velocity = [0,0,0]; /* clamp friction */ velocity = [0,0,0]; /* clamp friction */
} }
if (m_iCurNode < 0) { if (m_iCurNode < 0) {
print(sprintf("CBaseMonster::CheckNode: %s reached end\n", this.netname)); print(sprintf("^2CBaseMonster::CheckRoute^7: %s reached end\n", this.netname));
/* trigger when required */ /* mark that we've ended a sequence, if we're in one and que anim */
if (m_strRouteEnded) { if (m_iSequenceState == SEQUENCESTATE_ACTIVE) {
for (entity t = world; (t = find(t, CBaseTrigger::m_strTargetName, m_strRouteEnded));) { if (m_flSequenceEnd) {
CBaseTrigger trigger = (CBaseTrigger)t; float duration = frameduration(modelindex, m_flSequenceEnd);
if (trigger.Trigger != __NULL__) { m_iSequenceState = SEQUENCESTATE_ENDING;
trigger.Trigger(); think = FreeState;
} nextthink = time + duration;
print(sprintf("^2CBaseMonster::CheckRoute^7: %s overriding anim for %f seconds (modelindex %d, frame %d)\n", this.netname, duration, modelindex, m_flSequenceEnd));
} }
} }
ClearRoute(); ClearRoute();
@ -232,16 +258,20 @@ void CBaseMonster::Physics(void)
input_movevalues = [0,0,0]; input_movevalues = [0,0,0];
input_impulse = 0; input_impulse = 0;
input_buttons = 0; input_buttons = 0;
input_angles = angles = v_angle; input_angles = angles = v_angle;
input_timelength = frametime; input_timelength = frametime;
movetype = MOVETYPE_WALK;
CheckRoute(); /* override whatever we did above with this */
WalkRoute(); if (m_iSequenceState == SEQUENCESTATE_ACTIVE) {
runstandardplayerphysics(this); frame = m_flSequenceEnd;
movetype = MOVETYPE_NONE; } else {
IdleNoise(); movetype = MOVETYPE_WALK;
CheckRoute();
WalkRoute();
runstandardplayerphysics(this);
movetype = MOVETYPE_NONE;
IdleNoise();
}
/* support for think/nextthink */ /* support for think/nextthink */
if (think && nextthink > 0) { if (think && nextthink > 0) {

View file

@ -439,51 +439,62 @@ CBaseNPC::Physics(void)
input_movevalues = [0,0,0]; input_movevalues = [0,0,0];
input_impulse = 0; input_impulse = 0;
input_buttons = 0; input_buttons = 0;
if (style != MONSTER_DEAD) {
TalkPlayerGreet();
FollowChain();
if (m_eFollowing != world) {
FollowPlayer();
} else if (m_iFlags & MONSTER_FEAR) {
PanicFrame();
} else {
if (random() < 0.5) {
TalkPlayerAsk();
} else {
TalkPlayerIdle();
}
}
if (m_flPainTime > time) {
input_movevalues = [0,0,0];
} else {
spvel = vlen(velocity);
if (spvel < 5) {
frame = AnimIdle();
} else if (spvel <= 140) {
frame = AnimWalk();
} else if (spvel <= 240) {
frame = AnimRun();
}
}
}
input_angles = angles = v_angle; input_angles = angles = v_angle;
CheckRoute();
WalkRoute();
input_timelength = frametime; input_timelength = frametime;
runstandardplayerphysics(this); /* override whatever we did above with this */
Footsteps_Update(); if (m_iSequenceState == SEQUENCESTATE_ENDING) {
frame = m_flSequenceEnd;
} else {
if (style != MONSTER_DEAD) {
TalkPlayerGreet();
FollowChain();
if (m_eFollowing != world) {
FollowPlayer();
} else if (m_iFlags & MONSTER_FEAR) {
PanicFrame();
} else {
if (random() < 0.5) {
TalkPlayerAsk();
} else {
TalkPlayerIdle();
}
}
if (m_flPainTime > time) {
input_movevalues = [0,0,0];
} else {
spvel = vlen(velocity);
if (spvel < 5) {
frame = AnimIdle();
} else if (spvel <= 140) {
frame = AnimWalk();
} else if (spvel <= 240) {
frame = AnimRun();
}
}
}
CheckRoute();
WalkRoute();
runstandardplayerphysics(this);
Footsteps_Update();
}
if (!(flags & FL_ONGROUND) && velocity[2] < -100) { if (!(flags & FL_ONGROUND) && velocity[2] < -100) {
m_iFlags |= MONSTER_FALLING; m_iFlags |= MONSTER_FALLING;
} else { } else {
m_iFlags &= ~MONSTER_FALLING; m_iFlags &= ~MONSTER_FALLING;
} }
/* support for think/nextthink */
if (think && nextthink > 0) {
if (nextthink < time) {
think();
nextthink = 0.0f;
}
}
} }
void void

View file

@ -37,6 +37,8 @@ Allow a monster to be selected and given an action to perform.
This is done in the form of olaying an animation. This is done in the form of olaying an animation.
*/ */
float(float modidx, string framename) frameforname = #276;
float(float modidx, float framenum) frameduration = #277;
/* /*
* Scripted Sequences * Scripted Sequences
* ================== * ==================
@ -96,23 +98,52 @@ void scripted_sequence::Trigger(void)
CBaseMonster f; CBaseMonster f;
print(sprintf("^2scripted_sequence::Trigger^7: with spawnflags %d\n", spawnflags)); print(sprintf("^2scripted_sequence::Trigger^7: with spawnflags %d\n", spawnflags));
if (m_iMove == SS_WALK) { f = (CBaseMonster)find(world, CBaseEntity::m_strTargetName, m_strMonster);
f = (CBaseMonster)find(world, CBaseEntity::m_strTargetName, m_strMonster);
if (f) { /* target doesn't exist/hasn't spawned */
f.NewRoute(origin); if (!f) {
f.style = MONSTER_INSEQUENCE; print(sprintf("^1scripted_sequence::Trigger^7: Unknown target %s\n", m_strMonster));
f.m_flSequenceSpeed = 64; return;
f.m_strRouteEnded = m_strTarget; }
}
} else if (m_iMove == SS_RUN) { /* if we're told an anim, we better have it... or else. */
f = (CBaseMonster)find(world, CBaseEntity::m_strTargetName, m_strMonster); if (m_strActionAnim) {
if (f) { f.m_flSequenceEnd = frameforname(f.modelindex, m_strActionAnim);
f.NewRoute(origin); if (f.m_flSequenceEnd == -1) {
f.style = MONSTER_INSEQUENCE; print(sprintf("^1scripted_sequence::Trigger^7: Framegroup %s not found!\n", m_strActionAnim));
f.m_flSequenceSpeed = 256; return;
f.m_strRouteEnded = m_strTarget;
} }
} }
/* entity to trigger after sequence ends */
f.m_strRouteEnded = m_strTarget;
/* mark the state */
f.m_iSequenceState = SEQUENCESTATE_ACTIVE;
if (m_iMove == SS_WALK) {
f.NewRoute(origin);
f.m_flSequenceSpeed = 64;
} else if (m_iMove == SS_RUN) {
f.NewRoute(origin);
f.m_flSequenceSpeed = 256;
} else if (m_iMove == SS_NO) {
f.m_iSequenceState = SEQUENCESTATE_ENDING;
f.think = CBaseMonster::FreeState;
f.nextthink = time + frameduration(f.modelindex, f.m_flSequenceEnd);
} else if (m_iMove == SS_INSTANTANEOUS) {
setorigin(f, this.origin);
f.m_iSequenceState = SEQUENCESTATE_ENDING;
f.think = CBaseMonster::FreeState;
f.nextthink = time + frameduration(f.modelindex, f.m_flSequenceEnd);
} else if (m_iMove == SS_TURNTOFACE) {
/* turn instantly, only affect YAW. */
vector newangle = vectoangles(origin - f.origin);
f.angles[1] = newangle[1];
f.m_iSequenceState = SEQUENCESTATE_ENDING;
f.think = CBaseMonster::FreeState;
f.nextthink = time + frameduration(f.modelindex, f.m_flSequenceEnd);
}
} }
void scripted_sequence::Respawn(void) void scripted_sequence::Respawn(void)

View file

@ -119,8 +119,6 @@ monster_barney::Pain(int iHitBody)
void void
monster_barney::Death(int iHitBody) monster_barney::Death(int iHitBody)
{ {
CBaseNPC::Death(iHitBody);
WarnAllies(); WarnAllies();
int r = floor(random(0,ba_snddie.length)); int r = floor(random(0,ba_snddie.length));
@ -130,6 +128,9 @@ monster_barney::Death(int iHitBody)
frame = 25 + floor(random(0, 6)); frame = 25 + floor(random(0, 6));
style = MONSTER_DEAD; style = MONSTER_DEAD;
} }
/* now mark our state as 'dead' */
CBaseNPC::Death(iHitBody);
} }
void void

View file

@ -152,8 +152,6 @@ monster_scientist::Pain(int iHitBody)
void void
monster_scientist::Death(int iHitBody) monster_scientist::Death(int iHitBody)
{ {
CBaseNPC::Death(iHitBody);
WarnAllies(); WarnAllies();
int r = floor(random(0,sci_snddie.length)); int r = floor(random(0,sci_snddie.length));
@ -163,6 +161,9 @@ monster_scientist::Death(int iHitBody)
frame = SCIA_DIE_SIMPLE + floor(random(0, 6)); frame = SCIA_DIE_SIMPLE + floor(random(0, 6));
style = MONSTER_DEAD; style = MONSTER_DEAD;
} }
/* now mark our state as 'dead' */
CBaseNPC::Death(iHitBody);
} }
void void