Simplified a lot of the Barney/Scientist code by expanding CBaseNPC
This commit is contained in:
parent
dd16fd1684
commit
bb0b4d8f6c
8 changed files with 927 additions and 825 deletions
|
@ -21,6 +21,19 @@ enum {
|
|||
MONSTER_DEAD
|
||||
};
|
||||
|
||||
enumflags {
|
||||
MSF_WAITTILLSEEN,
|
||||
MSF_GAG,
|
||||
MSF_MONSTERCLIP,
|
||||
MSF_RESERVED1,
|
||||
MSF_PRISONER,
|
||||
MSF_RESERVED2,
|
||||
MSF_RESERVED3,
|
||||
MSF_WAITFORSCRIPT,
|
||||
MSF_PREDISASTER,
|
||||
MSF_FADECORPSE
|
||||
};
|
||||
|
||||
class CBaseMonster:CBaseEntity
|
||||
{
|
||||
int body;
|
||||
|
|
|
@ -14,13 +14,36 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/* NPCs are more advanced than regular monsters in that they express emotions
|
||||
* and are able to interact more with the environment */
|
||||
|
||||
#define PLAYER_DETECT_RADIUS 512
|
||||
|
||||
enumflags
|
||||
{
|
||||
MONSTER_USED,
|
||||
MONSTER_FEAR,
|
||||
MONSTER_METPLAYER,
|
||||
MONSTER_FALLING,
|
||||
MONSTER_CANFOLLOW
|
||||
};
|
||||
|
||||
class CBaseNPC:CBaseMonster
|
||||
{
|
||||
/* our NPCs can have a unique pitch to their voice */
|
||||
float m_flPitch;
|
||||
float m_flNextSentence;
|
||||
int m_iFlags;
|
||||
|
||||
entity m_eFollowing;
|
||||
entity m_eFollowingChain;
|
||||
vector m_vecLastUserPos;
|
||||
float m_flChangePath;
|
||||
float m_flTraceTime;
|
||||
|
||||
/* damage/combat related */
|
||||
float m_flPainTime;
|
||||
|
||||
/* sentences identifiers */
|
||||
string m_talkAnswer; /* random answer to whenever a question is asked */
|
||||
|
@ -28,6 +51,7 @@ class CBaseNPC:CBaseMonster
|
|||
string m_talkAllyShot; /* asks to not shoot an ally further */
|
||||
string m_talkGreet; /* greet other NPCs */
|
||||
string m_talkIdle; /* idle chatter */
|
||||
string m_talkHearing; /* what did we just hear? */
|
||||
string m_talkSmelling; /* is something smelling bad? */
|
||||
string m_talkStare; /* when NPC is being stared at */
|
||||
string m_talkSurvived; /* we're near death */
|
||||
|
@ -47,8 +71,69 @@ class CBaseNPC:CBaseMonster
|
|||
void() CBaseNPC;
|
||||
virtual void(string) Speak;
|
||||
virtual void(string) Sentence;
|
||||
virtual void() WarnAllies;
|
||||
virtual void() FollowPlayer;
|
||||
virtual void() FollowChain;
|
||||
virtual void() Physics;
|
||||
virtual int() AnimIdle;
|
||||
virtual int() AnimWalk;
|
||||
virtual int() AnimRun;
|
||||
virtual void() PlayerUse;
|
||||
virtual void() PanicFrame;
|
||||
virtual void() Hide;
|
||||
|
||||
/*virtual void() TalkAnswer;
|
||||
virtual void() TalkAsk;
|
||||
virtual void() TalkAllyShot;
|
||||
virtual void() TalkGreet;
|
||||
virtual void() TalkIdle;
|
||||
virtual void() TalkHearing;
|
||||
virtual void() TalkSmelling;
|
||||
virtual void() TalkStare;
|
||||
virtual void() TalkSurvived;
|
||||
virtual void() TalkWounded;*/
|
||||
virtual void() TalkPlayerAsk;
|
||||
virtual void() TalkPlayerGreet;
|
||||
virtual void() TalkPlayerIdle;
|
||||
virtual void() TalkPlayerWounded1;
|
||||
virtual void() TalkPlayerWounded2;
|
||||
virtual void() TalkPlayerWounded3;
|
||||
virtual void() TalkUnfollow;
|
||||
virtual void() TalkFollow;
|
||||
virtual void() TalkStopFollow;
|
||||
};
|
||||
|
||||
int
|
||||
CBaseNPC::AnimIdle(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
CBaseNPC::AnimWalk(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
CBaseNPC::AnimRun(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
CBaseNPC::WarnAllies(void)
|
||||
{
|
||||
for (entity b = world; (b = find(b, ::classname, classname));) {
|
||||
if (vlen(b.origin - origin) < PLAYER_DETECT_RADIUS) {
|
||||
CBaseNPC w = (CBaseNPC)b;
|
||||
w.m_iFlags |= MONSTER_METPLAYER;
|
||||
w.m_eFollowing = world;
|
||||
w.m_eFollowingChain = world;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CBaseNPC::Sentence(string sentence)
|
||||
{
|
||||
|
@ -78,8 +163,364 @@ CBaseNPC::Speak(string sentence)
|
|||
multicast(origin, MULTICAST_PVS);
|
||||
}
|
||||
|
||||
void
|
||||
CBaseNPC::TalkPlayerGreet(void)
|
||||
{
|
||||
if (m_flNextSentence > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_iFlags & MONSTER_METPLAYER) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (entity p = world; (p = find(p, ::classname, "player"));) {
|
||||
/* Find players in a specific radius */
|
||||
if (vlen(p.origin - origin) < PLAYER_DETECT_RADIUS) {
|
||||
/* If we can't physically see him, don't do anything */
|
||||
traceline(origin, p.origin, FALSE, this);
|
||||
if (trace_ent != p) {
|
||||
continue;
|
||||
}
|
||||
Sentence(m_talkPlayerGreet);
|
||||
m_flNextSentence = time + 10.0;
|
||||
m_iFlags |= MONSTER_METPLAYER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CBaseNPC::TalkPlayerIdle(void)
|
||||
{
|
||||
if (spawnflags & MSF_PREDISASTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_flNextSentence > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (entity p = world; (p = find(p, ::classname, "player"));) {
|
||||
/* Find players in a specific radius */
|
||||
if (vlen(p.origin - origin) < PLAYER_DETECT_RADIUS) {
|
||||
/* If we can't physically see him, don't do anything */
|
||||
traceline(origin, p.origin, FALSE, this);
|
||||
if (trace_ent != p) {
|
||||
continue;
|
||||
}
|
||||
Sentence(m_talkPlayerIdle);
|
||||
m_flNextSentence = time + 10.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CBaseNPC::TalkPlayerAsk(void)
|
||||
{
|
||||
if (spawnflags & MSF_PREDISASTER) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_flNextSentence > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (entity p = world; (p = find(p, ::classname, "player"));) {
|
||||
/* Find players in a specific radius */
|
||||
if (vlen(p.origin - origin) < PLAYER_DETECT_RADIUS) {
|
||||
/* If we can't physically see him, don't do anything */
|
||||
traceline(origin, p.origin, FALSE, this);
|
||||
if (trace_ent != p) {
|
||||
continue;
|
||||
}
|
||||
Sentence(m_talkPlayerAsk);
|
||||
m_flNextSentence = time + 10.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CBaseNPC::TalkPlayerWounded1(void)
|
||||
{
|
||||
if (m_flNextSentence > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (base_health < health) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (entity p = world; (p = find(p, ::classname, "player"));) {
|
||||
/* Find players in a specific radius */
|
||||
if (vlen(p.origin - origin) < PLAYER_DETECT_RADIUS) {
|
||||
/* If we can't physically see him, don't do anything */
|
||||
traceline(origin, p.origin, FALSE, this);
|
||||
if (trace_ent != p) {
|
||||
continue;
|
||||
}
|
||||
Sentence(m_talkPlayerWounded3);
|
||||
m_flNextSentence = time + 10.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void
|
||||
CBaseNPC::TalkPlayerWounded2(void)
|
||||
{
|
||||
if (m_flNextSentence > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((base_health / 2) < health) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (entity p = world; (p = find(p, ::classname, "player"));) {
|
||||
/* Find players in a specific radius */
|
||||
if (vlen(p.origin - origin) < PLAYER_DETECT_RADIUS) {
|
||||
/* If we can't physically see him, don't do anything */
|
||||
traceline(origin, p.origin, FALSE, this);
|
||||
if (trace_ent != p) {
|
||||
continue;
|
||||
}
|
||||
Sentence(m_talkPlayerWounded3);
|
||||
m_flNextSentence = time + 10.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CBaseNPC::TalkPlayerWounded3(void)
|
||||
{
|
||||
if (m_flNextSentence > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (entity p = world; (p = find(p, ::classname, "player"));) {
|
||||
/* Find players in a specific radius */
|
||||
if (vlen(p.origin - origin) < PLAYER_DETECT_RADIUS) {
|
||||
/* If we can't physically see him, don't do anything */
|
||||
traceline(origin, p.origin, FALSE, this);
|
||||
if (trace_ent != p) {
|
||||
continue;
|
||||
}
|
||||
Sentence(m_talkPlayerWounded3);
|
||||
m_flNextSentence = time + 10.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CBaseNPC::TalkUnfollow(void)
|
||||
{
|
||||
Sentence(m_talkUnfollow);
|
||||
m_flNextSentence = time + 10.0;
|
||||
}
|
||||
|
||||
void
|
||||
CBaseNPC::TalkFollow(void)
|
||||
{
|
||||
Sentence(m_talkFollow);
|
||||
m_flNextSentence = time + 10.0;
|
||||
}
|
||||
|
||||
void
|
||||
CBaseNPC::TalkStopFollow(void)
|
||||
{
|
||||
Sentence(m_talkStopFollow);
|
||||
m_flNextSentence = time + 10.0;
|
||||
}
|
||||
|
||||
void
|
||||
CBaseNPC::FollowPlayer(void)
|
||||
{
|
||||
v_angle = vectoangles(m_eFollowingChain.origin - origin);
|
||||
v_angle[0] = 0;
|
||||
v_angle[1] = Math_FixDelta(v_angle[1]);
|
||||
v_angle[2] = 0;
|
||||
|
||||
/* Give up after 1024 units */
|
||||
if (vlen(m_eFollowingChain.origin - origin) > 1024) {
|
||||
m_eFollowing = world;
|
||||
} else if (vlen(m_eFollowingChain.origin - origin) > 64) {
|
||||
input_movevalues[0] = 240;
|
||||
|
||||
other = world;
|
||||
traceline(origin, m_eFollowingChain.origin, MOVE_OTHERONLY, this);
|
||||
|
||||
/* Tracing failed, there's world geometry in the way */
|
||||
if (trace_fraction < 1.0f) {
|
||||
v_angle = vectoangles(m_vecLastUserPos - origin);
|
||||
v_angle[0] = 0;
|
||||
v_angle[1] = Math_FixDelta(v_angle[1]);
|
||||
v_angle[2] = 0;
|
||||
} else {
|
||||
m_vecLastUserPos = m_eFollowingChain.origin;
|
||||
}
|
||||
|
||||
/* Trace again to see if another hostage is in our path and if so
|
||||
* follow them instead, this makes pathing easier */
|
||||
traceline(origin, /*mins, maxs,*/ m_vecLastUserPos, FALSE, this);
|
||||
if (trace_ent.classname == classname) {
|
||||
CBaseNPC que = (CBaseNPC)trace_ent;
|
||||
if (que.m_eFollowingChain == m_eFollowing) {
|
||||
if (trace_ent != this) {
|
||||
m_eFollowingChain = trace_ent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CBaseNPC::PanicFrame(void)
|
||||
{
|
||||
m_iFlags |= MONSTER_METPLAYER;
|
||||
maxspeed = 240;
|
||||
input_movevalues = [maxspeed, 0, 0];
|
||||
|
||||
if (m_flTraceTime < time) {
|
||||
traceline(origin, origin + (v_forward * 64), FALSE, this);
|
||||
|
||||
if (trace_fraction < 1.0f) {
|
||||
m_flChangePath = 0.0f;
|
||||
}
|
||||
m_flTraceTime = time + 0.5f;
|
||||
}
|
||||
|
||||
if (m_flChangePath < time) {
|
||||
float add;
|
||||
vector pos;
|
||||
|
||||
pos = origin + [0,0,-18];
|
||||
if (random() < 0.5) {
|
||||
add = 45;
|
||||
} else {
|
||||
add = -45;
|
||||
}
|
||||
|
||||
/* test every 45 degrees */
|
||||
for (int i = 0; i < 8; i++) {
|
||||
v_angle[1] = Math_FixDelta(v_angle[1] + add);
|
||||
makevectors(v_angle);
|
||||
traceline(pos, pos + (v_forward * 64), FALSE, this);
|
||||
if (trace_fraction >= 1.0f) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_flChangePath = time + floor(random(2,10));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CBaseNPC::FollowChain(void)
|
||||
{
|
||||
/* Deal with a hostage being rescued when it's following someone else */
|
||||
if (m_eFollowingChain.classname == classname) {
|
||||
if (m_eFollowingChain.solid == SOLID_NOT) {
|
||||
m_eFollowingChain = m_eFollowing;
|
||||
}
|
||||
}
|
||||
/* Deal with the hostage losing its rescuer (death) */
|
||||
if (m_eFollowing.health <= 0) {
|
||||
m_eFollowing = world;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CBaseNPC::Physics(void)
|
||||
{
|
||||
float spvel;
|
||||
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;
|
||||
input_timelength = frametime;
|
||||
|
||||
runstandardplayerphysics(this);
|
||||
Footsteps_Update();
|
||||
|
||||
if (!(flags & FL_ONGROUND) && velocity[2] < -100) {
|
||||
m_iFlags |= MONSTER_FALLING;
|
||||
} else {
|
||||
m_iFlags &= ~MONSTER_FALLING;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CBaseNPC::PlayerUse(void)
|
||||
{
|
||||
if (m_iFlags & MONSTER_FEAR) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* can't press use any non-allies */
|
||||
if (!(m_iFlags & MONSTER_CANFOLLOW)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((m_eFollowing == world)) {
|
||||
if (!(m_iFlags & MONSTER_USED)) {
|
||||
m_iFlags |= MONSTER_USED;
|
||||
}
|
||||
|
||||
TalkFollow();
|
||||
m_eFollowing = eActivator;
|
||||
m_eFollowingChain = m_eFollowing;
|
||||
m_vecLastUserPos = m_eFollowing.origin;
|
||||
} else {
|
||||
TalkUnfollow();
|
||||
m_eFollowing = world;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CBaseNPC::Hide(void)
|
||||
{
|
||||
m_eFollowing = world;
|
||||
CBaseMonster::Hide();
|
||||
}
|
||||
|
||||
void
|
||||
CBaseNPC::CBaseNPC(void)
|
||||
{
|
||||
|
||||
CBaseMonster::CBaseMonster();
|
||||
m_eFollowing = world;
|
||||
}
|
||||
|
|
|
@ -65,20 +65,35 @@ string slv_sndpain[] = {
|
|||
"aslave/slv_pain2.wav"
|
||||
};
|
||||
|
||||
class monster_alien_slave:CBaseMonster
|
||||
class monster_alien_slave:CBaseNPC
|
||||
{
|
||||
float m_flIdleTime;
|
||||
float m_flPainTime;
|
||||
|
||||
|
||||
void() monster_alien_slave;
|
||||
|
||||
virtual void(int) Death;
|
||||
virtual void(int) Pain;
|
||||
virtual void(void) IdleChat;
|
||||
virtual void(void) Respawn;
|
||||
};
|
||||
|
||||
void
|
||||
monster_alien_slave::IdleChat(void)
|
||||
{
|
||||
if (m_flIdleTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sentence(m_talkIdle);
|
||||
|
||||
m_flIdleTime = time + 5.0f + random(0,20);
|
||||
}
|
||||
|
||||
void
|
||||
monster_alien_slave::Pain(int iHitBody)
|
||||
{
|
||||
CBaseMonster::Pain(iHitBody);
|
||||
CBaseNPC::Pain(iHitBody);
|
||||
|
||||
if (m_flPainTime > time) {
|
||||
return;
|
||||
|
@ -116,13 +131,13 @@ monster_alien_slave::Death(int iHitBody)
|
|||
}
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseMonster::Death(iHitBody);
|
||||
CBaseNPC::Death(iHitBody);
|
||||
}
|
||||
|
||||
void
|
||||
monster_alien_slave::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
CBaseNPC::Respawn();
|
||||
frame = SLV_IDLE;
|
||||
}
|
||||
|
||||
|
@ -133,10 +148,30 @@ monster_alien_slave::monster_alien_slave(void)
|
|||
precache_sound(slv_sndpain[i]);
|
||||
}
|
||||
|
||||
m_talkAnswer = "";
|
||||
m_talkAsk = "";
|
||||
m_talkAllyShot = "";
|
||||
m_talkGreet = "SLV_ALERT";
|
||||
m_talkIdle = "!SLV_IDLE";
|
||||
m_talkSmelling = "";
|
||||
m_talkStare = "";
|
||||
m_talkSurvived = "";
|
||||
m_talkWounded = "";
|
||||
|
||||
m_talkPlayerAsk = "";
|
||||
m_talkPlayerGreet = "!SLV_ALERT";
|
||||
m_talkPlayerIdle = "";
|
||||
m_talkPlayerWounded1 = "";
|
||||
m_talkPlayerWounded2 = "";
|
||||
m_talkPlayerWounded3 = "";
|
||||
m_talkUnfollow = "";
|
||||
m_talkFollow = "";
|
||||
m_talkStopFollow = "";
|
||||
|
||||
netname = "Alien Slave";
|
||||
model = "models/islave.mdl";
|
||||
base_health = Skill_GetValue("islave_health");
|
||||
base_mins = [-16,-16,0];
|
||||
base_maxs = [16,16,72];
|
||||
CBaseMonster::CBaseMonster();
|
||||
CBaseNPC::CBaseNPC();
|
||||
}
|
||||
|
|
|
@ -21,48 +21,33 @@ Barney Calhoun
|
|||
*/
|
||||
|
||||
enum {
|
||||
BARNEY_IDLE,
|
||||
BARNEY_WALK,
|
||||
BARNEY_RUN,
|
||||
BARNEY_DEAD
|
||||
BA_IDLE1,
|
||||
BA_IDLE2,
|
||||
BA_IDLE3,
|
||||
BA_IDLE4,
|
||||
BA_WALK,
|
||||
BA_RUN,
|
||||
BA_SHOOT1,
|
||||
BA_SHOOT2,
|
||||
BA_DRAW,
|
||||
BA_HOLSTER,
|
||||
BA_RELOAD,
|
||||
BA_TURNLEFT,
|
||||
BA_TURNRIGHT,
|
||||
BA_FLINCH_LA,
|
||||
BA_FLINCH_RA,
|
||||
BA_FLINCH_LL,
|
||||
BA_FLINCH_RL,
|
||||
BA_FLINCH_SML
|
||||
};
|
||||
|
||||
enum {
|
||||
BARNA_IDLE1,
|
||||
BARNA_IDLE2,
|
||||
BARNA_IDLE3,
|
||||
BARNA_IDLE4,
|
||||
BARNA_WALK,
|
||||
BARNA_RUN,
|
||||
BARNA_SHOOT1,
|
||||
BARNA_SHOOT2,
|
||||
BARNA_DRAW,
|
||||
BARNA_HOLSTER,
|
||||
BARNA_RELOAD,
|
||||
BARNA_TURNLEFT,
|
||||
BARNA_TURNRIGHT,
|
||||
BARNA_FLINCH_LA,
|
||||
BARNA_FLINCH_RA,
|
||||
BARNA_FLINCH_LL,
|
||||
BARNA_FLINCH_RL,
|
||||
BARNA_FLINCH_SML
|
||||
};
|
||||
|
||||
enumflags
|
||||
{
|
||||
BARNF_USED,
|
||||
BARNF_FEAR,
|
||||
BARNF_SEEN,
|
||||
BARNF_FALLING
|
||||
};
|
||||
|
||||
string barney_snddie[] = {
|
||||
string ba_snddie[] = {
|
||||
"barney/ba_die1.wav",
|
||||
"barney/ba_die1.wav",
|
||||
"barney/ba_die2.wav"
|
||||
};
|
||||
|
||||
string barney_sndpain[] = {
|
||||
string ba_sndpain[] = {
|
||||
"barney/ba_pain1.wav",
|
||||
"barney/ba_pain1.wav",
|
||||
"barney/ba_pain1.wav"
|
||||
|
@ -70,211 +55,50 @@ string barney_sndpain[] = {
|
|||
|
||||
class monster_barney:CBaseNPC
|
||||
{
|
||||
vector m_vecLastUserPos;
|
||||
entity m_eUser;
|
||||
entity m_eRescuer;
|
||||
|
||||
float m_flPainTime;
|
||||
float m_flChangePath;
|
||||
float m_flTraceTime;
|
||||
int m_iFlags;
|
||||
void() monster_barney;
|
||||
|
||||
virtual void() touch;
|
||||
virtual void() Hide;
|
||||
virtual void() Respawn;
|
||||
virtual void() PlayerUse;
|
||||
virtual void(int) Pain;
|
||||
virtual void(int) Death;
|
||||
virtual void() Physics;
|
||||
virtual void() WarnOthers;
|
||||
virtual int() AnimIdle;
|
||||
virtual int() AnimWalk;
|
||||
virtual int() AnimRun;
|
||||
};
|
||||
|
||||
void monster_barney::WarnOthers(void)
|
||||
int
|
||||
monster_barney::AnimIdle(void)
|
||||
{
|
||||
for (entity b = world; (b = find(b, ::classname, "monster_barney"));) {
|
||||
if (vlen(b.origin - origin) < 512) {
|
||||
monster_barney sci = (monster_barney)b;
|
||||
sci.m_iFlags |= BARNF_SEEN;
|
||||
sci.m_eUser = world;
|
||||
sci.m_eRescuer = world;
|
||||
}
|
||||
}
|
||||
return BA_IDLE1;
|
||||
}
|
||||
|
||||
void monster_barney::Physics(void)
|
||||
int
|
||||
monster_barney::AnimWalk(void)
|
||||
{
|
||||
float spvel;
|
||||
input_movevalues = [0,0,0];
|
||||
input_impulse = 0;
|
||||
input_buttons = 0;
|
||||
|
||||
if (style != BARNEY_DEAD) {
|
||||
if (!(m_iFlags & BARNF_SEEN)) {
|
||||
for (entity b = world; (b = find(b, ::classname, "player"));) {
|
||||
/* Find players in a 256 unit radius */
|
||||
if (vlen(b.origin - origin) < 256) {
|
||||
/* If we can't physically see him, don't say hi. */
|
||||
traceline(origin, b.origin, FALSE, this);
|
||||
if (trace_ent != b) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Sentence(m_talkPlayerGreet);
|
||||
m_iFlags |= BARNF_SEEN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Deal with a hostage being rescued when it's following someone else */
|
||||
if (m_eRescuer.classname == "monster_barney") {
|
||||
if (m_eRescuer.solid == SOLID_NOT) {
|
||||
m_eRescuer = m_eUser;
|
||||
}
|
||||
}
|
||||
/* Deal with the hostage losing its rescuer (death) */
|
||||
if (m_eUser.health <= 0) {
|
||||
m_eUser = world;
|
||||
}
|
||||
|
||||
if (m_eUser!= world) {
|
||||
v_angle = vectoangles(m_eRescuer.origin - origin);
|
||||
v_angle[0] = 0;
|
||||
v_angle[1] = Math_FixDelta(v_angle[1]);
|
||||
v_angle[2] = 0;
|
||||
|
||||
/* Give up after 1024 units */
|
||||
if (vlen(m_eRescuer.origin - origin) > 1024) {
|
||||
m_eUser = world;
|
||||
} else if (vlen(m_eRescuer.origin - origin) > 64) {
|
||||
input_movevalues[0] = 240;
|
||||
|
||||
other = world;
|
||||
traceline(origin, /*mins, maxs, */m_eRescuer.origin, MOVE_OTHERONLY, this);
|
||||
|
||||
/* Tracing failed, there's world geometry in the way */
|
||||
if (trace_fraction < 1.0f) {
|
||||
v_angle = vectoangles(m_vecLastUserPos - origin);
|
||||
v_angle[0] = 0;
|
||||
v_angle[1] = Math_FixDelta(v_angle[1]);
|
||||
v_angle[2] = 0;
|
||||
} else {
|
||||
m_vecLastUserPos = m_eRescuer.origin;
|
||||
}
|
||||
|
||||
/* Trace again to see if another hostage is in our path and if so
|
||||
* follow them instead, this makes pathing easier */
|
||||
traceline(origin, /*mins, maxs,*/ m_vecLastUserPos, FALSE, this);
|
||||
if (trace_ent.classname == "monster_barney") {
|
||||
monster_barney que = (monster_barney)trace_ent;
|
||||
if (que.m_eRescuer == m_eUser) {
|
||||
if (trace_ent != this) {
|
||||
m_eRescuer = trace_ent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (m_iFlags & BARNF_FEAR) {
|
||||
m_iFlags |= BARNF_SEEN;
|
||||
maxspeed = 240;
|
||||
input_movevalues = [maxspeed, 0, 0];
|
||||
|
||||
if (m_flTraceTime < time) {
|
||||
traceline(origin, origin + (v_forward * 64), FALSE, this);
|
||||
|
||||
if (trace_fraction < 1.0f) {
|
||||
m_flChangePath = 0.0f;
|
||||
}
|
||||
m_flTraceTime = time + 0.5f;
|
||||
}
|
||||
|
||||
if (m_flChangePath < time) {
|
||||
float add;
|
||||
vector pos;
|
||||
|
||||
pos = origin + [0,0,-18];
|
||||
if (random() < 0.5) {
|
||||
add = 45;
|
||||
} else {
|
||||
add = -45;
|
||||
}
|
||||
|
||||
/* test every 45 degrees */
|
||||
for (int i = 0; i < 8; i++) {
|
||||
v_angle[1] = Math_FixDelta(v_angle[1] + add);
|
||||
makevectors(v_angle);
|
||||
traceline(pos, pos + (v_forward * 64), FALSE, this);
|
||||
if (trace_fraction >= 1.0f) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_flChangePath = time + floor(random(2,10));
|
||||
}
|
||||
} else {
|
||||
//Sentence(m_talkPlayerIdle);
|
||||
}
|
||||
|
||||
if (m_flPainTime > time) {
|
||||
input_movevalues = [0,0,0];
|
||||
} else {
|
||||
spvel = vlen(velocity);
|
||||
|
||||
if (spvel < 5) {
|
||||
frame = BARNA_IDLE1;
|
||||
} else if (spvel <= 140) {
|
||||
frame = BARNA_WALK;
|
||||
} else if (spvel <= 240) {
|
||||
frame = BARNA_RUN;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
input_angles = angles = v_angle;
|
||||
input_timelength = frametime;
|
||||
|
||||
runstandardplayerphysics(this);
|
||||
Footsteps_Update();
|
||||
|
||||
if (!(flags & FL_ONGROUND) && velocity[2] < -100) {
|
||||
m_iFlags |= BARNF_FALLING;
|
||||
} else {
|
||||
m_iFlags -= (flags & BARNF_FALLING);
|
||||
}
|
||||
return BA_WALK;
|
||||
}
|
||||
|
||||
void monster_barney::touch(void)
|
||||
int
|
||||
monster_barney::AnimRun(void)
|
||||
{
|
||||
if (other.movetype == MOVETYPE_WALK) {
|
||||
velocity = normalize(other.origin - origin) * -128;
|
||||
}
|
||||
return BA_RUN;
|
||||
}
|
||||
|
||||
void monster_barney::PlayerUse(void)
|
||||
void
|
||||
monster_barney::PlayerUse(void)
|
||||
{
|
||||
if (m_iFlags & BARNF_FEAR) {
|
||||
if (spawnflags & MSF_PREDISASTER) {
|
||||
Sentence("!BA_POK");
|
||||
return;
|
||||
}
|
||||
if ((m_eUser == world)) {
|
||||
if (!(m_iFlags & BARNF_USED)) {
|
||||
m_iFlags |= BARNF_USED;
|
||||
}
|
||||
|
||||
Sentence(m_talkFollow);
|
||||
m_eUser = eActivator;
|
||||
m_eRescuer = m_eUser;
|
||||
m_vecLastUserPos = m_eUser.origin;
|
||||
} else {
|
||||
Sentence(m_talkUnfollow);
|
||||
m_eUser = world;
|
||||
}
|
||||
CBaseNPC::PlayerUse();
|
||||
}
|
||||
|
||||
void monster_barney::Pain(int iHitBody)
|
||||
void
|
||||
monster_barney::Pain(int iHitBody)
|
||||
{
|
||||
|
||||
WarnOthers();
|
||||
WarnAllies();
|
||||
|
||||
if (m_flPainTime > time) {
|
||||
return;
|
||||
|
@ -284,94 +108,56 @@ void monster_barney::Pain(int iHitBody)
|
|||
return;
|
||||
}
|
||||
|
||||
int rand = floor(random(0,barney_sndpain.length));
|
||||
Speak(barney_sndpain[rand]);
|
||||
|
||||
frame = BARNA_FLINCH_LA + floor(random(0, 5));
|
||||
m_iFlags |= BARNF_FEAR;
|
||||
int rand = floor(random(0,ba_sndpain.length));
|
||||
Speak(ba_sndpain[rand]);
|
||||
|
||||
frame = BA_FLINCH_LA + floor(random(0, 5));
|
||||
m_iFlags |= MONSTER_FEAR;
|
||||
m_flPainTime = time + 0.25f;
|
||||
}
|
||||
|
||||
void monster_barney::Death(int iHitBody)
|
||||
void
|
||||
monster_barney::Death(int iHitBody)
|
||||
{
|
||||
int r;
|
||||
r = floor(random(0,barney_snddie.length));
|
||||
Speak(barney_snddie[r]);
|
||||
CBaseNPC::Death(iHitBody);
|
||||
|
||||
WarnOthers();
|
||||
WarnAllies();
|
||||
|
||||
think = Respawn;
|
||||
nextthink = time + 10.0f;
|
||||
int r = floor(random(0,ba_snddie.length));
|
||||
Speak(ba_snddie[r]);
|
||||
|
||||
m_eUser = world;
|
||||
//customphysics = __NULL__;
|
||||
m_iFlags = 0x0;
|
||||
|
||||
if (health < -50) {
|
||||
Gib();
|
||||
return;
|
||||
}
|
||||
|
||||
flags &= ~FL_MONSTER;
|
||||
movetype = MOVETYPE_NONE;
|
||||
solid = SOLID_CORPSE;
|
||||
|
||||
if (style != BARNEY_DEAD) {
|
||||
if (style != MONSTER_DEAD) {
|
||||
frame = 25 + floor(random(0, 6));
|
||||
style = BARNEY_DEAD;
|
||||
style = MONSTER_DEAD;
|
||||
}
|
||||
}
|
||||
|
||||
void monster_barney::Hide(void)
|
||||
void
|
||||
monster_barney::Respawn(void)
|
||||
{
|
||||
setmodel(this, "");
|
||||
m_eUser = world;
|
||||
solid = SOLID_NOT;
|
||||
movetype = MOVETYPE_NONE;
|
||||
customphysics = __NULL__;
|
||||
CBaseNPC::Respawn();
|
||||
m_iFlags |= MONSTER_CANFOLLOW;
|
||||
}
|
||||
|
||||
void monster_barney::Respawn(void)
|
||||
void
|
||||
monster_barney::monster_barney(void)
|
||||
{
|
||||
v_angle[0] = Math_FixDelta(m_oldAngle[0]);
|
||||
v_angle[1] = Math_FixDelta(m_oldAngle[1]);
|
||||
v_angle[2] = Math_FixDelta(m_oldAngle[2]);
|
||||
|
||||
flags |= FL_MONSTER;
|
||||
setorigin(this, m_oldOrigin);
|
||||
angles = v_angle;
|
||||
solid = SOLID_SLIDEBOX;
|
||||
movetype = MOVETYPE_WALK;
|
||||
setmodel(this, m_oldModel);
|
||||
setsize(this, VEC_HULL_MIN + [0,0,36], VEC_HULL_MAX + [0,0,36]);
|
||||
m_eUser = world;
|
||||
takedamage = DAMAGE_YES;
|
||||
iBleeds = TRUE;
|
||||
style = BARNEY_IDLE;
|
||||
customphysics = Physics;
|
||||
frame = BARNA_IDLE1;
|
||||
SendFlags |= NPC_FRAME;
|
||||
health = 50;
|
||||
velocity = [0,0,0];
|
||||
m_iFlags = 0x0;
|
||||
SendFlags = 0xff;
|
||||
}
|
||||
|
||||
void monster_barney::monster_barney(void)
|
||||
{
|
||||
for (int i = 0; i < barney_sndpain.length; i++) {
|
||||
precache_sound(barney_sndpain[i]);
|
||||
for (int i = 0; i < ba_sndpain.length; i++) {
|
||||
precache_sound(ba_sndpain[i]);
|
||||
}
|
||||
for (int i = 0; i < barney_snddie.length; i++) {
|
||||
precache_sound(barney_snddie[i]);
|
||||
for (int i = 0; i < ba_snddie.length; i++) {
|
||||
precache_sound(ba_snddie[i]);
|
||||
}
|
||||
|
||||
/* TODO
|
||||
* BA_MAD - When player gets too naughty
|
||||
* */
|
||||
m_talkAnswer = "!BA_ANSWER";
|
||||
m_talkAsk = "";
|
||||
m_talkAllyShot = "!BA_SCARED";
|
||||
m_talkAsk = "!BA_QUESTION";
|
||||
m_talkAllyShot = "!BA_SHOOT";
|
||||
m_talkGreet = "";
|
||||
m_talkIdle = "";
|
||||
m_talkIdle = "!BA_IDLE";
|
||||
m_talkHearing = "!BA_HEAR";
|
||||
m_talkSmelling = "!BA_SMELL";
|
||||
m_talkStare = "!BA_STARE";
|
||||
m_talkSurvived = "!BA_WOUND";
|
||||
|
@ -389,7 +175,8 @@ void monster_barney::monster_barney(void)
|
|||
|
||||
model = "models/barney.mdl";
|
||||
netname = "Barney";
|
||||
CBaseEntity::CBaseEntity();
|
||||
precache_model(m_oldModel);
|
||||
Respawn();
|
||||
base_health = 50;
|
||||
base_mins = [-16,-16,0];
|
||||
base_maxs = [16,16,72];
|
||||
CBaseNPC::CBaseNPC();
|
||||
}
|
||||
|
|
|
@ -93,15 +93,35 @@ string bull_sndpain[] = {
|
|||
|
||||
class monster_bullchicken:CBaseMonster
|
||||
{
|
||||
float m_flIdleTime;
|
||||
float m_flPainTime;
|
||||
|
||||
void() monster_bullchicken;
|
||||
|
||||
virtual void(int) Death;
|
||||
virtual void(int) Pain;
|
||||
virtual void(void) IdleNoise;
|
||||
virtual void(void) Respawn;
|
||||
};
|
||||
|
||||
void
|
||||
monster_bullchicken::IdleNoise(void)
|
||||
{
|
||||
/* don't make noise if we're dead (corpse) */
|
||||
if (style == MONSTER_DEAD) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_flIdleTime > time) {
|
||||
return;
|
||||
}
|
||||
/* timing needs to adjusted as sounds conflict */
|
||||
m_flIdleTime = time + 2.0f + random(0,5);
|
||||
|
||||
int rand = floor(random(0, bull_sndidle.length));
|
||||
Sound(bull_sndidle[rand]);
|
||||
}
|
||||
|
||||
void
|
||||
monster_bullchicken::Pain(int iHitBody)
|
||||
{
|
||||
|
|
|
@ -45,15 +45,155 @@ enum {
|
|||
GARG_BUST
|
||||
};
|
||||
|
||||
/* Flame thrower sounds
|
||||
* gar_flameoff1
|
||||
* gar_flameon1
|
||||
* gar_flamerun1 */
|
||||
|
||||
/* similar to bullsquid, groans during and after attacks */
|
||||
|
||||
string garg_sndattack[] = {
|
||||
"garg/gar_attack1.wav",
|
||||
"garg/gar_attack2.wav",
|
||||
"garg/gar_attack3.wav"
|
||||
};
|
||||
|
||||
string garg_sndalert[] = {
|
||||
"garg/gar_alert1.wav",
|
||||
"garg/gar_alert2.wav",
|
||||
"garg/gar_alert3.wav"
|
||||
};
|
||||
|
||||
string garg_snddie[] = {
|
||||
"garg/gar_die1.wav",
|
||||
"garg/gar_die2.wav"
|
||||
};
|
||||
|
||||
string garg_sndidle[] = {
|
||||
"garg/gar_idle1.wav",
|
||||
"garg/gar_idle2.wav",
|
||||
"garg/gar_idle3.wav",
|
||||
"garg/gar_idle4.wav",
|
||||
"garg/gar_idle5.wav",
|
||||
"garg/gar_breathe1.wav",
|
||||
"garg/gar_breathe2.wav",
|
||||
"garg/gar_breathe3.wav"
|
||||
};
|
||||
|
||||
/* has unique foot step sounds */
|
||||
string garg_sndstep[] = {
|
||||
"garg/gar_step1.wav",
|
||||
"garg/gar_step2.wav"
|
||||
};
|
||||
|
||||
string garg_sndpain[] = {
|
||||
"garg/gar_pain1.wav",
|
||||
"garg/gar_pain2.wav",
|
||||
"garg/gar_pain3.wav"
|
||||
};
|
||||
|
||||
|
||||
class monster_gargantua:CBaseMonster
|
||||
{
|
||||
float m_flIdleTime;
|
||||
float m_flPainTime;
|
||||
|
||||
void() monster_gargantua;
|
||||
|
||||
virtual void(int) Death;
|
||||
virtual void(int) Pain;
|
||||
virtual void(void) IdleNoise;
|
||||
virtual void(void) Respawn;
|
||||
};
|
||||
|
||||
void
|
||||
monster_gargantua::IdleNoise(void)
|
||||
{
|
||||
/* don't make noise if we're dead (corpse) */
|
||||
if (style == MONSTER_DEAD) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_flIdleTime > time) {
|
||||
return;
|
||||
}
|
||||
/* timing needs to adjusted as sounds conflict */
|
||||
m_flIdleTime = time + 2.0f + random(0,5);
|
||||
|
||||
int rand = floor(random(0, garg_sndidle.length));
|
||||
Sound(garg_sndidle[rand]);
|
||||
}
|
||||
|
||||
void
|
||||
monster_gargantua::Pain(int iHitBody)
|
||||
{
|
||||
CBaseMonster::Pain(iHitBody);
|
||||
|
||||
if (m_flPainTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (random() < 0.25f) {
|
||||
return;
|
||||
}
|
||||
|
||||
int rand = floor(random(0,garg_sndpain.length));
|
||||
Sound(garg_sndpain[rand]);
|
||||
frame = (random() < 0.5) ? GARG_FLINCH : GARG_FLINCH2;
|
||||
m_flPainTime = time + 0.25f;
|
||||
}
|
||||
|
||||
void
|
||||
monster_gargantua::Death(int iHitBody)
|
||||
{
|
||||
/* if we're already dead (corpse) don't change animations */
|
||||
if (style != MONSTER_DEAD) {
|
||||
|
||||
frame = GARG_DIE;
|
||||
|
||||
/* the sound */
|
||||
int rand = floor(random(0,garg_snddie.length));
|
||||
Sound(garg_snddie[rand]);
|
||||
}
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseMonster::Death(iHitBody);
|
||||
}
|
||||
|
||||
void
|
||||
monster_gargantua::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
frame = GARG_IDLE;
|
||||
/* takes damage from explosives only
|
||||
* takedamage = DAMAGE_NO; */
|
||||
iBleeds = FALSE;
|
||||
}
|
||||
|
||||
void monster_gargantua::monster_gargantua(void)
|
||||
{
|
||||
for (int i = 0; i <garg_sndalert.length; i++) {
|
||||
precache_sound(garg_sndattack[i]);
|
||||
}
|
||||
for (int i = 0; i <garg_sndattack.length; i++) {
|
||||
precache_sound(garg_sndattack[i]);
|
||||
}
|
||||
for (int i = 0; i < garg_snddie.length; i++) {
|
||||
precache_sound(garg_snddie[i]);
|
||||
}
|
||||
for (int i = 0; i < garg_sndidle.length; i++) {
|
||||
precache_sound(garg_sndidle[i]);
|
||||
}
|
||||
for (int i = 0; i < garg_sndpain.length; i++) {
|
||||
precache_sound(garg_sndpain[i]);
|
||||
}
|
||||
for (int i = 0; i < garg_sndstep.length; i++) {
|
||||
precache_sound(garg_sndstep[i]);
|
||||
}
|
||||
|
||||
netname = "Gargantua";
|
||||
model = "models/garg.mdl";
|
||||
base_health = Skill_GetValue("gargantua_health");
|
||||
base_mins = [-32,-32,0];
|
||||
base_maxs = [32,32,128];
|
||||
CBaseMonster::CBaseMonster();
|
||||
|
|
|
@ -32,7 +32,7 @@ enum {
|
|||
GR_LEFTARMFLINCH,
|
||||
GR_LAUNCHNADE,
|
||||
GR_THROWNADE,
|
||||
GR_IDLE1,
|
||||
GR_IDLE,
|
||||
GR_IDLE2,
|
||||
GR_COMBATIDLE,
|
||||
GR_FRONTKICK,
|
||||
|
@ -122,13 +122,133 @@ string gr_sndpain[] = {
|
|||
"hgrunt/gr_pain5.wav"
|
||||
};
|
||||
|
||||
class monster_human_grunt:CBaseMonster
|
||||
class monster_human_grunt:CBaseNPC
|
||||
{
|
||||
float m_flIdleTime;
|
||||
float m_flPainTime;
|
||||
|
||||
void() monster_human_grunt;
|
||||
|
||||
virtual void() Scream;
|
||||
virtual void() IdleChat;
|
||||
virtual void() Respawn;
|
||||
virtual void(int) Pain;
|
||||
virtual void(int) Death;
|
||||
|
||||
};
|
||||
|
||||
void monster_human_grunt::Scream(void)
|
||||
{
|
||||
if (m_flIdleTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sentence(m_talkAllyShot);
|
||||
m_flIdleTime = time + 5.0f;
|
||||
}
|
||||
|
||||
void monster_human_grunt::IdleChat(void)
|
||||
{
|
||||
if (m_flIdleTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sentence(m_talkIdle);
|
||||
|
||||
/* Sentence(m_talkPlayerIdle); */
|
||||
/* come up with logic to make them repsone to questions
|
||||
* Sentence(m_talkAsk);
|
||||
* Sentence(m_talkAnswer);
|
||||
*/
|
||||
m_flIdleTime = time + 5.0f + random(0,20);
|
||||
}
|
||||
|
||||
void
|
||||
monster_human_grunt::Pain(int iHitBody)
|
||||
{
|
||||
CBaseMonster::Pain(iHitBody);
|
||||
|
||||
if (m_flPainTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (random() < 0.25f) {
|
||||
return;
|
||||
}
|
||||
|
||||
int rand = floor(random(0,gr_sndpain.length));
|
||||
Sound(gr_sndpain[rand]);
|
||||
frame = GR_FLINCH;
|
||||
m_flPainTime = time + 0.25f;
|
||||
}
|
||||
|
||||
void
|
||||
monster_human_grunt::Death(int iHitBody)
|
||||
{
|
||||
/* if we're already dead (corpse) don't change animations */
|
||||
if (style != MONSTER_DEAD) {
|
||||
/* headshots == different animation */
|
||||
/* this animation may not have been used, but it looks cool */
|
||||
if (iHitBody == BODY_HEAD) {
|
||||
if (random() < 0.5) {
|
||||
frame = GR_DIEHS;
|
||||
} else {
|
||||
frame = GR_DIEBACK;
|
||||
}
|
||||
} else {
|
||||
frame = GR_DIE;
|
||||
}
|
||||
}
|
||||
|
||||
/* set the functional differences */
|
||||
CBaseMonster::Death(iHitBody);
|
||||
}
|
||||
|
||||
void
|
||||
monster_human_grunt::Respawn(void)
|
||||
{
|
||||
CBaseMonster::Respawn();
|
||||
frame = GR_IDLE;
|
||||
}
|
||||
|
||||
|
||||
void monster_human_grunt::monster_human_grunt(void)
|
||||
{
|
||||
for (int i = 0; i < gr_sndpain.length; i++) {
|
||||
precache_sound(gr_sndpain[i]);
|
||||
}
|
||||
for (int i = 0; i < gr_snddie.length; i++) {
|
||||
precache_sound(gr_snddie[i]);
|
||||
}
|
||||
|
||||
/* Adding some into other slots in hopes it feels right
|
||||
* listed below are other setences that might need their own:
|
||||
* !HG_MONST - Monster HG_ALERT
|
||||
* !HG_GREN - Grenade toss
|
||||
* !HG_CHECK - Sector check question
|
||||
* !HG_CLEAR - Sector clear response */
|
||||
|
||||
m_talkAnswer = "!HG_ANSWER";
|
||||
m_talkAsk = "!HG_QUEST";
|
||||
m_talkAllyShot = "!HG_COVER";
|
||||
m_talkGreet = "";
|
||||
m_talkIdle = "!HG_IDLE";
|
||||
m_talkSmelling = "";
|
||||
m_talkStare = "";
|
||||
m_talkSurvived = "!HG_CLEAR";
|
||||
m_talkWounded = "!HG_CHECK";
|
||||
|
||||
m_talkPlayerAsk = "";
|
||||
m_talkPlayerGreet = "!HG_ALERT";
|
||||
m_talkPlayerIdle = "!HG_CHARGE";
|
||||
m_talkPlayerWounded1 = "";
|
||||
m_talkPlayerWounded2 = "";
|
||||
m_talkPlayerWounded3 = "";
|
||||
m_talkUnfollow = "";
|
||||
m_talkFollow = "";
|
||||
m_talkStopFollow = "";
|
||||
|
||||
|
||||
netname = "Grunt";
|
||||
model = "models/hgrunt.mdl";
|
||||
base_health = Skill_GetValue("hgrunt_health");
|
||||
|
|
|
@ -20,13 +20,6 @@ Scientist
|
|||
|
||||
*/
|
||||
|
||||
enum {
|
||||
MONSTER_IDLE,
|
||||
MONSTER_WALK,
|
||||
MONSTER_RUN,
|
||||
MONSTER_DEAD
|
||||
};
|
||||
|
||||
enum {
|
||||
SCIA_WALK,
|
||||
SCIA_WALKSCARED,
|
||||
|
@ -73,15 +66,6 @@ enum {
|
|||
SCIA_DEADTABLE3
|
||||
};
|
||||
|
||||
enumflags
|
||||
{
|
||||
SCIF_USED,
|
||||
SCIF_SCARED,
|
||||
SCIF_FEAR,
|
||||
SCIF_SEEN,
|
||||
SCIF_FALLING
|
||||
};
|
||||
|
||||
string sci_snddie[] = {
|
||||
"scientist/sci_die1.wav",
|
||||
"scientist/sci_die2.wav",
|
||||
|
@ -89,110 +73,6 @@ string sci_snddie[] = {
|
|||
"scientist/sci_die4.wav"
|
||||
};
|
||||
|
||||
/* chat and idle sounds are handled via sentences.txt
|
||||
* this should be deleted and redone at some point
|
||||
*/
|
||||
|
||||
string sci_sndchitchat[] = {
|
||||
"scientist/absolutely.wav",
|
||||
"scientist/absolutelynot.wav",
|
||||
"scientist/administrator.wav",
|
||||
"scientist/alienappeal.wav",
|
||||
"scientist/alientrick.wav",
|
||||
"scientist/allnominal.wav",
|
||||
"scientist/areyouthink.wav",
|
||||
"scientist/asexpected.wav",
|
||||
"scientist/beverage.wav",
|
||||
"scientist/bloodsample.wav",
|
||||
"scientist/cantbeserious.wav",
|
||||
"scientist/chaostheory.wav",
|
||||
"scientist/completelywrong.wav",
|
||||
"scientist/containfail.wav",
|
||||
"scientist/correcttheory.wav",
|
||||
"scientist/dine.wav",
|
||||
"scientist/dontknow.wav",
|
||||
"scientist/donuteater.wav",
|
||||
"scientist/doyousmell.wav",
|
||||
"scientist/evergetout.wav",
|
||||
"scientist/everseen.wav",
|
||||
"scientist/fascinating.wav",
|
||||
"scientist/goodpaper.wav",
|
||||
"scientist/headcrab.wav",
|
||||
"scientist/hideglasses.wav",
|
||||
"scientist/hopenominal.wav",
|
||||
"scientist/howinteresting.wav",
|
||||
"scientist/hungryyet.wav",
|
||||
"scientist/ibelieveso.wav",
|
||||
"scientist/idontthinkso.wav",
|
||||
"scientist/importantspecies.wav",
|
||||
"scientist/improbable.wav",
|
||||
"scientist/imsure.wav",
|
||||
"scientist/inconclusive.wav",
|
||||
"scientist/ipredictedthis.wav",
|
||||
"scientist/justasked.wav",
|
||||
"scientist/lambdalab.wav",
|
||||
"scientist/limitsok.wav",
|
||||
"scientist/lowervoice.wav",
|
||||
"scientist/luckwillchange.wav",
|
||||
"scientist/needsleep.wav",
|
||||
"scientist/neverseen.wav",
|
||||
"scientist/nodoubt.wav",
|
||||
"scientist/nogrant.wav",
|
||||
"scientist/noguess.wav",
|
||||
"scientist/noidea.wav",
|
||||
"scientist/noo.wav",
|
||||
"scientist/notcertain.wav",
|
||||
"scientist/nothostile.wav",
|
||||
"scientist/notsure.wav",
|
||||
"scientist/ofcourse.wav",
|
||||
"scientist/ofcoursenot.wav",
|
||||
"scientist/organicmatter.wav",
|
||||
"scientist/perculiarmarks.wav",
|
||||
"scientist/perculiarodor.wav",
|
||||
"scientist/perhaps.wav",
|
||||
"scientist/positively.wav",
|
||||
"scientist/repeat.wav",
|
||||
"scientist/reportflux.wav",
|
||||
"scientist/rescueus.wav",
|
||||
"scientist/ridiculous.wav",
|
||||
"scientist/right.wav",
|
||||
"scientist/rightway.wav",
|
||||
"scientist/rumorclean.wav",
|
||||
"scientist/runtest.wav",
|
||||
"scientist/seencup.wav",
|
||||
"scientist/shakeunification.wav",
|
||||
"scientist/shutdownchart.wav",
|
||||
"scientist/shutup.wav",
|
||||
"scientist/simulation.wav",
|
||||
"scientist/smellburning.wav",
|
||||
"scientist/softethics.wav",
|
||||
"scientist/stimulating.wav",
|
||||
"scientist/stopasking.wav",
|
||||
"scientist/thatsodd.wav",
|
||||
"scientist/theoretically.wav",
|
||||
"scientist/uselessphd.wav",
|
||||
"scientist/waithere.wav",
|
||||
"scientist/whatnext.wav",
|
||||
"scientist/whocansay.wav",
|
||||
"scientist/whoresponsible.wav",
|
||||
"scientist/whyaskme.wav",
|
||||
"scientist/yees.wav"
|
||||
};
|
||||
|
||||
string sci_sndhear[] = {
|
||||
"scientist/hearsomething.wav",
|
||||
"scientist/startle1.wav",
|
||||
"scientist/startle2.wav",
|
||||
"scientist/startle3.wav",
|
||||
"scientist/startle4.wav",
|
||||
"scientist/startle5.wav",
|
||||
"scientist/startle6.wav",
|
||||
"scientist/startle7.wav",
|
||||
"scientist/startle8.wav",
|
||||
"scientist/startle9.wav",
|
||||
"scientist/whatissound.wav"
|
||||
};
|
||||
|
||||
string sci_sndpain[] = {
|
||||
"scientist/sci_pain1.wav",
|
||||
"scientist/sci_pain2.wav",
|
||||
|
@ -206,359 +86,52 @@ string sci_sndpain[] = {
|
|||
"scientist/sci_pain10.wav"
|
||||
};
|
||||
|
||||
string sci_sndsee[] = {
|
||||
"scientist/afellowsci.wav",
|
||||
"scientist/ahfreeman.wav",
|
||||
"scientist/freeman.wav",
|
||||
"scientist/freemanalive.wav",
|
||||
"scientist/goodtoseeyou.wav",
|
||||
"scientist/greetings.wav",
|
||||
"scientist/greetings2.wav",
|
||||
"scientist/hello.wav",
|
||||
"scientist/hellofreeman.wav",
|
||||
"scientist/hellofromlab.wav",
|
||||
"scientist/hellothere.wav",
|
||||
"scientist/inmesstoo.wav",
|
||||
"scientist/newhevsuit.wav"
|
||||
};
|
||||
|
||||
string sci_sndscream[] = {
|
||||
"scientist/scream1.wav",
|
||||
"scientist/scream2.wav",
|
||||
"scientist/scream3.wav",
|
||||
"scientist/scream4.wav",
|
||||
"scientist/dontwantdie.wav",
|
||||
"scientist/scream5.wav",
|
||||
"scientist/scream6.wav",
|
||||
"scientist/scream7.wav",
|
||||
"scientist/evergetout.wav",
|
||||
//"scientist/scream8.wav",
|
||||
//"scientist/scream9.wav",
|
||||
"scientist/scream10.wav",
|
||||
"scientist/scream11.wav",
|
||||
"scientist/getoutalive.wav",
|
||||
"scientist/scream12.wav",
|
||||
"scientist/scream13.wav",
|
||||
"scientist/scream14.wav",
|
||||
"scientist/scream15.wav",
|
||||
"scientist/scream16.wav",
|
||||
"scientist/getoutofhere.wav",
|
||||
"scientist/scream17.wav",
|
||||
"scientist/scream18.wav",
|
||||
"scientist/scream19.wav",
|
||||
"scientist/gottogetout.wav",
|
||||
"scientist/scream20.wav",
|
||||
"scientist/scream21.wav",
|
||||
"scientist/scream22.wav",
|
||||
"scientist/youinsane.wav",
|
||||
"scientist/scream23.wav",
|
||||
"scientist/scream24.wav",
|
||||
"scientist/scream25.wav",
|
||||
"scientist/whatyoudoing.wav",
|
||||
"scientist/canttakemore.wav",
|
||||
"scientist/madness.wav",
|
||||
"scientist/noplease.wav",
|
||||
"scientist/getoutofhere.wav",
|
||||
"scientist/sorryimleaving.wav",
|
||||
};
|
||||
|
||||
string sci_sndstop[] = {
|
||||
"scientist/stop1.wav",
|
||||
"scientist/stop2.wav",
|
||||
"scientist/stop3.wav",
|
||||
"scientist/stop4.wav",
|
||||
"scientist/sorryimleaving.wav"
|
||||
};
|
||||
|
||||
string sci_snduse[] = {
|
||||
"scientist/alright.wav",
|
||||
"scientist/excellentteam.wav",
|
||||
"scientist/fellowscientist.wav",
|
||||
"scientist/fine.wav",
|
||||
"scientist/hopeyouknow.wav",
|
||||
"scientist/leadtheway.wav",
|
||||
"scientist/letsgo.wav",
|
||||
"scientist/yes3.wav",
|
||||
"scientist/yesletsgo.wav"
|
||||
};
|
||||
|
||||
string sci_snduseno[] = {
|
||||
"scientist/beenaburden.wav",
|
||||
"scientist/illwait.wav",
|
||||
"scientist/illwaithere.wav",
|
||||
"scientist/istay.wav",
|
||||
"scientist/reconsider.wav",
|
||||
"scientist/slowingyou.wav",
|
||||
"scientist/whyleavehere.wav"
|
||||
};
|
||||
|
||||
string sci_sndidle[] = {
|
||||
"scientist/hideglasses.wav",
|
||||
"scientist/weartie.wav",
|
||||
"scientist/runtest.wav",
|
||||
"scientist/limitsok.wav",
|
||||
"scientist/asexpected.wav",
|
||||
"scientist/thatsodd.wav",
|
||||
"scientist/allnominal.wav",
|
||||
"scientist/shutdownchart.wav",
|
||||
"scientist/reportflux.wav",
|
||||
"scientist/simulation.wav",
|
||||
"scientist/hopenominal.wav",
|
||||
};
|
||||
|
||||
class monster_scientist:CBaseNPC
|
||||
{
|
||||
vector m_vecLastUserPos;
|
||||
entity m_eUser;
|
||||
entity m_eRescuer;
|
||||
|
||||
float m_flScaredTime;
|
||||
float m_flScreamTime;
|
||||
float m_flPainTime;
|
||||
float m_flChangePath;
|
||||
float m_flTraceTime;
|
||||
int m_iFlags;
|
||||
void() monster_scientist;
|
||||
|
||||
virtual void() touch;
|
||||
virtual void() Hide;
|
||||
virtual void() Respawn;
|
||||
virtual void() PlayerUse;
|
||||
virtual void(int) Pain;
|
||||
virtual void(int) Death;
|
||||
virtual void() Physics;
|
||||
virtual void() Scream;
|
||||
virtual void() WarnOthers;
|
||||
virtual void() IdleChat;
|
||||
virtual int() AnimIdle;
|
||||
virtual int() AnimWalk;
|
||||
virtual int() AnimRun;
|
||||
};
|
||||
|
||||
void monster_scientist::WarnOthers(void)
|
||||
int
|
||||
monster_scientist::AnimIdle(void)
|
||||
{
|
||||
for (entity b = world; (b = find(b, ::classname, "monster_scientist"));) {
|
||||
if (vlen(b.origin - origin) < 512) {
|
||||
monster_scientist sci = (monster_scientist)b;
|
||||
sci.m_iFlags |= SCIF_SCARED | SCIF_FEAR | SCIF_SEEN;
|
||||
sci.m_eUser = world;
|
||||
sci.m_eRescuer = world;
|
||||
sci.m_flScaredTime = time + 2.5f;
|
||||
sci.Scream();
|
||||
}
|
||||
}
|
||||
return SCIA_IDLE1;
|
||||
}
|
||||
|
||||
void monster_scientist::Scream(void)
|
||||
int
|
||||
monster_scientist::AnimWalk(void)
|
||||
{
|
||||
if (m_flScreamTime > time) {
|
||||
return SCIA_WALK;
|
||||
}
|
||||
|
||||
int
|
||||
monster_scientist::AnimRun(void)
|
||||
{
|
||||
return SCIA_RUN;
|
||||
}
|
||||
|
||||
void
|
||||
monster_scientist::PlayerUse(void)
|
||||
{
|
||||
if (spawnflags & MSF_PREDISASTER) {
|
||||
Sentence("!SC_POK");
|
||||
return;
|
||||
}
|
||||
|
||||
int rand = floor(random(0,sci_sndscream.length));
|
||||
Speak(sci_sndscream[rand]);
|
||||
m_flScreamTime = time + 5.0f;
|
||||
CBaseNPC::PlayerUse();
|
||||
}
|
||||
|
||||
void monster_scientist::IdleChat(void)
|
||||
void
|
||||
monster_scientist::Pain(int iHitBody)
|
||||
{
|
||||
if (m_flScreamTime > time) {
|
||||
return;
|
||||
}
|
||||
|
||||
int rand = floor(random(0,sci_sndchitchat.length));
|
||||
Speak(sci_sndchitchat[rand]);
|
||||
m_flScreamTime = time + 5.0f + random(0,20);
|
||||
}
|
||||
|
||||
void monster_scientist::Physics(void)
|
||||
{
|
||||
float spvel;
|
||||
input_movevalues = [0,0,0];
|
||||
input_impulse = 0;
|
||||
input_buttons = 0;
|
||||
|
||||
if (style != MONSTER_DEAD) {
|
||||
if (!(m_iFlags & SCIF_SEEN)) {
|
||||
for (entity b = world; (b = find(b, ::classname, "player"));) {
|
||||
/* Find players in a 256 unit radius */
|
||||
if (vlen(b.origin - origin) < 256) {
|
||||
/* If we can't physically see him, don't say hi. */
|
||||
traceline(origin, b.origin, FALSE, this);
|
||||
if (trace_ent != b) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (random() < 0.5) {
|
||||
int rand = floor(random(0,sci_sndsee.length));
|
||||
Speak(sci_sndsee[rand]);
|
||||
}
|
||||
|
||||
m_iFlags |= SCIF_SEEN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Deal with a hostage being rescued when it's following someone else */
|
||||
if (m_eRescuer.classname == "monster_scientist") {
|
||||
if (m_eRescuer.solid == SOLID_NOT) {
|
||||
m_eRescuer = m_eUser;
|
||||
}
|
||||
}
|
||||
/* Deal with the hostage losing its rescuer (death) */
|
||||
if (m_eUser.health <= 0) {
|
||||
m_eUser = world;
|
||||
}
|
||||
|
||||
if (m_eUser!= world) {
|
||||
v_angle = vectoangles(m_eRescuer.origin - origin);
|
||||
v_angle[0] = 0;
|
||||
v_angle[1] = Math_FixDelta(v_angle[1]);
|
||||
v_angle[2] = 0;
|
||||
|
||||
/* Give up after 1024 units */
|
||||
if (vlen(m_eRescuer.origin - origin) > 1024) {
|
||||
m_eUser = world;
|
||||
} else if (vlen(m_eRescuer.origin - origin) > 64) {
|
||||
input_movevalues[0] = 240;
|
||||
|
||||
other = world;
|
||||
traceline(origin, /*mins, maxs, */m_eRescuer.origin, MOVE_OTHERONLY, this);
|
||||
|
||||
/* Tracing failed, there's world geometry in the way */
|
||||
if (trace_fraction < 1.0f) {
|
||||
v_angle = vectoangles(m_vecLastUserPos - origin);
|
||||
v_angle[0] = 0;
|
||||
v_angle[1] = Math_FixDelta(v_angle[1]);
|
||||
v_angle[2] = 0;
|
||||
} else {
|
||||
m_vecLastUserPos = m_eRescuer.origin;
|
||||
}
|
||||
|
||||
/* Trace again to see if another hostage is in our path and if so
|
||||
* follow them instead, this makes pathing easier */
|
||||
traceline(origin, /*mins, maxs,*/ m_vecLastUserPos, FALSE, this);
|
||||
if (trace_ent.classname == "monster_scientist") {
|
||||
monster_scientist que = (monster_scientist)trace_ent;
|
||||
if (que.m_eRescuer == m_eUser) {
|
||||
if (trace_ent != this) {
|
||||
m_eRescuer = trace_ent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (m_iFlags & SCIF_FEAR) {
|
||||
m_iFlags |= SCIF_SEEN;
|
||||
Scream();
|
||||
maxspeed = 240;
|
||||
input_movevalues = [maxspeed, 0, 0];
|
||||
|
||||
if (m_flTraceTime < time) {
|
||||
traceline(origin, origin + (v_forward * 64), FALSE, this);
|
||||
|
||||
if (trace_fraction < 1.0f) {
|
||||
m_flChangePath = 0.0f;
|
||||
}
|
||||
m_flTraceTime = time + 0.5f;
|
||||
}
|
||||
|
||||
if (m_flChangePath < time) {
|
||||
float add;
|
||||
vector pos;
|
||||
|
||||
pos = origin + [0,0,-18];
|
||||
if (random() < 0.5) {
|
||||
add = 45;
|
||||
} else {
|
||||
add = -45;
|
||||
}
|
||||
|
||||
/* test every 45 degrees */
|
||||
for (int i = 0; i < 8; i++) {
|
||||
v_angle[1] = Math_FixDelta(v_angle[1] + add);
|
||||
makevectors(v_angle);
|
||||
traceline(pos, pos + (v_forward * 64), FALSE, this);
|
||||
if (trace_fraction >= 1.0f) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_flChangePath = time + floor(random(2,10));
|
||||
}
|
||||
} else {
|
||||
IdleChat();
|
||||
}
|
||||
|
||||
if (m_flScaredTime < time && m_iFlags & SCIF_SCARED) {
|
||||
m_iFlags &= ~SCIF_SCARED;
|
||||
}
|
||||
|
||||
if (m_flPainTime > time) {
|
||||
input_movevalues = [0,0,0];
|
||||
} else {
|
||||
spvel = vlen(velocity);
|
||||
|
||||
if (spvel < 5) {
|
||||
frame = (m_iFlags & SCIF_SCARED) ? SCIA_SCARED1:SCIA_IDLE1;
|
||||
} else if (spvel <= 140) {
|
||||
frame = (m_iFlags & SCIF_SCARED) ? SCIA_WALKSCARED:SCIA_WALK;
|
||||
} else if (spvel <= 240) {
|
||||
frame = (m_iFlags & SCIF_SCARED) ? SCIA_RUNSCARED:SCIA_RUN;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
input_angles = angles = v_angle;
|
||||
input_timelength = frametime;
|
||||
|
||||
runstandardplayerphysics(this);
|
||||
Footsteps_Update();
|
||||
|
||||
if (!(flags & FL_ONGROUND) && velocity[2] < -100) {
|
||||
if (!(m_iFlags & SCIF_FALLING)) {
|
||||
Speak(sci_sndscream[0]);
|
||||
}
|
||||
m_iFlags |= SCIF_FALLING;
|
||||
} else {
|
||||
m_iFlags -= (flags & SCIF_FALLING);
|
||||
}
|
||||
}
|
||||
|
||||
void monster_scientist::touch(void)
|
||||
{
|
||||
if (other.movetype == MOVETYPE_WALK) {
|
||||
velocity = normalize(other.origin - origin) * -128;
|
||||
}
|
||||
}
|
||||
|
||||
void monster_scientist::PlayerUse(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (m_iFlags & SCIF_FEAR) {
|
||||
return;
|
||||
}
|
||||
if ((m_eUser == world)) {
|
||||
if (!(m_iFlags & SCIF_USED)) {
|
||||
m_iFlags |= SCIF_USED;
|
||||
}
|
||||
|
||||
r = floor(random(0,sci_snduse.length));
|
||||
Speak(sci_snduse[r]);
|
||||
|
||||
m_eUser = eActivator;
|
||||
m_eRescuer = m_eUser;
|
||||
m_vecLastUserPos = m_eUser.origin;
|
||||
} else {
|
||||
r = floor(random(0,sci_snduseno.length));
|
||||
Speak(sci_snduseno[r]);
|
||||
|
||||
m_eUser = world;
|
||||
}
|
||||
}
|
||||
|
||||
void monster_scientist::Pain(int iHitBody)
|
||||
{
|
||||
|
||||
WarnOthers();
|
||||
WarnAllies();
|
||||
|
||||
if (m_flPainTime > time) {
|
||||
return;
|
||||
|
@ -571,79 +144,36 @@ void monster_scientist::Pain(int iHitBody)
|
|||
int rand = floor(random(0,sci_sndpain.length));
|
||||
Speak(sci_sndpain[rand]);
|
||||
|
||||
frame = SCIA_FLINCH + floor(random(0, 5));
|
||||
m_iFlags |= SCIF_FEAR;
|
||||
|
||||
frame = SCIA_FLINCH + floor(random(0, 6));
|
||||
m_iFlags |= MONSTER_FEAR;
|
||||
m_flPainTime = time + 0.25f;
|
||||
}
|
||||
|
||||
void monster_scientist::Death(int iHitBody)
|
||||
void
|
||||
monster_scientist::Death(int iHitBody)
|
||||
{
|
||||
int r;
|
||||
r = floor(random(0,sci_snddie.length));
|
||||
CBaseNPC::Death(iHitBody);
|
||||
|
||||
WarnAllies();
|
||||
|
||||
int r = floor(random(0,sci_snddie.length));
|
||||
Speak(sci_snddie[r]);
|
||||
|
||||
WarnOthers();
|
||||
|
||||
think = Respawn;
|
||||
nextthink = time + 10.0f;
|
||||
|
||||
m_eUser = world;
|
||||
//customphysics = __NULL__;
|
||||
m_iFlags = 0x0;
|
||||
|
||||
if (health < -50) {
|
||||
Gib();
|
||||
return;
|
||||
}
|
||||
|
||||
flags &= ~FL_MONSTER;
|
||||
movetype = MOVETYPE_NONE;
|
||||
solid = SOLID_CORPSE;
|
||||
//takedamage = DAMAGE_NO;
|
||||
|
||||
if (style != MONSTER_DEAD) {
|
||||
frame = SCIA_DIE_SIMPLE + floor(random(0, 6));
|
||||
style = MONSTER_DEAD;
|
||||
}
|
||||
}
|
||||
|
||||
void monster_scientist::Hide(void)
|
||||
void
|
||||
monster_scientist::Respawn(void)
|
||||
{
|
||||
setmodel(this, "");
|
||||
m_eUser = world;
|
||||
solid = SOLID_NOT;
|
||||
movetype = MOVETYPE_NONE;
|
||||
customphysics = __NULL__;
|
||||
CBaseNPC::Respawn();
|
||||
m_iFlags |= MONSTER_CANFOLLOW;
|
||||
}
|
||||
|
||||
void monster_scientist::Respawn(void)
|
||||
{
|
||||
v_angle[0] = Math_FixDelta(m_oldAngle[0]);
|
||||
v_angle[1] = Math_FixDelta(m_oldAngle[1]);
|
||||
v_angle[2] = Math_FixDelta(m_oldAngle[2]);
|
||||
|
||||
flags |= FL_MONSTER;
|
||||
setorigin(this, m_oldOrigin);
|
||||
angles = v_angle;
|
||||
solid = SOLID_SLIDEBOX;
|
||||
movetype = MOVETYPE_WALK;
|
||||
setmodel(this, m_oldModel);
|
||||
setsize(this, VEC_HULL_MIN + [0,0,36], VEC_HULL_MAX + [0,0,36]);
|
||||
m_eUser = world;
|
||||
takedamage = DAMAGE_YES;
|
||||
iBleeds = TRUE;
|
||||
style = MONSTER_IDLE;
|
||||
customphysics = Physics;
|
||||
frame = SCIA_IDLE1;
|
||||
SendFlags |= NPC_FRAME;
|
||||
health = 50;
|
||||
velocity = [0,0,0];
|
||||
m_iFlags = 0x0;
|
||||
SendFlags = 0xff;
|
||||
}
|
||||
|
||||
void monster_scientist::monster_scientist(void)
|
||||
void
|
||||
monster_scientist::monster_scientist(void)
|
||||
{
|
||||
for (int i = 0; i < sci_sndpain.length; i++) {
|
||||
precache_sound(sci_sndpain[i]);
|
||||
|
@ -651,22 +181,38 @@ void monster_scientist::monster_scientist(void)
|
|||
for (int i = 0; i < sci_snddie.length; i++) {
|
||||
precache_sound(sci_snddie[i]);
|
||||
}
|
||||
for (int i = 0; i < sci_sndscream.length; i++) {
|
||||
precache_sound(sci_sndscream[i]);
|
||||
}
|
||||
for (int i = 0; i < sci_snduse.length; i++) {
|
||||
precache_sound(sci_snduse[i]);
|
||||
}
|
||||
for (int i = 0; i < sci_snduseno.length; i++) {
|
||||
precache_sound(sci_snduseno[i]);
|
||||
}
|
||||
for (int i = 0; i < sci_sndsee.length; i++) {
|
||||
precache_sound(sci_sndsee[i]);
|
||||
}
|
||||
for (int i = 0; i < sci_sndidle.length; i++) {
|
||||
precache_sound(sci_sndidle[i]);
|
||||
|
||||
if (spawnflags & MSF_PREDISASTER) {
|
||||
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";
|
||||
}
|
||||
|
||||
m_talkAnswer = "!SC_ANSWER";
|
||||
m_talkAllyShot = "!SC_PLFEAR";
|
||||
m_talkGreet = "";
|
||||
m_talkIdle = "!SC_IDLE";
|
||||
m_talkHearing = "!SC_HEAR";
|
||||
m_talkSmelling = "!SC_SMELL";
|
||||
m_talkStare = "!SC_STARE";
|
||||
m_talkSurvived = "!SC_WOUND";
|
||||
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_talkFollow = "!SC_OK";
|
||||
m_talkStopFollow = "!SC_STOP";
|
||||
|
||||
/* by default a random character etc. is chosen */
|
||||
body = -1;
|
||||
for (int i = 1; i < (tokenize(__fullspawndata)-1); i += 2) {
|
||||
switch (argv(i)) {
|
||||
|
@ -679,13 +225,11 @@ void monster_scientist::monster_scientist(void)
|
|||
}
|
||||
|
||||
model = "models/scientist.mdl";
|
||||
CBaseEntity::CBaseEntity();
|
||||
precache_model(m_oldModel);
|
||||
Respawn();
|
||||
base_mins = [-16,-16,0];
|
||||
base_maxs = [16,16,72];
|
||||
|
||||
/* has the body not been overriden, etc. choose a character for us */
|
||||
if (body == -1) {
|
||||
/* This stuff needs to be persistent because we can't guarantee that
|
||||
* the client-side geomset refresh happens. Don't shove this into Respawn */
|
||||
body = floor(random(1,5));
|
||||
}
|
||||
|
||||
|
@ -707,4 +251,6 @@ void monster_scientist::monster_scientist(void)
|
|||
m_flPitch = 100;
|
||||
netname = "Slick";
|
||||
}
|
||||
|
||||
CBaseNPC::CBaseNPC();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue