diff --git a/src/client/chat.c b/src/client/chat.c index c18d1ceb..31ce72cd 100644 --- a/src/client/chat.c +++ b/src/client/chat.c @@ -30,6 +30,25 @@ void Chat_Draw(void) { int i; + + /* the voting stuff resides here too, for now */ + if (serverkey("vote_cmd")) { + string tempstr; + vector temppos; + tempstr = sprintf("^3Vote: %s", serverkey("vote_cmd")); + temppos[0] = (video_res[0]/2) - (stringwidth(tempstr, TRUE, [12,12]) / 2); + temppos[1] = 96; + drawstring(temppos, tempstr, [12,12], [1,1,1], 1.0f, 0); + + tempstr = sprintf( + "^2Yes: %s ^1No: %s", + serverkey("votes_y"), + serverkey("votes_n") + ); + temppos[0] = (video_res[0]/2) - (stringwidth(tempstr, TRUE, [12,12]) / 2); + drawstring(temppos + [0,16], tempstr, [12,12], [1,1,1], 1.0f, 0); + } + g_chatpos[0] = video_mins[0] + 16; g_chatpos[1] = video_mins[1] + video_res[1] - 128; diff --git a/src/client/entities.c b/src/client/entities.c index e072a2c7..d225fd87 100644 --- a/src/client/entities.c +++ b/src/client/entities.c @@ -29,7 +29,9 @@ void CSQC_Ent_Update(float new) switch (t) { case ENT_ENTITY: CBaseEntity me = (CBaseEntity)self; - spawnfunc_CBaseEntity(); + if (new) { + spawnfunc_CBaseEntity(); + } me.ReadEntity(readfloat()); break; case ENT_PLAYER: @@ -50,6 +52,13 @@ void CSQC_Ent_Update(float new) case ENT_AMBIENTSOUND: Sound_ParseLoopingEntity(self, new); break; + case ENT_ENVLASER: + env_laser l = (env_laser)self; + if (new) { + spawnfunc_env_laser(); + } + l.ReadEntity(readfloat()); + break; default: if (Game_Entity_Update(t, new) == FALSE) { error("Unknown entity type update received.\n"); diff --git a/src/client/entry.c b/src/client/entry.c index 76ad2c9f..f23d8265 100644 --- a/src/client/entry.c +++ b/src/client/entry.c @@ -29,6 +29,8 @@ CSQC_Init(float apilevel, string enginename, float engineversion) registercommand("-use"); registercommand("+duck"); registercommand("-duck"); + registercommand( "callvote" ); + registercommand( "vote" ); /* Requested by Slacer */ registercommand("+zoomin"); @@ -569,6 +571,16 @@ CSQC_ConsoleCommand(string sCMD) tokenize(sCMD); switch (argv(0)) { + case "vote": + if (argv(1) == "yes") { + sendevent("VoteY", ""); + } else if (argv(1) == "no") { + sendevent("VoteN", ""); + } + break; + case "callvote": + sendevent("CallVote", "s", substring(sCMD, 9, strlen(sCMD)-9)); + break; case "+zoomin": pSeat->iZoomed = TRUE; break; diff --git a/src/client/npc.c b/src/client/npc.c index 35163e3a..40dd4f47 100644 --- a/src/client/npc.c +++ b/src/client/npc.c @@ -93,7 +93,7 @@ NPC_ReadEntity(float new) if (fl & NPC_BODY) pl.body = readbyte(); - if (new) { + if (new || (fl & NPC_BODY)) { setcustomskin(pl, "", sprintf("geomset 1 %i\n", pl.body)); } diff --git a/src/gs-entbase/client.src b/src/gs-entbase/client.src index b13bb8b0..629105a8 100644 --- a/src/gs-entbase/client.src +++ b/src/gs-entbase/client.src @@ -10,6 +10,7 @@ client/env_glow.cpp client/env_sound.cpp client/env_soundscape.cpp client/env_particle.cpp +client/env_laser.cpp client/func_lod.cpp client/func_dustmotes.cpp client/sky_camera.cpp diff --git a/src/gs-entbase/client/env_laser.cpp b/src/gs-entbase/client/env_laser.cpp new file mode 100644 index 00000000..01825bd1 --- /dev/null +++ b/src/gs-entbase/client/env_laser.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +void(float radius, vector texcoordbias) R_EndPolygonRibbon = #0; + +enumflags +{ + ENVLASER_CHANGED_ORIGIN, + ENVLASER_CHANGED_ANGLES, + ENVLASER_CHANGED_TEXTURE, + ENVLASER_CHANGED_ENDTEXTURE, + ENVLASER_CHANGED_STATE +}; + +class env_laser +{ + int m_iState; + string m_strBeamTex; + string m_strEndTex; + + void() env_laser; + + virtual void() Init; + virtual void() Initialized; + virtual void(float flChanged) ReadEntity; + virtual float(void) predraw; +}; + +float env_laser::predraw(void) +{ + if (!m_iState) { + return PREDRAW_NEXT; + } + + R_BeginPolygon(m_strBeamTex, 0, 0); + R_PolygonVertex(angles, [0,0], [1,1,1], 1.0f); + R_PolygonVertex(origin, [0,1], [1,1,1], 1.0f); + R_EndPolygonRibbon(2, [1,0]); + + addentity(this); + return PREDRAW_NEXT; +} + +void env_laser::ReadEntity(float flChanged) +{ + print("FUCK!\n"); + if (flChanged & ENVLASER_CHANGED_ORIGIN) { + origin[0] = readcoord(); + origin[1] = readcoord(); + origin[2] = readcoord(); + } + if (flChanged & ENVLASER_CHANGED_ANGLES) { + angles[0] = readcoord(); + angles[1] = readcoord(); + angles[2] = readcoord(); + } + if (flChanged & ENVLASER_CHANGED_TEXTURE) { + m_strBeamTex = sprintf("%s_0.tga", readstring()); + } + if (flChanged & ENVLASER_CHANGED_ENDTEXTURE) { + m_strEndTex = readstring(); + } + if (flChanged & ENVLASER_CHANGED_STATE) { + m_iState = readbyte(); + } + + drawmask = MASK_ENGINE; + setorigin(this, origin); +} + +void env_laser::Init(void) +{ +} + +void env_laser::Initialized(void) +{ +} + +void env_laser::env_laser(void) +{ +} diff --git a/src/gs-entbase/server/baseentity.cpp b/src/gs-entbase/server/baseentity.cpp index a6520763..bf25a722 100644 --- a/src/gs-entbase/server/baseentity.cpp +++ b/src/gs-entbase/server/baseentity.cpp @@ -202,7 +202,7 @@ void CBaseEntity :: CBaseEntity ( void ) m_rendercolor = [1,1,1]; m_rendermode = 0;*/ - gflags |= GF_CANRESPAWN; + gflags = GF_CANRESPAWN; effects |= EF_NOSHADOW; int nfields = tokenize( __fullspawndata ); @@ -234,7 +234,7 @@ void CBaseEntity :: CBaseEntity ( void ) m_rendercolor = stov( argv( i + 1 ) ); break; case "alpha": - m_renderamt = stof( argv( i + 1 ) ) / 255; + m_renderamt = stof( argv( i + 1 ) ); break; case "renderamt": m_renderamt = stof( argv( i + 1 ) ) / 255; @@ -281,7 +281,7 @@ void CBaseEntity::RendermodeUpdate(void) } colormod = m_rendercolor; - alpha = bound(0.001, ( m_renderamt / 255 ), 1.0); + alpha = bound(0.001, m_renderamt, 1.0); if ( m_rendermode == RM_ADDITIVE ) { effects = EF_FLAG2; // SSQC: EF_ADDITIVE diff --git a/src/gs-entbase/server/basemonster.cpp b/src/gs-entbase/server/basemonster.cpp index 3a7f8a99..02b07495 100644 --- a/src/gs-entbase/server/basemonster.cpp +++ b/src/gs-entbase/server/basemonster.cpp @@ -16,6 +16,11 @@ class CBaseMonster:CBaseEntity { + int body; + int oldnet_body; + vector oldnet_velocity; + float m_flPitch; + void() CBaseMonster; virtual void() touch; @@ -26,8 +31,61 @@ class CBaseMonster:CBaseEntity virtual void(int) vDeath; virtual void() Physics; virtual void() Gib; + virtual void(string) Speak; + virtual float(entity, float) SendEntity; + virtual void() ParentUpdate; }; +void CBaseMonster::Speak(string msg) +{ + WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); + WriteByte(MSG_MULTICAST, EV_SPEAK); + WriteEntity(MSG_MULTICAST, this); + WriteString(MSG_MULTICAST, msg); + WriteFloat(MSG_MULTICAST, m_flPitch); + msg_entity = this; + multicast(origin, MULTICAST_PVS); +} + +float CBaseMonster::SendEntity(entity ePEnt, float fChanged) +{ + if (modelindex == 0) { + return FALSE; + } + + WriteByte(MSG_ENTITY, ENT_NPC); + WriteShort(MSG_ENTITY, fChanged); + + if (fChanged & NPC_MODELINDEX) + WriteShort(MSG_ENTITY, modelindex); + if (fChanged & NPC_ORIGIN_X) + WriteCoord(MSG_ENTITY, origin[0]); + if (fChanged & NPC_ORIGIN_Y) + WriteCoord(MSG_ENTITY, origin[1]); + if (fChanged & NPC_ORIGIN_Z) + WriteCoord(MSG_ENTITY, origin[2]); + if (fChanged & NPC_ANGLES_X) + WriteFloat(MSG_ENTITY, angles[0]); + if (fChanged & NPC_ANGLES_Y) + WriteFloat(MSG_ENTITY, angles[1]); + if (fChanged & NPC_ANGLES_Z) + WriteFloat(MSG_ENTITY, angles[2]); + if (fChanged & NPC_VELOCITY_X) + WriteCoord(MSG_ENTITY, velocity[0]); + if (fChanged & NPC_VELOCITY_Y) + WriteCoord(MSG_ENTITY, velocity[1]); + if (fChanged & NPC_VELOCITY_Z) + WriteCoord(MSG_ENTITY, velocity[2]); + if (fChanged & NPC_FRAME) + WriteByte(MSG_ENTITY, frame); + if (fChanged & NPC_SKIN) + WriteByte(MSG_ENTITY, skin); + if (fChanged & NPC_BODY) + WriteByte(MSG_ENTITY, body); + + return TRUE; +} + void CBaseMonster::Gib(void) { takedamage = DAMAGE_NO; @@ -61,6 +119,44 @@ void CBaseMonster::PlayerUse(void) } +void CBaseMonster::ParentUpdate(void) +{ + if (modelindex != oldnet_modelindex) + SendFlags |= NPC_MODELINDEX; + if (origin[0] != oldnet_origin[0]) + SendFlags |= NPC_ORIGIN_X; + if (origin[1] != oldnet_origin[1]) + SendFlags |= NPC_ORIGIN_Y; + if (origin[2] != oldnet_origin[2]) + SendFlags |= NPC_ORIGIN_Z; + if (angles[0] != oldnet_angles[0]) + SendFlags |= NPC_ANGLES_X; + if (angles[1] != oldnet_angles[1]) + SendFlags |= NPC_ANGLES_Y; + if (angles[2] != oldnet_angles[2]) + SendFlags |= NPC_ANGLES_Z; + if (velocity[0] != oldnet_velocity[0]) + SendFlags |= NPC_VELOCITY_X; + if (velocity[1] != oldnet_velocity[1]) + SendFlags |= NPC_VELOCITY_Y; + if (velocity[2] != oldnet_velocity[2]) + SendFlags |= NPC_VELOCITY_Z; + if (frame != oldnet_frame) + SendFlags |= NPC_FRAME; + if (skin != oldnet_skin) + SendFlags |= NPC_SKIN; + if (body != oldnet_body) + SendFlags |= NPC_BODY; + + oldnet_modelindex = modelindex; + oldnet_origin = origin; + oldnet_angles = angles; + oldnet_velocity = velocity; + oldnet_frame = frame; + oldnet_skin = skin; + oldnet_body = body; +} + void CBaseMonster::vPain(int iHitBody) { @@ -88,6 +184,7 @@ void CBaseMonster::Hide(void) void CBaseMonster::Respawn(void) { + flags |= FL_MONSTER; setorigin(this, m_oldOrigin); angles = v_angle; solid = SOLID_SLIDEBOX; diff --git a/src/gs-entbase/server/env_laser.cpp b/src/gs-entbase/server/env_laser.cpp index 55f5300d..4c33b85d 100644 --- a/src/gs-entbase/server/env_laser.cpp +++ b/src/gs-entbase/server/env_laser.cpp @@ -19,9 +19,18 @@ "target" Target when triggered. "killtarget" Target to kill when triggered. -Shoots a frickin beam. +Shoots a frickin lazer. */ +enumflags +{ + ENVLASER_CHANGED_ORIGIN, + ENVLASER_CHANGED_ANGLES, + ENVLASER_CHANGED_TEXTURE, + ENVLASER_CHANGED_ENDTEXTURE, + ENVLASER_CHANGED_STATE +}; + enumflags { ENVLAZ_STARTON, @@ -36,6 +45,7 @@ enumflags class env_laser:CBaseTrigger { int m_iState; + int m_iStateOld; float m_flDPS; string m_strLaserDest; string m_strBeamTex; @@ -46,6 +56,8 @@ class env_laser:CBaseTrigger virtual void() think; virtual void() Trigger; virtual void() Respawn; + virtual void() ParentUpdate; + virtual float(entity, float) SendEntity; }; void env_laser::think(void) @@ -59,6 +71,7 @@ void env_laser::think(void) } t = (CBaseTrigger)find(world, CBaseEntity::m_strTargetName, m_strLaserDest); + angles = t.origin; if (!t) { print("env_laser without valid target. Aborting\n"); @@ -66,7 +79,6 @@ void env_laser::think(void) } traceline(origin, t.origin, FALSE, this); - te_beam(world, origin, t.origin); if (trace_ent.takedamage) { Damage_Apply(trace_ent, this, rint(m_flDPS), 0, DMG_GENERIC); @@ -92,15 +104,81 @@ void env_laser::Respawn(void) } } +float env_laser::SendEntity(entity ePEnt, float fChanged) +{ + WriteByte(MSG_ENTITY, ENT_ENVLASER); + WriteFloat(MSG_ENTITY, fChanged); + + if (fChanged & ENVLASER_CHANGED_ORIGIN) { + WriteCoord(MSG_ENTITY, origin[0]); + WriteCoord(MSG_ENTITY, origin[1]); + WriteCoord(MSG_ENTITY, origin[2]); + } + if (fChanged & ENVLASER_CHANGED_ANGLES) { + WriteCoord(MSG_ENTITY, angles[0]); + WriteCoord(MSG_ENTITY, angles[1]); + WriteCoord(MSG_ENTITY, angles[2]); + } + if (fChanged & ENVLASER_CHANGED_TEXTURE) { + WriteString(MSG_ENTITY, m_strBeamTex); + } + if (fChanged & ENVLASER_CHANGED_ENDTEXTURE) { + WriteString(MSG_ENTITY, m_strEndTex); + } + if (fChanged & ENVLASER_CHANGED_STATE) { + WriteByte(MSG_ENTITY, m_iState); + } + + return TRUE; +} + +void env_laser::ParentUpdate(void) +{ + /* Check our fields for networking */ + if (origin != oldnet_origin) { + SendFlags |= ENVLASER_CHANGED_ORIGIN; + SendFlags |= ENVLASER_CHANGED_ANGLES; + SendFlags |= ENVLASER_CHANGED_STATE; + SendFlags |= ENVLASER_CHANGED_TEXTURE; + oldnet_origin = origin; + } + if (angles != oldnet_angles) { + SendFlags |= ENVLASER_CHANGED_ORIGIN; + SendFlags |= ENVLASER_CHANGED_ANGLES; + SendFlags |= ENVLASER_CHANGED_STATE; + SendFlags |= ENVLASER_CHANGED_TEXTURE; + oldnet_angles = angles; + } + if (m_iState != m_iStateOld) { + SendFlags |= ENVLASER_CHANGED_ORIGIN; + SendFlags |= ENVLASER_CHANGED_ANGLES; + SendFlags |= ENVLASER_CHANGED_STATE; + SendFlags |= ENVLASER_CHANGED_TEXTURE; + m_iStateOld = m_iState; + } + + if (m_parent) { + entity p = find(world, CBaseEntity::m_strTargetName, m_parent); + + if (!p) { + return; + } + + setorigin(this, p.origin); + } +} + void env_laser::env_laser(void) { for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) { switch (argv(i)) { case "texture": m_strBeamTex = argv(i + 1); + precache_model(m_strBeamTex); break; case "EndSprite": m_strEndTex = argv(i + 1); + precache_model(m_strEndTex); break; case "LaserTarget": m_strLaserDest = argv(i + 1); @@ -114,4 +192,6 @@ void env_laser::env_laser(void) } CBaseTrigger::CBaseTrigger(); + gflags = GF_CANRESPAWN; + pvsflags = PVSF_IGNOREPVS; } diff --git a/src/menu-fn/m_internetgames.cpp b/src/menu-fn/m_internetgames.cpp index bcd5ff98..54055c27 100644 --- a/src/menu-fn/m_internetgames.cpp +++ b/src/menu-fn/m_internetgames.cpp @@ -26,13 +26,18 @@ CMainButton inet_btnChatRooms; CMainButton inet_btnDone; CFrame inet_frServers; -CServerList inet_lbServers; +CListBox inet_lbServers_Name; +CListBox inet_lbServers_Ping; +CListBox inet_lbServers_Map; +CListBox inet_lbServers_Game; +CListBox inet_lbServers_Players; +CListBox inet_lbServers_Addresses; CScrollbar inet_sbServers; /* Button Callbacks */ void inet_btnjoin(void) { - string addr = inet_lbServers.GetSelectedItem(); + string addr = inet_lbServers_Addresses.GetSelectedItem(); if (addr) { localcmd(sprintf("connect %s\n", addr)); @@ -43,7 +48,7 @@ void inet_btncreate_start(void) static void inet_btncreate_end(void) { g_menupage = PAGE_CREATEGAMEINET; } - cvar_set("sv_public", "1"); + cvar_set("sv_public", "2"); localsound("../media/launch_upmenu1.wav"); header.SetStartEndPos(30,172,45,45); header.SetStartEndSize(156,26,460,80); @@ -72,24 +77,65 @@ void inet_btnrefresh(void) int count = 0; int added = 0; - //Master_RefreshCache(); - count = gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT); - inet_lbServers.Clear(); + Master_RefreshCache(); + count = gethostcachevalue(SLIST_HOSTCACHETOTALCOUNT); + + inet_lbServers_Name.Clear(); + inet_lbServers_Ping.Clear(); + inet_lbServers_Map.Clear(); + inet_lbServers_Game.Clear(); + inet_lbServers_Players.Clear(); + inet_lbServers_Addresses.Clear(); for (int i = 0; i < count; i++) { - string address = gethostcachestring(srv_fldAdress, i); + string address; + string players; + string ping; + + address = gethostcachestring(srv_fldAdress, i); + + /* skip LAN */ if (!address || Server_IsLan(address)) { continue; } - inet_lbServers.AddEntry(address); + + players = sprintf("%d/%d", + stof(gethostcachestring(srv_fldPlayers, i)), + stof(gethostcachestring(srv_fldMaxplayers, i)) + ); + ping = sprintf("%d", gethostcachevalue(srv_fldPing, i)); + inet_lbServers_Name.AddEntry(gethostcachestring(srv_fldName, i)); + inet_lbServers_Ping.AddEntry(ping); + inet_lbServers_Map.AddEntry(gethostcachestring(srv_fldMap, i)); + inet_lbServers_Game.AddEntry(gethostcachestring(srv_fldGame, i)); + inet_lbServers_Players.AddEntry(players); + inet_lbServers_Addresses.AddEntry(address); print(sprintf("Adding %s to the Internet server list\n", address)); added++; } - print(sprintf("Added %i Internet servers.\n", added)); inet_sbServers.SetMax(added); } +void inet_lb_clicked(int val) +{ + inet_lbServers_Name.SetSelected(val); + inet_lbServers_Ping.SetSelected(val); + inet_lbServers_Map.SetSelected(val); + inet_lbServers_Game.SetSelected(val); + inet_lbServers_Players.SetSelected(val); + inet_lbServers_Addresses.SetSelected(val); +} +void inet_lb_changed(int val) +{ + inet_lbServers_Name.SetScroll(val); + inet_lbServers_Ping.SetScroll(val); + inet_lbServers_Map.SetScroll(val); + inet_lbServers_Game.SetScroll(val); + inet_lbServers_Players.SetScroll(val); + inet_lbServers_Addresses.SetScroll(val); +} + void menu_internetgames_init(void) { fn_inet = spawn(CWidget); @@ -147,15 +193,42 @@ void menu_internetgames_init(void) inet_frServers.SetSize(464-16,294); Widget_Add(fn_inet, inet_frServers); - inet_lbServers = spawn(CServerList); - inet_lbServers.SetPos(166+3,141+3); - inet_lbServers.SetSize(464-6-16,294-6); - Widget_Add(fn_inet, inet_lbServers); + inet_lbServers_Name = spawn(CListBox); + inet_lbServers_Name.SetPos(166+3,141+3); + inet_lbServers_Name.SetSize(188,294-6); + inet_lbServers_Name.SetChanged(inet_lb_clicked); + Widget_Add(fn_inet, inet_lbServers_Name); + + inet_lbServers_Ping = spawn(CListBox); + inet_lbServers_Ping.SetPos(357,141+3); + inet_lbServers_Ping.SetSize(50,294-6); + inet_lbServers_Ping.SetChanged(inet_lb_clicked); + Widget_Add(fn_inet, inet_lbServers_Ping); + + inet_lbServers_Map = spawn(CListBox); + inet_lbServers_Map.SetPos(407,141+3); + inet_lbServers_Map.SetSize(69,294-6); + inet_lbServers_Map.SetChanged(inet_lb_clicked); + Widget_Add(fn_inet, inet_lbServers_Map); + + inet_lbServers_Game = spawn(CListBox); + inet_lbServers_Game.SetPos(476,141+3); + inet_lbServers_Game.SetSize(76,294-6); + inet_lbServers_Game.SetChanged(inet_lb_clicked); + Widget_Add(fn_inet, inet_lbServers_Game); + + inet_lbServers_Players = spawn(CListBox); + inet_lbServers_Players.SetPos(552,141+3); + inet_lbServers_Players.SetSize(62,294-6); + inet_lbServers_Players.SetChanged(inet_lb_clicked); + Widget_Add(fn_inet, inet_lbServers_Players); + + inet_lbServers_Addresses = spawn(CListBox); inet_sbServers = spawn(CScrollbar); inet_sbServers.SetPos(614,141); inet_sbServers.SetHeight(294); - //inet_sbServers.SetCallback(vm_sbres_changed); + inet_sbServers.SetCallback(inet_lb_changed); //xinet_sbServers.SetMax(g_resolutions.length); Widget_Add(fn_inet, inet_sbServers); @@ -169,9 +242,9 @@ void menu_internetgames_init(void) void menu_internetgames_draw(void) { Widget_Draw(fn_inet); - Master_ResortCache(); + resorthostcache(); drawpic([g_menuofs[0]+45,g_menuofs[1]+45], g_bmp[HEAD_INETGAMES],[460,80], [1,1,1], 1.0f, 1); - + /* Labels */ WLabel_Static(252, 128, m_reslbl[IDS_SERVER_GAMESERVER], 10, 10, [1,1,1], 1.0f, 0, font_arial); diff --git a/src/menu-fn/m_langames.cpp b/src/menu-fn/m_langames.cpp index f0170121..5edecc7d 100644 --- a/src/menu-fn/m_langames.cpp +++ b/src/menu-fn/m_langames.cpp @@ -22,18 +22,24 @@ CMainButton lan_btnRefresh; CMainButton lan_btnDone; CFrame lan_frServers; -CServerList lan_lbServers; +CListBox lan_lbServers_Name; +CListBox lan_lbServers_Ping; +CListBox lan_lbServers_Map; +CListBox lan_lbServers_Game; +CListBox lan_lbServers_Players; +CListBox lan_lbServers_Addresses; CScrollbar lan_sbServers; /* Button Callbacks */ void lan_btnjoin(void) { - string addr = lan_lbServers.GetSelectedItem(); + string addr = lan_lbServers_Addresses.GetSelectedItem(); if (addr) { localcmd(sprintf("connect %s\n", addr)); } } + void lan_btncreate_start(void) { static void lan_btncreate_end(void) { @@ -62,21 +68,42 @@ void lan_btndone_start(void) header.SetHeader(HEAD_LAN); header.SetExecute(lan_btndone_end); } + void lan_btnrefresh(void) { int count = 0; int added = 0; - //Master_RefreshCache(); + Master_RefreshCache(); count = gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT); - lan_lbServers.Clear(); + lan_lbServers_Name.Clear(); + lan_lbServers_Ping.Clear(); + lan_lbServers_Map.Clear(); + lan_lbServers_Game.Clear(); + lan_lbServers_Players.Clear(); + lan_lbServers_Addresses.Clear(); for (int i = 0; i < count; i++) { - string address = gethostcachestring(srv_fldAdress, i); + string address; + string players; + string ping; + + address = gethostcachestring(srv_fldAdress, i); if (!address || !Server_IsLan(address)) { continue; } - lan_lbServers.AddEntry(address); + + players = sprintf("%d/%d", + stof(gethostcachestring(srv_fldPlayers, i)), + stof(gethostcachestring(srv_fldMaxplayers, i)) + ); + ping = sprintf("%d", gethostcachevalue(srv_fldPing, i)); + lan_lbServers_Name.AddEntry(gethostcachestring(srv_fldName, i)); + lan_lbServers_Ping.AddEntry(ping); + lan_lbServers_Map.AddEntry(gethostcachestring(srv_fldMap, i)); + lan_lbServers_Game.AddEntry(gethostcachestring(srv_fldGame, i)); + lan_lbServers_Players.AddEntry(players); + lan_lbServers_Addresses.AddEntry(address); print(sprintf("Adding %s to the LAN server list\n", address)); added++; } @@ -84,6 +111,26 @@ void lan_btnrefresh(void) lan_sbServers.SetMax(added); } +void lan_lb_clicked(int val) +{ + lan_lbServers_Name.SetSelected(val); + lan_lbServers_Ping.SetSelected(val); + lan_lbServers_Map.SetSelected(val); + lan_lbServers_Game.SetSelected(val); + lan_lbServers_Players.SetSelected(val); + lan_lbServers_Addresses.SetSelected(val); +} + +void lan_lb_changed(int val) +{ + lan_lbServers_Name.SetScroll(val); + lan_lbServers_Ping.SetScroll(val); + lan_lbServers_Map.SetScroll(val); + lan_lbServers_Game.SetScroll(val); + lan_lbServers_Players.SetScroll(val); + lan_lbServers_Addresses.SetScroll(val); +} + void menu_langames_init(void) { fn_lan = spawn(CWidget); @@ -123,15 +170,42 @@ void menu_langames_init(void) lan_frServers.SetSize(434-16,309); Widget_Add(fn_lan, lan_frServers); - lan_lbServers = spawn(CServerList); - lan_lbServers.SetPos(196+3,140+3); - lan_lbServers.SetSize(434-6-16,309-6); - Widget_Add(fn_lan, lan_lbServers); + lan_lbServers_Name = spawn(CListBox); + lan_lbServers_Name.SetPos(199,140+3); + lan_lbServers_Name.SetSize(178,309-6); + lan_lbServers_Name.SetChanged(lan_lb_clicked); + Widget_Add(fn_lan, lan_lbServers_Name); + + lan_lbServers_Ping = spawn(CListBox); + lan_lbServers_Ping.SetPos(377,140+3); + lan_lbServers_Ping.SetSize(45,309-6); + lan_lbServers_Ping.SetChanged(lan_lb_clicked); + Widget_Add(fn_lan, lan_lbServers_Ping); + + lan_lbServers_Map = spawn(CListBox); + lan_lbServers_Map.SetPos(422,140+3); + lan_lbServers_Map.SetSize(75,309-6); + lan_lbServers_Map.SetChanged(lan_lb_clicked); + Widget_Add(fn_lan, lan_lbServers_Map); + + lan_lbServers_Game = spawn(CListBox); + lan_lbServers_Game.SetPos(497,140+3); + lan_lbServers_Game.SetSize(75,309-6); + lan_lbServers_Game.SetChanged(lan_lb_clicked); + Widget_Add(fn_lan, lan_lbServers_Game); + + lan_lbServers_Players = spawn(CListBox); + lan_lbServers_Players.SetPos(572,140+3); + lan_lbServers_Players.SetSize(42,309-6); + lan_lbServers_Players.SetChanged(lan_lb_clicked); + Widget_Add(fn_lan, lan_lbServers_Players); + + lan_lbServers_Addresses = spawn(CListBox); lan_sbServers = spawn(CScrollbar); lan_sbServers.SetPos(614,141); lan_sbServers.SetHeight(309); - //lan_sbServers.SetCallback(vm_sbres_changed); + lan_sbServers.SetCallback(lan_lb_changed); //xlan_sbServers.SetMax(g_resolutions.length); Widget_Add(fn_lan, lan_sbServers); } diff --git a/src/menu-fn/m_multiplayer.cpp b/src/menu-fn/m_multiplayer.cpp index 79aa264b..9fd1d870 100644 --- a/src/menu-fn/m_multiplayer.cpp +++ b/src/menu-fn/m_multiplayer.cpp @@ -162,12 +162,14 @@ void menu_multiplayer_init(void) //mp_btnControls.SetExecute(btn_console); mp_btnControls.SetPos(50,332); Widget_Add(fn_multiplayer, mp_btnControls); - + mp_btnDone = spawn(CMainButton); mp_btnDone.SetImage(BTN_DONE); mp_btnDone.SetExecute(mp_btndone_start); mp_btnDone.SetPos(50,364); Widget_Add(fn_multiplayer, mp_btnDone); + + Master_UpdateCache(); } void menu_multiplayer_draw(void) @@ -197,7 +199,6 @@ void menu_multiplayer_draw(void) g_connected = TRUE; g_connectstatus = CONNECT_NONE; mp_btninet_start(); - inet_btnrefresh(); } mp_dgConnect.Draw(); WField_Static(162, 180, m_reslbl[IDS_WON_LOGIN], 320, 260, diff --git a/src/menu-fn/master.cpp b/src/menu-fn/master.cpp index 4662b989..a8a6117b 100644 --- a/src/menu-fn/master.cpp +++ b/src/menu-fn/master.cpp @@ -23,6 +23,7 @@ float srv_fldPing; float srv_fldPlayers; float srv_fldMaxplayers; float srv_fldMap; +float srv_fldGame; string Master_Resolve(void) { @@ -50,62 +51,34 @@ int Master_GetTotalServers(void) return gethostcachevalue(SLIST_HOSTCACHETOTALCOUNT); } -void Master_GetInternetList(void) -{ - print("Updating host cache...\n"); - string url = sprintf("%s:%d",MASTER_DNS,MASTER_PORT); - cvar_set("net_master1", url); - localcmd("net_master2 \"\"\n"); - localcmd("net_master3 \"\"\n"); - localcmd("net_master4 \"\"\n"); - localcmd("net_master5 \"\"\n"); - localcmd("net_master6 \"\"\n"); - localcmd("net_master7 \"\"\n"); - localcmd("net_master8 \"\"\n"); - localcmd("net_masterextra1 \"\"\n"); - localcmd("net_masterextra2 \"\"\n"); - localcmd("net_masterextra3 \"\"\n"); - localcmd("net_masterextra4 \"\"\n"); - localcmd("net_masterextra5 \"\"\n"); - localcmd("net_masterextra6 \"\"\n"); - localcmd("net_masterextra7 \"\"\n"); - localcmd("net_masterextra8 \"\"\n"); - resethostcachemasks(); - sethostcachesort( gethostcacheindexforkey( "ping" ), FALSE ); - refreshhostcache(); - resorthostcache(); -} - -void Master_GetLANList(void) -{ - localcmd("net_master1 \"localhost\"\n"); - localcmd("net_master2 \"\"\n"); - localcmd("net_master3 \"\"\n"); - localcmd("net_master4 \"\"\n"); - localcmd("net_master5 \"\"\n"); - localcmd("net_master6 \"\"\n"); - localcmd("net_master7 \"\"\n"); - localcmd("net_master8 \"\"\n"); - localcmd("net_masterextra1 \"\"\n"); - localcmd("net_masterextra2 \"\"\n"); - localcmd("net_masterextra3 \"\"\n"); - localcmd("net_masterextra4 \"\"\n"); - localcmd("net_masterextra5 \"\"\n"); - localcmd("net_masterextra6 \"\"\n"); - localcmd("net_masterextra7 \"\"\n"); - localcmd("net_masterextra8 \"\"\n"); - resethostcachemasks(); - sethostcachesort( gethostcacheindexforkey( "ping" ), FALSE ); - refreshhostcache(TRUE); - resorthostcache(); -} - void Master_RefreshCache(void) { print("Refreshing host cache...\n"); resethostcachemasks(); + //sethostcachemaskstring( 0, gethostcacheindexforkey( "gamedir" ), cvar_string("game"), SLIST_TEST_EQUAL ); sethostcachesort( gethostcacheindexforkey( "ping" ), FALSE ); refreshhostcache(FALSE); + resorthostcache(); + int a = gethostcachevalue(SLIST_HOSTCACHETOTALCOUNT); + + if (a) { + print(sprintf("Master reports a total of %i servers.\n", a)); + } +} + +void Master_UpdateCache(void) +{ + print("Updating host cache...\n"); + resethostcachemasks(); + //sethostcachemaskstring( 0, gethostcacheindexforkey( "gamedir" ), cvar_string("game"), SLIST_TEST_EQUAL ); + sethostcachesort( gethostcacheindexforkey( "ping" ), FALSE ); + refreshhostcache(TRUE); + resorthostcache(); + int a = gethostcachevalue(SLIST_HOSTCACHETOTALCOUNT); + + if (a) { + print(sprintf("Master reports a total of %i servers.\n", a)); + } } void Master_ResortCache(void) @@ -117,5 +90,51 @@ void Master_ResortCache(void) srv_fldPlayers = gethostcacheindexforkey("numhumans"); srv_fldMaxplayers = gethostcacheindexforkey("maxplayers"); srv_fldMap = gethostcacheindexforkey("map"); + srv_fldGame = gethostcacheindexforkey("game"); +} + +void Master_GetInternetList(void) +{ + /*string url = sprintf("%s:%d",MASTER_DNS,MASTER_PORT); + localcmd("net_master1 \"localhost\"\n"); + localcmd("net_master2 \"\"\n"); + localcmd("net_master3 \"\"\n"); + localcmd("net_master4 \"\"\n"); + localcmd("net_master5 \"\"\n"); + localcmd("net_master6 \"\"\n"); + localcmd("net_master7 \"\"\n"); + localcmd("net_master8 \"\"\n"); + cvar_set("net_masterextra1", url); + localcmd("net_masterextra2 \"\"\n"); + localcmd("net_masterextra3 \"\"\n"); + localcmd("net_masterextra4 \"\"\n"); + localcmd("net_masterextra5 \"\"\n"); + localcmd("net_masterextra6 \"\"\n"); + localcmd("net_masterextra7 \"\"\n"); + localcmd("net_masterextra8 \"\"\n");*/ + + Master_UpdateCache(); +} + +void Master_GetLANList(void) +{ + /*localcmd("net_master1 \"localhost\"\n"); + localcmd("net_master2 \"\"\n"); + localcmd("net_master3 \"\"\n"); + localcmd("net_master4 \"\"\n"); + localcmd("net_master5 \"\"\n"); + localcmd("net_master6 \"\"\n"); + localcmd("net_master7 \"\"\n"); + localcmd("net_master8 \"\"\n"); + localcmd("net_masterextra1 \"\"\n"); + localcmd("net_masterextra2 \"\"\n"); + localcmd("net_masterextra3 \"\"\n"); + localcmd("net_masterextra4 \"\"\n"); + localcmd("net_masterextra5 \"\"\n"); + localcmd("net_masterextra6 \"\"\n"); + localcmd("net_masterextra7 \"\"\n"); + localcmd("net_masterextra8 \"\"\n");*/ + + Master_UpdateCache(); } diff --git a/src/server/cstrike/progs.src b/src/server/cstrike/progs.src index c1c59476..7058db80 100755 --- a/src/server/cstrike/progs.src +++ b/src/server/cstrike/progs.src @@ -87,6 +87,6 @@ spawn.c input.c client.c ../client.c - +../vote.c ../entry.c #endlist diff --git a/src/server/entry.c b/src/server/entry.c index 6614801b..617a68e9 100644 --- a/src/server/entry.c +++ b/src/server/entry.c @@ -27,6 +27,7 @@ void StartFrame(void) } Game_StartFrame(); + Vote_Frame(); } void ClientConnect(float csqc_active) diff --git a/src/server/gearbox/input.c b/src/server/gearbox/input.c index 89e95e36..54cf641b 100644 --- a/src/server/gearbox/input.c +++ b/src/server/gearbox/input.c @@ -42,6 +42,7 @@ Game_Input(void) if (self.impulse == 101) { pl.health = 100; pl.armor = 100; + pl.g_items |= ITEM_SUIT; Weapons_AddItem(pl, WEAPON_CROWBAR); Weapons_AddItem(pl, WEAPON_GLOCK); Weapons_AddItem(pl, WEAPON_PYTHON); diff --git a/src/server/gearbox/progs.src b/src/server/gearbox/progs.src index 4e6c5ee4..5920ee01 100755 --- a/src/server/gearbox/progs.src +++ b/src/server/gearbox/progs.src @@ -19,9 +19,42 @@ ../logging.c ../nodes.c ../../gs-entbase/server.src + +../valve/monster_apache.cpp +../valve/monster_alien_controller.cpp +../valve/monster_alien_grunt.cpp +../valve/monster_alien_slave.cpp +../valve/monster_babycrab.cpp +../valve/monster_barnacle.cpp +../valve/monster_barney.cpp +../valve/monster_barney_dead.cpp +../valve/monster_bigmomma.cpp +../valve/monster_bloater.cpp +../valve/monster_bullchicken.cpp +../valve/monster_cockroach.cpp +../valve/monster_flyer_flock.cpp +../valve/monster_gargantua.cpp +../valve/monster_gman.cpp +../valve/monster_headcrab.cpp +../valve/monster_hevsuit_dead.cpp +../valve/monster_houndeye.cpp +../valve/monster_human_grunt.cpp +../valve/monster_hgrunt_dead.cpp +../valve/monster_human_assassin.cpp +../valve/monster_ichthyosaur.cpp +../valve/monster_leech.cpp +../valve/monster_miniturret.cpp +../valve/monster_nihilanth.cpp +../valve/monster_osprey.cpp ../valve/monster_rat.cpp -../valve/monster_scientist.cpp ../valve/monster_scientist_dead.cpp +../valve/monster_sitting_scientist.cpp +../valve/monster_scientist.cpp +../valve/monster_sentry.cpp +../valve/monster_tentacle.cpp +../valve/monster_turret.cpp +../valve/monster_zombie.cpp + ../../shared/decals.c ../../shared/effects.c ../../shared/spraylogo.cpp @@ -86,5 +119,6 @@ ../flashlight.c input.c ../valve/spawn.c +../vote.c ../entry.c #endlist diff --git a/src/server/hunger/progs.src b/src/server/hunger/progs.src index 8db92fa5..768b4ca0 100755 --- a/src/server/hunger/progs.src +++ b/src/server/hunger/progs.src @@ -83,5 +83,6 @@ ../flashlight.c input.c ../valve/spawn.c +../vote.c ../entry.c #endlist diff --git a/src/server/poke646/progs.src b/src/server/poke646/progs.src index 20be21ba..39dd0764 100755 --- a/src/server/poke646/progs.src +++ b/src/server/poke646/progs.src @@ -68,5 +68,6 @@ client.c ../flashlight.c input.c ../valve/spawn.c +../vote.c ../entry.c #endlist diff --git a/src/server/rewolf/progs.src b/src/server/rewolf/progs.src index 3390265a..5948f177 100755 --- a/src/server/rewolf/progs.src +++ b/src/server/rewolf/progs.src @@ -69,5 +69,6 @@ client.c ../flashlight.c input.c ../valve/spawn.c +../vote.c ../entry.c #endlist diff --git a/src/server/scihunt/monster_scientist.cpp b/src/server/scihunt/monster_scientist.cpp index f965d077..2087eed0 100644 --- a/src/server/scihunt/monster_scientist.cpp +++ b/src/server/scihunt/monster_scientist.cpp @@ -299,9 +299,8 @@ string sci_sndidle[] = { "scientist/hopenominal.wav", }; -class monster_scientist:CBaseEntity +class monster_scientist:CBaseMonster { - int body; vector m_vecLastUserPos; entity m_eUser; entity m_eRescuer; @@ -311,17 +310,7 @@ class monster_scientist:CBaseEntity float m_flPainTime; float m_flChangePath; float m_flTraceTime; - float m_flPitch; int m_iFlags; - - int old_modelindex; - vector old_origin; - vector old_angles; - vector old_velocity; - int old_frame; - int old_skin; - int old_body; - void() monster_scientist; virtual void() touch; @@ -332,70 +321,10 @@ class monster_scientist:CBaseEntity virtual void(int) vDeath; virtual void() Physics; virtual void() Scream; - virtual void() Gib; - virtual float(entity, float) SendEntity; virtual void() WarnOthers; - virtual void(string) Speak; virtual void() IdleChat; }; -float monster_scientist::SendEntity(entity ePEnt, float fChanged) -{ - if (modelindex == 0) { - return FALSE; - } - - WriteByte(MSG_ENTITY, ENT_NPC); - WriteShort(MSG_ENTITY, fChanged); - - if (fChanged & NPC_MODELINDEX) - WriteShort(MSG_ENTITY, modelindex); - if (fChanged & NPC_ORIGIN_X) - WriteCoord(MSG_ENTITY, origin[0]); - if (fChanged & NPC_ORIGIN_Y) - WriteCoord(MSG_ENTITY, origin[1]); - if (fChanged & NPC_ORIGIN_Z) - WriteCoord(MSG_ENTITY, origin[2]); - if (fChanged & NPC_ANGLES_X) - WriteFloat(MSG_ENTITY, angles[0]); - if (fChanged & NPC_ANGLES_Y) - WriteFloat(MSG_ENTITY, angles[1]); - if (fChanged & NPC_ANGLES_Z) - WriteFloat(MSG_ENTITY, angles[2]); - if (fChanged & NPC_VELOCITY_X) - WriteCoord(MSG_ENTITY, velocity[0]); - if (fChanged & NPC_VELOCITY_Y) - WriteCoord(MSG_ENTITY, velocity[1]); - if (fChanged & NPC_VELOCITY_Z) - WriteCoord(MSG_ENTITY, velocity[2]); - if (fChanged & NPC_FRAME) - WriteByte(MSG_ENTITY, frame); - if (fChanged & NPC_SKIN) - WriteByte(MSG_ENTITY, skin); - if (fChanged & NPC_BODY) - WriteByte(MSG_ENTITY, body); - - return TRUE; -} - -void monster_scientist::Speak(string msg) -{ - WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); - WriteByte(MSG_MULTICAST, EV_SPEAK); - WriteEntity(MSG_MULTICAST, this); - WriteString(MSG_MULTICAST, msg); - WriteFloat(MSG_MULTICAST, m_flPitch); - msg_entity = this; - multicast(origin, MULTICAST_PVS); -} - -void monster_scientist::Gib(void) -{ - takedamage = DAMAGE_NO; - Effect_GibHuman(this.origin); - Hide(); -} - void monster_scientist::WarnOthers(void) { for (entity b = world; (b = find(b, ::classname, "monster_scientist"));) { @@ -576,41 +505,6 @@ void monster_scientist::Physics(void) runstandardplayerphysics(this); Footsteps_Update(); - if (modelindex != old_modelindex) - SendFlags |= NPC_MODELINDEX; - if (origin[0] != old_origin[0]) - SendFlags |= NPC_ORIGIN_X; - if (origin[1] != old_origin[1]) - SendFlags |= NPC_ORIGIN_Y; - if (origin[2] != old_origin[2]) - SendFlags |= NPC_ORIGIN_Z; - if (angles[0] != old_angles[0]) - SendFlags |= NPC_ANGLES_X; - if (angles[1] != old_angles[1]) - SendFlags |= NPC_ANGLES_Y; - if (angles[2] != old_angles[2]) - SendFlags |= NPC_ANGLES_Z; - if (velocity[0] != old_velocity[0]) - SendFlags |= NPC_VELOCITY_X; - if (velocity[1] != old_velocity[1]) - SendFlags |= NPC_VELOCITY_Y; - if (velocity[2] != old_velocity[2]) - SendFlags |= NPC_VELOCITY_Z; - if (frame != old_frame) - SendFlags |= NPC_FRAME; - if (skin != old_skin) - SendFlags |= NPC_SKIN; - if (body != old_body) - SendFlags |= NPC_BODY; - - old_modelindex = modelindex; - old_origin = origin; - old_angles = angles, - old_velocity = velocity, - old_frame = frame; - old_skin = skin; - old_body = body; - if (!(flags & FL_ONGROUND) && velocity[2] < -100) { if (!(m_iFlags & SCIF_FALLING)) { Speak(sci_sndscream[0]); @@ -687,7 +581,6 @@ void monster_scientist::vDeath(int iHitBody) think = Respawn; nextthink = time + 10.0f; - SendFlags |= NPC_FRAME; m_eUser = world; //customphysics = __NULL__; m_iFlags = 0x0; @@ -736,6 +629,7 @@ void monster_scientist::Respawn(void) style = SCI_IDLE; customphysics = Physics; frame = SCIA_IDLE1; + SendFlags |= NPC_FRAME | NPC_BODY; health = 50; velocity = [0,0,0]; m_iFlags = 0x0; @@ -770,14 +664,28 @@ void monster_scientist::monster_scientist(void) precache_sound(sci_sndidle[i]); } + body = -1; + for (int i = 1; i < (tokenize(__fullspawndata)-1); i += 2) { + switch (argv(i)) { + case "body": + body = stoi(argv(i+1)) + 1; + break; + default: + break; + } + } + model = "models/scientist.mdl"; CBaseEntity::CBaseEntity(); precache_model(m_oldModel); Respawn(); - /* 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)); + 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)); + } + switch (body) { case 1: m_flPitch = 105; @@ -796,6 +704,5 @@ void monster_scientist::monster_scientist(void) m_flPitch = 100; netname = "Slick"; } + SendFlags |= NPC_FRAME | NPC_BODY; } - -CLASSEXPORT(qreate_arcade, monster_scientist) diff --git a/src/server/scihunt/progs.src b/src/server/scihunt/progs.src index b3856a84..b82a1f59 100755 --- a/src/server/scihunt/progs.src +++ b/src/server/scihunt/progs.src @@ -21,9 +21,41 @@ ../nodes.c ../../gs-entbase/server.src + +../valve/monster_apache.cpp +../valve/monster_alien_controller.cpp +../valve/monster_alien_grunt.cpp +../valve/monster_alien_slave.cpp +../valve/monster_babycrab.cpp +../valve/monster_barnacle.cpp +../valve/monster_barney.cpp +../valve/monster_barney_dead.cpp +../valve/monster_bigmomma.cpp +../valve/monster_bloater.cpp +../valve/monster_bullchicken.cpp +../valve/monster_cockroach.cpp +../valve/monster_flyer_flock.cpp +../valve/monster_gargantua.cpp +../valve/monster_gman.cpp +../valve/monster_headcrab.cpp +../valve/monster_hevsuit_dead.cpp +../valve/monster_houndeye.cpp +../valve/monster_human_grunt.cpp +../valve/monster_hgrunt_dead.cpp +../valve/monster_human_assassin.cpp +../valve/monster_ichthyosaur.cpp +../valve/monster_leech.cpp +../valve/monster_miniturret.cpp +../valve/monster_nihilanth.cpp +../valve/monster_osprey.cpp ../valve/monster_rat.cpp -monster_scientist.cpp ../valve/monster_scientist_dead.cpp +../valve/monster_sitting_scientist.cpp +monster_scientist.cpp +../valve/monster_sentry.cpp +../valve/monster_tentacle.cpp +../valve/monster_turret.cpp +../valve/monster_zombie.cpp ../../shared/decals.c ../../shared/effects.c @@ -89,5 +121,6 @@ server.c input.c ../valve/spawn.c +../vote.c ../entry.c #endlist diff --git a/src/server/tfc/progs.src b/src/server/tfc/progs.src index e317bc80..cedb658d 100755 --- a/src/server/tfc/progs.src +++ b/src/server/tfc/progs.src @@ -72,5 +72,6 @@ client.c ../flashlight.c input.c ../valve/spawn.c +../vote.c ../entry.c #endlist diff --git a/src/server/valve/input.c b/src/server/valve/input.c index 1894d52f..8cbc29ac 100644 --- a/src/server/valve/input.c +++ b/src/server/valve/input.c @@ -48,6 +48,7 @@ void Game_Input(void) if (self.impulse == 101) { pl.health = 100; pl.armor = 100; + pl.g_items |= ITEM_SUIT; Weapons_AddItem(pl, WEAPON_CROWBAR); Weapons_AddItem(pl, WEAPON_GLOCK); Weapons_AddItem(pl, WEAPON_PYTHON); diff --git a/src/server/valve/monster_alien_controller.cpp b/src/server/valve/monster_alien_controller.cpp new file mode 100644 index 00000000..519afc5a --- /dev/null +++ b/src/server/valve/monster_alien_controller.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_alien_controller (0 0.8 0.8) (-16 -16 0) (16 16 72) + +Monster. +*/ + +class monster_alien_controller:CBaseMonster +{ + void() monster_alien_controller; +}; + +void monster_alien_controller::monster_alien_controller(void) +{ + netname = "Alien Controller"; + model = "models/controller.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_alien_grunt.cpp b/src/server/valve/monster_alien_grunt.cpp new file mode 100644 index 00000000..3b2e99d5 --- /dev/null +++ b/src/server/valve/monster_alien_grunt.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_alien_grunt (0 0.8 0.8) (-32 -32 0) (32 32 64) + +Monster. +*/ + +class monster_alien_grunt:CBaseMonster +{ + void() monster_alien_grunt; + virtual void() Respawn; +}; + +void monster_alien_grunt::Respawn(void) +{ + CBaseMonster::Respawn(); + setsize(this, [-32,-32,0], [32,32,64]); +} + +void monster_alien_grunt::monster_alien_grunt(void) +{ + netname = "Alien Grunt"; + model = "models/agrunt.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_alien_slave.cpp b/src/server/valve/monster_alien_slave.cpp new file mode 100644 index 00000000..a4fe2537 --- /dev/null +++ b/src/server/valve/monster_alien_slave.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_alien_slave (0 0.8 0.8) (-16 -16 0) (16 16 72) + +Monster. +*/ + +class monster_alien_slave:CBaseMonster +{ + void() monster_alien_slave; +}; + +void monster_alien_slave::monster_alien_slave(void) +{ + netname = "Alien Slave"; + model = "models/islave.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_apache.cpp b/src/server/valve/monster_apache.cpp new file mode 100644 index 00000000..2aa911d5 --- /dev/null +++ b/src/server/valve/monster_apache.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_apache (0 0.8 0.8) (-300 -300 -172) (300 300 8) + +Monster. +*/ + +class monster_apache:CBaseMonster +{ + void() monster_apache; + virtual void() Respawn; +}; + +void monster_apache::Respawn(void) +{ + CBaseMonster::Respawn(); + movetype = MOVETYPE_NONE; + takedamage = DAMAGE_NO; + iBleeds = FALSE; + setsize(this, [-300,-300,-172], [300, 300, 8]); +} + +void monster_apache::monster_apache(void) +{ + netname = "Apache"; + model = "models/apache.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_babycrab.cpp b/src/server/valve/monster_babycrab.cpp new file mode 100644 index 00000000..8e5c8e65 --- /dev/null +++ b/src/server/valve/monster_babycrab.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_babycrab (0 0.8 0.8) (-16 -16 0) (16 16 36) + +Monster. +*/ + +class monster_babycrab:CBaseMonster +{ + void() monster_babycrab; + virtual void() Respawn; +}; + +void monster_babycrab::Respawn(void) +{ + CBaseMonster::Respawn(); + setsize(this, [-16,-16,0], [16,16,36]); +} + +void monster_babycrab::monster_babycrab(void) +{ + netname = "Baby Headcrab"; + model = "models/baby_headcrab.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_barnacle.cpp b/src/server/valve/monster_barnacle.cpp new file mode 100644 index 00000000..db0f4e1b --- /dev/null +++ b/src/server/valve/monster_barnacle.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_barnacle (0 0.8 0.8) (-16 -16 -36) (16 16 0) + +Monster. +*/ + +class monster_barnacle:CBaseMonster +{ + void() monster_barnacle; + virtual void() Respawn; +}; + +void monster_barnacle::Respawn(void) +{ + CBaseMonster::Respawn(); + setsize(this, [-16,-16,-36], [16,16,0]); +} + +void monster_barnacle::monster_barnacle(void) +{ + netname = "Barnacle"; + model = "models/barnacle.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_barney.cpp b/src/server/valve/monster_barney.cpp new file mode 100644 index 00000000..07876a48 --- /dev/null +++ b/src/server/valve/monster_barney.cpp @@ -0,0 +1,478 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_barney (0 0.8 0.8) (-16 -16 0) (16 16 72) + +Monster. +*/ + +enum { + BARNEY_IDLE, + BARNEY_WALK, + BARNEY_RUN, + BARNEY_DEAD +}; + +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[] = { + "barney/ba_die1.wav", + "barney/ba_die1.wav", + "barney/ba_die2.wav" +}; + +string barney_sndchitchat[] = { + "barney/ba_pain1.wav", + "barney/ba_pain1.wav", + "barney/ba_pain1.wav" +}; + +string barney_sndhear[] = { + "barney/ba_pain1.wav", + "barney/ba_pain1.wav", + "barney/ba_pain1.wav" +}; + +string barney_sndpain[] = { + "barney/ba_pain1.wav", + "barney/ba_pain1.wav", + "barney/ba_pain1.wav" +}; + +string barney_sndsee[] = { + "barney/ba_pain1.wav", + "barney/ba_pain1.wav", + "barney/ba_pain1.wav" +}; + +string barney_sndscream[] = { + "barney/ba_pain1.wav", + "barney/ba_pain1.wav", + "barney/ba_pain1.wav" +}; + +string barney_sndstop[] = { + "barney/ba_pain1.wav", + "barney/ba_pain1.wav", + "barney/ba_pain1.wav" +}; + +string barney_snduse[] = { + "barney/ba_pain1.wav", + "barney/ba_pain1.wav", + "barney/ba_pain1.wav" +}; + +string barney_snduseno[] = { + "barney/ba_pain1.wav", + "barney/ba_pain1.wav", + "barney/ba_pain1.wav" +}; + +string barney_sndidle[] = { + "barney/ba_pain1.wav", + "barney/ba_pain1.wav", + "barney/ba_pain1.wav" +}; + +class monster_barney:CBaseMonster +{ + 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_barney; + + virtual void() touch; + virtual void() Hide; + virtual void() Respawn; + virtual void() PlayerUse; + virtual void(int) vPain; + virtual void(int) vDeath; + virtual void() Physics; + virtual void() Scream; + virtual void() WarnOthers; + virtual void() IdleChat; +}; + +void monster_barney::WarnOthers(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; + sci.m_flScaredTime = time + 2.5f; + sci.Scream(); + } + } +} + +void monster_barney::Scream(void) +{ + if (m_flScreamTime > time) { + return; + } + + int rand = floor(random(0,barney_sndscream.length)); + Speak(barney_sndscream[rand]); + m_flScreamTime = time + 5.0f; +} + +void monster_barney::IdleChat(void) +{ + if (m_flScreamTime > time) { + return; + } + + int rand = floor(random(0,barney_sndchitchat.length)); + Speak(barney_sndchitchat[rand]); + m_flScreamTime = time + 5.0f + random(0,20); +} + +void monster_barney::Physics(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; + } + + if (random() < 0.5) { + int rand = floor(random(0,barney_sndsee.length)); + Speak(barney_sndsee[rand]); + } + + 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; + 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_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) { + if (!(m_iFlags & BARNF_FALLING)) { + Speak(barney_sndscream[0]); + } + m_iFlags |= BARNF_FALLING; + } else { + m_iFlags -= (flags & BARNF_FALLING); + } +} + +void monster_barney::touch(void) +{ + if (other.movetype == MOVETYPE_WALK) { + velocity = normalize(other.origin - origin) * -128; + } +} + +void monster_barney::PlayerUse(void) +{ + int r; + + if (m_iFlags & BARNF_FEAR) { + return; + } + if ((m_eUser == world)) { + if (!(m_iFlags & BARNF_USED)) { + m_iFlags |= BARNF_USED; + } + + r = floor(random(0,barney_snduse.length)); + Speak(barney_snduse[r]); + + m_eUser = eActivator; + m_eRescuer = m_eUser; + m_vecLastUserPos = m_eUser.origin; + } else { + r = floor(random(0,barney_snduseno.length)); + Speak(barney_snduseno[r]); + + m_eUser = world; + } +} + +void monster_barney::vPain(int iHitBody) +{ + + WarnOthers(); + + if (m_flPainTime > time) { + return; + } + + if (random() < 0.25f) { + 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; + + m_flPainTime = time + 0.25f; +} + +void monster_barney::vDeath(int iHitBody) +{ + int r; + r = floor(random(0,barney_snddie.length)); + Speak(barney_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; + + if (style != BARNEY_DEAD) { + frame = 25 + floor(random(0, 6)); + style = BARNEY_DEAD; + } +} + +void monster_barney::Hide(void) +{ + setmodel(this, ""); + m_eUser = world; + solid = SOLID_NOT; + movetype = MOVETYPE_NONE; + customphysics = __NULL__; +} + +void monster_barney::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 = 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 < barney_snddie.length; i++) { + precache_sound(barney_snddie[i]); + } + for (int i = 0; i < barney_sndscream.length; i++) { + precache_sound(barney_sndscream[i]); + } + for (int i = 0; i < barney_snduse.length; i++) { + precache_sound(barney_snduse[i]); + } + for (int i = 0; i < barney_snduseno.length; i++) { + precache_sound(barney_snduseno[i]); + } + for (int i = 0; i < barney_sndsee.length; i++) { + precache_sound(barney_sndsee[i]); + } + for (int i = 0; i < barney_sndidle.length; i++) { + precache_sound(barney_sndidle[i]); + } + + model = "models/barney.mdl"; + CBaseEntity::CBaseEntity(); + precache_model(m_oldModel); + Respawn(); +} diff --git a/src/server/valve/monster_barney_dead.cpp b/src/server/valve/monster_barney_dead.cpp new file mode 100644 index 00000000..9152d371 --- /dev/null +++ b/src/server/valve/monster_barney_dead.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_barney_dead (0 0.8 0.8) (-16 -16 0) (16 16 72) + +Monster. +*/ + +class monster_barney_dead:CBaseEntity +{ + int m_iPose; + void() monster_barney_dead; + + virtual void() Hide; + virtual void() Respawn; + virtual void(int) vPain; + virtual void(int) vDeath; + virtual void() Gib; +}; + +void monster_barney_dead::Gib(void) +{ + takedamage = DAMAGE_NO; + Effect_GibHuman(this.origin); + Hide(); +} + +void monster_barney_dead::vPain(int iHitBody) +{ + +} + +void monster_barney_dead::vDeath(int iHitBody) +{ + if (health < -50) { + Gib(); + return; + } +} + +void monster_barney_dead::Hide(void) +{ + setmodel(this, ""); + solid = SOLID_NOT; + movetype = MOVETYPE_NONE; +} + +void monster_barney_dead::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]); + + setorigin(this, m_oldOrigin); + angles = v_angle; + solid = SOLID_CORPSE; + movetype = MOVETYPE_NONE; + setmodel(this, m_oldModel); + setsize(this, VEC_HULL_MIN + [0,0,36], VEC_HULL_MAX + [0,0,36]); + takedamage = DAMAGE_YES; + health = 0; + velocity = [0,0,0]; + iBleeds = TRUE; + frame = 35 + m_iPose; +} + +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(); +} diff --git a/src/server/valve/monster_bigmomma.cpp b/src/server/valve/monster_bigmomma.cpp new file mode 100644 index 00000000..e88a5365 --- /dev/null +++ b/src/server/valve/monster_bigmomma.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_bigmomma (0 0.8 0.8) (-95 -95 0) (95 95 190) + +Monster. +*/ + +class monster_bigmomma:CBaseMonster +{ + void() monster_bigmomma; + virtual void() Respawn; +}; + +void monster_bigmomma::Respawn(void) +{ + CBaseMonster::Respawn(); + setsize(this, [-95,-95,0], [95,95,190]); +} + +void monster_bigmomma::monster_bigmomma(void) +{ + netname = "Big Momma"; + model = "models/big_mom.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_bloater.cpp b/src/server/valve/monster_bloater.cpp new file mode 100644 index 00000000..87ad946a --- /dev/null +++ b/src/server/valve/monster_bloater.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_bloater (0 0.8 0.8) (-16 -16 0) (16 16 72) + +Monster. +*/ + +class monster_bloater:CBaseMonster +{ + void() monster_bloater; +}; + +void monster_bloater::monster_bloater(void) +{ + netname = "Floater"; + model = "models/floater.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_bullchicken.cpp b/src/server/valve/monster_bullchicken.cpp new file mode 100644 index 00000000..865afb11 --- /dev/null +++ b/src/server/valve/monster_bullchicken.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_bullchicken (0 0.8 0.8) (-32 -32 0) (32 32 64) + +Monster. +*/ + +class monster_bullchicken:CBaseMonster +{ + void() monster_bullchicken; + virtual void() Respawn; +}; + +void monster_bullchicken::Respawn(void) +{ + CBaseMonster::Respawn(); + setsize(this, [-32,-32,0], [32,32,64]); +} + +void monster_bullchicken::monster_bullchicken(void) +{ + netname = "Bullsquid"; + model = "models/bullsquid.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_cockroach.cpp b/src/server/valve/monster_cockroach.cpp new file mode 100644 index 00000000..4d64bde6 --- /dev/null +++ b/src/server/valve/monster_cockroach.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_cockroach (0 0.8 0.8) (-4 -4 0) (4 4 4) + +Monster. +*/ + +class monster_cockroach:CBaseMonster +{ + void() monster_cockroach; + virtual void() Respawn; +}; + +void monster_cockroach::Respawn(void) +{ + CBaseMonster::Respawn(); + setsize(this, [-1,-1,0], [1,1,1]); +} + +void monster_cockroach::monster_cockroach(void) +{ + netname = "Cockroach"; + model = "models/roach.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_flyer_flock.cpp b/src/server/valve/monster_flyer_flock.cpp new file mode 100644 index 00000000..304ddd63 --- /dev/null +++ b/src/server/valve/monster_flyer_flock.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_flyer_flock (0 0.8 0.8) (-16 -16 0) (16 16 16) + +Monster. +*/ + +class monster_flyer_flock:CBaseMonster +{ + void() monster_flyer_flock; + virtual void() Respawn; +}; + +void monster_flyer_flock::Respawn(void) +{ + CBaseMonster::Respawn(); + setsize(this, [-16,-16,0], [16,16,16]); +} + +void monster_flyer_flock::monster_flyer_flock(void) +{ + netname = "Flyer"; + model = "models/aflock.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_gargantua.cpp b/src/server/valve/monster_gargantua.cpp new file mode 100644 index 00000000..ed5203c0 --- /dev/null +++ b/src/server/valve/monster_gargantua.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_gargantua (0 0.8 0.8) (-32 -32 0) (32 32 128) + +Monster. +*/ + +class monster_gargantua:CBaseMonster +{ + void() monster_gargantua; + virtual void() Respawn; +}; + +void monster_gargantua::Respawn(void) +{ + CBaseMonster::Respawn(); + setsize(this, [-32,-32,0], [32,32,128]); +} + +void monster_gargantua::monster_gargantua(void) +{ + netname = "Gargantua"; + model = "models/garg.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_gman.cpp b/src/server/valve/monster_gman.cpp new file mode 100644 index 00000000..4f2a375d --- /dev/null +++ b/src/server/valve/monster_gman.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_gman (0 0.8 0.8) (-16 -16 0) (16 16 72) + +Monster. +*/ + +class monster_gman:CBaseMonster +{ + void() monster_gman; + virtual void() Respawn; +}; + +void monster_gman::Respawn(void) +{ + CBaseMonster::Respawn(); + movetype = MOVETYPE_NONE; + takedamage = DAMAGE_NO; + iBleeds = FALSE; +} + +void monster_gman::monster_gman(void) +{ + netname = "G-Man"; + model = "models/gman.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_headcrab.cpp b/src/server/valve/monster_headcrab.cpp new file mode 100644 index 00000000..4d7cb50e --- /dev/null +++ b/src/server/valve/monster_headcrab.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_headcrab (0 0.8 0.8) (-16 -16 0) (16 16 36) + +Monster. +*/ + +class monster_headcrab:CBaseMonster +{ + void() monster_headcrab; + virtual void() Respawn; +}; + +void monster_headcrab::Respawn(void) +{ + CBaseMonster::Respawn(); + setsize(this, [-16,-16,0], [16,16,36]); +} + +void monster_headcrab::monster_headcrab(void) +{ + netname = "Headcrab"; + model = "models/headcrab.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_hevsuit_dead.cpp b/src/server/valve/monster_hevsuit_dead.cpp new file mode 100644 index 00000000..93bc30b7 --- /dev/null +++ b/src/server/valve/monster_hevsuit_dead.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_hevsuit_dead (0 0.8 0.8) (-16 -16 0) (16 16 72) + +Monster. +*/ + +class monster_hevsuit_dead:CBaseMonster +{ + int m_iPose; + void() monster_hevsuit_dead; + + virtual void() Hide; + virtual void() Respawn; + virtual void(int) vPain; + virtual void(int) vDeath; + virtual void() Gib; +}; + +void monster_hevsuit_dead::Gib(void) +{ + takedamage = DAMAGE_NO; + Effect_GibHuman(this.origin); + Hide(); +} + +void monster_hevsuit_dead::vPain(int iHitBody) +{ + +} + +void monster_hevsuit_dead::vDeath(int iHitBody) +{ + if (health < -50) { + Gib(); + return; + } +} + +void monster_hevsuit_dead::Hide(void) +{ + setmodel(this, ""); + solid = SOLID_NOT; + movetype = MOVETYPE_NONE; +} + +void monster_hevsuit_dead::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]); + + setorigin(this, m_oldOrigin); + angles = v_angle; + solid = SOLID_CORPSE; + movetype = MOVETYPE_NONE; + setmodel(this, m_oldModel); + setsize(this, VEC_HULL_MIN + [0,0,36], VEC_HULL_MAX + [0,0,36]); + takedamage = DAMAGE_YES; + health = 0; + velocity = [0,0,0]; + iBleeds = TRUE; + frame = 73 + m_iPose; + SendFlags |= NPC_BODY; +} + +void monster_hevsuit_dead::monster_hevsuit_dead(void) +{ + model = "models/player.mdl"; + body = 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": + body = stoi(argv(i+1)) + 1; + break; + case "skin": + skin = stoi(argv(i+1)); + break; + default: + break; + } + } + + CBaseEntity::CBaseEntity(); + precache_model(m_oldModel); + Respawn(); +} diff --git a/src/server/valve/monster_hgrunt_dead.cpp b/src/server/valve/monster_hgrunt_dead.cpp new file mode 100644 index 00000000..a65ae1e1 --- /dev/null +++ b/src/server/valve/monster_hgrunt_dead.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_hgrunt_dead (0 0.8 0.8) (-16 -16 0) (16 16 72) + +Monster. +*/ + +class monster_hgrunt_dead:CBaseMonster +{ + int m_iPose; + void() monster_hgrunt_dead; + + virtual void() Hide; + virtual void() Respawn; + virtual void(int) vPain; + virtual void(int) vDeath; + virtual void() Gib; +}; + +void monster_hgrunt_dead::Gib(void) +{ + takedamage = DAMAGE_NO; + Effect_GibHuman(this.origin); + Hide(); +} + +void monster_hgrunt_dead::vPain(int iHitBody) +{ + +} + +void monster_hgrunt_dead::vDeath(int iHitBody) +{ + if (health < -50) { + Gib(); + return; + } +} + +void monster_hgrunt_dead::Hide(void) +{ + setmodel(this, ""); + solid = SOLID_NOT; + movetype = MOVETYPE_NONE; +} + +void monster_hgrunt_dead::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]); + + setorigin(this, m_oldOrigin); + angles = v_angle; + solid = SOLID_CORPSE; + movetype = MOVETYPE_NONE; + setmodel(this, m_oldModel); + setsize(this, VEC_HULL_MIN + [0,0,36], VEC_HULL_MAX + [0,0,36]); + takedamage = DAMAGE_YES; + health = 0; + velocity = [0,0,0]; + iBleeds = TRUE; + frame = 44 + m_iPose; + SendFlags |= NPC_BODY; +} + +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": + body = stoi(argv(i+1)) + 1; + break; + case "skin": + skin = stoi(argv(i+1)); + break; + default: + break; + } + } + + CBaseEntity::CBaseEntity(); + precache_model(m_oldModel); + Respawn(); +} diff --git a/src/server/valve/monster_houndeye.cpp b/src/server/valve/monster_houndeye.cpp new file mode 100644 index 00000000..4339db9d --- /dev/null +++ b/src/server/valve/monster_houndeye.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_houndeye (0 0.8 0.8) (-16 -16 0) (16 16 36) + +Monster. +*/ + +class monster_houndeye:CBaseMonster +{ + void() monster_houndeye; + virtual void() Respawn; +}; + +void monster_houndeye::Respawn(void) +{ + CBaseMonster::Respawn(); + setsize(this, [-16,-16,0], [16,16,36]); +} + +void monster_houndeye::monster_houndeye(void) +{ + netname = "Houndeye"; + model = "models/houndeye.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_human_assassin.cpp b/src/server/valve/monster_human_assassin.cpp new file mode 100644 index 00000000..0a7a34bd --- /dev/null +++ b/src/server/valve/monster_human_assassin.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_human_assassin (0 0.8 0.8) (-16 -16 0) (16 16 72) + +Monster. +*/ + +class monster_human_assassin:CBaseMonster +{ + void() monster_human_assassin; +}; + +void monster_human_assassin::monster_human_assassin(void) +{ + netname = "Assassin"; + model = "models/hassassin.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_human_grunt.cpp b/src/server/valve/monster_human_grunt.cpp new file mode 100644 index 00000000..85beb866 --- /dev/null +++ b/src/server/valve/monster_human_grunt.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_human_grunt (0 0.8 0.8) (-16 -16 0) (16 16 72) + +Monster. +*/ + +class monster_human_grunt:CBaseMonster +{ + void() monster_human_grunt; +}; + +void monster_human_grunt::monster_human_grunt(void) +{ + netname = "Grunt"; + model = "models/hgrunt.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_ichthyosaur.cpp b/src/server/valve/monster_ichthyosaur.cpp new file mode 100644 index 00000000..1193d5dc --- /dev/null +++ b/src/server/valve/monster_ichthyosaur.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_ichthyosaur (0 0.8 0.8) (-32 -32 0) (32 32 64) + +Monster. +*/ + +class monster_ichthyosaur:CBaseMonster +{ + void() monster_ichthyosaur; + virtual void() Respawn; +}; + +void monster_ichthyosaur::Respawn(void) +{ + CBaseMonster::Respawn(); + setsize(this, [-32,-32,0], [32,32,64]); +} + +void monster_ichthyosaur::monster_ichthyosaur(void) +{ + netname = "Ichthyosaur"; + model = "models/icky.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_leech.cpp b/src/server/valve/monster_leech.cpp new file mode 100644 index 00000000..fd58f394 --- /dev/null +++ b/src/server/valve/monster_leech.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_leech (0 0.8 0.8) (-6 -6 0) (6 6 6) + +Monster. +*/ + +class monster_leech:CBaseMonster +{ + void() monster_leech; + virtual void() Respawn; +}; + +void monster_leech::Respawn(void) +{ + CBaseMonster::Respawn(); + setsize(this, [-6,-6,0], [6,6,6]); +} + +void monster_leech::monster_leech(void) +{ + netname = "Leech"; + model = "models/leech.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_miniturret.cpp b/src/server/valve/monster_miniturret.cpp new file mode 100644 index 00000000..c14ec9fc --- /dev/null +++ b/src/server/valve/monster_miniturret.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_miniturret (0 0.8 0.8) (-16 -16 -32) (16 16 32) + +Monster. +*/ + +class monster_miniturret:CBaseMonster +{ + void() monster_miniturret; + virtual void() Respawn; +}; + +void monster_miniturret::Respawn(void) +{ + CBaseMonster::Respawn(); + setsize(this, [-16,-16,-32], [16,16,32]); +} + +void monster_miniturret::monster_miniturret(void) +{ + netname = "Mini-Turret"; + model = "models/miniturret.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_nihilanth.cpp b/src/server/valve/monster_nihilanth.cpp new file mode 100644 index 00000000..b2c75788 --- /dev/null +++ b/src/server/valve/monster_nihilanth.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_nihilanth (0 0.8 0.8) (-192 -192 0) (192 192 384) + +Monster. +*/ + +class monster_nihilanth:CBaseMonster +{ + void() monster_nihilanth; + virtual void() Respawn; +}; + +void monster_nihilanth::Respawn(void) +{ + CBaseMonster::Respawn(); + setsize(this, [-192,-192,-32], [192,192,384]); +} + +void monster_nihilanth::monster_nihilanth(void) +{ + netname = "Nihilanth"; + model = "models/nihilanth.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_osprey.cpp b/src/server/valve/monster_osprey.cpp new file mode 100644 index 00000000..0c298dfc --- /dev/null +++ b/src/server/valve/monster_osprey.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_osprey (0 0.8 0.8) (-480 -480 -112) (480 480 24) + +Monster. +*/ + +class monster_osprey:CBaseMonster +{ + void() monster_osprey; + virtual void() Respawn; +}; + +void monster_osprey::Respawn(void) +{ + CBaseMonster::Respawn(); + movetype = MOVETYPE_NONE; + takedamage = DAMAGE_NO; + iBleeds = FALSE; + setsize(this, [-480,-480,-112], [480,480,24]); +} + +void monster_osprey::monster_osprey(void) +{ + netname = "Osprey"; + model = "models/osprey.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_rat.cpp b/src/server/valve/monster_rat.cpp index 7896bea1..d5272f69 100644 --- a/src/server/valve/monster_rat.cpp +++ b/src/server/valve/monster_rat.cpp @@ -14,13 +14,26 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/*QUAKED monster_rat (0 0.8 0.8) (-6 -6 0) (6 6 6) + +Monster. +*/ + class monster_rat:CBaseEntity { void() monster_rat; + virtual void() Respawn; }; +void monster_rat::Respawn(void) +{ + CBaseMonster::Respawn(); + setsize(this, [-6,-6,-0], [6,6,6]); +} + void monster_rat::monster_rat(void) { + netname = "Rat"; CBaseEntity::CBaseEntity(); precache_model("models/bigrat.mdl"); solid = SOLID_SLIDEBOX; diff --git a/src/server/valve/monster_scientist.cpp b/src/server/valve/monster_scientist.cpp index 29bb4e2e..ad28ea43 100644 --- a/src/server/valve/monster_scientist.cpp +++ b/src/server/valve/monster_scientist.cpp @@ -14,13 +14,692 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/*QUAKED monster_scientist (0 0.8 0.8) (-16 -16 0) (16 16 72) + +Monster. +*/ + +enum { + SCI_IDLE, + SCI_WALK, + SCI_RUN, + SCI_DEAD +}; + +enum { + SCIA_WALK, + SCIA_WALKSCARED, + SCIA_RUN, + SCIA_RUNSCARED, + SCIA_RUNLOOK, + SCIA_180LEFT, + SCIA_180RIGHT, + SCIA_FLINCH, + SCIA_PAIN, + SCIA_PAINLEFT, + SCIA_PAINRIGHT, + SCIA_PAINLEGLEFT, + SCIA_PAINLEGRIGHT, + SCIA_IDLE1, + SCIA_IDLE2, + SCIA_IDLE3, + SCIA_IDLE4, + SCIA_IDLE5, + SCIA_IDLE6, + SCIA_SCARED_END, + SCIA_SCARED1, + SCIA_SCARED2, + SCIA_SCARED3, + SCIA_SCARED4, + SCIA_PANIC, + SCIA_FEAR1, + SCIA_FEAR2, + SCIA_CRY, + SCIA_SCI1, + SCIA_SCI2, + SCIA_SCI3, + SCIA_DIE_SIMPLE, + SCIA_DIE_FORWARD1, + SCIA_DIE_FORWARD2, + SCIA_DIE_BACKWARD, + SCIA_DIE_HEADSHOT, + SCIA_DIE_GUTSHOT, + SCIA_LYING1, + SCIA_LYING2, + SCIA_DEADSIT, + SCIA_DEADTABLE1, + SCIA_DEADTABLE2, + SCIA_DEADTABLE3 +}; + +enumflags +{ + SCIF_USED, + SCIF_SCARED, + SCIF_FEAR, + SCIF_SEEN, + SCIF_FALLING +}; + +string sci_snddie[] = { + "scientist/sci_die1.wav", + "scientist/sci_die2.wav", + "scientist/sci_die3.wav", + "scientist/sci_die4.wav" +}; + +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", + "scientist/sci_pain3.wav", + "scientist/sci_pain4.wav", + "scientist/sci_pain5.wav", + "scientist/sci_pain6.wav", + "scientist/sci_pain7.wav", + "scientist/sci_pain8.wav", + "scientist/sci_pain9.wav", + "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:CBaseMonster { + 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) vPain; + virtual void(int) vDeath; + virtual void() Physics; + virtual void() Scream; + virtual void() WarnOthers; + virtual void() IdleChat; }; +void monster_scientist::WarnOthers(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(); + } + } +} + +void monster_scientist::Scream(void) +{ + if (m_flScreamTime > time) { + return; + } + + int rand = floor(random(0,sci_sndscream.length)); + Speak(sci_sndscream[rand]); + m_flScreamTime = time + 5.0f; +} + +void monster_scientist::IdleChat(void) +{ + 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 != SCI_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::vPain(int iHitBody) +{ + + WarnOthers(); + + if (m_flPainTime > time) { + return; + } + + if (random() < 0.25f) { + return; + } + + int rand = floor(random(0,sci_sndpain.length)); + Speak(sci_sndpain[rand]); + + frame = SCIA_FLINCH + floor(random(0, 5)); + m_iFlags |= SCIF_FEAR; + + m_flPainTime = time + 0.25f; +} + +void monster_scientist::vDeath(int iHitBody) +{ + int r; + 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 != SCI_DEAD) { + frame = SCIA_DIE_SIMPLE + floor(random(0, 6)); + style = SCI_DEAD; + } +} + +void monster_scientist::Hide(void) +{ + setmodel(this, ""); + m_eUser = world; + solid = SOLID_NOT; + movetype = MOVETYPE_NONE; + customphysics = __NULL__; +} + +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 = SCI_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) { + for (int i = 0; i < sci_sndpain.length; i++) { + precache_sound(sci_sndpain[i]); + } + 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]); + } + + body = -1; + for (int i = 1; i < (tokenize(__fullspawndata)-1); i += 2) { + switch (argv(i)) { + case "body": + body = stoi(argv(i+1)) + 1; + break; + default: + break; + } + } + model = "models/scientist.mdl"; - CBaseMonster::CBaseMonster(); + CBaseEntity::CBaseEntity(); + precache_model(m_oldModel); + Respawn(); + + 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)); + } + + switch (body) { + 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"; + } } diff --git a/src/server/valve/monster_scientist_dead.cpp b/src/server/valve/monster_scientist_dead.cpp index 664b9181..19ff565e 100644 --- a/src/server/valve/monster_scientist_dead.cpp +++ b/src/server/valve/monster_scientist_dead.cpp @@ -14,6 +14,11 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/*QUAKED monster_scientist_dead (0 0.8 0.8) (-16 -16 0) (16 16 72) + +Monster. +*/ + enum { DSCIA_LYING1 = 37, DSCIA_LYING2, @@ -24,7 +29,7 @@ enum { DSCIA_DEADHANG }; -class monster_scientist_dead:CBaseEntity +class monster_scientist_dead:CBaseMonster { int m_iPose; void() monster_scientist_dead; @@ -79,6 +84,7 @@ void monster_scientist_dead::Respawn(void) health = 0; velocity = [0,0,0]; iBleeds = TRUE; + SendFlags |= NPC_BODY; switch (m_iPose) { case 1: @@ -112,6 +118,13 @@ void monster_scientist_dead::monster_scientist_dead(void) switch (argv(i)) { case "pose": m_iPose = stoi(argv(i+1)); + break; + case "body": + body = stoi(argv(i+1)) + 1; + break; + case "skin": + skin = stoi(argv(i+1)); + break; default: break; } diff --git a/src/server/valve/monster_sentry.cpp b/src/server/valve/monster_sentry.cpp new file mode 100644 index 00000000..956445e4 --- /dev/null +++ b/src/server/valve/monster_sentry.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_sentry (0 0.8 0.8) (-16 -16 0) (16 16 72) + +Monster. +*/ + +class monster_sentry:CBaseMonster +{ + void() monster_sentry; +}; + +void monster_sentry::monster_sentry(void) +{ + netname = "Sentry"; + model = "models/sentry.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_sitting_scientist.cpp b/src/server/valve/monster_sitting_scientist.cpp new file mode 100644 index 00000000..c4169f51 --- /dev/null +++ b/src/server/valve/monster_sitting_scientist.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_sitting_scientist (0 0.8 0.8) (-14 -14 0) (14 14 36) + +Monster. +*/ + +enum { + DSCIA_LYING1 = 37, + DSCIA_LYING2, + DSCIA_DEADSIT, + DSCIA_DEADTABLE1, + DSCIA_DEADTABLE2, + DSCIA_DEADTABLE3, + DSCIA_DEADHANG +}; + +class monster_sitting_scientist:CBaseMonster +{ + int m_iPose; + void() monster_sitting_scientist; + + virtual void() Hide; + virtual void() Respawn; + virtual void(int) vPain; + virtual void(int) vDeath; + virtual void() Gib; +}; + +void monster_sitting_scientist::Gib(void) +{ + takedamage = DAMAGE_NO; + Effect_GibHuman(this.origin); + Hide(); +} + +void monster_sitting_scientist::vPain(int iHitBody) +{ + +} + +void monster_sitting_scientist::vDeath(int iHitBody) +{ + if (health < -50) { + Gib(); + return; + } +} + +void monster_sitting_scientist::Hide(void) +{ + setmodel(this, ""); + solid = SOLID_NOT; + movetype = MOVETYPE_NONE; +} + +void monster_sitting_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]); + + setorigin(this, m_oldOrigin); + angles = v_angle; + solid = SOLID_BBOX; + movetype = MOVETYPE_NONE; + setmodel(this, m_oldModel); + setsize(this, [-14,-14,0],[14,14,36]); + takedamage = DAMAGE_YES; + health = 0; + velocity = [0,0,0]; + iBleeds = TRUE; + SendFlags |= NPC_BODY; + frame = 74; + droptofloor(); +} + +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": + body = stoi(argv(i+1)) + 1; + break; + case "skin": + skin = stoi(argv(i+1)); + break; + default: + break; + } + } + + 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)); + } + + switch (body) { + 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"; + } + + CBaseEntity::CBaseEntity(); + precache_model(m_oldModel); +} diff --git a/src/server/valve/monster_tentacle.cpp b/src/server/valve/monster_tentacle.cpp new file mode 100644 index 00000000..0e3ecdc3 --- /dev/null +++ b/src/server/valve/monster_tentacle.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_tentacle (0 0.8 0.8) (-32 -32 0) (32 32 64) + +Monster. +*/ + +class monster_tentacle:CBaseMonster +{ + void() monster_tentacle; + virtual void() Respawn; +}; + +void monster_tentacle::Respawn(void) +{ + CBaseMonster::Respawn(); + setsize(this, [-32,-32,0], [32,32,64]); +} + +void monster_tentacle::monster_tentacle(void) +{ + netname = "Tentacle"; + model = "models/tentacle2.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_turret.cpp b/src/server/valve/monster_turret.cpp new file mode 100644 index 00000000..00249ac6 --- /dev/null +++ b/src/server/valve/monster_turret.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_turret (0 0.8 0.8) (-16 -16 0) (16 16 72) + +Monster. +*/ + +class monster_turret:CBaseMonster +{ + void() monster_turret; +}; + +void monster_turret::monster_turret(void) +{ + netname = "Turret"; + model = "models/turret.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/src/server/valve/monster_zombie.cpp b/src/server/valve/monster_zombie.cpp new file mode 100644 index 00000000..427c2840 --- /dev/null +++ b/src/server/valve/monster_zombie.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +/*QUAKED monster_zombie (0 0.8 0.8) (-16 -16 0) (16 16 72) + +Monster. +*/ + +enum { + ZOMA_IDLE, + ZOMA_TURNLEFT, + ZOMA_TURNRIGHT, + ZOMA_FLINCHSM, + ZOMA_FLINCH, + ZOMA_FLINCHBIG, + ZOMA_RISE, + ZOMA_FALLING, + ZOMA_ATTACK1, + ZOMA_ATTACK2, + ZOMA_WALK, + ZOMA_FLINCHLA, + ZOMA_FLINCHRA, + ZOMA_FLINCHLEFT, + ZOMA_FLINCHRIGHT, + ZOMA_DIEHS, + ZOMA_DIEHS2, + ZOMA_DIE, + ZOMA_DIEBACK, + ZOMA_DIEFORWARD, + ZOMA_PAUSE, + ZOMA_WALLBUST, + ZOMA_WALLKICK, + ZOMA_WINDOWBUST, + ZOMA_SODA, + ZOMA_SLIDEIDLE, + ZOMA_SLIDE, + ZOMA_VENTIDLE, + ZOMA_VENT, + ZOMA_DEADIDLE, + ZOMA_DEAD, + ZOMA_FREAKDIE, + ZOMA_FREAK, + ZOMA_EATTABLE, + ZOMA_EAT, + ZOMA_EATSTAND, + ZOMA_DOORIP, + ZOMA_PULLSCI, + ZOMA_EAT2, + ZOMA_EAT2STAND, + ZOMA_VENT2IDLE, + ZOMA_VENT2, + ZOMA_HAUL, + ZOMA_RISESNACK +}; + +enum { + ZOMB_IDLE, + ZOMB_WALK, + ZOMB_DEAD +}; + +class monster_zombie:CBaseMonster +{ + float m_flScaredTime; + float m_flScreamTime; + float m_flPainTime; + float m_flChangePath; + float m_flTraceTime; + float m_flPitch; + int m_iFlags; + + void() monster_zombie; + + virtual void(int) vPain; + virtual void(int) vDeath; + virtual void(void) Respawn; +}; + +void monster_zombie::vPain(int iHitBody) +{ + if (m_flPainTime > time) { + return; + } + + if (random() < 0.25f) { + return; + } + + int rand = floor(random(0,sci_sndpain.length)); + Speak(sci_sndpain[rand]); + frame = ZOMA_FLINCH + floor(random(0, 2)); + m_flPainTime = time + 0.25f; +} + +void monster_zombie::vDeath(int iHitBody) +{ + int r; + + think = Respawn; + nextthink = time + 10.0f; + + SendFlags |= NPC_FRAME; + m_iFlags = 0x0; + + if (health < -50) { + Gib(); + return; + } + + flags &= ~FL_MONSTER; + movetype = MOVETYPE_NONE; + solid = SOLID_CORPSE; + + if (style != ZOMB_DEAD) { + frame = ZOMA_DIE + floor(random(0, 3)); + style = ZOMB_DEAD; + } +} + +void monster_zombie::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]); + + 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]); + takedamage = DAMAGE_YES; + iBleeds = TRUE; + customphysics = Physics; + frame = ZOMA_IDLE; + SendFlags |= NPC_FRAME; + health = 50; + velocity = [0,0,0]; + m_iFlags = 0x0; + SendFlags = 0xff; + style = ZOMB_IDLE; + netname = "Zombie"; +} + +void monster_zombie::monster_zombie(void) +{ + model = "models/zombie.mdl"; + CBaseEntity::CBaseEntity(); + precache_model(m_oldModel); + Respawn(); +} diff --git a/src/server/valve/progs.src b/src/server/valve/progs.src index e063b789..91d344a0 100755 --- a/src/server/valve/progs.src +++ b/src/server/valve/progs.src @@ -18,9 +18,42 @@ defs.h ../logging.c ../nodes.c ../../gs-entbase/server.src -monster_rat.cpp -monster_scientist.cpp -monster_scientist_dead.cpp + +../valve/monster_apache.cpp +../valve/monster_alien_controller.cpp +../valve/monster_alien_grunt.cpp +../valve/monster_alien_slave.cpp +../valve/monster_babycrab.cpp +../valve/monster_barnacle.cpp +../valve/monster_barney.cpp +../valve/monster_barney_dead.cpp +../valve/monster_bigmomma.cpp +../valve/monster_bloater.cpp +../valve/monster_bullchicken.cpp +../valve/monster_cockroach.cpp +../valve/monster_flyer_flock.cpp +../valve/monster_gargantua.cpp +../valve/monster_gman.cpp +../valve/monster_headcrab.cpp +../valve/monster_hevsuit_dead.cpp +../valve/monster_houndeye.cpp +../valve/monster_human_grunt.cpp +../valve/monster_hgrunt_dead.cpp +../valve/monster_human_assassin.cpp +../valve/monster_ichthyosaur.cpp +../valve/monster_leech.cpp +../valve/monster_miniturret.cpp +../valve/monster_nihilanth.cpp +../valve/monster_osprey.cpp +../valve/monster_rat.cpp +../valve/monster_scientist_dead.cpp +../valve/monster_sitting_scientist.cpp +../valve/monster_scientist.cpp +../valve/monster_sentry.cpp +../valve/monster_tentacle.cpp +../valve/monster_turret.cpp +../valve/monster_zombie.cpp + ../../shared/decals.c ../../shared/effects.c ../../shared/spraylogo.cpp @@ -74,5 +107,6 @@ damage.c ../flashlight.c input.c spawn.c +../vote.c ../entry.c #endlist diff --git a/src/server/vote.c b/src/server/vote.c new file mode 100644 index 00000000..99465681 --- /dev/null +++ b/src/server/vote.c @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * 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. + */ + +var string g_strVoteCmd; +var float g_flVoteTime; +var int g_iVoteState; +var int autocvar_mp_allowvote = TRUE; + +enum { + VOTE_INACTIVE, + VOTE_INPROGRESS, + VOTE_PASSED +}; + +/* +================= +Vote_End +================= +*/ +void +Vote_End(void) +{ + + localcmd(sprintf("%s\n", g_strVoteCmd)); + g_flVoteTime = 0.0f; + g_iVoteState = VOTE_INACTIVE; +} + + +/* +================= +Vote_Reset + +Make sure all the cached stuff is reset. +================= +*/ +void +Vote_Reset(void) +{ + forceinfokey(world, "votes_y", "0"); + forceinfokey(world, "votes_n", "0"); + forceinfokey(world, "vote_cmd", ""); + + for ( entity e = world; ( e = find( e, classname, "player" ) ); ) { + e.flags &= ~FL_VOTED; + } +} + +/* +================= +Vote_Passed + +Called whenever enough people agreed, or time has run out with enougn YES's +================= +*/ +void +Vote_Passed(void) +{ + g_flVoteTime = time + 5.0f; + g_iVoteState = VOTE_PASSED; + bprint(PRINT_CHAT, "Vote passed.\n"); + g_strVoteCmd = serverkey("vote_cmd"); + Vote_Reset(); +} + +/* +================= +Vote_Failed + +Called whenever enough people disagreed, or time has run out below the limit +================= +*/ +void +Vote_Failed(void) +{ + g_flVoteTime = 0.0; + g_iVoteState = VOTE_INACTIVE; + bprint(PRINT_CHAT, "Vote failed.\n"); + Vote_Reset(); +} + +/* +================= +Vote_Frame + +Called in ServerFrame... every single frame. +================= +*/ +void +Vote_Frame(void) +{ + if (time >= g_flVoteTime) { + + if (g_iVoteState == VOTE_INPROGRESS) { + if (serverkeyfloat("votes_y") > serverkeyfloat("votes_n")) { + Vote_Passed(); + } else { + Vote_Failed(); + } + } else if (g_iVoteState == VOTE_PASSED) { + Vote_End(); + } + } +} + +/* +================= +CSEv_VoteY + +'vote yes' +================= +*/ +void +CSEv_VoteY(void) +{ + /* No vote is in progress */ + if (g_iVoteState != VOTE_INPROGRESS) { + return; + } + + if (self.classname != "player") { + return; + } + + if (self.flags & FL_VOTED) { + return; + } + + forceinfokey(world, "votes_y", ftos(serverkeyfloat("votes_y")+1)); + self.flags |= FL_VOTED; + + /* HACK: Is there a better way to do this? */ + float playernums = 0; + for ( entity eFind = world; ( eFind = find( eFind, classname, "player" ) ); ) { + playernums++; + } + + /* We need at least half the players agreeing. */ + if (serverkeyfloat("votes_y") > rint(playernums / 2)) { + Vote_Passed(); + return; + } + + if (serverkeyfloat("votes_n") + serverkeyfloat("votes_y") == playernums) { + g_flVoteTime = time + 0.0f; + } +} + +/* +================= +CSEv_VoteN + +'vote no' +================= +*/ +void +CSEv_VoteN(void) +{ + /* No vote is in progress */ + if (g_iVoteState != VOTE_INPROGRESS) { + return; + } + + if (self.classname != "player") { + return; + } + + if (self.flags & FL_VOTED) { + return; + } + + forceinfokey(world, "votes_n", ftos(serverkeyfloat("votes_n")+1)); + self.flags |= FL_VOTED; + + /* HACK: Is there a better way to do this? */ + float playernums = 0; + for ( entity eFind = world; ( eFind = find( eFind, classname, "player" ) ); ) { + playernums++; + } + + /* We need at least half the players disagreeing. */ + if (serverkeyfloat("votes_n") > rint(playernums / 2)) { + Vote_Failed(); + return; + } + + if (serverkeyfloat("votes_n") + serverkeyfloat("votes_y") == playernums) { + g_flVoteTime = time + 0.0f; + } +} + + +/* +================= +Vote_InitiateVote + +Send the info to the clients and set the timer up +================= +*/ +void +Vote_InitiateVote(string votemsg) +{ + /* A vote is in progress */ + if (g_iVoteState != VOTE_INACTIVE) { + return; + } + + if (self.classname != "player") { + return; + } + + Vote_Reset(); + + forceinfokey(world, "vote_cmd", votemsg); + g_flVoteTime = time + 30.0f; + g_iVoteState = VOTE_INPROGRESS; +} + +/* +================= +CSEv_CallVote_s + +Initiates a vote via the 'callvote' client command. +================= +*/ +void +CSEv_CallVote_s(string text) +{ + if (autocvar_mp_allowvote == FALSE) { + return; + } + + /* No vote is in progress */ + if (g_iVoteState != VOTE_INACTIVE) { + sprint(self, PRINT_CHAT, "A vote is already in progress.\n"); + return; + } + + tokenize(text); + switch (argv(0)) { + case "map": + /*if (whichpack(sprintf("maps/%s.bsp", argv(1))) == __NULL__) { + sprint(self, PRINT_CHAT, sprintf("Map '%s' not available on server.\n", argv(1))); + break; + }*/ + case "kick": + case "slowmo": + case "timelimit": + case "fraglimit": + case "map_restart": + case "nextmap": + Vote_InitiateVote(sprintf("%s %s", argv(0), argv(1))); + CSEv_VoteY(); + break; + default: + sprint(self, PRINT_CHAT, sprintf("Cannot callvote for '%s'.\n", argv(0))); + } + +} + +void +Vote_Init(void) +{ + Vote_Reset(); +} diff --git a/src/shared/defs.h b/src/shared/defs.h index 07d6ed97..6109927c 100644 --- a/src/shared/defs.h +++ b/src/shared/defs.h @@ -41,31 +41,32 @@ const vector VEC_PLAYER_CVIEWPOS = [0,0,12]; #define INPUT_BUTTON7 0x00000040 #define INPUT_BUTTON8 0x00000080 -// Engine reserved flags -#define FL_FLY (1<<0) -#define FL_SWIM (1<<1) -#define FL_GLIMPSE (1<<2) -#define FL_CLIENT (1<<3) -#define FL_INWATER (1<<4) -#define FL_MONSTER (1<<5) -#define FL_GODMODE (1<<6) -#define FL_NOTARGET (1<<7) -#define FL_ITEM (1<<8) -#define FL_ONGROUND (1<<9) -#define FL_PARTIALGROUND (1<<10) -#define FL_WATERJUMP (1<<11) -#define FL_JUMPRELEASED (1<<12) +/* engine reserved */ +#define FL_FLY (1<<0) +#define FL_SWIM (1<<1) +#define FL_GLIMPSE (1<<2) +#define FL_CLIENT (1<<3) +#define FL_INWATER (1<<4) +#define FL_MONSTER (1<<5) +#define FL_GODMODE (1<<6) +#define FL_NOTARGET (1<<7) +#define FL_ITEM (1<<8) +#define FL_ONGROUND (1<<9) +#define FL_PARTIALGROUND (1<<10) +#define FL_WATERJUMP (1<<11) +#define FL_JUMPRELEASED (1<<12) #define FL_FINDABLE_NONSOLID (1<<14) -#define FLQW_LAGGEDMOVE (1<<16) +#define FLQW_LAGGEDMOVE (1<<16) -// FreeCS flags +/* nuclide */ +#define FL_ONLADDER (1<<13) #define FL_FLASHLIGHT (1<<17) -#define FL_REMOVEME (1<<18) +#define FL_REMOVEME (1<<18) #define FL_CROUCHING (1<<19) #define FL_SEMI_TOGGLED (1<<20) -#define FL_FROZEN (1<<21) -#define FL_ONLADDER (1<<13) - +#define FL_FROZEN (1<<21) +#define FL_VOTED (1<<22) +#define FL_RESERVED (1<<23) #define UPDATE_ALL 16777215 /* global hitmesh definitions */ diff --git a/src/shared/entities.h b/src/shared/entities.h index de4028ff..03fa597f 100644 --- a/src/shared/entities.h +++ b/src/shared/entities.h @@ -19,6 +19,7 @@ enum { ENT_PLAYER, ENT_NPC, ENT_AMBIENTSOUND, + ENT_ENVLASER, ENT_SPRITE, ENT_SPRAY, #ifdef VALVE diff --git a/src/shared/valve/w_hornetgun.c b/src/shared/valve/w_hornetgun.c index 6018a69c..d31edcdf 100644 --- a/src/shared/valve/w_hornetgun.c +++ b/src/shared/valve/w_hornetgun.c @@ -160,18 +160,17 @@ w_hornetgun_release(void) int r; r = (float)input_sequence % 3; switch (r) { - case 0: - Weapons_ViewAnimation(HORNETGUN_IDLE); - pl.w_idle_next = 1.875f; - break; case 1: Weapons_ViewAnimation(HORNETGUN_FIDGET1); pl.w_idle_next = 2.5f; break; - default: + case 2: Weapons_ViewAnimation(HORNETGUN_FIDGET2); pl.w_idle_next = 2.1875f; break; + default: + Weapons_ViewAnimation(HORNETGUN_IDLE); + pl.w_idle_next = 1.875f; } } diff --git a/src/shared/valve/w_python.c b/src/shared/valve/w_python.c index 97027f87..62b4d994 100644 --- a/src/shared/valve/w_python.c +++ b/src/shared/valve/w_python.c @@ -214,22 +214,22 @@ w_python_release(void) { player pl = (player)self; -#ifdef CSQC if (pl.w_idle_next > 0.0) { return; } int r = (float)input_sequence % 4; + switch (r) { - case 0: + case 1: Weapons_ViewAnimation(PYTHON_IDLE1); pl.w_idle_next = 2.33f; break; - case 1: + case 2: Weapons_ViewAnimation(PYTHON_FIDGET); pl.w_idle_next = 5.66f; break; - case 2: + case 3: Weapons_ViewAnimation(PYTHON_IDLE2); pl.w_idle_next = 2.0f; break; @@ -238,7 +238,6 @@ w_python_release(void) pl.w_idle_next = 2.93f; break; } -#endif } void diff --git a/src/shared/valve/w_rpg.c b/src/shared/valve/w_rpg.c index 31218324..32ebfc07 100644 --- a/src/shared/valve/w_rpg.c +++ b/src/shared/valve/w_rpg.c @@ -37,6 +37,7 @@ void w_rpg_precache(void) precache_model("sprites/laserdot.spr"); precache_sound("weapons/rocketfire1.wav"); } + void w_rpg_updateammo(player pl) { #ifdef SSQC @@ -87,32 +88,6 @@ void w_rpg_holster(void) } -void w_rpg_release(void) -{ - player pl = (player)self; - if (pl.w_idle_next > 0.0) { - return; - } - - int r = (float)input_sequence % 3; - - if (pl.a_ammo1 > 0) { - if (r == 1) { - Weapons_ViewAnimation(RPG_FIDGET); - } else { - Weapons_ViewAnimation(RPG_IDLE); - } - } else { - if (r == 1) { - Weapons_ViewAnimation(RPG_FIDGET_UL); - } else { - Weapons_ViewAnimation(RPG_IDLE_UL); - } - } - - pl.w_idle_next = 6.0f; -} - void w_rpg_primary(void) { player pl = (player)self; @@ -182,25 +157,10 @@ void w_rpg_primary(void) pl.rpg_mag--; #endif - pl.w_attack_next = 1.0f; + pl.w_attack_next = pl.w_idle_next = 2.5f; } -void w_rpg_secondary(void) -{ - player pl = (player)self; - - if (pl.w_attack_next > 0.0) { - return; - } - - /* toggle laser */ - pl.a_ammo3 = 1 - pl.a_ammo3; - - pl.w_attack_next = 1.0f; - w_rpg_release(); -} - void w_rpg_reload(void) { player pl = (player)self; @@ -238,6 +198,57 @@ void w_rpg_reload(void) pl.w_idle_next = 10.0f; } +void w_rpg_release(void) +{ + player pl = (player)self; + if (pl.w_idle_next > 0.0) { + return; + } + +#ifdef CSQC + if (pl.a_ammo1 <= 0 && pl.a_ammo2 > 0) { + w_rpg_reload(); + } +#else + if (pl.rpg_mag <= 0 && pl.ammo_rocket > 0) { + w_rpg_reload(); + } +#endif + + int r = (float)input_sequence % 3; + + if (pl.a_ammo1 > 0) { + if (r == 1) { + Weapons_ViewAnimation(RPG_FIDGET); + } else { + Weapons_ViewAnimation(RPG_IDLE); + } + } else { + if (r == 1) { + Weapons_ViewAnimation(RPG_FIDGET_UL); + } else { + Weapons_ViewAnimation(RPG_IDLE_UL); + } + } + + pl.w_idle_next = 6.0f; +} + +void w_rpg_secondary(void) +{ + player pl = (player)self; + + if (pl.w_attack_next > 0.0) { + return; + } + + /* toggle laser */ + pl.a_ammo3 = 1 - pl.a_ammo3; + + pl.w_attack_next = 1.0f; + w_rpg_release(); +} + float w_rpg_aimanim(void) { return self.flags & FL_CROUCHING ? ANIM_CR_AIMRPG : ANIM_AIMRPG;