monster_scientist: rebased off latest in FreeHL, should clean up and inherit most of these functions, but this will do for now

This commit is contained in:
Xylemon 2023-04-23 04:12:00 -07:00
parent 181090b701
commit e5c2636fb6
1 changed files with 119 additions and 55 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016-2020 Marco Cawthorne <marco@icculus.org> * Copyright (c) 2016-2023 Marco Cawthorne <marco@icculus.org>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@ -14,6 +14,14 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
/*QUAKED monster_scientist (0 0.8 0.8) (-16 -16 0) (16 16 72)
HALF-LIFE (1998) ENTITY
Scientist
*/
var int autocvar_sh_scialert = FALSE; var int autocvar_sh_scialert = FALSE;
var int autocvar_sh_scispeed = 40; var int autocvar_sh_scispeed = 40;
var int autocvar_sh_sciattack = FALSE; var int autocvar_sh_sciattack = FALSE;
@ -69,10 +77,11 @@ class monster_scientist:NSTalkMonster
{ {
void(void) monster_scientist; void(void) monster_scientist;
virtual void(void) Spawned;
virtual void(void) Respawn; virtual void(void) Respawn;
virtual void(void) Pain; virtual void(void) Pain;
virtual void(void) Death; virtual void(void) Death;
virtual void(void) OnPlayerUse; virtual void(void) PlayerUse;
virtual void(void) TalkPanic; virtual void(void) TalkPanic;
virtual int(void) AnimIdle; virtual int(void) AnimIdle;
virtual int(void) AnimWalk; virtual int(void) AnimWalk;
@ -82,6 +91,8 @@ class monster_scientist:NSTalkMonster
virtual void(void) AttackNeedle; virtual void(void) AttackNeedle;
virtual void(void) FallNoise; virtual void(void) FallNoise;
virtual void(string, string) SpawnKey;
}; };
void void
@ -205,28 +216,42 @@ monster_scientist::TalkPanic(void)
m_flNextSentence = time + 2.0 + random(0,3); m_flNextSentence = time + 2.0 + random(0,3);
} }
void
monster_scientist::PlayerUse(void)
{
if (spawnflags & MSF_PREDISASTER) {
Sentence("!SC_POK");
return;
}
if (m_iFlags & MONSTER_FEAR) {
bprint(PRINT_HIGH, sprintf("I'm not following you evil person!"));
return;
}
super::OnPlayerUse();
}
void void
monster_scientist::Pain(void) monster_scientist::Pain(void)
{ {
/* don't bother if we're fully dead */ /* make everyone on edge */
if (IsAlive() == false) WarnAllies();
if (m_flAnimTime > time) {
return; return;
}
if (autocvar_sh_sciattack) if (random() < 0.25f) {
super::Pain();
StartleAllies();
if (InAnimation() == true)
return; return;
}
if (random() < 0.25f) if (IsAlive() == true) {
return; Sound_Speak(this, "monster_scientist.pain");
SetFrame(SCIA_FLINCH + floor(random(0, 6)));
Sound_Speak(this, "monster_scientist.pain"); m_iFlags |= MONSTER_FEAR;
frame = SCIA_FLINCH + floor(random(0, 6)); m_flAnimTime = time + 0.25f;
m_flAnimTime = time + 0.25f; }
m_iFlags |= MONSTER_FEAR;
} }
void void
@ -235,14 +260,14 @@ monster_scientist::Death(void)
bool deathcheck = false; bool deathcheck = false;
HLGameRules rules = (HLGameRules)g_grMode; HLGameRules rules = (HLGameRules)g_grMode;
/* upset everyone */
StartleAllies(); StartleAllies();
if (IsAlive() == true) { if (IsAlive() == true) {
if (g_dmg_eAttacker.flags & FL_CLIENT) SetFrame(SCIA_DIE_SIMPLE + floor(random(0, 6)));
rules.ScientistKill((player)g_dmg_eAttacker, (entity)this); rules.ScientistKill((player)g_dmg_eAttacker, (entity)this);
Plugin_PlayerObituary(g_dmg_eAttacker, this, g_dmg_iWeapon, g_dmg_iHitBody, g_dmg_iDamage); Plugin_PlayerObituary(g_dmg_eAttacker, this, g_dmg_iWeapon, g_dmg_iHitBody, g_dmg_iDamage);
SetFrame(SCIA_DIE_SIMPLE + floor(random(0, 6)));
Sound_Speak(this, "monster_scientist.die"); Sound_Speak(this, "monster_scientist.die");
deathcheck = true; deathcheck = true;
} }
@ -255,23 +280,14 @@ monster_scientist::Death(void)
rules.RegisterSciDeath(); rules.RegisterSciDeath();
} }
/* will not respawn by themselves in this mode */ /* will not respawn by themselves in these modes */
if (g_chosen_mode == SHMODE_STANDARD) if (g_chosen_mode == SHMODE_STANDARD || g_chosen_mode == SHMODE_STEALTH)
return; return;
think = Respawn; think = Respawn;
nextthink = time + 10.0f; nextthink = time + 10.0f;
} }
void
monster_scientist::OnPlayerUse(void)
{
if (m_iFlags & MONSTER_FEAR)
return;
super::OnPlayerUse();
}
void void
monster_scientist::Respawn(void) monster_scientist::Respawn(void)
{ {
@ -279,11 +295,8 @@ monster_scientist::Respawn(void)
super::Respawn(); super::Respawn();
m_iFlags |= MONSTER_CANFOLLOW; m_iFlags |= MONSTER_CANFOLLOW;
PlayerUse = OnPlayerUse;
health = base_health = Skill_GetValue("scientist_health", 20);
takedamage = DAMAGE_YES;
if (autocvar_sh_scialert || g_chosen_mode == SHMODE_STANDARD) { if (autocvar_sh_scialert || g_chosen_mode == SHMODE_STANDARD || g_chosen_mode == SHMODE_STEALTH) {
m_iFlags |= MONSTER_FEAR; m_iFlags |= MONSTER_FEAR;
} }
@ -314,43 +327,94 @@ monster_scientist::Respawn(void)
} }
void void
monster_scientist::monster_scientist(void) monster_scientist::SpawnKey(string strKey, string strValue)
{ {
spawnflags |= MSF_MULTIPLAYER; switch (strKey) {
case "body":
SetBody(stoi(strValue) + 1);
break;
default:
super::SpawnKey(strKey, strValue);
}
}
precache_sound("scientist/scream04.wav"); void
precache_sound("scientist/scream05.wav"); monster_scientist::Spawned(void)
precache_sound("scientist/scream06.wav"); {
precache_sound("scientist/scream07.wav"); if (spawnflags & MSF_PREDISASTER) {
precache_sound("scientist/scream08.wav"); m_talkAsk = "";
m_talkPlayerAsk = "!SC_PQUEST";
m_talkPlayerGreet = "!SC_PHELLO";
m_talkPlayerIdle = "!SC_PIDLE";
} else {
m_talkAsk = "!SC_QUESTION";
m_talkPlayerAsk = "!SC_QUESTION";
m_talkPlayerGreet = "!SC_HELLO";
m_talkPlayerIdle = "!SC_PIDLE";
}
Sound_Precache("monster_scientist.die");
Sound_Precache("monster_scientist.pain");
m_talkAsk = "!SC_QUESTION";
m_talkPlayerAsk = "!SC_PQUEST";
m_talkPlayerGreet = "!SC_PHELLO";
m_talkPlayerIdle = "!SC_PIDLE";
m_talkAnswer = "!SC_ANSWER"; m_talkAnswer = "!SC_ANSWER";
m_talkAllyShot = "!SC_PLFEAR"; m_talkAllyShot = "!SC_PLFEAR";
m_talkGreet = ""; m_talkGreet = "!SC_HELLO";
m_talkIdle = "!SC_IDLE"; m_talkIdle = "!SC_IDLE";
m_talkHearing = "!SC_HEAR"; m_talkHearing = "!SC_HEAR";
m_talkSmelling = "!SC_SMELL"; m_talkSmelling = "!SC_SMELL";
m_talkStare = "!SC_STARE"; m_talkStare = "!SC_STARE";
m_talkSurvived = "!SC_WOUND"; m_talkSurvived = "!SC_WOUND";
m_talkWounded = "!SC_MORTAL"; m_talkWounded = "!SC_MORTAL";
/* they seem to use predisaster lines regardless of disaster state */
m_talkPlayerWounded1 = "!SC_CUREA";
m_talkPlayerWounded2 = "!SC_CUREB";
m_talkPlayerWounded3 = "!SC_CUREC";
m_talkUnfollow = "!SC_WAIT"; m_talkUnfollow = "!SC_WAIT";
m_talkFollow = "!SC_OK"; m_talkFollow = "!SC_OK";
m_talkStopFollow = "!SC_STOP"; m_talkStopFollow = "!SC_STOP";
m_iBody = -1;
if (autocvar_sh_sciattack)
m_iAlliance = MAL_ALIEN;
model = "models/scientist.mdl"; model = "models/scientist.mdl";
base_mins = [-16,-16,0]; base_mins = [-16,-16,0];
base_maxs = [16,16,72]; base_maxs = [16,16,72];
base_health = Skill_GetValue("scientist_health", 20); base_health = Skill_GetValue("scientist_health", 20);
precache_model(model);
iBleeds = true; super::Spawned();
Sound_Precache("monster_scientist.die");
Sound_Precache("monster_scientist.pain");
/* has the body not been overriden, etc. choose a character for us */
if (m_iBody == -1) {
SetBody((int)floor(random(1,5)));
}
switch (m_iBody) {
case 1:
m_flPitch = 105;
netname = "Walter";
break;
case 2:
m_flPitch = 100;
netname = "Einstein";
break;
case 3:
m_flPitch = 95;
netname = "Luther";
SetSkin(1);
break;
default:
m_flPitch = 100;
netname = "Slick";
}
}
void
monster_scientist::monster_scientist(void)
{
/* TODO they still need to attack each other for madness */
if (g_chosen_mode == SHMODE_MADNESS)
m_iAlliance = MAL_ALIEN;
if (autocvar_sh_sciattack)
m_iAlliance = MAL_ALIEN;
} }