monster_scientist: improve attack visuals, make attack trace against player so they can miss, poison is now curable upon healing

This commit is contained in:
Xylemon 2023-04-26 16:07:40 -07:00
parent b39524854f
commit 1845012d6c
1 changed files with 38 additions and 19 deletions

View File

@ -164,8 +164,10 @@ int
monster_scientist::AttackMelee(void) monster_scientist::AttackMelee(void)
{ {
/* visual */ /* visual */
AnimPlay(28); AnimPlay(61);
m_flAttackThink = m_flAnimTime; m_flAttackThink = m_flAnimTime;
/* TODO set needle sub-model
SetBody(this, "", "geomset 0 5\n"); */
float r = random(); float r = random();
@ -178,7 +180,7 @@ monster_scientist::AttackMelee(void)
Sentence("!SC_CUREC"); Sentence("!SC_CUREC");
/* functional */ /* functional */
ScheduleThink(AttackNeedle, 0.25f); ScheduleThink(AttackNeedle, 1.0f);
return (1); return (1);
} }
@ -186,12 +188,25 @@ monster_scientist::AttackMelee(void)
* a little messy but it works */ * a little messy but it works */
.NSTimer poisonTimer; .NSTimer poisonTimer;
.entity poisonSource; .entity poisonSource;
.float OldTargetHealth;
/* a function for poison that slowly kills the target */ /* a function for poison that slowly kills the target */
static void static void
monster_scientist_NeedleAttack(entity target) monster_scientist_NeedleAttack(entity target)
{ {
bool isDead = false; bool isDead = false;
bool isHealed = false;
/* if increase in target's health, then they are cured */
if (target.OldTargetHealth > 0) {
if (target.OldTargetHealth < target.health) {
isDead = true; // misleading but less code
isHealed = true;
target.flags &= ~FL_NOTARGET;
}
}
if (isHealed != true)
Damage_Apply(target, target.poisonSource, 10, 0, DMG_POISON); Damage_Apply(target, target.poisonSource, 10, 0, DMG_POISON);
/* since corpses have "health" do an extra check */ /* since corpses have "health" do an extra check */
@ -201,13 +216,16 @@ monster_scientist_NeedleAttack(entity target)
isDead = true; isDead = true;
if (isDead) { if (isDead) {
/* the attacker laughs at a sucessful kill if they're not dead /* the attacker laughs at a sucessful kill if they're not dead */
* TODO Sound_Speak needs to have an override speach option */ if (target.poisonSource.solid != SOLID_CORPSE)
if (target.poisonSource.solid != SOLID_CORPSE) { if (isHealed == false) // don't laugh if the victim is cured
Sound_Speak(target.poisonSource, "monster_scientist.laugh"); Sound_Speak(target.poisonSource, "monster_scientist.laugh");
}
target.poisonTimer.StopTimer(); target.poisonTimer.StopTimer();
} }
/* update our health value for next cycle */
target.OldTargetHealth = target.health;
} }
void void
@ -221,24 +239,25 @@ monster_scientist::AttackNeedle(void)
/* look for our victim */ /* look for our victim */
traceline(origin, m_eEnemy.origin, FALSE, this); traceline(origin, m_eEnemy.origin, FALSE, this);
/* if the entity can't take damage, don't bother */ /* if the entity can't take damage, don't bother */
if (trace_fraction >= 1.0 || trace_ent.takedamage != DAMAGE_YES) { if (trace_fraction >= 1.0 || trace_ent.takedamage != DAMAGE_YES) {
return; return;
} }
/* set the timer for the poison /* trace to see if the target is in front of us, if not then fail attack */
* flag the vitcim so they aren't attacked again (unless Invasion) */ if (vlen(origin - m_eEnemy.origin) < 96) {
if not (g_chosen_mode == SHMODE_INVASION) { /* set the timer for the poison
trace_ent.flags |= FL_NOTARGET; * flag the vitcim so they aren't attacked again (unless Invasion) */
if not (g_chosen_mode == SHMODE_INVASION) {
trace_ent.flags |= FL_NOTARGET;
}
trace_ent.poisonSource = this;
trace_ent.poisonTimer = trace_ent.poisonTimer.ScheduleTimer(trace_ent, AttackNeedle_PoisonDamage, 3.0f, true);
/* apply our poison attack to the victim */
monster_scientist_NeedleAttack(trace_ent);
} }
trace_ent.poisonSource = this;
trace_ent.poisonTimer = trace_ent.poisonTimer.ScheduleTimer(trace_ent, AttackNeedle_PoisonDamage, 3.0f, true);
/* apply our poison attack to the victim */
monster_scientist_NeedleAttack(trace_ent);
/* visual */
AnimPlay(30);
} }
/* TODO someday these will use the ACT system */ /* TODO someday these will use the ACT system */
@ -425,7 +444,7 @@ monster_scientist::Respawn(void)
/* scientists are always afraid in standard hunting /* scientists are always afraid in standard hunting
* and scialert mode */ * and scialert mode */
if (autocvar_sh_scialert || g_chosen_mode == SHMODE_STANDARD) { if (autocvar_sh_scialert || g_chosen_mode == SHMODE_STANDARD || g_chosen_mode == SHMODE_MADNESS || g_chosen_mode == SHMODE_INVASION) {
m_iFlags |= MONSTER_FEAR; m_iFlags |= MONSTER_FEAR;
} }