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 */
var float g_flHDRIrisMinValue = 0.0;
var float g_flHDRIrisMaxValue = 1.75;
var float g_flHDRIrisMultiplier = 1.25;
var float g_flHDRIrisMaxValue = 2.0;
var float g_flHDRIrisMultiplier = 1.0;
var float g_flHDRIrisFadeUp = 0.1;
var float g_flHDRIrisFadeDown = 0.5;

View File

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

View File

@ -439,51 +439,62 @@ CBaseNPC::Physics(void)
input_movevalues = [0,0,0];
input_impulse = 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;
CheckRoute();
WalkRoute();
input_timelength = frametime;
runstandardplayerphysics(this);
Footsteps_Update();
/* override whatever we did above with this */
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) {
m_iFlags |= MONSTER_FALLING;
} else {
m_iFlags &= ~MONSTER_FALLING;
}
/* support for think/nextthink */
if (think && nextthink > 0) {
if (nextthink < time) {
think();
nextthink = 0.0f;
}
}
}
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.
*/
float(float modidx, string framename) frameforname = #276;
float(float modidx, float framenum) frameduration = #277;
/*
* Scripted Sequences
* ==================
@ -96,23 +98,52 @@ void scripted_sequence::Trigger(void)
CBaseMonster f;
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);
if (f) {
f.NewRoute(origin);
f.style = MONSTER_INSEQUENCE;
f.m_flSequenceSpeed = 64;
f.m_strRouteEnded = m_strTarget;
}
} else if (m_iMove == SS_RUN) {
f = (CBaseMonster)find(world, CBaseEntity::m_strTargetName, m_strMonster);
if (f) {
f.NewRoute(origin);
f.style = MONSTER_INSEQUENCE;
f.m_flSequenceSpeed = 256;
f.m_strRouteEnded = m_strTarget;
f = (CBaseMonster)find(world, CBaseEntity::m_strTargetName, m_strMonster);
/* target doesn't exist/hasn't spawned */
if (!f) {
print(sprintf("^1scripted_sequence::Trigger^7: Unknown target %s\n", m_strMonster));
return;
}
/* if we're told an anim, we better have it... or else. */
if (m_strActionAnim) {
f.m_flSequenceEnd = frameforname(f.modelindex, m_strActionAnim);
if (f.m_flSequenceEnd == -1) {
print(sprintf("^1scripted_sequence::Trigger^7: Framegroup %s not found!\n", m_strActionAnim));
return;
}
}
/* 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)

View File

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

View File

@ -152,8 +152,6 @@ monster_scientist::Pain(int iHitBody)
void
monster_scientist::Death(int iHitBody)
{
CBaseNPC::Death(iHitBody);
WarnAllies();
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));
style = MONSTER_DEAD;
}
/* now mark our state as 'dead' */
CBaseNPC::Death(iHitBody);
}
void