diff --git a/src/gs-entbase/client/baseentity.cpp b/src/gs-entbase/client/baseentity.cpp index 7861dce1..8135b7d1 100644 --- a/src/gs-entbase/client/baseentity.cpp +++ b/src/gs-entbase/client/baseentity.cpp @@ -149,9 +149,13 @@ CBaseEntity::predraw(void) /* mouth flapping action */ bonecontrol5 = getchannellevel(this, CHAN_VOICE) * 20; + m_flBaseTime = frame1time; frame1time += clframetime; ProcessWordQue(); + processmodelevents(modelindex, frame, m_flBaseTime, + frame1time, ModelEvent); + if (alpha > 0.0) addentity(this); @@ -371,6 +375,23 @@ CBaseEntity::customphysics(void) } } +void +CBaseEntity::ModelEvent(float fTimeStamp, int iCode, string sData) +{ + switch (iCode) { + case 1004: + sound(this, CHAN_BODY, sData, 1.0f, ATTN_NORM); + break; + /* things handled on the server-side */ + case 1003: + break; + default: + dprint(sprintf("^3[CLIENT]^7 Unknown model-event code " \ + "%i with data %s\n", iCode, sData)); + break; + } +} + void CBaseEntity::Init(void) { isCSQC = TRUE; diff --git a/src/gs-entbase/client/baseentity.h b/src/gs-entbase/client/baseentity.h index dac18f9c..d657bcd7 100644 --- a/src/gs-entbase/client/baseentity.h +++ b/src/gs-entbase/client/baseentity.h @@ -29,6 +29,9 @@ class CBaseEntity int m_iSentenceCount; int m_iSentencePos; + /* model events */ + float m_flBaseTime; + void(void) CBaseEntity; virtual void(void) Init; virtual void(void) Initialized; @@ -39,6 +42,7 @@ class CBaseEntity virtual float(void) predraw; virtual void(void) postdraw; virtual void(void) customphysics; + virtual void(float, int, string) ModelEvent; #ifdef GS_RENDERFX virtual void(void) RenderFXPass; diff --git a/src/gs-entbase/server/baseentity.cpp b/src/gs-entbase/server/baseentity.cpp index 445e1120..f32b734f 100644 --- a/src/gs-entbase/server/baseentity.cpp +++ b/src/gs-entbase/server/baseentity.cpp @@ -287,6 +287,11 @@ CBaseEntity::SpawnInit(void) for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) { SpawnKey(argv(i), argv(i+1)); } + + /* some entity might involuntarily call SpawnInit as part of being + a member of CBaseEntity. So we need to make sure that it doesn't + inherit stuff from the last previously loaded entity */ + __fullspawndata = ""; } void @@ -331,6 +336,9 @@ CBaseEntity::SpawnKey(string strKey, string strValue) case "angles": angles = stov(strValue); break; + case "angle": + angles[1] = stof(strValue); + break; case "solid": solid = stof(strValue); break; @@ -372,7 +380,12 @@ CBaseEntity::SpawnKey(string strKey, string strValue) case "model": model = strValue; break; + case "classname": + case "spawnflags": + break; default: + print(sprintf("^3%s^7::SpawnKey:: Unknown key '%s' with value '%s'\n", + classname, strKey, strValue)); break; } } diff --git a/src/gs-entbase/server/basemonster.cpp b/src/gs-entbase/server/basemonster.cpp index 8bcd7b87..53803f31 100644 --- a/src/gs-entbase/server/basemonster.cpp +++ b/src/gs-entbase/server/basemonster.cpp @@ -85,6 +85,9 @@ class CBaseMonster:CBaseEntity vector m_vecSequenceAngle; vector m_vecTurnAngle; + /* model events */ + float m_flBaseTime; + /* attack/alliance system */ entity m_eEnemy; float m_flFOV; @@ -109,6 +112,7 @@ class CBaseMonster:CBaseEntity virtual void(void) IdleNoise; virtual void(void) Gib; virtual void(string) Sound; + virtual void(float, int, string) ModelEvent; /* see/hear subsystem */ float m_flSeeTime; @@ -500,6 +504,31 @@ CBaseMonster::NewRoute(vector destination) } } +void +CBaseMonster::ModelEvent(float fTimeStamp, int iCode, string sData) +{ + switch (iCode) { + case 1003: + for (entity f = world; (f = find(f, ::targetname, sData));) { + CBaseTrigger trigger = (CBaseTrigger)f; + if (trigger.Trigger != __NULL__) { + trigger.Trigger(this, TRIG_TOGGLE); + dprint(sprintf("^2%s^7::^3ModelEvent^7: " \ + "Calling trigger '%s'\n", + classname, sData)); + } + } + break; + /* things handled on the client-side */ + case 1004: + break; + default: + dprint(sprintf("^3[SERVER]^7 Unknown model-event code " \ + "%i with data %s\n", iCode, sData)); + break; + } +} + void CBaseMonster::Physics(void) { diff --git a/src/gs-entbase/server/basenpc.cpp b/src/gs-entbase/server/basenpc.cpp index 2cd16763..f8befd22 100644 --- a/src/gs-entbase/server/basenpc.cpp +++ b/src/gs-entbase/server/basenpc.cpp @@ -486,7 +486,6 @@ CBaseNPC::Physics(void) CheckRoute(); WalkRoute(); runstandardplayerphysics(this); - Footsteps_Update(); SetOrigin(origin); } @@ -504,7 +503,11 @@ CBaseNPC::Physics(void) } } + m_flBaseTime = frame1time; frame1time += frametime; + + processmodelevents(modelindex, frame, m_flBaseTime, + frame1time, ModelEvent); } void CBaseNPC::Respawn(void) diff --git a/src/gs-entbase/server/basetrigger.cpp b/src/gs-entbase/server/basetrigger.cpp index 4a6ff396..5afce0dc 100644 --- a/src/gs-entbase/server/basetrigger.cpp +++ b/src/gs-entbase/server/basetrigger.cpp @@ -183,6 +183,5 @@ CBaseTrigger::SpawnKey(string strKey, string strValue) void CBaseTrigger::CBaseTrigger(void) { - m_strMessage = ""; CBaseEntity::CBaseEntity(); } diff --git a/src/gs-entbase/server/env_render.cpp b/src/gs-entbase/server/env_render.cpp index 218085fa..54393d1d 100644 --- a/src/gs-entbase/server/env_render.cpp +++ b/src/gs-entbase/server/env_render.cpp @@ -18,9 +18,9 @@ "targetname" Name "target" Target when triggered. "killtarget" Target to kill when triggered. -"rendermode" Render-Mode the target changes to -"renderamt" Render-Alpha the target changes to -"rendercolor" Render-Color the target changes to +"rendermode" Render-Mode the target changes to. +"renderamt" Render-Alpha the target changes to. +"rendercolor" Render-Color the target changes to. Changes the visual appearance of a target. */ @@ -70,5 +70,5 @@ env_render::Trigger(entity act, int state) void env_render::env_render(void) { - CBaseEntity::CBaseEntity(); + CBaseTrigger::CBaseTrigger(); } diff --git a/src/server/cstrike/armoury_entity.cpp b/src/server/cstrike/armoury_entity.cpp index 61735dd4..bf393934 100644 --- a/src/server/cstrike/armoury_entity.cpp +++ b/src/server/cstrike/armoury_entity.cpp @@ -106,6 +106,7 @@ class armoury_entity:CBaseEntity void(void) armoury_entity; virtual void(void) touch; virtual void(void) Respawn; + virtual void(string, string) SpawnKey; }; void @@ -142,6 +143,31 @@ armoury_entity::Respawn(void) droptofloor(); } +void +armoury_entity::SpawnKey(string strKey, string strValue) +{ + switch (strKey) { + case "count": + m_iCount = stoi(strValue); + break; + case "item": + int id = stoi(strValue); + + if (id < 0 || id >= 19) { + print(sprintf("^1armoury_entity with invalid item %i. ignoring\n", m_iItem)); + remove(this); + return; + } + + m_iItem = g_cstrike_armouryitems[id]; + model = sArmouryModels[id]; + break; + default: + CBaseEntity::SpawnKey(strKey, strValue); + break; + } +} + void armoury_entity::armoury_entity(void) { @@ -151,28 +177,5 @@ armoury_entity::armoury_entity(void) } m_iCount = 1; - - for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) { - switch (argv(i)) { - case "count": - m_iCount = stoi(argv(i+1)); - break; - case "item": - int id = stoi(argv(i+1)); - - if (id < 0 || id >= 19) { - print(sprintf("^1armoury_entity with invalid item %i. ignoring\n", m_iItem)); - remove(this); - return; - } - - m_iItem = g_cstrike_armouryitems[id]; - model = sArmouryModels[id]; - break; - default: - break; - } - } - CBaseEntity::CBaseEntity(); } diff --git a/src/server/valve/monster_barney_dead.cpp b/src/server/valve/monster_barney_dead.cpp index 61e611aa..15acce98 100644 --- a/src/server/valve/monster_barney_dead.cpp +++ b/src/server/valve/monster_barney_dead.cpp @@ -30,23 +30,27 @@ class monster_barney_dead:CBaseEntity virtual void(void) Hide; virtual void(void) Respawn; virtual void(void) Gib; + virtual void(string, string) SpawnKey; }; -void monster_barney_dead::Gib(void) +void +monster_barney_dead::Gib(void) { takedamage = DAMAGE_NO; FX_GibHuman(this.origin); Hide(); } -void monster_barney_dead::Hide(void) +void +monster_barney_dead::Hide(void) { SetModel(""); solid = SOLID_NOT; movetype = MOVETYPE_NONE; } -void monster_barney_dead::Respawn(void) +void +monster_barney_dead::Respawn(void) { v_angle[0] = Math_FixDelta(m_oldAngle[0]); v_angle[1] = Math_FixDelta(m_oldAngle[1]); @@ -65,20 +69,21 @@ void monster_barney_dead::Respawn(void) SetFrame(35 + m_iPose); } -void monster_barney_dead::monster_barney_dead(void) +void +monster_barney_dead::SpawnKey(string strKey, string strValue) +{ + switch (strKey) { + case "pose": + m_iPose = stoi(strValue); + break; + default: + CBaseMonster::SpawnKey(strKey, strValue); + } +} + +void +monster_barney_dead::monster_barney_dead(void) { model = "models/barney.mdl"; - - for (int i = 1; i < (tokenize(__fullspawndata)-1); i += 2) { - switch (argv(i)) { - case "pose": - m_iPose = stoi(argv(i+1)); - default: - break; - } - } - - CBaseEntity::CBaseEntity(); - precache_model(m_oldModel); - Respawn(); + CBaseMonster::CBaseMonster(); } diff --git a/src/server/valve/monster_hevsuit_dead.cpp b/src/server/valve/monster_hevsuit_dead.cpp index 7e819e76..f99937a2 100644 --- a/src/server/valve/monster_hevsuit_dead.cpp +++ b/src/server/valve/monster_hevsuit_dead.cpp @@ -30,23 +30,27 @@ class monster_hevsuit_dead:CBaseMonster virtual void(void) Hide; virtual void(void) Respawn; virtual void(void) Gib; + virtual void(string, string) SpawnKey; }; -void monster_hevsuit_dead::Gib(void) +void +monster_hevsuit_dead::Gib(void) { takedamage = DAMAGE_NO; FX_GibHuman(this.origin); Hide(); } -void monster_hevsuit_dead::Hide(void) +void +monster_hevsuit_dead::Hide(void) { SetModel(""); solid = SOLID_NOT; movetype = MOVETYPE_NONE; } -void monster_hevsuit_dead::Respawn(void) +void +monster_hevsuit_dead::Respawn(void) { v_angle[0] = Math_FixDelta(m_oldAngle[0]); v_angle[1] = Math_FixDelta(m_oldAngle[1]); @@ -66,28 +70,28 @@ void monster_hevsuit_dead::Respawn(void) SendFlags |= NPC_BODY; } -void monster_hevsuit_dead::monster_hevsuit_dead(void) +void +monster_hevsuit_dead::SpawnKey(string strKey, string strValue) +{ + switch (strKey) { + case "pose": + m_iPose = stoi(strValue); + break; + case "body": + SetBody(stoi(strValue) + 1); + break; + case "skin": + SetSkin(stoi(strValue)); + break; + default: + CBaseMonster::SpawnKey(strKey, strValue); + } +} + +void +monster_hevsuit_dead::monster_hevsuit_dead(void) { model = "models/player.mdl"; m_iBody = 2; - - for (int i = 1; i < (tokenize(__fullspawndata)-1); i += 2) { - switch (argv(i)) { - case "pose": - m_iPose = stoi(argv(i+1)); - break; - case "body": - SetBody(stoi(argv(i+1)) + 1); - break; - case "skin": - SetSkin(stoi(argv(i+1))); - break; - default: - break; - } - } - - CBaseEntity::CBaseEntity(); - precache_model(m_oldModel); - Respawn(); + CBaseMonster::CBaseMonster(); } diff --git a/src/server/valve/monster_hgrunt_dead.cpp b/src/server/valve/monster_hgrunt_dead.cpp index aa4108c6..77d6a1ca 100644 --- a/src/server/valve/monster_hgrunt_dead.cpp +++ b/src/server/valve/monster_hgrunt_dead.cpp @@ -30,23 +30,27 @@ class monster_hgrunt_dead:CBaseMonster virtual void(void) Hide; virtual void(void) Respawn; virtual void(void) Gib; + virtual void(string, string) SpawnKey; }; -void monster_hgrunt_dead::Gib(void) +void +monster_hgrunt_dead::Gib(void) { takedamage = DAMAGE_NO; FX_GibHuman(this.origin); Hide(); } -void monster_hgrunt_dead::Hide(void) +void +monster_hgrunt_dead::Hide(void) { SetModel(""); solid = SOLID_NOT; movetype = MOVETYPE_NONE; } -void monster_hgrunt_dead::Respawn(void) +void +monster_hgrunt_dead::Respawn(void) { v_angle[0] = Math_FixDelta(m_oldAngle[0]); v_angle[1] = Math_FixDelta(m_oldAngle[1]); @@ -66,27 +70,27 @@ void monster_hgrunt_dead::Respawn(void) SendFlags |= NPC_BODY; } -void monster_hgrunt_dead::monster_hgrunt_dead(void) +void +monster_hgrunt_dead::SpawnKey(string strKey, string strValue) +{ + switch (strKey) { + case "pose": + m_iPose = stoi(strValue); + break; + case "body": + m_iBody = stoi(strValue) + 1; + break; + case "skin": + skin = stoi(strValue); + break; + default: + CBaseMonster::SpawnKey(strKey, strValue); + } +} + +void +monster_hgrunt_dead::monster_hgrunt_dead(void) { model = "models/hgrunt.mdl"; - - for (int i = 1; i < (tokenize(__fullspawndata)-1); i += 2) { - switch (argv(i)) { - case "pose": - m_iPose = stoi(argv(i+1)); - break; - case "body": - m_iBody = stoi(argv(i+1)) + 1; - break; - case "skin": - skin = stoi(argv(i+1)); - break; - default: - break; - } - } - - CBaseEntity::CBaseEntity(); - precache_model(m_oldModel); - Respawn(); + CBaseMonster::CBaseMonster(); } diff --git a/src/server/valve/monster_scientist.cpp b/src/server/valve/monster_scientist.cpp index 769ff12b..d96df450 100644 --- a/src/server/valve/monster_scientist.cpp +++ b/src/server/valve/monster_scientist.cpp @@ -80,6 +80,7 @@ class monster_scientist:CBaseNPC virtual int(void) AnimIdle; virtual int(void) AnimWalk; virtual int(void) AnimRun; + virtual void(string, string) SpawnKey; }; int @@ -152,6 +153,18 @@ monster_scientist::Respawn(void) m_iFlags |= MONSTER_CANFOLLOW; } +void +monster_scientist::SpawnKey(string strKey, string strValue) +{ + switch (strKey) { + case "body": + SetBody(stoi(strValue) + 1); + break; + default: + CBaseEntity::SpawnKey(strKey, strValue); + } +} + void monster_scientist::monster_scientist(void) { @@ -187,48 +200,36 @@ monster_scientist::monster_scientist(void) m_talkUnfollow = "!SC_WAIT"; m_talkFollow = "!SC_OK"; m_talkStopFollow = "!SC_STOP"; - - /* by default a random character etc. is chosen */ - int body = -1; - for (int i = 1; i < (tokenize(__fullspawndata)-1); i += 2) { - switch (argv(i)) { - case "body": - body = stoi(argv(i+1)) + 1; - SetBody(body); - break; - default: - break; - } - } + m_iBody = -1; model = "models/scientist.mdl"; base_mins = [-16,-16,0]; base_maxs = [16,16,72]; base_health = Skill_GetValue("scientist_health"); + CBaseNPC::CBaseNPC(); + /* has the body not been overriden, etc. choose a character for us */ - if (body == -1) { + 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"; + 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"; } - - CBaseNPC::CBaseNPC(); } diff --git a/src/server/valve/monster_scientist_dead.cpp b/src/server/valve/monster_scientist_dead.cpp index cd05c283..8e823794 100644 --- a/src/server/valve/monster_scientist_dead.cpp +++ b/src/server/valve/monster_scientist_dead.cpp @@ -41,23 +41,27 @@ class monster_scientist_dead:CBaseMonster virtual void(void) Hide; virtual void(void) Respawn; virtual void(void) Gib; + virtual void(string, string) SpawnKey; }; -void monster_scientist_dead::Gib(void) +void +monster_scientist_dead::Gib(void) { takedamage = DAMAGE_NO; FX_GibHuman(this.origin); Hide(); } -void monster_scientist_dead::Hide(void) +void +monster_scientist_dead::Hide(void) { SetModel(""); solid = SOLID_NOT; movetype = MOVETYPE_NONE; } -void monster_scientist_dead::Respawn(void) +void +monster_scientist_dead::Respawn(void) { v_angle[0] = Math_FixDelta(m_oldAngle[0]); v_angle[1] = Math_FixDelta(m_oldAngle[1]); @@ -101,27 +105,27 @@ void monster_scientist_dead::Respawn(void) droptofloor(); } -void monster_scientist_dead::monster_scientist_dead(void) +void +monster_scientist_dead::SpawnKey(string strKey, string strValue) +{ + switch (strKey) { + case "pose": + m_iPose = stoi(strValue); + break; + case "body": + SetBody(stoi(strValue) + 1); + break; + case "skin": + SetSkin(stoi(strValue)); + break; + default: + CBaseMonster::SpawnKey(strKey, strValue); + } +} + +void +monster_scientist_dead::monster_scientist_dead(void) { model = "models/scientist.mdl"; - - for (int i = 1; i < (tokenize(__fullspawndata)-1); i += 2) { - switch (argv(i)) { - case "pose": - m_iPose = stoi(argv(i+1)); - break; - case "body": - m_iBody = stoi(argv(i+1)) + 1; - break; - case "skin": - skin = stoi(argv(i+1)); - break; - default: - break; - } - } - - CBaseEntity::CBaseEntity(); - precache_model(m_oldModel); - Respawn(); + CBaseMonster::CBaseMonster(); } diff --git a/src/server/valve/monster_sitting_scientist.cpp b/src/server/valve/monster_sitting_scientist.cpp index fbe45915..b4aff432 100644 --- a/src/server/valve/monster_sitting_scientist.cpp +++ b/src/server/valve/monster_sitting_scientist.cpp @@ -42,6 +42,7 @@ class monster_sitting_scientist:CBaseMonster virtual void(void) Respawn; virtual void(void) Death; virtual void(void) Gib; + virtual void(string, string) SpawnKey; }; void @@ -91,52 +92,51 @@ monster_sitting_scientist::Respawn(void) droptofloor(); } +void +monster_sitting_scientist::SpawnKey(string strKey, string strValue) +{ + switch (strKey) { + case "pose": + m_iPose = stoi(strValue); + break; + case "body": + SetBody(stoi(strValue) + 1); + break; + case "skin": + SetSkin(stoi(strValue)); + break; + default: + CBaseMonster::SpawnKey(strKey, strValue); + } +} + void monster_sitting_scientist::monster_sitting_scientist(void) { model = "models/scientist.mdl"; - - for (int i = 1; i < (tokenize(__fullspawndata)-1); i += 2) { - switch (argv(i)) { - case "pose": - m_iPose = stoi(argv(i+1)); - break; - case "body": - m_iBody = stoi(argv(i+1)) + 1; - break; - case "skin": - skin = stoi(argv(i+1)); - break; - default: - break; - } - } + CBaseMonster::CBaseMonster(); + /* has the body not been overriden, etc. choose a character for us */ if (m_iBody == -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 */ - m_iBody = floor(random(1,5)); + 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"; - skin = 1; - break; - default: - m_flPitch = 100; - netname = "Slick"; + 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"; } - - CBaseEntity::CBaseEntity(); - precache_model(m_oldModel); }