2020-03-26 03:24:33 -07:00
|
|
|
/*
|
2022-07-07 09:10:14 -07:00
|
|
|
* Copyright (c) 2016-2022 Vera Visions LLC.
|
2020-03-26 03:24:33 -07:00
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
|
|
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
2022-07-07 09:10:14 -07:00
|
|
|
*/
|
2020-03-26 03:24:33 -07:00
|
|
|
|
2021-10-19 16:18:36 -07:00
|
|
|
#ifdef SERVER
|
2021-10-22 11:51:51 -07:00
|
|
|
void
|
|
|
|
NSTalkMonster::Save(float handle)
|
|
|
|
{
|
|
|
|
SaveString(handle, "talkAnswer", m_talkAnswer);
|
|
|
|
SaveString(handle, "talkAsk", m_talkAsk);
|
|
|
|
SaveString(handle, "talkAllyShot", m_talkAllyShot);
|
|
|
|
SaveString(handle, "talkGreet", m_talkGreet);
|
|
|
|
SaveString(handle, "talkIdle", m_talkIdle);
|
|
|
|
SaveString(handle, "talkPanic", m_talkPanic);
|
|
|
|
SaveString(handle, "talkHearing", m_talkHearing);
|
|
|
|
SaveString(handle, "talkSmelling", m_talkSmelling);
|
|
|
|
SaveString(handle, "talkStare", m_talkStare);
|
|
|
|
SaveString(handle, "talkSurvived", m_talkSurvived);
|
|
|
|
SaveString(handle, "talkWounded", m_talkWounded);
|
|
|
|
SaveString(handle, "talkPlayerAsk", m_talkPlayerAsk);
|
|
|
|
SaveString(handle, "talkPlayerGreet", m_talkPlayerGreet);
|
|
|
|
SaveString(handle, "talkPlayerIdle", m_talkPlayerIdle);
|
|
|
|
SaveString(handle, "talkPlayerWounded1", m_talkPlayerWounded1);
|
|
|
|
SaveString(handle, "talkPlayerWounded2", m_talkPlayerWounded2);
|
|
|
|
SaveString(handle, "talkPlayerWounded3", m_talkPlayerWounded3);
|
|
|
|
SaveString(handle, "talkUnfollow", m_talkUnfollow);
|
|
|
|
SaveString(handle, "talkFollow", m_talkFollow);
|
|
|
|
SaveString(handle, "talkStopFollow", m_talkStopFollow);
|
|
|
|
|
|
|
|
super::Save(handle);
|
|
|
|
}
|
|
|
|
void
|
|
|
|
NSTalkMonster::Restore(string strKey, string strValue)
|
|
|
|
{
|
|
|
|
switch (strKey) {
|
|
|
|
case "talkAnswer":
|
|
|
|
m_talkAnswer = strValue;
|
|
|
|
break;
|
|
|
|
case "talkAsk":
|
|
|
|
m_talkAsk = strValue;
|
|
|
|
break;
|
|
|
|
case "talkAllyShot":
|
|
|
|
m_talkAllyShot = strValue;
|
|
|
|
break;
|
|
|
|
case "talkGreet":
|
|
|
|
m_talkGreet = strValue;
|
|
|
|
break;
|
|
|
|
case "talkIdle":
|
|
|
|
m_talkIdle = strValue;
|
|
|
|
break;
|
|
|
|
case "talkPanic":
|
|
|
|
m_talkPanic = strValue;
|
|
|
|
break;
|
|
|
|
case "talkHearing":
|
|
|
|
m_talkHearing = strValue;
|
|
|
|
break;
|
|
|
|
case "talkSmelling":
|
|
|
|
m_talkSmelling = strValue;
|
|
|
|
break;
|
|
|
|
case "talkStare":
|
|
|
|
m_talkStare = strValue;
|
|
|
|
break;
|
|
|
|
case "talkSurvived":
|
|
|
|
m_talkSurvived = strValue;
|
|
|
|
break;
|
|
|
|
case "talkWounded":
|
|
|
|
m_talkWounded = strValue;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "talkPlayerAsk":
|
|
|
|
m_talkPlayerAsk = strValue;
|
|
|
|
break;
|
|
|
|
case "talkPlayerGreet":
|
|
|
|
m_talkPlayerGreet = strValue;
|
|
|
|
break;
|
|
|
|
case "talkPlayerIdle":
|
|
|
|
m_talkPlayerIdle = strValue;
|
|
|
|
break;
|
|
|
|
case "talkPlayerWounded1":
|
|
|
|
m_talkPlayerWounded1 = strValue;
|
|
|
|
break;
|
|
|
|
case "talkPlayerWounded2":
|
|
|
|
m_talkPlayerWounded2 = strValue;
|
|
|
|
break;
|
|
|
|
case "talkPlayerWounded3":
|
|
|
|
m_talkPlayerWounded3 = strValue;
|
|
|
|
break;
|
|
|
|
case "talkUnfollow":
|
|
|
|
m_talkUnfollow = strValue;
|
|
|
|
break;
|
|
|
|
case "talkFollow":
|
|
|
|
m_talkFollow = strValue;
|
|
|
|
break;
|
|
|
|
case "talkStopFollow":
|
|
|
|
m_talkStopFollow = strValue;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
super::Restore(strKey, strValue);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-26 23:34:24 -07:00
|
|
|
void
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::WarnAllies(void)
|
2020-03-26 23:34:24 -07:00
|
|
|
{
|
|
|
|
for (entity b = world; (b = find(b, ::classname, classname));) {
|
|
|
|
if (vlen(b.origin - origin) < PLAYER_DETECT_RADIUS) {
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster w = (NSTalkMonster)b;
|
2020-03-26 23:34:24 -07:00
|
|
|
w.m_iFlags |= MONSTER_METPLAYER;
|
|
|
|
w.m_eFollowing = world;
|
|
|
|
w.m_eFollowingChain = world;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-03-06 08:43:08 -08:00
|
|
|
void
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::StartleAllies(void)
|
2021-03-06 08:43:08 -08:00
|
|
|
{
|
|
|
|
for (entity b = world; (b = find(b, ::classname, classname));) {
|
|
|
|
if (vlen(b.origin - origin) < PLAYER_DETECT_RADIUS) {
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster w = (NSTalkMonster)b;
|
2021-03-06 08:43:08 -08:00
|
|
|
w.m_iFlags |= MONSTER_FEAR;
|
|
|
|
w.m_eFollowing = world;
|
|
|
|
w.m_eFollowingChain = world;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-03-26 23:34:24 -07:00
|
|
|
|
2020-03-26 03:24:33 -07:00
|
|
|
void
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::Sentence(string sentence)
|
2020-03-26 03:24:33 -07:00
|
|
|
{
|
2022-07-17 00:04:01 -07:00
|
|
|
if (GetState() == MONSTER_DEAD)
|
2021-09-11 15:21:28 -07:00
|
|
|
return;
|
|
|
|
|
2020-03-26 03:24:33 -07:00
|
|
|
string seq = Sentences_GetSamples(sentence);
|
|
|
|
|
2021-05-10 02:33:31 -07:00
|
|
|
if (seq == "")
|
2020-03-26 03:24:33 -07:00
|
|
|
return;
|
|
|
|
|
|
|
|
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
|
|
|
WriteByte(MSG_MULTICAST, EV_SENTENCE);
|
|
|
|
WriteEntity(MSG_MULTICAST, this);
|
2020-03-26 04:19:27 -07:00
|
|
|
WriteString(MSG_MULTICAST, seq);
|
2020-03-26 03:24:33 -07:00
|
|
|
msg_entity = this;
|
|
|
|
multicast(origin, MULTICAST_PVS);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::Speak(string sentence)
|
2020-03-26 03:24:33 -07:00
|
|
|
{
|
2022-07-17 00:04:01 -07:00
|
|
|
if (GetState() == MONSTER_DEAD)
|
2021-09-11 15:21:28 -07:00
|
|
|
return;
|
|
|
|
|
2020-03-26 03:24:33 -07:00
|
|
|
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
|
|
|
WriteByte(MSG_MULTICAST, EV_SPEAK);
|
|
|
|
WriteEntity(MSG_MULTICAST, this);
|
|
|
|
WriteString(MSG_MULTICAST, sentence);
|
|
|
|
WriteFloat(MSG_MULTICAST, m_flPitch);
|
|
|
|
msg_entity = this;
|
|
|
|
multicast(origin, MULTICAST_PVS);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::TalkPlayerGreet(void)
|
2020-03-26 23:34:24 -07:00
|
|
|
{
|
2020-03-29 02:49:35 -07:00
|
|
|
if (m_iSequenceState != SEQUENCESTATE_NONE)
|
|
|
|
return;
|
|
|
|
|
2021-05-10 02:33:31 -07:00
|
|
|
if (m_flNextSentence > time)
|
2020-03-26 23:34:24 -07:00
|
|
|
return;
|
|
|
|
|
2021-05-10 02:33:31 -07:00
|
|
|
if (m_iFlags & MONSTER_METPLAYER)
|
2020-03-26 23:34:24 -07:00
|
|
|
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
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::TalkPlayerIdle(void)
|
2020-03-26 23:34:24 -07:00
|
|
|
{
|
2020-03-29 02:49:35 -07:00
|
|
|
if (m_iSequenceState != SEQUENCESTATE_NONE)
|
|
|
|
return;
|
2022-04-02 00:10:25 -07:00
|
|
|
if (HasSpawnFlags(MSF_PREDISASTER))
|
2020-03-26 23:34:24 -07:00
|
|
|
return;
|
2020-11-24 03:29:29 -08:00
|
|
|
if (m_flNextSentence > time)
|
2020-03-26 23:34:24 -07:00
|
|
|
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
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::TalkPlayerAsk(void)
|
2020-03-26 23:34:24 -07:00
|
|
|
{
|
2020-03-29 02:49:35 -07:00
|
|
|
if (m_iSequenceState != SEQUENCESTATE_NONE)
|
|
|
|
return;
|
2022-04-02 00:10:25 -07:00
|
|
|
if (HasSpawnFlags(MSF_PREDISASTER))
|
2020-03-26 23:34:24 -07:00
|
|
|
return;
|
2020-11-24 03:29:29 -08:00
|
|
|
if (m_flNextSentence > time)
|
2020-03-26 23:34:24 -07:00
|
|
|
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
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::TalkPlayerWounded1(void)
|
2020-03-26 23:34:24 -07:00
|
|
|
{
|
2020-03-29 02:49:35 -07:00
|
|
|
if (m_iSequenceState != SEQUENCESTATE_NONE)
|
|
|
|
return;
|
|
|
|
|
2021-05-10 02:33:31 -07:00
|
|
|
if (m_flNextSentence > time)
|
2020-03-26 23:34:24 -07:00
|
|
|
return;
|
|
|
|
|
2021-05-10 02:33:31 -07:00
|
|
|
if (base_health < health)
|
2020-03-26 23:34:24 -07:00
|
|
|
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
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::TalkPlayerWounded2(void)
|
2020-03-26 23:34:24 -07:00
|
|
|
{
|
2020-03-29 02:49:35 -07:00
|
|
|
if (m_iSequenceState != SEQUENCESTATE_NONE)
|
|
|
|
return;
|
|
|
|
|
2021-05-10 02:33:31 -07:00
|
|
|
if (m_flNextSentence > time)
|
2020-03-26 23:34:24 -07:00
|
|
|
return;
|
|
|
|
|
2021-05-10 02:33:31 -07:00
|
|
|
if ((base_health / 2) < health)
|
2020-03-26 23:34:24 -07:00
|
|
|
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
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::TalkPlayerWounded3(void)
|
2020-03-26 23:34:24 -07:00
|
|
|
{
|
2020-03-29 02:49:35 -07:00
|
|
|
if (m_iSequenceState != SEQUENCESTATE_NONE)
|
|
|
|
return;
|
|
|
|
|
2021-05-10 02:33:31 -07:00
|
|
|
if (m_flNextSentence > time)
|
2020-03-26 23:34:24 -07:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-06 08:43:08 -08:00
|
|
|
void
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::TalkPanic(void)
|
2021-03-06 08:43:08 -08:00
|
|
|
{
|
|
|
|
if (m_iSequenceState != SEQUENCESTATE_NONE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Sentence(m_talkPanic);
|
|
|
|
m_flNextSentence = time + 2.5;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-03-26 23:34:24 -07:00
|
|
|
void
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::TalkUnfollow(void)
|
2020-03-26 23:34:24 -07:00
|
|
|
{
|
2020-03-29 02:49:35 -07:00
|
|
|
if (m_iSequenceState != SEQUENCESTATE_NONE)
|
|
|
|
return;
|
|
|
|
|
2020-03-26 23:34:24 -07:00
|
|
|
Sentence(m_talkUnfollow);
|
|
|
|
m_flNextSentence = time + 10.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::TalkFollow(void)
|
2020-03-26 23:34:24 -07:00
|
|
|
{
|
2020-03-29 02:49:35 -07:00
|
|
|
if (m_iSequenceState != SEQUENCESTATE_NONE)
|
|
|
|
return;
|
|
|
|
|
2020-03-26 23:34:24 -07:00
|
|
|
Sentence(m_talkFollow);
|
|
|
|
m_flNextSentence = time + 10.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::TalkStopFollow(void)
|
2020-03-26 23:34:24 -07:00
|
|
|
{
|
2020-03-29 02:49:35 -07:00
|
|
|
if (m_iSequenceState != SEQUENCESTATE_NONE)
|
|
|
|
return;
|
|
|
|
|
2020-03-26 23:34:24 -07:00
|
|
|
Sentence(m_talkStopFollow);
|
|
|
|
m_flNextSentence = time + 10.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::FollowPlayer(void)
|
2020-03-26 03:24:33 -07:00
|
|
|
{
|
2020-03-26 23:34:24 -07:00
|
|
|
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) {
|
2022-01-25 20:07:25 -08:00
|
|
|
input_movevalues[0] = GetChaseSpeed();
|
2020-03-26 23:34:24 -07:00
|
|
|
|
|
|
|
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]);
|
2020-03-29 03:56:46 -07:00
|
|
|
v_angle[2] = 0;
|
2020-03-26 23:34:24 -07:00
|
|
|
} 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) {
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster que = (NSTalkMonster)trace_ent;
|
2020-03-26 23:34:24 -07:00
|
|
|
if (que.m_eFollowingChain == m_eFollowing) {
|
|
|
|
if (trace_ent != this) {
|
|
|
|
m_eFollowingChain = trace_ent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::PanicFrame(void)
|
2020-03-26 23:34:24 -07:00
|
|
|
{
|
|
|
|
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) {
|
2021-03-06 08:43:08 -08:00
|
|
|
v_angle[1] -= 180 + ((random() - 0.5) * 90);
|
|
|
|
v_angle[1] = Math_FixDelta(v_angle[1]);
|
2020-03-26 23:34:24 -07:00
|
|
|
m_flChangePath = time + floor(random(2,10));
|
2021-03-06 08:43:08 -08:00
|
|
|
angles = input_angles = v_angle;
|
2020-03-26 23:34:24 -07:00
|
|
|
}
|
2021-03-06 08:43:08 -08:00
|
|
|
|
|
|
|
if (m_flNextSentence > time)
|
|
|
|
return;
|
|
|
|
|
|
|
|
TalkPanic();
|
2020-03-26 23:34:24 -07:00
|
|
|
}
|
2020-03-26 03:24:33 -07:00
|
|
|
|
2020-03-26 23:34:24 -07:00
|
|
|
void
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::FollowChain(void)
|
2020-03-26 23:34:24 -07:00
|
|
|
{
|
|
|
|
/* 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
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::Physics(void)
|
2020-03-26 23:34:24 -07:00
|
|
|
{
|
|
|
|
input_movevalues = [0,0,0];
|
|
|
|
input_impulse = 0;
|
|
|
|
input_buttons = 0;
|
2020-03-29 02:21:26 -07:00
|
|
|
input_timelength = frametime;
|
2020-08-03 14:39:57 -07:00
|
|
|
input_angles = v_angle;
|
2020-03-29 02:21:26 -07:00
|
|
|
|
2020-11-24 03:29:29 -08:00
|
|
|
/* make sure we're forgetting about enemies and attack states in sequence */
|
2020-09-10 04:36:19 -07:00
|
|
|
if (m_iSequenceState != SEQUENCESTATE_NONE) {
|
2020-11-24 03:29:29 -08:00
|
|
|
m_eEnemy = __NULL__;
|
2022-07-17 00:04:01 -07:00
|
|
|
SetState(MONSTER_IDLE);
|
2020-09-10 04:36:19 -07:00
|
|
|
}
|
|
|
|
|
2020-03-29 02:21:26 -07:00
|
|
|
/* override whatever we did above with this */
|
|
|
|
if (m_iSequenceState == SEQUENCESTATE_ENDING) {
|
2020-08-07 05:07:38 -07:00
|
|
|
input_angles = v_angle = angles = m_vecSequenceAngle;
|
2020-04-22 14:33:18 -07:00
|
|
|
SetFrame(m_flSequenceEnd);
|
2020-03-29 02:21:26 -07:00
|
|
|
} else {
|
2022-07-17 00:04:01 -07:00
|
|
|
if (GetState() != MONSTER_DEAD) {
|
2020-11-23 12:39:40 -08:00
|
|
|
if (m_iSequenceState == SEQUENCESTATE_NONE) {
|
|
|
|
SeeThink();
|
|
|
|
AttackThink();
|
|
|
|
TalkPlayerGreet();
|
|
|
|
FollowChain();
|
|
|
|
|
|
|
|
if (m_eFollowing != world) {
|
|
|
|
FollowPlayer();
|
|
|
|
input_angles = angles = v_angle;
|
|
|
|
} else if (m_iFlags & MONSTER_FEAR) {
|
|
|
|
PanicFrame();
|
2020-03-29 02:21:26 -07:00
|
|
|
} else {
|
2020-11-23 12:39:40 -08:00
|
|
|
if (random() < 0.5) {
|
|
|
|
TalkPlayerAsk();
|
|
|
|
} else {
|
|
|
|
TalkPlayerIdle();
|
|
|
|
}
|
2020-03-29 02:21:26 -07:00
|
|
|
}
|
2020-03-26 23:34:24 -07:00
|
|
|
}
|
|
|
|
|
2022-05-01 22:45:30 -07:00
|
|
|
AnimationUpdate();
|
2020-03-26 23:34:24 -07:00
|
|
|
}
|
2020-03-29 02:21:26 -07:00
|
|
|
CheckRoute();
|
|
|
|
WalkRoute();
|
2022-04-09 19:21:00 -07:00
|
|
|
hitcontentsmaski = CONTENTBITS_MONSTER;
|
2022-04-10 06:59:40 -07:00
|
|
|
|
|
|
|
if (CanCrouch())
|
|
|
|
PMoveCustom_RunCrouchPhysics(this);
|
|
|
|
else
|
|
|
|
PMoveCustom_RunPlayerPhysics(this);
|
|
|
|
|
2020-04-22 14:33:18 -07:00
|
|
|
SetOrigin(origin);
|
2020-03-26 23:34:24 -07:00
|
|
|
}
|
|
|
|
|
2021-09-16 16:24:47 -07:00
|
|
|
if (!(flags & FL_ONGROUND) && velocity[2] < -415) {
|
2021-09-16 15:41:58 -07:00
|
|
|
if (!(m_iFlags & MSF_FALLING)) {
|
|
|
|
FallNoise();
|
|
|
|
}
|
|
|
|
|
|
|
|
m_iFlags |= MSF_FALLING;
|
2020-03-26 23:34:24 -07:00
|
|
|
} else {
|
2021-09-16 15:41:58 -07:00
|
|
|
m_iFlags &= ~MSF_FALLING;
|
2020-03-26 23:34:24 -07:00
|
|
|
}
|
2020-03-29 02:21:26 -07:00
|
|
|
|
|
|
|
/* support for think/nextthink */
|
2020-03-30 01:40:38 -07:00
|
|
|
if (think && nextthink > 0.0f) {
|
2020-03-29 02:21:26 -07:00
|
|
|
if (nextthink < time) {
|
|
|
|
nextthink = 0.0f;
|
2020-03-30 01:00:37 -07:00
|
|
|
think();
|
2020-03-29 02:21:26 -07:00
|
|
|
}
|
|
|
|
}
|
2020-08-03 14:39:57 -07:00
|
|
|
|
2020-09-10 01:34:14 -07:00
|
|
|
m_flBaseTime = frame1time;
|
2020-08-03 14:39:57 -07:00
|
|
|
frame1time += frametime;
|
2020-09-10 01:34:14 -07:00
|
|
|
|
|
|
|
processmodelevents(modelindex, frame, m_flBaseTime,
|
2021-01-06 04:58:37 -08:00
|
|
|
frame1time, Game_ServerModelEvent);
|
2020-03-26 23:34:24 -07:00
|
|
|
}
|
|
|
|
|
2020-11-24 03:29:29 -08:00
|
|
|
void
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::Respawn(void)
|
2020-04-12 06:50:42 -07:00
|
|
|
{
|
2021-10-19 16:18:36 -07:00
|
|
|
NSMonster::Respawn();
|
2020-04-12 06:50:42 -07:00
|
|
|
m_eFollowing = world;
|
|
|
|
m_eFollowingChain = world;
|
|
|
|
}
|
|
|
|
|
2020-03-26 23:34:24 -07:00
|
|
|
void
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::OnPlayerUse(void)
|
2020-03-26 23:34:24 -07:00
|
|
|
{
|
2021-05-10 02:33:31 -07:00
|
|
|
if (m_iFlags & MONSTER_FEAR)
|
2020-03-26 23:34:24 -07:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* can't press use any non-allies */
|
2021-05-10 02:33:31 -07:00
|
|
|
if (!(m_iFlags & MONSTER_CANFOLLOW))
|
2020-03-26 23:34:24 -07:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-10 19:33:42 -07:00
|
|
|
void
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::SpawnKey(string strKey, string strValue)
|
2020-09-10 19:33:42 -07:00
|
|
|
{
|
|
|
|
switch (strKey) {
|
|
|
|
case "UnUseSentence":
|
|
|
|
m_talkUnfollow = strcat("!", strValue);
|
|
|
|
break;
|
|
|
|
case "UseSentence":
|
|
|
|
m_talkFollow = strcat("!", strValue);
|
|
|
|
break;
|
|
|
|
default:
|
2021-10-19 16:18:36 -07:00
|
|
|
NSMonster::SpawnKey(strKey, strValue);
|
2020-09-10 19:33:42 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-26 23:34:24 -07:00
|
|
|
void
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::Hide(void)
|
2020-03-26 23:34:24 -07:00
|
|
|
{
|
|
|
|
m_eFollowing = world;
|
2021-10-19 16:18:36 -07:00
|
|
|
NSMonster::Hide();
|
2020-03-26 23:34:24 -07:00
|
|
|
}
|
|
|
|
|
2021-10-19 16:18:36 -07:00
|
|
|
float
|
|
|
|
NSTalkMonster::SendEntity(entity ePEnt, float fChanged)
|
|
|
|
{
|
|
|
|
if (!modelindex)
|
|
|
|
return (0);
|
|
|
|
|
|
|
|
if (clienttype(ePEnt) != CLIENTTYPE_REAL)
|
|
|
|
return (0);
|
|
|
|
|
|
|
|
WriteByte(MSG_ENTITY, ENT_TALKMONSTER);
|
|
|
|
|
|
|
|
/* don't network triggers unless provoked */
|
|
|
|
/*if (cvar("developer") == 0 && m_iRenderMode == RM_TRIGGER)
|
|
|
|
return (0);*/
|
|
|
|
|
|
|
|
/* broadcast how much data is expected to be read */
|
|
|
|
WriteFloat(MSG_ENTITY, fChanged);
|
|
|
|
|
|
|
|
/* really trying to get our moneys worth with 23 bits of mantissa */
|
|
|
|
if (fChanged & BASEFL_CHANGED_ORIGIN) {
|
|
|
|
WriteCoord(MSG_ENTITY, origin[0]);
|
|
|
|
WriteCoord(MSG_ENTITY, origin[1]);
|
|
|
|
WriteCoord(MSG_ENTITY, origin[2]);
|
|
|
|
}
|
|
|
|
if (fChanged & BASEFL_CHANGED_ANGLES) {
|
2022-07-17 00:04:01 -07:00
|
|
|
WriteShort(MSG_ENTITY, 0);
|
2021-10-19 16:18:36 -07:00
|
|
|
WriteShort(MSG_ENTITY, angles[1] * 32767 / 360);
|
2022-07-17 00:04:01 -07:00
|
|
|
WriteShort(MSG_ENTITY, 0);
|
2021-10-19 16:18:36 -07:00
|
|
|
}
|
|
|
|
if (fChanged & BASEFL_CHANGED_MODELINDEX) {
|
|
|
|
WriteShort(MSG_ENTITY, modelindex);
|
|
|
|
}
|
|
|
|
if (fChanged & BASEFL_CHANGED_SOLID) {
|
|
|
|
WriteByte(MSG_ENTITY, solid);
|
|
|
|
}
|
|
|
|
if (fChanged & BASEFL_CHANGED_MOVETYPE) {
|
|
|
|
WriteByte(MSG_ENTITY, movetype);
|
|
|
|
}
|
|
|
|
if (fChanged & BASEFL_CHANGED_SIZE) {
|
|
|
|
WriteCoord(MSG_ENTITY, mins[0]);
|
|
|
|
WriteCoord(MSG_ENTITY, mins[1]);
|
|
|
|
WriteCoord(MSG_ENTITY, mins[2]);
|
|
|
|
WriteCoord(MSG_ENTITY, maxs[0]);
|
|
|
|
WriteCoord(MSG_ENTITY, maxs[1]);
|
|
|
|
WriteCoord(MSG_ENTITY, maxs[2]);
|
|
|
|
}
|
|
|
|
if (fChanged & BASEFL_CHANGED_FRAME) {
|
|
|
|
WriteByte(MSG_ENTITY, frame);
|
2022-01-20 16:23:29 -08:00
|
|
|
WriteFloat(MSG_ENTITY, frame1time);
|
2021-10-19 16:18:36 -07:00
|
|
|
}
|
|
|
|
if (fChanged & BASEFL_CHANGED_SKIN) {
|
|
|
|
WriteByte(MSG_ENTITY, skin + 128);
|
|
|
|
}
|
|
|
|
if (fChanged & BASEFL_CHANGED_EFFECTS) {
|
|
|
|
WriteFloat(MSG_ENTITY, effects);
|
|
|
|
}
|
|
|
|
if (fChanged & BASEFL_CHANGED_BODY) {
|
|
|
|
WriteByte(MSG_ENTITY, m_iBody);
|
|
|
|
}
|
|
|
|
if (fChanged & BASEFL_CHANGED_SCALE) {
|
|
|
|
WriteFloat(MSG_ENTITY, scale);
|
|
|
|
}
|
|
|
|
if (fChanged & BASEFL_CHANGED_VELOCITY) {
|
|
|
|
WriteFloat(MSG_ENTITY, velocity[0]);
|
|
|
|
WriteFloat(MSG_ENTITY, velocity[1]);
|
|
|
|
WriteFloat(MSG_ENTITY, velocity[2]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fChanged & BASEFL_CHANGED_RENDERMODE) {
|
|
|
|
WriteByte(MSG_ENTITY, m_iRenderMode);
|
2022-01-21 12:24:25 -08:00
|
|
|
WriteByte(MSG_ENTITY, m_iRenderFX);
|
2021-10-19 16:18:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if (fChanged & BASEFL_CHANGED_RENDERCOLOR) {
|
|
|
|
WriteFloat(MSG_ENTITY, m_vecRenderColor[0]);
|
|
|
|
WriteFloat(MSG_ENTITY, m_vecRenderColor[1]);
|
|
|
|
WriteFloat(MSG_ENTITY, m_vecRenderColor[2]);
|
|
|
|
}
|
|
|
|
if (fChanged & BASEFL_CHANGED_RENDERAMT) {
|
|
|
|
WriteFloat(MSG_ENTITY, m_flRenderAmt);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
NSTalkMonster::SentenceSample
|
|
|
|
|
|
|
|
whatever comes out of the 'mouth',
|
|
|
|
============
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
NSTalkMonster::SentenceSample(string sample)
|
|
|
|
{
|
|
|
|
sound(this, CHAN_VOICE, sample, 1.0, ATTN_NORM, 100, SOUNDFLAG_FOLLOW);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
NSTalkMonster::ProcessWordQue
|
|
|
|
|
|
|
|
Handles the sentences word que
|
|
|
|
============
|
|
|
|
*/
|
2020-03-26 23:34:24 -07:00
|
|
|
void
|
2021-10-19 16:18:36 -07:00
|
|
|
NSTalkMonster::ProcessWordQue(void)
|
2020-03-26 23:34:24 -07:00
|
|
|
{
|
2021-10-19 16:18:36 -07:00
|
|
|
if (time < 1 || !m_iSentenceCount) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_flSentenceTime > time) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
SentenceSample(m_pSentenceQue[m_iSentencePos].m_strSnd);
|
|
|
|
|
2022-05-11 12:49:04 -07:00
|
|
|
NSLog("^2NSEntity::^3ProcessWordQue^7: Speaking %s", m_pSentenceQue[m_iSentencePos].m_strSnd);
|
2021-10-19 16:18:36 -07:00
|
|
|
m_iSentencePos++;
|
|
|
|
|
|
|
|
if (m_iSentencePos == m_iSentenceCount) {
|
|
|
|
memfree(m_pSentenceQue);
|
|
|
|
m_iSentenceCount = 0;
|
|
|
|
m_iSentencePos = 0;
|
|
|
|
m_pSentenceQue = 0;
|
|
|
|
} else {
|
|
|
|
m_flSentenceTime = time + m_pSentenceQue[m_iSentencePos - 1].m_flLength;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
============
|
|
|
|
NSTalkMonster::Sentence
|
|
|
|
|
|
|
|
we'll pass it a sentences.txt word (e.g. !BA_TEST) and start queing it
|
|
|
|
============
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
NSTalkMonster::Sentence(string msg)
|
|
|
|
{
|
|
|
|
/* not defined */
|
|
|
|
if (msg == "") {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_iSentenceCount) {
|
|
|
|
memfree(m_pSentenceQue);
|
|
|
|
m_iSentenceCount = 0;
|
|
|
|
m_pSentenceQue = 0;
|
|
|
|
m_iSentencePos = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_iSentenceCount = tokenize(Sentences_GetSamples(msg));
|
|
|
|
m_pSentenceQue = memalloc(sizeof(sound_t) * m_iSentenceCount);
|
|
|
|
|
|
|
|
/* first we have to get the info out of the token */
|
|
|
|
for (int i = 0; i < m_iSentenceCount; i++) {
|
|
|
|
m_pSentenceQue[i].m_strSnd = sprintf("%s.wav", argv(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* process more info, we'll need to override argv() here */
|
|
|
|
for (int i = 0; i < m_iSentenceCount; i++) {
|
|
|
|
m_pSentenceQue[i].m_strSnd = Sentences_ProcessSample(m_pSentenceQue[i].m_strSnd);
|
|
|
|
m_pSentenceQue[i].m_flLength = soundlength(m_pSentenceQue[i].m_strSnd);
|
|
|
|
m_pSentenceQue[i].m_flPitch = 100;
|
|
|
|
}
|
|
|
|
m_flSentenceTime = time;
|
|
|
|
}
|
|
|
|
|
|
|
|
float
|
|
|
|
NSTalkMonster::predraw(void)
|
|
|
|
{
|
|
|
|
float render;
|
|
|
|
render = super::predraw();
|
|
|
|
|
|
|
|
/* mouth flapping action */
|
|
|
|
bonecontrol5 = getchannellevel(this, CHAN_VOICE) * 20;
|
|
|
|
m_flBaseTime = frame1time;
|
|
|
|
ProcessWordQue();
|
|
|
|
|
2022-05-04 11:19:19 -07:00
|
|
|
/* pause/unpause CHAN_VOICE */
|
2022-05-04 10:59:42 -07:00
|
|
|
if (serverkeyfloat(SERVERKEY_PAUSESTATE) != 1) {
|
2022-05-04 11:19:19 -07:00
|
|
|
/* resume; negative soundofs makes soundupdate act absolute */
|
|
|
|
if (m_bWasPaused == true)
|
2022-05-04 10:59:42 -07:00
|
|
|
soundupdate(this, CHAN_VOICE, "", 1.0, ATTN_NORM, 0, 0, -m_sndVoiceOffs);
|
2022-05-04 11:19:19 -07:00
|
|
|
|
2022-05-04 10:59:42 -07:00
|
|
|
m_bWasPaused = false;
|
|
|
|
} else {
|
2022-05-04 11:19:19 -07:00
|
|
|
/* called once when pausing */
|
|
|
|
if (m_bWasPaused == false)
|
|
|
|
m_sndVoiceOffs = getsoundtime(this, CHAN_VOICE); /* length into the sample */
|
|
|
|
|
|
|
|
/* make silent and keep updating so the sample doesn't stop */
|
|
|
|
soundupdate(this, CHAN_VOICE, "", 0.0, ATTN_NORM, 0, 0, -m_sndVoiceOffs);
|
2022-05-04 10:59:42 -07:00
|
|
|
m_bWasPaused = true;
|
|
|
|
}
|
|
|
|
|
2021-10-19 16:18:36 -07:00
|
|
|
return render;
|
|
|
|
}
|
|
|
|
|
2022-01-21 12:24:25 -08:00
|
|
|
/*
|
|
|
|
============
|
|
|
|
NSTalkMonster::ReceiveEntity
|
|
|
|
============
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
NSTalkMonster::ReceiveEntity(float flNew, float flChanged)
|
|
|
|
{
|
|
|
|
if (flChanged & BASEFL_CHANGED_ORIGIN) {
|
|
|
|
origin[0] = readcoord();
|
|
|
|
origin[1] = readcoord();
|
|
|
|
origin[2] = readcoord();
|
|
|
|
}
|
|
|
|
if (flChanged & BASEFL_CHANGED_ANGLES) {
|
|
|
|
angles[0] = readshort() / (32767 / 360);
|
|
|
|
angles[1] = readshort() / (32767 / 360);
|
|
|
|
angles[2] = readshort() / (32767 / 360);
|
|
|
|
}
|
|
|
|
if (flChanged & BASEFL_CHANGED_MODELINDEX) {
|
|
|
|
setmodelindex(this, readshort());
|
|
|
|
}
|
|
|
|
if (flChanged & BASEFL_CHANGED_SOLID) {
|
|
|
|
solid = readbyte();
|
|
|
|
}
|
|
|
|
if (flChanged & BASEFL_CHANGED_MOVETYPE) {
|
|
|
|
movetype = readbyte();
|
|
|
|
|
|
|
|
if (movetype == MOVETYPE_PHYSICS) {
|
|
|
|
movetype = MOVETYPE_NONE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (flChanged & BASEFL_CHANGED_SIZE) {
|
|
|
|
mins[0] = readcoord();
|
|
|
|
mins[1] = readcoord();
|
|
|
|
mins[2] = readcoord();
|
|
|
|
maxs[0] = readcoord();
|
|
|
|
maxs[1] = readcoord();
|
|
|
|
maxs[2] = readcoord();
|
|
|
|
setsize(this, mins, maxs);
|
|
|
|
}
|
|
|
|
if (flChanged & BASEFL_CHANGED_FRAME) {
|
|
|
|
frame = readbyte();
|
|
|
|
frame1time = readfloat();
|
|
|
|
frame2time = frame1time;
|
|
|
|
}
|
|
|
|
if (flChanged & BASEFL_CHANGED_SKIN) {
|
|
|
|
skin = readbyte() - 128;
|
|
|
|
}
|
|
|
|
if (flChanged & BASEFL_CHANGED_EFFECTS) {
|
|
|
|
effects = readfloat();
|
|
|
|
}
|
|
|
|
if (flChanged & BASEFL_CHANGED_BODY) {
|
|
|
|
m_iBody = readbyte();
|
|
|
|
setcustomskin(this, "", sprintf("geomset 1 %i\n", m_iBody));
|
|
|
|
}
|
|
|
|
if (flChanged & BASEFL_CHANGED_SCALE) {
|
|
|
|
scale = readfloat();
|
|
|
|
}
|
|
|
|
if (flChanged & BASEFL_CHANGED_VELOCITY) {
|
|
|
|
velocity[0] = readfloat();
|
|
|
|
velocity[1] = readfloat();
|
|
|
|
velocity[2] = readfloat();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flChanged & BASEFL_CHANGED_RENDERMODE) {
|
|
|
|
m_iRenderMode = readbyte();
|
|
|
|
m_iRenderFX = readbyte();
|
|
|
|
}
|
|
|
|
if (flChanged & BASEFL_CHANGED_RENDERCOLOR) {
|
|
|
|
m_vecRenderColor[0] = readfloat();
|
|
|
|
m_vecRenderColor[1] = readfloat();
|
|
|
|
m_vecRenderColor[2] = readfloat();
|
|
|
|
}
|
|
|
|
if (flChanged & BASEFL_CHANGED_RENDERAMT) {
|
|
|
|
m_flRenderAmt = readfloat();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (modelindex) {
|
|
|
|
drawmask = MASK_ENGINE;
|
|
|
|
} else {
|
|
|
|
drawmask = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scale == 0.0)
|
|
|
|
scale = 1.0f;
|
|
|
|
|
|
|
|
setorigin(this, origin);
|
|
|
|
}
|
|
|
|
|
2021-10-19 16:18:36 -07:00
|
|
|
void
|
|
|
|
NSTalkMonster_ParseSentence(void)
|
|
|
|
{
|
|
|
|
entity ent;
|
|
|
|
NSTalkMonster targ;
|
|
|
|
string sentence;
|
|
|
|
float e;
|
|
|
|
|
|
|
|
/* parse packets */
|
|
|
|
e = readentitynum();
|
|
|
|
sentence = readstring();
|
|
|
|
|
|
|
|
ent = findfloat(world, entnum, e);
|
|
|
|
|
|
|
|
if (ent) {
|
2022-05-04 21:31:37 -07:00
|
|
|
if (ent.classname != "NSTalkMonster" && ent.classname != "ambient_generic")
|
2022-05-11 12:49:04 -07:00
|
|
|
NSLog("^3 NSTalkMonster_ParseSentence ^7: Entity %d not a NSTalkMonster!", e);
|
2021-10-19 16:18:36 -07:00
|
|
|
else {
|
|
|
|
targ = (NSTalkMonster)ent;
|
|
|
|
targ.Sentence(sentence);
|
2022-05-11 12:49:04 -07:00
|
|
|
NSLog("^3 NSTalkMonster_ParseSentence ^7: Entity %d saying %s", e, sentence);
|
2021-10-19 16:18:36 -07:00
|
|
|
}
|
|
|
|
} else {
|
2022-05-11 12:49:04 -07:00
|
|
|
NSLog("^3 NSTalkMonster_ParseSentence ^7: Entity %d not in PVS", e);
|
2021-10-19 16:18:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void
|
|
|
|
NSTalkMonster::NSTalkMonster(void)
|
|
|
|
{
|
|
|
|
#ifdef SERVER
|
2020-03-26 23:34:24 -07:00
|
|
|
m_eFollowing = world;
|
2021-10-19 16:18:36 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef CLIENT
|
|
|
|
void
|
|
|
|
NSTalkMonster_ReadEntity(float new)
|
|
|
|
{
|
|
|
|
NSTalkMonster me = (NSTalkMonster)self;
|
|
|
|
if (new) {
|
|
|
|
spawnfunc_NSTalkMonster();
|
|
|
|
}
|
2022-01-20 16:23:29 -08:00
|
|
|
me.ReceiveEntity(new, readfloat());
|
2020-03-26 03:24:33 -07:00
|
|
|
}
|
2021-10-19 16:18:36 -07:00
|
|
|
#endif
|