diff --git a/Source/builtins.h b/Source/builtins.h index 2dd398a2..8c62bfe5 100644 --- a/Source/builtins.h +++ b/Source/builtins.h @@ -2583,7 +2583,7 @@ float(string conname, float inevtype, float parama, float paramb, float paramc) Forwards input events to the named console. Mouse updates should be absolute only. */ #endif -#ifdef CSQC +#if defined(CSQC) || defined(MENU) void(string newcaption) setwindowcaption = #0:setwindowcaption; /* Part of FTE_CSQC_WINDOWCAPTION Replaces the title of the game window, as seen when task switching or just running in windowed mode. */ diff --git a/Source/client/cstrike/defs.h b/Source/client/cstrike/defs.h index ff5fd2c5..50bd0b62 100755 --- a/Source/client/cstrike/defs.h +++ b/Source/client/cstrike/defs.h @@ -73,6 +73,13 @@ struct float fBob; float damage_alpha; vector damage_pos; + + /* Camera Bob */ + float flCamMove; + float flCamTime; + int iCamCycle; + float flCamFracSin; + float flCamDelta; //Player fields entity ePlayer; diff --git a/Source/client/entry.c b/Source/client/entry.c index 3f680a42..9adec35f 100644 --- a/Source/client/entry.c +++ b/Source/client/entry.c @@ -630,16 +630,78 @@ float CSQC_Ent_ParseMapEntity(void) switch (strField) { case "classname": - /*if (strValue == "env_cubemap") { - iClass = TRUE; - eEnt = spawn(CEnvCubemap); - } else */if (strValue == "worldspawn") { + switch (strValue) { + case "worldspawn": eEnt = spawn(worldspawn); iClass = TRUE; - } else if (strValue == "env_sound") { + break; + case "env_sound": eEnt = spawn(env_sound); iClass = TRUE; - } else { + break; + #ifdef REWOLF + case "decore_asteroid": + eEnt = spawn(decore_asteroid); + iClass = TRUE; + break; + case "decore_baboon": + eEnt = spawn(decore_baboon); + iClass = TRUE; + break; + case "decore_bodygib": + eEnt = spawn(decore_bodygib); + iClass = TRUE; + break; + case "decore_butterflyflock": + eEnt = spawn(decore_butterflyflock); + iClass = TRUE; + break; + case "decore_explodable": + eEnt = spawn(decore_explodable); + iClass = TRUE; + break; + case "decore_foot": + eEnt = spawn(decore_foot); + iClass = TRUE; + break; + case "decore_goldskull": + eEnt = spawn(decore_goldskull); + iClass = TRUE; + break; + case "decore_hatgib": + eEnt = spawn(decore_hatgib); + iClass = TRUE; + break; + case "decore_nest": + eEnt = spawn(decore_nest); + iClass = TRUE; + break; + case "decore_pteradon": + eEnt = spawn(decore_pteradon); + iClass = TRUE; + break; + case "decore_torch": + eEnt = spawn(decore_torch); + iClass = TRUE; + break; + case "decore_spacedebris": + eEnt = spawn(decore_spacedebris); + iClass = TRUE; + break; + case "decore_swampplants": + eEnt = spawn(decore_swampplants); + iClass = TRUE; + break; + case "decore_mushroom": + eEnt = spawn(decore_mushroom); + iClass = TRUE; + break; + case "decore_mushroom2": + eEnt = spawn(decore_mushroom2); + iClass = TRUE; + break; + #endif + default: eEnt.classname = strValue; } break; diff --git a/Source/client/rewolf.src b/Source/client/rewolf.src index 0fe5065b..e23b9305 100755 --- a/Source/client/rewolf.src +++ b/Source/client/rewolf.src @@ -3,6 +3,7 @@ #define CSQC #define VALVE +#define REWOLF #includelist ../builtins.h @@ -16,10 +17,12 @@ defs.h vgui.h util.c -valve/init.c +rewolf/init.c ../gs-entbase/client.src +rewolf/decore.cpp + sound.c text.c voice.c @@ -63,7 +66,7 @@ valve/view.c view.c damage.c chat.c -valve/hud.c +rewolf/hud.c valve/hud_weaponselect.c valve/scoreboard.c diff --git a/Source/client/rewolf/decore.cpp b/Source/client/rewolf/decore.cpp new file mode 100644 index 00000000..da58d2df --- /dev/null +++ b/Source/client/rewolf/decore.cpp @@ -0,0 +1,176 @@ +/*** +* +* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved. +* +* See the file LICENSE attached with the sources for usage details. +* +****/ + +class CBaseDecor:CBaseEntity +{ + int m_iBody; + virtual void(string, string) SpawnKey; +}; + +void CBaseDecor::Initialized(void) +{ + setmodel(this, model); + setorigin(this, origin); + setcustomskin(this, "", sprintf("geomset 0 %i\n", m_iBody)); + drawmask = MASK_ENGINE; +} + +void CBaseDecor::SpawnKey(string strField, string strKey) +{ + switch (strField) { + case "body": + m_iBody = stoi(strKey); + break; + default: + CBaseEntity::SpawnKey(strField, strKey); + break; + } +} + +/* Let's begin */ +class decore_asteroid:CBaseDecor +{ + virtual void() Initialized = { + model = "models/asteroid.mdl"; + CBaseDecor::Initialized(); + }; +}; + +class decore_baboon:CBaseDecor +{ + virtual void() Initialized = { + model = "models/baboon.mdl"; + CBaseDecor::Initialized(); + }; +}; + +class decore_bodygib:CBaseDecor +{ + void() decore_bodygib = { + model = "models/bodygib.mdl"; + CBaseDecor::Initialized(); + }; +}; + +class decore_butterflyflock:CBaseDecor +{ + virtual void() Initialized = { + model = "models/butterfly.mdl"; + CBaseDecor::Initialized(); + }; +}; + +class decore_explodable:CBaseDecor +{ + virtual void() Initialized = { + model = "models/EXPLODABLE!!!!"; + CBaseDecor::Initialized(); + }; +}; + +class decore_foot:CBaseDecor +{ + virtual void() Initialized = { + model = "models/FOOT!!!!"; + CBaseDecor::Initialized(); + }; +}; + +class decore_goldskull:CBaseDecor +{ + virtual void() Initialized = { + model = "models/goldskull.mdl"; + CBaseDecor::Initialized(); + }; +}; + +class decore_hatgib:CBaseDecor +{ + virtual void() Initialized = { + model = "models/hatgib.mdl"; + CBaseDecor::Initialized(); + }; +}; + +class decore_nest:CBaseDecor +{ + virtual void() Initialized = { + model = "models/ornest.mdl"; + CBaseDecor::Initialized(); + }; +}; + +class decore_pteradon:CBaseDecor +{ + virtual void() Initialized = { + model = "models/pteradon2.mdl"; + CBaseDecor::Initialized(); + }; +}; + +class decore_torch:CBaseDecor +{ + virtual void() Initialized = { + precache_model("sprites/torch.spr"); + model = "models/torch.mdl"; + CBaseDecor::Initialized(); + this.effects |= EF_FULLBRIGHT; + + sprite flame = spawn(sprite); + setorigin(flame, origin + [0,0,24]); + setmodel(flame, "sprites/torch.spr"); + flame.effects = EF_ADDITIVE; + flame.drawmask = MASK_ENGINE; + flame.maxframe = modelframecount(flame.modelindex); + flame.loops = 1; + flame.framerate = 10; + flame.nextthink = time + 0.05f; + }; +}; + +class decore_spacedebris:CBaseDecor +{ + virtual void() Initialized = { + CBaseDecor::Initialized(); + }; + + virtual void(string strField, string strKey) SpawnKey = { + switch (strField) { + case "modelname": + model = strKey; + break; + default: + CBaseEntity::SpawnKey(strField, strKey); + break; + } + }; +}; + +class decore_swampplants:CBaseDecor +{ + virtual void() Initialized = { + model = "models/swampstuff.mdl"; + CBaseDecor::Initialized(); + }; +}; + +class decore_mushroom:CBaseDecor +{ + virtual void() Initialized = { + model = "models/mushroom.mdl"; + CBaseDecor::Initialized(); + }; +}; + +class decore_mushroom2:CBaseDecor +{ + virtual void() Initialized = { + model = "models/mushroom2.mdl"; + CBaseDecor::Initialized(); + }; +}; diff --git a/Source/client/rewolf/hud.c b/Source/client/rewolf/hud.c new file mode 100644 index 00000000..df457d1c --- /dev/null +++ b/Source/client/rewolf/hud.c @@ -0,0 +1,257 @@ +/*** +* +* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved. +* +* See the file LICENSE attached with the sources for usage details. +* +****/ + +/* Use first frame for drawing (needs precache) */ +#define HUD_NUMS "sprites/640hud7.spr_0.tga" +#define GM_NUMS "sprites/numbers.spr_0.tga" + +#define HUD_ALPHA 0.5 + +/* New Gunman digits */ +#define NUMSIZE_X 18/256 +#define NUMSIZE_Y 32/32 + +float spr_hudnum[10] = { + 0 / 256, + 18 / 256, + (18*2) / 256, + (18*3) / 256, + (18*4) / 256, + (18*5) / 256, + (18*6) / 256, + (18*7) / 256, + (18*8) / 256, + (18*9) / 256 +}; + +void HUD_DrawWeaponSelect(void); + +void HUD_Init(void) +{ + precache_model("sprites/640hud7.spr"); + precache_model("sprites/numbers.spr"); + precache_model("sprites/armor.spr"); + precache_model("sprites/hudpulse.spr"); + precache_pic("gfx/vgui/640_metalhud_small.tga"); + precache_pic("gfx/vgui/640_metalhud.tga"); +} + +/* +================= +HUD_DrawNumber + +Draws a normal number +================= +*/ +void HUD_DrawNumber(int iNumber, vector vPos, float fAlpha, vector vColor) +{ + drawsubpic(vPos, [18,32], GM_NUMS, [spr_hudnum[iNumber], 0], + [NUMSIZE_X, NUMSIZE_Y], vColor, fAlpha, DRAWFLAG_ADDITIVE); +} + +void HUD_DrawSeperator(vector pos) +{ + drawsubpic(pos, [2,24], HUD_NUMS, [240/256, 0], + [2/256, 24/128], g_hud_color, HUD_ALPHA, DRAWFLAG_ADDITIVE); +} + +/* +================= +HUD_DrawNums + +Draws numerals quickly for health, armor etc. +================= +*/ +void HUD_DrawNums(float fNumber, vector vPos, float fAlpha, vector vColor) +{ + int iNumber = fNumber; + if (iNumber > 0) { + while (iNumber > 0) { + HUD_DrawNumber((float)iNumber % 10, vPos, fAlpha, vColor); + iNumber = iNumber / 10; + vPos[0] -= 20; + } + } else { + HUD_DrawNumber(0, vPos, fAlpha, vColor); + } +} + +/* +================= +HUD_DrawHealth + +Draw the current amount of health +================= +*/ +void HUD_DrawHealth(void) +{ + vector pos; + vector hcol; + player pl; + + pl = (player)pSeat->ePlayer; + + /* Shift digits by 128 units for the larger HUD */ + if (video_res[0] <= 640) { + pos = video_mins + [0, video_res[1] - 128]; + } else { + pos = video_mins + [128, video_res[1] - 128]; + } + + /* Obligatory low-health color tint */ + if (pl.health <= 25) { + hcol = [1,0,0]; + } else { + hcol = [0,1,1]; + } + + /* Because we've got little space, the number 100 is its own graphic */ + if (pl.health >= 100) { + drawsubpic(pos+[34,30], [42,32], GM_NUMS, [192/256, 0], + [42/256, 32/32], hcol, 1.0f, DRAWFLAG_ADDITIVE); + } else { + HUD_DrawNums(pl.health, pos + [56,30], 1.0f, hcol); + } + + if (pl.armor >= 100) { + drawsubpic(pos+[34,64], [42,32], GM_NUMS, [192/256, 0], + [42/256, 32/32], [0,1,0], 1.0f, DRAWFLAG_ADDITIVE); + } else { + HUD_DrawNums(pl.armor, pos + [56,64], 1.0f, [0,1,0]); + } + + /* Minimal VS Larger HUD */ + if (video_res[0] <= 640) { + drawpic(pos, "gfx/vgui/640_metalhud_small.tga", [128,128], + [1,1,1], 1.0f); + } else { + pos[0] -= 128; + + /* Armor bar */ + float ap = pl.armor / 100; + if (ap) { + drawsubpic(pos+[28,18], [95*ap,32], "sprites/armor.spr_0.tga", + [0, 0], [0.7421875*ap, 1], [1,1,1], 1.0f, DRAWFLAG_NORMAL); + } + + /* Health, TODO: make it scroll */ + if (pl.health <= 20) { + drawpic(pos + [35,53], "sprites/hudpulse.spr_4.tga", [128,32], + [1,1,1], 1.0f, DRAWFLAG_ADDITIVE); + } else if (pl.health <= 40) { + drawpic(pos + [35,53], "sprites/hudpulse.spr_3.tga", [128,32], + [1,1,1], 1.0f, DRAWFLAG_ADDITIVE); + } else if (pl.health <= 60) { + drawpic(pos + [35,53], "sprites/hudpulse.spr_2.tga", [128,32], + [1,1,1], 1.0f, DRAWFLAG_ADDITIVE); + } else if (pl.health <= 80) { + drawpic(pos + [35,53], "sprites/hudpulse.spr_1.tga", [128,32], + [1,1,1], 1.0f, DRAWFLAG_ADDITIVE); + } else { + drawpic(pos + [35,53], "sprites/hudpulse.spr_0.tga", [128,32], + [1,1,1], 1.0f, DRAWFLAG_ADDITIVE); + } + + drawpic(pos, "gfx/vgui/640_metalhud.tga", [256,128], [1,1,1], 1.0f); + } +} + +void HUD_DrawAmmo1(void) +{ + player pl = (player)pSeat->ePlayer; + vector pos; + static int old_ammo1; + static float ammo1_alpha; + + if (pl.a_ammo1 != old_ammo1) { + ammo1_alpha = 1.0; + old_ammo1 = pl.a_ammo1; + } + + if (ammo1_alpha >= HUD_ALPHA) { + ammo1_alpha -= frametime * 0.5; + } else { + ammo1_alpha = HUD_ALPHA; + } + + pos = video_mins + [video_res[0] - 48, video_res[1] - 42]; + + /* Magazine/Clip */ + if (pl.a_ammo1 != -1) { + HUD_DrawNums(pl.a_ammo1, pos + [-80,0], ammo1_alpha, g_hud_color); + } + + HUD_DrawSeperator(pos + [-50,0]); +} + +void HUD_DrawAmmo2(void) +{ + player pl = (player)pSeat->ePlayer; + vector pos; + + static int old_ammo2; + static float ammo2_alpha; + + if (pl.a_ammo2 != old_ammo2) { + ammo2_alpha = 1.0; + old_ammo2 = pl.a_ammo2; + } + + if (ammo2_alpha >= HUD_ALPHA) { + ammo2_alpha -= frametime * 0.5; + } else { + ammo2_alpha = HUD_ALPHA; + } + + pos = video_mins + [video_res[0] - 48, video_res[1] - 42]; + + /* Leftover Ammo */ + HUD_DrawNums(pl.a_ammo2, pos, ammo2_alpha, g_hud_color); +} + +void HUD_DrawAmmo3(void) +{ + player pl = (player)pSeat->ePlayer; + vector pos; + + static int old_ammo3; + static float ammo3_alpha; + + if (pl.a_ammo3 != old_ammo3) { + ammo3_alpha = 1.0; + old_ammo3 = pl.a_ammo3; + } + + if (ammo3_alpha >= HUD_ALPHA) { + ammo3_alpha -= frametime * 0.5; + } else { + ammo3_alpha = HUD_ALPHA; + } + + pos = video_mins + [video_res[0] - 48, video_res[1] - 42]; + + /* Special */ + if (pl.a_ammo3) { + HUD_DrawNums(pl.a_ammo3, pos + [0, -32], ammo3_alpha, g_hud_color); + } +} + +void HUD_Draw(void) +{ + g_hud_color = autocvar_con_color * (1 / 255); + + Damage_Draw(); + HUD_DrawHealth(); + Weapons_DrawCrosshair(); + HUD_DrawWeaponSelect(); +} + +void VGUI_DrawSpectatorHUD(void) +{ + // FIXME +} diff --git a/Source/client/rewolf/init.c b/Source/client/rewolf/init.c new file mode 100644 index 00000000..4146b5a2 --- /dev/null +++ b/Source/client/rewolf/init.c @@ -0,0 +1,29 @@ +/*** +* +* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved. +* +* See the file LICENSE attached with the sources for usage details. +* +****/ + +/* +================= +Client_Init + +Comparable to worldspawn in SSQC in that it's mostly used for precaches +================= +*/ +void Client_Init(float apilevel, string enginename, float engineversion) +{ + precache_model("sprites/640hud1.spr"); + precache_model("sprites/640hud2.spr"); + precache_model("sprites/640hud3.spr"); + precache_model("sprites/640hud4.spr"); + precache_model("sprites/640hud5.spr"); + precache_model("sprites/640hud6.spr"); +} + +void Game_RendererRestarted(string rstr) +{ + +} diff --git a/Source/client/scihunt/init.c b/Source/client/scihunt/init.c index ccb895e2..4f88c33f 100644 --- a/Source/client/scihunt/init.c +++ b/Source/client/scihunt/init.c @@ -6,6 +6,12 @@ * ****/ +/* FIXME: Remove this once the builtin exists */ +float getchannellevel(entity foo, float chanid) +{ + return bound(0, cos(time), 1) * 100; +} + /* This really shouldn't be here, but it'll be fine for the time being */ .int initedsci; float Scientist_PreDraw(void) @@ -15,6 +21,8 @@ float Scientist_PreDraw(void) setcustomskin(self, "", sprintf("geomset 1 %d\n", self.colormod[0])); self.initedsci = TRUE; } + + self.bonecontrol5 = getchannellevel(self, CHAN_VOICE); /* HACK: We're abusing this networked field, so reset */ self.colormod = [0,0,0]; diff --git a/Source/client/valve/defs.h b/Source/client/valve/defs.h index bdf497bb..deb8c21a 100644 --- a/Source/client/valve/defs.h +++ b/Source/client/valve/defs.h @@ -21,6 +21,13 @@ struct float fBob; float damage_alpha; vector damage_pos; + + /* Camera Bob */ + float flCamMove; + float flCamTime; + int iCamCycle; + float flCamFracSin; + float flCamDelta; //Player fields entity ePlayer; diff --git a/Source/client/valve/scoreboard.c b/Source/client/valve/scoreboard.c index 65343a3a..f002f1ec 100644 --- a/Source/client/valve/scoreboard.c +++ b/Source/client/valve/scoreboard.c @@ -1,3 +1,14 @@ +/*** +* +* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved. +* +* See the file LICENSE attached with the sources for usage details. +* +****/ + +#define SCORE_HEADER_C [255/255,156/255,0] +#define SCORE_LINE_C [255/255,200/255,0] + void Scores_Init(void) { @@ -5,5 +16,55 @@ void Scores_Init(void) void Scores_Draw(void) { + vector pos; + player pl; + pl = (player)pSeat->ePlayer; + pos = video_mins + [(video_res[0] / 2) - 145, 30]; + + drawfill(pos, [290, 1], SCORE_LINE_C, 1.0f, DRAWFLAG_ADDITIVE); + + drawfont = FONT_20; + drawstring(pos + [0,-18], "Player", [20,20], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE); + drawstring(pos + [124,-18], "kills / deaths", [20,20], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE); + drawstring(pos + [240,-18], "latency", [20,20], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE); + + pos[1] += 12; + for (int i = -1; i > -32; i--) { + float l; + string ping; + string kills; + string deaths; + string name; + + name = getplayerkeyvalue(i, "name"); + + /* Out of players */ + if (!name) { + break; + } else if (name == getplayerkeyvalue(pl.entnum-1, "name")) { + drawfill(pos, [290, 13], [0,0,1], 0.5f, DRAWFLAG_ADDITIVE); + } + + drawstring(pos, getplayerkeyvalue(i, "name"), [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE); + drawstring(pos + [154,0], "/", [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE); + + /* Get the kills and align them left to right */ + kills = getplayerkeyvalue(i, "frags"); + l = stringwidth(kills, FALSE, [20,20]); + drawstring(pos + [150 - l,0], kills, [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE); + + /* Deaths are right to left aligned */ + deaths = getplayerkeyvalue(i, "*deaths"); + drawstring(pos + [165,0], deaths, [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE); + + /* Get the latency and align it left to right */ + ping = getplayerkeyvalue(i, "ping"); + l = stringwidth(ping, FALSE, [20,20]); + + drawstring(pos + [290 - l,0], ping, [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE); + pos[1] += 20; + } + + drawfont = FONT_CON; } diff --git a/Source/client/view.c b/Source/client/view.c index 8857ee2b..18426ae3 100644 --- a/Source/client/view.c +++ b/Source/client/view.c @@ -6,6 +6,8 @@ * ****/ +var int autocvar_v_cambob = FALSE; + void View_Init(void) { #ifdef CSTRIKE @@ -66,7 +68,7 @@ void View_CalcBob(void) float cycle; vector vel; - + if (self.flags & FL_ONGROUND == -1) { return; } @@ -89,6 +91,52 @@ void View_CalcBob(void) pSeat->fBob = bound(-7, fBob, 4); } +/* +================= +View_CalcCameraBob +================= +*/ + +void View_CalcCamBob(void) +{ + float flPlayerSpeed; + + if (!autocvar_v_cambob) { + return; + } + + flPlayerSpeed = vlen(pSeat->vPlayerVelocity); + + if (flPlayerSpeed < 5) { + pSeat->flCamMove = 0; + pSeat->flCamTime = 0; + } else if (pSeat->fPlayerFlags & FL_ONGROUND) { + if ( flPlayerSpeed > 210 ) { + pSeat->flCamMove = clframetime * 3; + } else if (flPlayerSpeed > 100) { + pSeat->flCamMove = clframetime * 1.5; + } else { + pSeat->flCamMove = clframetime; + } + } + + pSeat->flCamTime = (pSeat->flCamTime += pSeat->flCamMove); + pSeat->iCamCycle = (int)pSeat->flCamTime; + pSeat->flCamFracSin = fabs(sin(pSeat->flCamTime * M_PI)); + pSeat->flCamDelta = pSeat->flCamFracSin * 0.002 * flPlayerSpeed; + + if ((pSeat->fPlayerFlags & FL_CROUCHING) && (pSeat->fPlayerFlags & FL_ONGROUND)) { + pSeat->flCamDelta *= 6; + } + view_angles[0] += pSeat->flCamDelta; + + if (pSeat->iCamCycle & 1) { + pSeat->flCamDelta = -pSeat->flCamDelta; + } + + view_angles[2] += pSeat->flCamDelta; +} + /* ==================== View_DropPunchAngle @@ -184,6 +232,7 @@ void View_DrawViewModel(void) } addentity(eViewModel); } + View_CalcCamBob(); } void View_PostDraw(void) diff --git a/Source/gs-entbase/client/baseentity.cpp b/Source/gs-entbase/client/baseentity.cpp index 9d83c349..3e42e621 100644 --- a/Source/gs-entbase/client/baseentity.cpp +++ b/Source/gs-entbase/client/baseentity.cpp @@ -8,10 +8,11 @@ string __fullspawndata; -class CBaseEntity { +class CBaseEntity +{ string targetname; string target; - + void() CBaseEntity; virtual void() Init; @@ -19,8 +20,9 @@ class CBaseEntity { virtual void(string, string) SpawnKey; }; -void CBaseEntity :: SpawnKey (string strField, string strKey) { - switch ( strField ) { +void CBaseEntity::SpawnKey(string strField, string strKey) +{ + switch (strField) { case "targetname": targetname = strKey; break; @@ -28,29 +30,29 @@ void CBaseEntity :: SpawnKey (string strField, string strKey) { target = strKey; break; case "origin": - origin = stov( strKey ); - setorigin( this, origin ); + origin = stov(strKey); + setorigin(this, origin); break; case "angles": - angles = stov( strKey ); + angles = stov(strKey); break; case "model": model = strKey; break; case "style": - style = stof( strKey ); + style = stof(strKey); break; case "color": - color = stov( strKey ); + color = stov(strKey); break; case "movetype": - movetype = stof( strKey ); + movetype = stof(strKey); break; case "solid": - solid = stof( strKey ); + solid = stof(strKey); break; case "scale": - scale = stof( strKey ); + scale = stof(strKey); break; default: //dprint(sprintf("Unknown field %s, value %s\n", strField, strKey)); diff --git a/Source/gs-entbase/client/env_sound.cpp b/Source/gs-entbase/client/env_sound.cpp index 3243bee2..f2f01ff1 100644 --- a/Source/gs-entbase/client/env_sound.cpp +++ b/Source/gs-entbase/client/env_sound.cpp @@ -85,7 +85,8 @@ reverbinfo_t reverbPresets [35] = { { 1.0000f, 0.7000f, 0.3162f, 0.4477f, 1.0000f, 1.5100f, 1.2500f, 1.1400f, 0.8913f, 0.0200f, [0,0,0], 1.4125f, 0.0300f, [0,0,0], 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } }; -class env_sound:CBaseEntity { +class env_sound:CBaseEntity +{ int m_iRoomType; int m_iRadius; @@ -222,7 +223,7 @@ void env_sound::env_sound(void) } } -void env_sound::SpawnKey (string strField, string strKey) +void env_sound::SpawnKey(string strField, string strKey) { switch (strField) { case "roomtype": diff --git a/Source/gs-entbase/client/sky.c b/Source/gs-entbase/client/sky.c index e832c4ff..48a46335 100644 --- a/Source/gs-entbase/client/sky.c +++ b/Source/gs-entbase/client/sky.c @@ -10,6 +10,9 @@ var string g_skyname = "desert"; void Sky_Update(void) { + if (serverkeyfloat("*bspversion") != 30) { + return; + } localcmd(sprintf("sky %s\n", g_skyname)); } diff --git a/Source/gs-entbase/client/sprite.cpp b/Source/gs-entbase/client/sprite.cpp index b86bcf43..ac2657fd 100644 --- a/Source/gs-entbase/client/sprite.cpp +++ b/Source/gs-entbase/client/sprite.cpp @@ -46,8 +46,8 @@ void Sprite_Animated(void) me.colormod[1] = readfloat(); me.colormod[2] = readfloat(); me.drawmask = MASK_ENGINE; - me.nextthink = time + ( 1 / me.framerate ); - me.maxframe = modelframecount( me.modelindex ); + me.nextthink = time + (1 / me.framerate); + me.maxframe = modelframecount(me.modelindex); me.loops = 1; /* repeats */ setorigin(me, me.origin); } @@ -67,8 +67,8 @@ void Sprite_ParseEvent(void) spr.colormod[1] = readfloat(); spr.colormod[2] = readfloat(); spr.drawmask = MASK_ENGINE; - spr.nextthink = time + ( 1 / spr.framerate ); - spr.maxframe = modelframecount( spr.modelindex ); + spr.nextthink = time + (1 / spr.framerate); + spr.maxframe = modelframecount(spr.modelindex); spr.loops = 0; /* does not repeat */ setorigin(spr, spr.origin); } diff --git a/Source/gs-entbase/client/text.cpp b/Source/gs-entbase/client/text.cpp index b91649ab..e140b422 100644 --- a/Source/gs-entbase/client/text.cpp +++ b/Source/gs-entbase/client/text.cpp @@ -24,6 +24,7 @@ gametext_t g_textchannels[5]; void GameText_Draw(void) { + drawfont = FONT_20; for (int i = 0; i < 5; i++) { float a = 0.0f; vector rpos; @@ -37,8 +38,7 @@ void GameText_Draw(void) if (g_textchannels[i].m_flTime > mtime) { continue; } - - strwidth = stringwidth(g_textchannels[i].m_strMessage, TRUE, [12,12]); + strwidth = stringwidth(g_textchannels[i].m_strMessage, TRUE, [20,20]); if (g_textchannels[i].m_flPosX == -1) { rpos[0] = (video_res[0] / 2) - (strwidth/2); @@ -67,13 +67,15 @@ void GameText_Draw(void) } if (g_textchannels[i].m_flPosX >= 0.5) { - drawstring(rpos, g_textchannels[i].m_strMessage, '12 12', g_textchannels[i].m_vecColor2, a, 0 ); + drawstring(rpos, g_textchannels[i].m_strMessage, '20 20', g_textchannels[i].m_vecColor2, a, DRAWFLAG_ADDITIVE ); } else { - drawstring(rpos, g_textchannels[i].m_strMessage, '12 12', g_textchannels[i].m_vecColor2, a, 0 ); + drawstring(rpos, g_textchannels[i].m_strMessage, '20 20', g_textchannels[i].m_vecColor2, a, DRAWFLAG_ADDITIVE ); } g_textchannels[i].m_flTime += clframetime; } + + drawfont = FONT_CON; } void GameText_Parse(void) diff --git a/Source/gs-entbase/server.src b/Source/gs-entbase/server.src index bf2931e9..28f365a5 100644 --- a/Source/gs-entbase/server.src +++ b/Source/gs-entbase/server.src @@ -2,6 +2,7 @@ ../gs-entbase/server/defs.h ../gs-entbase/server/baseentity.cpp ../gs-entbase/server/basetrigger.cpp +../gs-entbase/server/basemonster.cpp ../gs-entbase/server/ambient_generic.cpp ../gs-entbase/server/cycler.cpp ../gs-entbase/server/cycler_sprite.cpp @@ -24,6 +25,7 @@ ../gs-entbase/server/func_illusionary.cpp ../gs-entbase/server/func_ladder.cpp ../gs-entbase/server/func_train.cpp +../gs-entbase/server/func_tracktrain.cpp ../gs-entbase/server/func_pushable.cpp ../gs-entbase/server/func_wall.cpp ../gs-entbase/server/func_wall_toggle.cpp diff --git a/Source/gs-entbase/server/ambient_generic.cpp b/Source/gs-entbase/server/ambient_generic.cpp index 7044b92f..43954bb9 100644 --- a/Source/gs-entbase/server/ambient_generic.cpp +++ b/Source/gs-entbase/server/ambient_generic.cpp @@ -6,8 +6,7 @@ * ****/ -enumflags -{ +enumflags { AS_ARADIUS, AS_SRADIUS, AS_MRADIUS, @@ -22,15 +21,10 @@ class ambient_generic:CBaseTrigger string m_strSoundPath; float m_flVolume; float m_flRadius; - int m_iToggleSwitch; - float m_flPitch; + int m_iToggleSwitch; int m_iLoop; -/* int m_iPreset; - float m_flVolume_Start; - float m_flFadeIn; - float m_flFadeOut;*/ // TODO: Do this in CSQC void() ambient_generic; virtual void() Respawn; @@ -42,6 +36,7 @@ void ambient_generic::UseNormal(void) { sound(this, CHAN_VOICE, m_strActivePath, m_flVolume, m_flRadius, m_flPitch); } + void ambient_generic::UseLoop(void) { if (m_iToggleSwitch == TRUE) { @@ -50,7 +45,6 @@ void ambient_generic::UseLoop(void) m_strActivePath = m_strSoundPath; } m_iToggleSwitch = 1 - m_iToggleSwitch; - UseNormal(); } @@ -71,13 +65,13 @@ void ambient_generic::Respawn(void) m_iToggleSwitch = TRUE; UseNormal(); } - + if (m_iLoop) { Trigger = UseLoop; } } -void ambient_generic::ambient_generic (void) +void ambient_generic::ambient_generic(void) { for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) { switch (argv(i)) { @@ -92,7 +86,6 @@ void ambient_generic::ambient_generic (void) break; case "volume": m_flVolume = stof(argv(i+1)); - //volume = __NULL__; break; case "pitch": m_flPitch = stof(argv(i+1)); @@ -103,7 +96,7 @@ void ambient_generic::ambient_generic (void) } if (!m_strSoundPath) { - objerror("ambient_generic: No sound file specified. Aborting."); + objerror("ambient_generic: No sound file specified!"); } precache_sound(m_strSoundPath); @@ -125,6 +118,6 @@ void ambient_generic::ambient_generic (void) m_flRadius = ATTN_STATIC; } - ambient_generic::Respawn(); CBaseTrigger::CBaseTrigger(); + ambient_generic::Respawn(); } diff --git a/Source/gs-entbase/server/baseentity.cpp b/Source/gs-entbase/server/baseentity.cpp index 5e37885b..89459c6e 100644 --- a/Source/gs-entbase/server/baseentity.cpp +++ b/Source/gs-entbase/server/baseentity.cpp @@ -50,6 +50,7 @@ void CBaseEntity :: CBaseEntity ( void ) gflags |= GF_CANRESPAWN; m_oldModel = Util_FixModel(model); + precache_model(m_oldModel); m_oldSolid = solid; m_oldHealth = health; m_oldOrigin = origin; diff --git a/Source/gs-entbase/server/basemonster.cpp b/Source/gs-entbase/server/basemonster.cpp new file mode 100644 index 00000000..35eb1aea --- /dev/null +++ b/Source/gs-entbase/server/basemonster.cpp @@ -0,0 +1,101 @@ +/*** +* +* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved. +* +* See the file LICENSE attached with the sources for usage details. +* +****/ + +class CBaseMonster:CBaseEntity +{ + void() CBaseMonster; + + 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() Gib; +}; + +void CBaseMonster::Gib(void) +{ + takedamage = DAMAGE_NO; + Effect_GibHuman(this.origin); + Hide(); +} + +void CBaseMonster::Physics(void) +{ + input_movevalues = [0,0,0]; + input_impulse = 0; + input_buttons = 0; + + input_angles = angles = v_angle; + input_timelength = frametime; + movetype = MOVETYPE_WALK; + + runstandardplayerphysics(this); + movetype = MOVETYPE_NONE; +} + +void CBaseMonster::touch(void) +{ + if (other.movetype == MOVETYPE_WALK) { + velocity = normalize(other.origin - origin) * -128; + } +} + +void CBaseMonster::PlayerUse(void) +{ + +} + +void CBaseMonster::vPain(int iHitBody) +{ + +} + +void CBaseMonster::vDeath(int iHitBody) +{ + customphysics = __NULL__; + + if (health < -50) { + Gib(); + return; + } + + solid = SOLID_CORPSE; +} + +void CBaseMonster::Hide(void) +{ + setmodel(this, ""); + solid = SOLID_NOT; + movetype = MOVETYPE_NONE; + customphysics = __NULL__; +} + +void CBaseMonster::Respawn(void) +{ + setorigin(this, m_oldOrigin); + angles = v_angle; + solid = SOLID_SLIDEBOX; + movetype = MOVETYPE_NONE; + 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; + health = 100; + velocity = [0,0,0]; +} + +void CBaseMonster::CBaseMonster(void) +{ + CBaseEntity::CBaseEntity(); + precache_model(m_oldModel); + Respawn(); +} diff --git a/Source/gs-entbase/server/cycler.cpp b/Source/gs-entbase/server/cycler.cpp index 698a7197..999474b9 100644 --- a/Source/gs-entbase/server/cycler.cpp +++ b/Source/gs-entbase/server/cycler.cpp @@ -28,6 +28,7 @@ Notes class cycler:CBaseTrigger { void() cycler; + virtual void() Respawn; virtual void(entity, int, int) vPain; }; @@ -41,12 +42,16 @@ void cycler::vPain(entity attacker, int type, int damage) health = 9999; } -void cycler::cycler(void) +void cycler::Respawn(void) { - CBaseEntity::CBaseEntity(); - precache_model(m_oldModel); - setmodel(this, m_oldModel); + CBaseEntity::Respawn(); solid = SOLID_BBOX; takedamage = DAMAGE_YES; health = 9999; } + +void cycler::cycler(void) +{ + CBaseEntity::CBaseEntity(); + Respawn(); +} diff --git a/Source/gs-entbase/server/cycler_sprite.cpp b/Source/gs-entbase/server/cycler_sprite.cpp index 25c6867b..30df4809 100644 --- a/Source/gs-entbase/server/cycler_sprite.cpp +++ b/Source/gs-entbase/server/cycler_sprite.cpp @@ -16,6 +16,5 @@ class cycler_sprite:CBaseTrigger void cycler_sprite::cycler_sprite(void) { CBaseEntity::CBaseEntity(); - precache_model(m_oldModel); - Respawn(); + CBaseEntity::Respawn(); } diff --git a/Source/gs-entbase/server/env_explosion.cpp b/Source/gs-entbase/server/env_explosion.cpp index 9041e557..ad4443ab 100644 --- a/Source/gs-entbase/server/env_explosion.cpp +++ b/Source/gs-entbase/server/env_explosion.cpp @@ -43,8 +43,9 @@ void env_explosion::Trigger(void) Effect_CreateExplosion(origin); if (!(spawnflags & ENVEXPLO_NODAMAGE)) { - Damage_Radius(origin, this, 500, m_iMagnitude, TRUE); + Damage_Radius(origin, this, m_iMagnitude, m_iMagnitude * 2.5f, TRUE); } + // TODO: Respawn after round instead? if (!(spawnflags & ENVEXPLO_REPEATABLE)) { remove(this); diff --git a/Source/gs-entbase/server/env_sprite.cpp b/Source/gs-entbase/server/env_sprite.cpp index cd6c2d07..19bb487a 100644 --- a/Source/gs-entbase/server/env_sprite.cpp +++ b/Source/gs-entbase/server/env_sprite.cpp @@ -94,6 +94,10 @@ void env_sprite::env_sprite(void) if (!m_flFramerate) { m_flFramerate = 10; } + + if (!m_flScale) { + m_flScale = 1.0f; + } CBaseTrigger::CBaseTrigger(); precache_model(m_oldModel); diff --git a/Source/gs-entbase/server/func_breakable.cpp b/Source/gs-entbase/server/func_breakable.cpp index d23e8057..4e0a5a66 100755 --- a/Source/gs-entbase/server/func_breakable.cpp +++ b/Source/gs-entbase/server/func_breakable.cpp @@ -31,6 +31,7 @@ class func_breakable:CBaseTrigger void() func_breakable; virtual void() Respawn; + virtual void() Explode; virtual void() Trigger; virtual void() PlayerTouch; /*virtual void() PressureDeath;*/ @@ -74,6 +75,20 @@ void func_breakable::vPain (entity attacker, int type, int damage) } } + +void func_breakable::Explode(void) +{ + vector vWorldPos; + vWorldPos[0] = absmin[0] + ( 0.5 * ( absmax[0] - absmin[0] ) ); + vWorldPos[1] = absmin[1] + ( 0.5 * ( absmax[1] - absmin[1] ) ); + vWorldPos[2] = absmin[2] + ( 0.5 * ( absmax[2] - absmin[2] ) ); + Effect_BreakModel(20, absmin, absmax, '0 0 0', m_iMaterial); + Effect_CreateExplosion(vWorldPos); + Damage_Radius(vWorldPos, this, m_flExplodeMag, m_flExplodeMag * 2.5f, TRUE); + CBaseTrigger::UseTargets(); + CBaseEntity::Hide(); +} + void func_breakable::vDeath (entity attacker, int type, int damage) { if (m_iMaterial == MATERIAL_GLASS_UNBREAKABLE) { @@ -82,18 +97,21 @@ void func_breakable::vDeath (entity attacker, int type, int damage) health = 0; print(sprintf("BREAK: %v [x] %v [=] %d\n", mins, maxs, vlen(mins - maxs))); - Effect_BreakModel(20, absmin, absmax, '0 0 0', m_iMaterial); + /* This may seem totally absurd. That's because it is. It's very + * unreliable but exploding breakables in close proximity it WILL cause + * an OVERFLOW because we'll be busy running through thousands + * of entities in total when one breakable damages another in a frame. + * The only way around this is to set a hard-coded limit of loops per + * frame and that would break functionality. */ if (m_flExplodeMag) { - vector vWorldPos; - vWorldPos[0] = absmin[0] + ( 0.5 * ( absmax[0] - absmin[0] ) ); - vWorldPos[1] = absmin[1] + ( 0.5 * ( absmax[1] - absmin[1] ) ); - vWorldPos[2] = absmin[2] + ( 0.5 * ( absmax[2] - absmin[2] ) ); - Effect_CreateExplosion(vWorldPos); + think = Explode; + nextthink = time + random(0.0,0.5); + } else { + Effect_BreakModel(20, absmin, absmax, '0 0 0', m_iMaterial); + CBaseTrigger::UseTargets(); + CBaseEntity::Hide(); } - - CBaseTrigger::UseTargets(); - CBaseEntity::Hide(); } void func_breakable::Trigger(void) diff --git a/Source/gs-entbase/server/func_rotating.cpp b/Source/gs-entbase/server/func_rotating.cpp index c086ce8e..46f1c6c3 100644 --- a/Source/gs-entbase/server/func_rotating.cpp +++ b/Source/gs-entbase/server/func_rotating.cpp @@ -20,22 +20,24 @@ enumflags FR_LRADIUS }; -class CFuncRotating : CBaseTrigger +class func_rotating : CBaseTrigger { vector m_vecMoveDir; float m_flSpeed; - void() CFuncRotating; + float m_flDamage; + void() func_rotating; virtual void() Respawn; virtual void() Trigger; virtual void() Rotate; + virtual void() Blocked; virtual void() SetMovementDirection; }; -void CFuncRotating :: Rotate( void ) +void func_rotating :: Rotate( void ) { nextthink = ltime + 10.0f; } -void CFuncRotating :: Trigger ( void ) +void func_rotating :: Trigger ( void ) { if ( vlen( avelocity ) ) { avelocity = [0,0,0]; @@ -44,14 +46,18 @@ void CFuncRotating :: Trigger ( void ) } } -void CFuncRotating :: Blocked ( void ) +void func_rotating :: Blocked ( void ) { - if ( spawnflags & FR_FANPAIN ) { -// Damage_Apply( other, this, m_iDamage, other.origin, FALSE ); + if (avelocity == [0,0,0]) { + return; + } + + if (other.takedamage == DAMAGE_YES) { + Damage_Apply(other, this, m_flDamage, other.origin, TRUE); } } -void CFuncRotating :: Respawn ( void ) +void func_rotating :: Respawn ( void ) { movetype = MOVETYPE_PUSH; setorigin( this, origin ); @@ -68,9 +74,15 @@ void CFuncRotating :: Respawn ( void ) think = Rotate; nextthink = ltime + 1.5f; } + + blocked = Blocked; + + if (spawnflags & FR_FANPAIN) { + touch = Blocked; + } } -void CFuncRotating :: SetMovementDirection ( void ) +void func_rotating :: SetMovementDirection ( void ) { if ( spawnflags & FR_ZAXIS ) { m_vecMoveDir = '0 0 1'; @@ -85,7 +97,7 @@ void CFuncRotating :: SetMovementDirection ( void ) } } -void CFuncRotating :: CFuncRotating ( void ) +void func_rotating :: func_rotating ( void ) { precache_model( model ); for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) { @@ -96,18 +108,19 @@ void CFuncRotating :: CFuncRotating ( void ) case "speed": m_flSpeed = stof( argv( i + 1 ) ); break; + case "dmg": + m_flDamage = stof( argv( i + 1 ) ); + break; default: break; } } - + if ( !m_flSpeed ) { m_flSpeed = 100; } CBaseTrigger::CBaseTrigger(); - CFuncRotating::SetMovementDirection(); - CFuncRotating::Respawn(); + func_rotating::SetMovementDirection(); + func_rotating::Respawn(); } - -CLASSEXPORT( func_rotating, CFuncRotating ) diff --git a/Source/gs-entbase/server/func_tracktrain.cpp b/Source/gs-entbase/server/func_tracktrain.cpp new file mode 100644 index 00000000..2b25c864 --- /dev/null +++ b/Source/gs-entbase/server/func_tracktrain.cpp @@ -0,0 +1,118 @@ +/*** +* +* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved. +* +* See the file LICENSE attached with the sources for usage details. +* +****/ + +class func_tracktrain:CBaseTrigger +{ + float m_flSpeed; + + void() func_tracktrain; + virtual void() Find; + virtual void() NextPath; + virtual void() GoToTarget; + virtual void() Trigger; + virtual void() Respawn; +}; + +void func_tracktrain::GoToTarget(void) +{ + float flTravelTime; + vector vel_to_pos; + entity f; + + f = find(world, CBaseTrigger::m_strTargetName, m_strTarget); + + if (!f) { + print("^1func_tracktrain^7: Trigger-Target not found! Removing.\n"); + return; + } + + vel_to_pos = (f.origin - origin); + flTravelTime = (vlen(vel_to_pos) / m_flSpeed); + + if (!flTravelTime) { + NextPath(); + print(sprintf("TRAIN %s SPEED: %f\n", m_strTargetName, flTravelTime)); + return; + } + + velocity = (vel_to_pos * (1 / flTravelTime)); + think = NextPath; + nextthink = (time + flTravelTime); +} + +void func_tracktrain::NextPath(void) +{ + CBaseTrigger current_target; + + print(sprintf("^2func_tracktrain^7: Talking to current target %s... ", m_strTarget)); + current_target = (CBaseTrigger)find(world, CBaseTrigger::m_strTargetName, m_strTarget); + + if (!current_target) { + print("^1FAILED.\n"); + } else { + print("^2SUCCESS.\n"); + } + + m_strTarget = current_target.m_strTarget; + velocity = [0,0,0]; + GoToTarget(); +} + +void func_tracktrain::Trigger(void) +{ + GoToTarget(); +} + + +void func_tracktrain::Find(void) +{ + entity f = find(world, CBaseTrigger::m_strTargetName, m_strTarget); + + if (!f) { + print(sprintf("^1func_tracktrain^7: End-Target %s not found! Removing.\n",m_strTarget)); + remove(this); + return; + } + + print("^2func_tracktrain^7: Successfully found first target.\n"); + setorigin(this, f.origin); +} + +void func_tracktrain::Respawn(void) +{ + solid = SOLID_BSP; + movetype = MOVETYPE_PUSH; + //blocked = Blocked; + + setmodel(this, m_oldModel); + setorigin(this, m_oldOrigin); + + /* Make sure we got some time for the paths to spawn */ + nextthink = ltime + 0.1f; + think = Find; +} + +void func_tracktrain::func_tracktrain(void) +{ + for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) { + switch ( argv( i ) ) { + case "speed": + m_flSpeed = stof(argv(i+1)); + break; + default: + break; + } + } + + //if (!m_flSpeed) { + m_flSpeed = 50; + //} + + CBaseTrigger::CBaseTrigger(); + Respawn(); +} diff --git a/Source/gs-entbase/server/func_train.cpp b/Source/gs-entbase/server/func_train.cpp index 10c72a4f..1bcd7002 100644 --- a/Source/gs-entbase/server/func_train.cpp +++ b/Source/gs-entbase/server/func_train.cpp @@ -12,22 +12,82 @@ class func_train:CBaseTrigger void() func_train; virtual void() Find; - virtual void() MoveEnd; + virtual void() NextPath; + virtual void() GoToTarget; virtual void() Trigger; + virtual void() Respawn; }; +void func_train::GoToTarget(void) +{ + float flTravelTime; + vector vel_to_pos; + entity f; + + f = find(world, CBaseTrigger::m_strTargetName, m_strTarget); + + if (!f) { + print("^1func_train^7: Trigger-Target not found! Removing.\n"); + return; + } + + vector vecWorldPos; + vecWorldPos[0] = absmin[0] + ( 0.5 * ( absmax[0] - absmin[0] ) ); + vecWorldPos[1] = absmin[1] + ( 0.5 * ( absmax[1] - absmin[1] ) ); + vecWorldPos[2] = absmin[2] + ( 0.5 * ( absmax[2] - absmin[2] ) ); + + vel_to_pos = (f.origin - vecWorldPos); + flTravelTime = (vlen(vel_to_pos) / m_flSpeed); + + if (!flTravelTime) { + NextPath(); + print(sprintf("TRAIN %s SPEED: %f\n", m_strTargetName, flTravelTime)); + return; + } + + velocity = (vel_to_pos * (1 / flTravelTime)); + think = NextPath; + nextthink = (time + flTravelTime); +} + +void func_train::NextPath(void) +{ + CBaseTrigger current_target; + + print(sprintf("^2func_train^7: Talking to current target %s... ", m_strTarget)); + current_target = (CBaseTrigger)find(world, CBaseTrigger::m_strTargetName, m_strTarget); + + if (!current_target) { + print("^1FAILED.\n"); + } else { + print("^2SUCCESS.\n"); + } + + m_strTarget = current_target.m_strTarget; + velocity = [0,0,0]; + + if (m_strTarget) { + GoToTarget(); + } +} + +void func_train::Trigger(void) +{ + GoToTarget(); +} + + void func_train::Find(void) { entity f = find(world, CBaseTrigger::m_strTargetName, m_strTarget); if (!f) { - print("^1func_train^7: End-Target not found! Removing.\n"); + print(sprintf("^1func_train^7: End-Target %s not found! Removing.\n",m_strTarget)); remove(this); return; } print("^2func_train^7: Successfully found first target.\n"); - vector vecWorldPos; vecWorldPos[0] = absmin[0] + ( 0.5 * ( absmax[0] - absmin[0] ) ); vecWorldPos[1] = absmin[1] + ( 0.5 * ( absmax[1] - absmin[1] ) ); @@ -37,45 +97,22 @@ void func_train::Find(void) setorigin(this, vecWorldPos); } -void func_train::MoveEnd(void) +void func_train::Respawn(void) { - CBaseTrigger f = (CBaseTrigger)find(world, CBaseTrigger::m_strTargetName, m_strTarget); - m_strTarget = f.m_strTargetName; + solid = SOLID_BSP; + movetype = MOVETYPE_PUSH; + //blocked = Blocked; - velocity = [0,0,0]; -} + setmodel(this, m_oldModel); + setorigin(this, m_oldOrigin); -void func_train::Trigger(void) -{ - - entity f = find(world, CBaseTrigger::m_strTargetName, m_strTarget); - - if (!f) { - print("^1func_train^7: Trigger-Target not found! Removing.\n"); - return; - } - - vector vecWorldPos; - vecWorldPos[0] = absmin[0] + ( 0.5 * ( absmax[0] - absmin[0] ) ); - vecWorldPos[1] = absmin[1] + ( 0.5 * ( absmax[1] - absmin[1] ) ); - vecWorldPos[2] = absmin[2] + ( 0.5 * ( absmax[2] - absmin[2] ) ); - - vector vecDifference = (f.origin - vecWorldPos); - float flTravel = vlen(vecDifference); - float flTravelTime = (flTravel / m_flSpeed); - - think = MoveEnd; - nextthink = (time + flTravelTime); - - print(sprintf("TRAIN %s SPEED: %v\n", this.classname, (vecDifference * (1 / flTravelTime)))); - - //velocity = (vecDifference * (1 / flTravelTime)); + /* Make sure we got some time for the paths to spawn */ + nextthink = ltime + 0.1f; + think = Find; } void func_train::func_train(void) { - CBaseTrigger::CBaseTrigger(); - for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) { switch ( argv( i ) ) { case "speed": @@ -86,15 +123,10 @@ void func_train::func_train(void) } } - solid = SOLID_BSP; - movetype = MOVETYPE_PUSH; - //blocked = Blocked; + if (!m_flSpeed) { + m_flSpeed = 100; + } - setmodel(this, m_oldModel); - setorigin(this, m_oldOrigin); - - // start trains on the second frame, to make sure their targets have had - // a chance to spawn - nextthink = time + 0.25f; - think = Find; + CBaseTrigger::CBaseTrigger(); + Respawn(); } diff --git a/Source/gs-entbase/server/func_wall.cpp b/Source/gs-entbase/server/func_wall.cpp index fa6332ed..04c057bc 100644 --- a/Source/gs-entbase/server/func_wall.cpp +++ b/Source/gs-entbase/server/func_wall.cpp @@ -27,5 +27,3 @@ void func_wall :: Trigger ( void ) frame = 1 - frame; } -CLASSEXPORT(func_tracktrain, func_wall) - diff --git a/Source/gs-entbase/server/scripted_sequence.cpp b/Source/gs-entbase/server/scripted_sequence.cpp index 12bf1f1b..0799f56f 100644 --- a/Source/gs-entbase/server/scripted_sequence.cpp +++ b/Source/gs-entbase/server/scripted_sequence.cpp @@ -6,4 +6,96 @@ * ****/ -// TODO +/* + * Scripted Sequences + * ================== + * Allow a monster to be selected and given an action to perform. + * This is done in the form of an animation. + */ + + /* If enabled, the sequence can be triggered more than once. + * Otherwise the entity will be removed once the sequence is complete. */ + #define SSFL_REPEATABLE 4 + + /* Seemingly unused. */ + #define SSFL_LEAVECORPSE 8 + + /* If enabled, the sequence cannot be interrupted. + * The monster will ignore damage until the sequence is complete, + * as with the aiscripted_sequence entity. */ + #define SSFL_NOINTERRUPT 32 + + /* Seemingly unused. */ + #define SSFL_OVERRIDEAI 64 + + /* If enabled, when the sequence is completed, the monster will be placed back + * where the Action Animation started. */ + #define SSFL_NOSCRIPTMOVE 128 + +/* m_iMove, how we move to perform m_iActionAnim */ +enum { + SS_NO, /* Don't move or turn */ + SS_WALK, /* Walk to the scripted_sequence */ + SS_RUN, /* Run to the scripted_sequence */ + SS_UNUSED, + SS_INSTANTANEOUS, /* Warp to the location of the scripted_sequence and perform the animation. */ + SS_TURNTOFACE /* Turn to the scripted_sequence's angle before performing the animation. */ +}; + +class scripted_sequence:CBaseTrigger +{ + /* Target name OR classname description */ + string m_strMonster; + /* After the monster has moved to the action point, play this animation */ + string m_strActionAnim; + /* Animation to play until the scripted_sequence is triggered */ + string m_strIdleAnim; + /* Search radius for m_targetMonster if a classname is specified */ + float m_flSearchRadius; + /* How we move to perform m_iActionAnim */ + int m_iMove; + + void() scripted_sequence; + virtual void() Trigger; + virtual void() Respawn; +}; + +void scripted_sequence::Trigger(void) +{ + +} + +void scripted_sequence::Respawn(void) +{ + +} + +void scripted_sequence::scripted_sequence(void) +{ + int nfields = tokenize(__fullspawndata); + for (int i = 1; i < (nfields-1); i += 2) { + switch (argv(i)) { + case "m_iszEntity": + m_strMonster = argv(i+1); + break; + case "m_iszPlay": + m_strActionAnim = argv(i+1); + break; + case "m_iszIdle": + m_strIdleAnim = argv(i+1); + break; + case "m_flRadius": + m_flSearchRadius = stof(argv(i+1)); + break; + case "m_flRepeat": + break; + case "m_fMoveTo": + m_iMove = stoi(argv(i+1)); + break; + default: + break; + } + } +} + + diff --git a/Source/gs-entbase/server/stubs.cpp b/Source/gs-entbase/server/stubs.cpp index 7fd5cddb..e44c8645 100644 --- a/Source/gs-entbase/server/stubs.cpp +++ b/Source/gs-entbase/server/stubs.cpp @@ -11,7 +11,7 @@ class info_null void() info_null; }; -void info_null :: info_null ( void ) +void info_null::info_null(void) { remove( self ); } @@ -21,36 +21,11 @@ class info_notnull:CBaseTrigger void() info_notnull; }; -void info_notnull :: info_notnull ( void ) +void info_notnull::info_notnull(void) { CBaseTrigger::CBaseTrigger(); } -CLASSEXPORT( info_node, info_notnull ) -CLASSEXPORT( info_target, info_notnull ) -CLASSEXPORT( env_sound, info_null ) - -/*class CSuit : CBaseTrigger -{ - void CSuit; - virtual void() Trigger; -}; - -void CSuit :: Trigger ( void ) -{ - CBaseTrigger::UseTargets(); - remove( self ); -} - -void CSuit :: CSuit ( void ) -{ - CBaseTrigger::CBaseTrigger(); - - solid = SOLID_TRIGGER; - model = "models/w_suit.mdl"; - precache_model( model ); - setmodel( this, model ); - touch = Trigger; -} -SPAWNEXPORT item_suit ( void ) { spawnfunc_CSuit(); } -SPAWNEXPORT world_items ( void ) { spawnfunc_CSuit(); }*/ +CLASSEXPORT(info_node, info_notnull) +CLASSEXPORT(info_target, info_notnull) +CLASSEXPORT(env_sound, info_null) diff --git a/Source/gs-entbase/server/trigger_auto.cpp b/Source/gs-entbase/server/trigger_auto.cpp index 12d4120b..6acdc7c1 100644 --- a/Source/gs-entbase/server/trigger_auto.cpp +++ b/Source/gs-entbase/server/trigger_auto.cpp @@ -6,37 +6,43 @@ * ****/ -class trigger_auto : CBaseTrigger +class trigger_auto:CBaseTrigger { float m_flDelay; - + void() trigger_auto; virtual void() think; + virtual void() Respawn; }; -void trigger_auto :: think ( void ) +void trigger_auto::think(void) { // This is weird, because ents may not be spawned yet. // However, Half-Life doesn't care about this, either. // So why should we? - CBaseTrigger::UseTargets_Delay( m_flDelay ); + CBaseTrigger::UseTargets_Delay(m_flDelay); - if ( spawnflags & 1 ) { - remove( this ); + if (spawnflags & 1) { + remove(this); } } -void trigger_auto :: trigger_auto ( void ) +void trigger_auto::Respawn(void) { - for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) { - switch ( argv( i ) ) { + nextthink = time + 0.2f; +} + +void trigger_auto::trigger_auto(void) +{ + for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) { + switch (argv(i)) { case "delay": - m_flDelay = stof( argv( i + 1 ) ); + m_flDelay = stof(argv(i+1)); break; default: break; } } CBaseTrigger::CBaseTrigger(); - nextthink = time + 0.2f; + Respawn(); } diff --git a/Source/gs-entbase/server/trigger_changelevel.cpp b/Source/gs-entbase/server/trigger_changelevel.cpp index e734226c..a3b140bc 100644 --- a/Source/gs-entbase/server/trigger_changelevel.cpp +++ b/Source/gs-entbase/server/trigger_changelevel.cpp @@ -10,11 +10,11 @@ vector g_landmarkpos; enumflags { - LC_NOINTERMISSION, // Unused? + LC_NOINTERMISSION, LC_USEONLY }; -class trigger_changelevel : CBaseTrigger +class trigger_changelevel:CBaseTrigger { string m_strMap; string m_strLandmark; @@ -24,48 +24,48 @@ class trigger_changelevel : CBaseTrigger void() trigger_changelevel; virtual void() Change; virtual void() Trigger; - virtual int( entity, entity ) IsInside; + virtual void() Respawn; + virtual int(entity, entity) IsInside; }; -int trigger_changelevel :: IsInside ( entity ePlayer, entity eVolume ) { - if ( ePlayer.absmin[0] > eVolume.absmax[0] || +int trigger_changelevel::IsInside(entity ePlayer, entity eVolume) +{ + if (ePlayer.absmin[0] > eVolume.absmax[0] || ePlayer.absmin[1] > eVolume.absmax[1] || ePlayer.absmin[2] > eVolume.absmax[2] || ePlayer.absmax[0] < eVolume.absmin[0] || ePlayer.absmax[1] < eVolume.absmin[1] || - ePlayer.absmax[2] < eVolume.absmin[2] ) + ePlayer.absmax[2] < eVolume.absmin[2]) return FALSE; return TRUE; } -void trigger_changelevel :: Change ( void ) +void trigger_changelevel::Change(void) { - if ( m_strLandmark ) { - entity landmark = find( world, ::targetname, m_strLandmark ); + if (m_strLandmark) { + entity landmark = find(world, CBaseTrigger::m_strTargetName, m_strLandmark); g_landmarkpos = m_activator.origin - landmark.origin; - changelevel( m_strMap, m_strLandmark ); + changelevel(m_strMap, m_strLandmark); } else { - changelevel( m_strMap ); + changelevel(m_strMap); } } -void trigger_changelevel :: Trigger ( void ) +void trigger_changelevel::Trigger(void) { - //entity eVolume; - - if ( time < 5 ) { + if (time < 5) { return; } - - /*eVolume = find( world, ::targetname, m_strLandmark ); - if ( eVolume && eVolume.classname == "CTriggerVolume" ) { - if ( IsInside( other, eVolume ) == FALSE ) { + + /*eVolume = find(world, ::targetname, m_strLandmark); + if (eVolume && eVolume.classname == "CTriggerVolume") { + if (IsInside(other, eVolume) == FALSE) { return; } }*/ m_activator = other; - if ( m_flChangeDelay ) { + if (m_flChangeDelay) { think = Change; nextthink = time + m_flChangeDelay; } else { @@ -73,36 +73,48 @@ void trigger_changelevel :: Trigger ( void ) } } -void trigger_changelevel :: trigger_changelevel ( void ) +void trigger_changelevel::Respawn(void) { - for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) { - switch ( argv( i ) ) { + if (!(spawnflags & LC_USEONLY)) { + touch = Trigger; + } +} + +void trigger_changelevel::trigger_changelevel(void) +{ + for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) { + switch (argv(i)) { case "map": - m_strMap = argv( i + 1 ); + m_strMap = argv(i+1); break; case "landmark": - m_strLandmark = argv( i + 1 ); + m_strLandmark = argv(i+1); break; case "changedelay": - m_flChangeDelay = stof( argv( i + 1 ) ); + m_flChangeDelay = stof(argv(i+1)); break; default: break; } } CBaseTrigger::CBaseTrigger(); - - if ( !( spawnflags & LC_USEONLY ) ) { - touch = Trigger; - } - CBaseTrigger::InitBrushTrigger(); + trigger_changelevel::Respawn(); } -CLASSEXPORT( info_landmark, info_notnull ) - vector Landmark_GetSpot(void) { - entity landmark = find(world, targetname, startspot); + entity landmark = find(world, CBaseTrigger::m_strTargetName, startspot); + + if (!landmark) { + print(sprintf("^1ERROR^7: Cannot find startspot \"%s\"!\n",startspot)); + return __NULL__; + } + return landmark.origin + g_landmarkpos; } + +class info_landmark:CBaseTrigger +{ + +}; diff --git a/Source/gs-entbase/server/trigger_endsection.cpp b/Source/gs-entbase/server/trigger_endsection.cpp index 2f36464f..5d48ade5 100644 --- a/Source/gs-entbase/server/trigger_endsection.cpp +++ b/Source/gs-entbase/server/trigger_endsection.cpp @@ -6,12 +6,31 @@ * ****/ -class trigger_endsection : CBaseTrigger +class trigger_endsection:CBaseTrigger { + void() trigger_endsection; + virtual void() Trigger; + virtual void() Respawn; } -void trigger_endsection :: Trigger ( void ) +void trigger_endsection::Trigger ( void ) { localcmd( "disconnect\n" ); } + +/* TODO: Make this redundant */ +void trigger_endsection::Respawn(void) +{ + solid = SOLID_TRIGGER; +#ifdef GS_DEVELOPER + alpha = 0.5f; +#endif +} + +void trigger_endsection::trigger_endsection(void) +{ + CBaseEntity::CBaseEntity(); + CBaseTrigger::InitBrushTrigger(); + trigger_endsection::Respawn(); +} diff --git a/Source/gs-entbase/server/trigger_hurt.cpp b/Source/gs-entbase/server/trigger_hurt.cpp index 3135850a..674c47b3 100644 --- a/Source/gs-entbase/server/trigger_hurt.cpp +++ b/Source/gs-entbase/server/trigger_hurt.cpp @@ -26,8 +26,6 @@ class trigger_hurt:CBaseTrigger void trigger_hurt::Trigger(void) { - - if (solid != SOLID_NOT) { #ifdef GS_DEVELOPER print("trigger_hurt: de-activated.\n"); diff --git a/Source/gs-entbase/server/trigger_multiple.cpp b/Source/gs-entbase/server/trigger_multiple.cpp index 714bb67f..71960e62 100644 --- a/Source/gs-entbase/server/trigger_multiple.cpp +++ b/Source/gs-entbase/server/trigger_multiple.cpp @@ -14,7 +14,7 @@ enumflags TM_PUSHABLES }; -class trigger_multiple : CBaseTrigger +class trigger_multiple:CBaseTrigger { float m_flDelay; float m_flWait; @@ -23,7 +23,7 @@ class trigger_multiple : CBaseTrigger virtual void() Respawn; }; -void trigger_multiple :: touch ( void ) +void trigger_multiple::touch(void) { eActivator = other; @@ -31,8 +31,8 @@ void trigger_multiple :: touch ( void ) return; } - if ( m_flDelay > 0 ) { - CBaseTrigger::UseTargets_Delay( m_flDelay ); + if (m_flDelay > 0) { + CBaseTrigger::UseTargets_Delay(m_flDelay); } else { CBaseTrigger::UseTargets(); } @@ -49,7 +49,8 @@ void trigger_multiple :: touch ( void ) #endif } -void trigger_multiple :: Respawn ( void ) +/* TODO: Make this redundant */ +void trigger_multiple::Respawn(void) { solid = SOLID_TRIGGER; #ifdef GS_DEVELOPER @@ -57,15 +58,15 @@ void trigger_multiple :: Respawn ( void ) #endif } -void trigger_multiple :: trigger_multiple ( void ) +void trigger_multiple::trigger_multiple(void) { - for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) { - switch ( argv( i ) ) { + for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) { + switch (argv(i)) { case "delay": - m_flDelay = stof( argv( i + 1 ) ); + m_flDelay = stof(argv(i+1)); break; case "wait": - m_flWait = stof( argv( i + 1 ) ); + m_flWait = stof(argv(i+1)); break; default: break; diff --git a/Source/gs-entbase/server/trigger_once.cpp b/Source/gs-entbase/server/trigger_once.cpp index bbd78654..d2091483 100644 --- a/Source/gs-entbase/server/trigger_once.cpp +++ b/Source/gs-entbase/server/trigger_once.cpp @@ -26,7 +26,7 @@ void trigger_once::touch(void) { eActivator = other; - if ( m_flDelay > 0 ) { + if (m_flDelay > 0) { CBaseTrigger::UseTargets_Delay(m_flDelay); } else { CBaseTrigger::UseTargets(); @@ -37,6 +37,7 @@ void trigger_once::touch(void) #endif } +/* TODO: Make this redundant */ void trigger_once::Respawn(void) { solid = SOLID_TRIGGER; @@ -47,10 +48,10 @@ void trigger_once::Respawn(void) void trigger_once::trigger_once(void) { - for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) { - switch ( argv( i ) ) { + for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) { + switch (argv(i)) { case "delay": - m_flDelay = stof( argv( i + 1 ) ); + m_flDelay = stof(argv(i + 1)); break; default: break; diff --git a/Source/gs-entbase/server/trigger_push.cpp b/Source/gs-entbase/server/trigger_push.cpp index 26f13aa5..e87f4a90 100644 --- a/Source/gs-entbase/server/trigger_push.cpp +++ b/Source/gs-entbase/server/trigger_push.cpp @@ -10,26 +10,28 @@ #define TP_STARTOFF 2 #define TP_AAAA 4 -class trigger_push : CBaseTrigger +class trigger_push:CBaseTrigger { vector m_vecMoveDir; float m_flDelay; float m_flSpeed; + void() trigger_push; + virtual void() touch; virtual void() Respawn; virtual void() Trigger; virtual void() SetMovementDirection; }; -void trigger_push :: SetMovementDirection ( void ) +void trigger_push::SetMovementDirection(void) { - if ( angles == '0 -1 0' ) { + if (angles == '0 -1 0') { m_vecMoveDir = '0 0 1'; - } else if ( angles == '0 -2 0' ) { + } else if (angles == '0 -2 0') { m_vecMoveDir = '0 0 -1'; } else { - makevectors( angles ); + makevectors(angles); m_vecMoveDir = v_forward; } @@ -37,19 +39,18 @@ void trigger_push :: SetMovementDirection ( void ) //m_vecMoveDir *= 1; } -void trigger_push :: Trigger ( void ) +void trigger_push::Trigger(void) { - if ( solid == SOLID_NOT ) { + if (solid == SOLID_NOT) { solid = SOLID_TRIGGER; } else { solid = SOLID_NOT; } } -void trigger_push :: touch ( void ) +void trigger_push::touch(void) { - switch( other.movetype ) - { + switch(other.movetype) { case MOVETYPE_NONE: case MOVETYPE_PUSH: case MOVETYPE_NOCLIP: @@ -57,16 +58,16 @@ void trigger_push :: touch ( void ) return; } - if ( other.solid != SOLID_NOT && other.solid != SOLID_BSP ) { - if ( spawnflags & TP_ONCE ) { + if (other.solid != SOLID_NOT && other.solid != SOLID_BSP) { + if (spawnflags & TP_ONCE) { other.velocity = other.velocity + (m_flSpeed * m_vecMoveDir); - if ( other.velocity[2] > 0 ) { + if (other.velocity[2] > 0) { other.flags &= ~FL_ONGROUND; } Hide(); } else { /*vector vecPush = m_flSpeed * m_vecMoveDir; - if ( other.flags & FL_BASEVELOCITY ) { + if (other.flags & FL_BASEVELOCITY) { vecPush = vecPush + other.basevelocity; } @@ -76,28 +77,28 @@ void trigger_push :: touch ( void ) } } -void trigger_push :: Respawn ( void ) +void trigger_push::Respawn(void) { - if ( angles == '0 0 0' ) { + if (angles == '0 0 0') { angles[1] = 360; } SetMovementDirection(); - if ( m_flSpeed == 0 ) { + if (m_flSpeed == 0) { m_flSpeed = 100; } - if ( spawnflags & TP_STARTOFF ) { + if (spawnflags & TP_STARTOFF) { solid = SOLID_NOT; } } -void trigger_push :: trigger_push ( void ) +void trigger_push::trigger_push(void) { - for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) { - switch ( argv( i ) ) { + for (int i = 1; i < (tokenize(__fullspawndata) - 1); i += 2) { + switch (argv(i)) { case "speed": - m_flSpeed = stof( argv( i + 1 ) ); + m_flSpeed = stof(argv(i + 1)); break; default: break; diff --git a/Source/gs-entbase/server/trigger_relay.cpp b/Source/gs-entbase/server/trigger_relay.cpp index 6827b752..b3d3c4b0 100644 --- a/Source/gs-entbase/server/trigger_relay.cpp +++ b/Source/gs-entbase/server/trigger_relay.cpp @@ -6,4 +6,4 @@ * ****/ -CLASSEXPORT( trigger_relay, trigger_once ) +CLASSEXPORT(trigger_relay, trigger_once) diff --git a/Source/gs-entbase/server/trigger_teleport.cpp b/Source/gs-entbase/server/trigger_teleport.cpp index 38f73951..1c0709be 100644 --- a/Source/gs-entbase/server/trigger_teleport.cpp +++ b/Source/gs-entbase/server/trigger_teleport.cpp @@ -6,16 +6,17 @@ * ****/ -class trigger_teleport : CBaseTrigger +class trigger_teleport:CBaseTrigger { void() trigger_teleport; + virtual void() touch; virtual void() Respawn; }; -void trigger_teleport :: touch ( void ) +void trigger_teleport::touch(void) { - if ( other.health > 0 || other.solid == SOLID_SLIDEBOX ) { + if (other.health > 0 || other.solid == SOLID_SLIDEBOX) { entity eTarget = find(world, CBaseTrigger::m_strTargetName, m_strTarget); if (eTarget) { @@ -24,7 +25,8 @@ void trigger_teleport :: touch ( void ) } } -void trigger_teleport :: Respawn( void ) +/* TODO: Make this redundant */ +void trigger_teleport::Respawn(void) { solid = SOLID_TRIGGER; #ifdef GS_DEVELOPER @@ -32,10 +34,10 @@ void trigger_teleport :: Respawn( void ) #endif } -void trigger_teleport :: trigger_teleport ( void ) +void trigger_teleport::trigger_teleport(void) { CBaseTrigger::CBaseTrigger(); CBaseTrigger::InitBrushTrigger(); } -CLASSEXPORT( info_teleport_destination, info_notnull ) +CLASSEXPORT(info_teleport_destination, info_notnull) diff --git a/Source/gs-entbase/server/trigger_transition.cpp b/Source/gs-entbase/server/trigger_transition.cpp index afd4b6fd..67afee96 100644 --- a/Source/gs-entbase/server/trigger_transition.cpp +++ b/Source/gs-entbase/server/trigger_transition.cpp @@ -11,13 +11,11 @@ class trigger_transition void() trigger_transition; }; -void trigger_transition :: trigger_transition ( void ) +void trigger_transition::trigger_transition(void) { solid = SOLID_NOT; movetype = MOVETYPE_NONE; - setmodel( this, model ); + setmodel(this, model); model = __NULL__; modelindex = 0; -} - -CLASSEXPORT( trigger_transition, trigger_transition ) +} diff --git a/Source/gs-entbase/server/world.cpp b/Source/gs-entbase/server/world.cpp deleted file mode 100644 index 98118458..00000000 --- a/Source/gs-entbase/server/world.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/*** -* -* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved. -* -* See the file LICENSE attached with the sources for usage details. -* -****/ - -class CWorld -{ - void() CWorld; - virtual void() Precaches; - virtual void() SetupLight; -}; - -void CWorld :: Precaches ( void ) -{ - Material_Init(); - Weapon_Init(); -} - -void CWorld :: SetupLight ( void ) -{ - // Valve BSP only - if ( serverkeyfloat( "*bspversion" ) == 30 ) { - lightstyle( 0, "m" ); - lightstyle( 1, "mmnmmommommnonmmonqnmmo" ); - lightstyle( 2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba" ); - lightstyle( 3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg" ); - lightstyle( 4, "mamamamamama" ); - lightstyle( 5, "jklmnopqrstuvwxyzyxwvutsrqponmlkj" ); - lightstyle( 6, "nmonqnmomnmomomno" ); - lightstyle( 7, "mmmaaaabcdefgmmmmaaaammmaamm" ); - lightstyle( 8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa" ); - lightstyle( 9, "aaaaaaaazzzzzzzz" ); - lightstyle( 10, "mmamammmmammamamaaamammma" ); - lightstyle( 11, "abcdefghijklmnopqrrqponmlkjihgfedcba" ); - } - - clientstat( 16, EV_FLOAT, ::view_ofs[2] ); -} - -void CWorld :: CWorld ( void ) -{ - CWorld::Precaches(); - CWorld::SetupLight(); -} - -//CLASSEXPORT( worldspawn, CWorld ) diff --git a/Source/menu-fn/entry.cpp b/Source/menu-fn/entry.cpp index 4a6b4ec6..4f337d15 100644 --- a/Source/menu-fn/entry.cpp +++ b/Source/menu-fn/entry.cpp @@ -8,6 +8,25 @@ var int g_initialized = FALSE; +const string AGPL_TEXT = "\ +========================================================================\ +The FREE-CS PROJECT \ +Copyright (C) 2016-2019 Marco Hladik \ +\ +This program is free software: you can redistribute it and/or modify\ +it under the terms of the GNU Affero General Public License as\ +published by the Free Software Foundation, either version 3 of the\ +License, or (at your option) any later version.\ +\ +This program is distributed in the hope that it will be useful,\ +but WITHOUT ANY WARRANTY; without even the implied warranty of\ +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\ +GNU Affero General Public License for more details.\ +\ +You should have received a copy of the GNU Affero General Public License\ +along with this program. If not, see .\ +========================================================================"; + void cvar_init(void) { /* TODO: Shove these into defaults.cfg instead of forcing them */ @@ -28,6 +47,9 @@ void m_init(void) { vector g_btnsize; + print(AGPL_TEXT); + print("\n\n"); + registercommand("menu_customgame"); font_console = loadfont( "font", "", "12", -1 ); font_label = loadfont( "label", "gfx/shell/mssansserif.ttf", "10 12 14", -1 ); diff --git a/Source/menu-fn/m_customgame.cpp b/Source/menu-fn/m_customgame.cpp index bf0a3bf9..6322df95 100644 --- a/Source/menu-fn/m_customgame.cpp +++ b/Source/menu-fn/m_customgame.cpp @@ -48,6 +48,13 @@ void game_printinfo(int i) print("==================================\n"); } +void games_set(int id) +{ + gameinfo_current = id; + setwindowcaption(games[id].game); + cvar_set("com_fullgamename", games[id].game); +} + void games_init(void) { int gameidx; @@ -145,7 +152,7 @@ void games_init(void) } } if (games[gameidx].gamedir == cvar_string("game")) { - gameinfo_current = gameidx; + games_set(gameidx); } game_printinfo(gameidx); } @@ -176,7 +183,7 @@ void customgame_btnactivate_start(void) { int nextgame = customgame_lbMods.GetSelected(); - gameinfo_current = nextgame; + games_set(nextgame); localcmd(sprintf("gamedir \"%s\"\n", games[nextgame].gamedir)); localcmd("snd_restart\nwait\nvid_reload\nmenu_restart\nmenu_customgame\n"); // TODO: Re-init important menu bits and bobs. diff --git a/Source/server/cstrike/main.c b/Source/server/cstrike/main.c index b6264d13..4137694a 100644 --- a/Source/server/cstrike/main.c +++ b/Source/server/cstrike/main.c @@ -16,9 +16,9 @@ void SV_SendChat(entity eSender, string sMessage, entity eEnt, float fType) if (eEnt) { msg_entity = eEnt; - multicast('0 0 0', MULTICAST_ONE); + multicast([0,0,0], MULTICAST_ONE); } else { - multicast('0 0 0', MULTICAST_ALL); + multicast([0,0,0], MULTICAST_ALL); } } @@ -40,33 +40,31 @@ void Game_ParseClientCommand(string sCommand) return; } - string chat = substring(sCommand, 4, strlen(sCommand) - 4); - // Players talk to players, spectators to spectators. if (self.health ) { if (argv(0) == "say") { - localcmd(sprintf("echo %s: %s\n", self.netname, chat)); - SV_SendChat(self, chat, world, 0); + localcmd(sprintf("echo %s: %s\n", self.netname, argv(1))); + SV_SendChat(self, argv(1), world, 0); return; } else if (argv(0) == "say_team") { - localcmd(sprintf("echo [TEAM %d] %s: %s\n", self.team, self.netname, chat)); + localcmd(sprintf("echo [TEAM %d] %s: %s\n", self.team, self.netname, argv(1))); for (entity eFind = world; (eFind = find(eFind, classname, "player"));) { if (eFind.team == self.team) { - SV_SendChat(self, chat, eFind, 1); + SV_SendChat(self, argv(1), eFind, 1); } } return; } } else { if (argv(0) == "say") { - localcmd(sprintf("echo [DEAD] %s: %s\n", self.netname, chat)); + localcmd(sprintf("echo [DEAD] %s: %s\n", self.netname, argv(1))); for (entity eFind = world; (eFind = find(eFind, classname, "spectator"));) { - SV_SendChat(self, chat, eFind, 1); + SV_SendChat(self, argv(1), eFind, 1); } return; } else if (argv(0) == "say_team") { - localcmd(sprintf("echo [DEAD] %s: %s\n", self.netname, chat)); - return; + localcmd(sprintf("echo [DEAD] %s: %s\n", self.netname, argv(1))); + return; } } @@ -75,108 +73,8 @@ void Game_ParseClientCommand(string sCommand) float Game_ConsoleCmd(string sCommand) { - /*CBot bot; - if (!self) { - for (other = world; (other = find(other, classname, "player"));) { - if (clienttype(other) == CLIENTTYPE_REAL) { - self = other; - break; - } - } - }*/ tokenize(sCommand); switch (argv(0)) { - /*case "bot_add": - bot = (CBot)spawnclient(); - if (!bot) { - print("Server is full\n"); - return TRUE; - } - bot.CreateRandom(); - break; - case "bot_follow": - if (!self) { - return TRUE; - } - for (other = world; (other = find(other, classname, "Player"));) { - if (clienttype(other) != CLIENTTYPE_BOT) { - continue; - } - bot = (CBot)other; - if (bot.route) { -// RT_RouteChange(bot.route, bot.origin, self.origin); - } else { -// RT_Destroy(bot.route); - // bot.route = RT_RouteCreate(bot.origin, self.origin); - } - } - break; - case "bot_kill": - if (!self) { - return TRUE; - } - for (other = world; (other = find(other, classname, "Player"));) { - if (clienttype(other) != CLIENTTYPE_BOT) { - continue; - } - if (argv(1)) { - if (other.netname == argv(1)) { - //Damage_Apply(other, other, 500, DAMAGE_SUICIDE, 0); - break; - } - } else { - //Damage_Apply(other, other, 500, DAMAGE_SUICIDE, 0); - } - } - break; - case "bot_kick": - if (!self) { - return TRUE; - } - for (other = world; (other = find(other, classname, "Player"));) { - if (clienttype(other) != CLIENTTYPE_BOT) { - continue; - } - if (argv(1)) { - if (other.netname == argv(1)) { - dropclient(other); - break; - } - } else { - dropclient(other); - } - } - break; - case "way_add": - if (!self) { - return TRUE; - } - Way_Waypoint_Create(self, TRUE); - break; - case "way_delete": - if (!self) { - return TRUE; - } - Way_Waypoint_Delete(Way_FindClosestWaypoint(self.origin)); - break; - case "way_radius": - if (!self) { - return TRUE; - } - Way_Waypoint_SetRadius(Way_FindClosestWaypoint(self.origin), stof(argv(1))); - break; - case "way_makejump": - if (!self) { - return TRUE; - } - Way_Waypoint_MakeJump(Way_FindClosestWaypoint(self.origin)); - break; - case "way_save": - Way_DumpWaypoints(argv(1)); - break; - case "way_load": - Way_ReadWaypoints(argv(1)); - break;*/ case "vox": Vox_Broadcast(argv(1)); break; @@ -338,23 +236,18 @@ void Game_Worldspawn(void) precache_sound("hostage/hos3.wav"); precache_sound("hostage/hos4.wav"); precache_sound("hostage/hos5.wav"); - precache_sound("player/pl_pain2.wav"); precache_sound("player/pl_pain4.wav"); precache_sound("player/pl_pain5.wav"); precache_sound("player/pl_pain6.wav"); precache_sound("player/pl_pain7.wav"); - precache_sound("player/die1.wav"); precache_sound("player/die2.wav"); precache_sound("player/die3.wav"); - precache_sound("player/headshot1.wav"); precache_sound("player/headshot2.wav"); precache_sound("player/headshot3.wav"); - precache_sound("items/tr_kevlar.wav"); - precache_sound("weapons/ak47-1.wav"); precache_sound("weapons/ak47-2.wav"); precache_sound("weapons/ak47_boltpull.wav"); diff --git a/Source/server/defs.h b/Source/server/defs.h index b0a620d2..81224005 100644 --- a/Source/server/defs.h +++ b/Source/server/defs.h @@ -9,6 +9,7 @@ #define CLASSEXPORT(classname,classa) void classname ( void ) { spawnfunc_##classa(); } var int autocvar_mp_flashlight = TRUE; +var int g_hlbsp_materials = FALSE; void Effect_Impact( int iType, vector vPos, vector vNormal ); void Effect_CreateExplosion( vector vPos ); @@ -31,6 +32,7 @@ entity eActivator; .entity eUser; .float material; .float armor; +.float deaths; .float fStepTime; string startspot; diff --git a/Source/server/entry.c b/Source/server/entry.c index c9f08917..f15877fd 100644 --- a/Source/server/entry.c +++ b/Source/server/entry.c @@ -94,8 +94,10 @@ void init(float prevprogs) } } fclose(fileMaterial); + g_hlbsp_materials = TRUE; } else { - error("Failed to load sound/materials.txt!\n"); + error("Failed to load sound/materials.txt!\n"); + g_hlbsp_materials = FALSE; } PMove_Init(); diff --git a/Source/server/footsteps.c b/Source/server/footsteps.c index 470baea9..6a6649ea 100755 --- a/Source/server/footsteps.c +++ b/Source/server/footsteps.c @@ -15,7 +15,7 @@ Footsteps_Update Run every frame for each player, plays material based footsteps ================= */ -void Footsteps_Update( void ) { +void Footsteps_Update(void) { float fSpeed; float fVol; string sMaterial = ""; @@ -24,20 +24,24 @@ void Footsteps_Update( void ) { if (self.flags & FL_CROUCHING) { return; } + + if (!g_hlbsp_materials) { + return; + } - if ( ( self.movetype == MOVETYPE_WALK ) && ( self.flags & FL_ONGROUND ) ) { - if ( ( self.velocity[0] == 0 && self.velocity[1] == 0 ) || self.fStepTime > time ) { + if ((self.movetype == MOVETYPE_WALK) && (self.flags & FL_ONGROUND)) { + if ((self.velocity[0] == 0 && self.velocity[1] == 0) || self.fStepTime > time) { return; } - fSpeed = vlen( self.velocity ); - traceline( self.origin + self.view_ofs, self.origin + '0 0 -48', FALSE, self ); - sTexture = getsurfacetexture( trace_ent, getsurfacenearpoint( trace_ent, trace_endpos ) ); + fSpeed = vlen(self.velocity); + traceline(self.origin + self.view_ofs, self.origin + '0 0 -48', FALSE, self); + sTexture = getsurfacetexture(trace_ent, getsurfacenearpoint(trace_ent, trace_endpos)); - if ( fSpeed < 140 ) { + if (fSpeed < 140) { self.fStepTime = time + 0.35; fVol = 0.15f; - } else if ( fSpeed < 270 ) { + } else if (fSpeed < 270) { self.fStepTime = time + 0.35; fVol = 0.35f; } else { @@ -45,7 +49,7 @@ void Footsteps_Update( void ) { fVol = 0.75; } - switch( (float)hash_get( hashMaterials, sTexture ) ) { + switch((float)hash_get(hashMaterials, sTexture)) { case 'M': sMaterial = "metal"; break; @@ -81,17 +85,17 @@ void Footsteps_Update( void ) { break; } - if ( self.iStep ) { - if ( random() < 0.5f ) { - sound( self, CHAN_BODY, sprintf( "player/pl_%s1.wav", sMaterial), fVol, ATTN_STATIC ); + if (self.iStep) { + if (random() < 0.5f) { + sound(self, CHAN_BODY, sprintf("player/pl_%s1.wav", sMaterial), fVol, ATTN_STATIC); } else { - sound( self, CHAN_BODY, sprintf( "player/pl_%s2.wav", sMaterial), fVol, ATTN_STATIC ); + sound(self, CHAN_BODY, sprintf("player/pl_%s2.wav", sMaterial), fVol, ATTN_STATIC); } } else { - if ( random() < 0.5f ) { - sound( self, CHAN_BODY, sprintf( "player/pl_%s3.wav", sMaterial), fVol, ATTN_STATIC ); + if (random() < 0.5f) { + sound(self, CHAN_BODY, sprintf("player/pl_%s3.wav", sMaterial), fVol, ATTN_STATIC); } else { - sound( self, CHAN_BODY, sprintf( "player/pl_%s4.wav", sMaterial), fVol, ATTN_STATIC ); + sound(self, CHAN_BODY, sprintf("player/pl_%s4.wav", sMaterial), fVol, ATTN_STATIC); } } diff --git a/Source/server/rewolf.src b/Source/server/rewolf.src index 4f0181ab..c4677d3b 100755 --- a/Source/server/rewolf.src +++ b/Source/server/rewolf.src @@ -17,6 +17,12 @@ defs.h ../gs-entbase/server.src valve/monster_rat.cpp valve/monster_scientist_dead.cpp +rewolf/gunman_cycler.cpp +rewolf/monster_human_bandit.cpp +rewolf/monster_human_chopper.cpp +rewolf/monster_human_demoman.cpp +rewolf/monster_human_gunman.cpp +rewolf/monster_human_unarmed.cpp ../shared/decals.c ../shared/effects.c @@ -52,6 +58,7 @@ valve/ammo.cpp ../shared/valve/weapon_common.c spawn.c +vox.c valve/client.c client.c @@ -61,7 +68,6 @@ server.c valve/damage.c traceattack.c -vox.c footsteps.c flashlight.c diff --git a/Source/server/rewolf/gunman_cycler.cpp b/Source/server/rewolf/gunman_cycler.cpp new file mode 100644 index 00000000..7fe5ac72 --- /dev/null +++ b/Source/server/rewolf/gunman_cycler.cpp @@ -0,0 +1,11 @@ +/*** +* +* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved. +* +* See the file LICENSE attached with the sources for usage details. +* +****/ + +class gunman_cycler:cycler +{ +}; diff --git a/Source/server/rewolf/monster_human_bandit.cpp b/Source/server/rewolf/monster_human_bandit.cpp new file mode 100644 index 00000000..7774c21c --- /dev/null +++ b/Source/server/rewolf/monster_human_bandit.cpp @@ -0,0 +1,10 @@ +class monster_human_bandit:CBaseMonster +{ + void() monster_human_bandit; +}; + +void monster_human_bandit::monster_human_bandit(void) +{ + model = "models/bandit.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/Source/server/rewolf/monster_human_chopper.cpp b/Source/server/rewolf/monster_human_chopper.cpp new file mode 100644 index 00000000..b38179d6 --- /dev/null +++ b/Source/server/rewolf/monster_human_chopper.cpp @@ -0,0 +1,20 @@ +/*** +* +* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved. +* +* See the file LICENSE attached with the sources for usage details. +* +****/ + +class monster_human_chopper:CBaseEntity +{ + void() monster_human_chopper; +}; + +void monster_human_chopper::monster_human_chopper(void) +{ + model = "models/chopper.mdl"; + CBaseEntity::CBaseEntity(); + setmodel(this, m_oldModel); + setorigin(this, origin); +} diff --git a/Source/server/rewolf/monster_human_demoman.cpp b/Source/server/rewolf/monster_human_demoman.cpp new file mode 100644 index 00000000..f5983fc8 --- /dev/null +++ b/Source/server/rewolf/monster_human_demoman.cpp @@ -0,0 +1,10 @@ +class monster_human_demoman:CBaseMonster +{ + void() monster_human_demoman; +}; + +void monster_human_demoman::monster_human_demoman(void) +{ + model = "models/demolitionman.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/Source/server/rewolf/monster_human_gunman.cpp b/Source/server/rewolf/monster_human_gunman.cpp new file mode 100644 index 00000000..df8b15ab --- /dev/null +++ b/Source/server/rewolf/monster_human_gunman.cpp @@ -0,0 +1,10 @@ +class monster_human_gunman:CBaseMonster +{ + void() monster_human_gunman; +}; + +void monster_human_gunman::monster_human_gunman(void) +{ + model = "models/gunmantrooper.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/Source/server/rewolf/monster_human_unarmed.cpp b/Source/server/rewolf/monster_human_unarmed.cpp new file mode 100644 index 00000000..85bbac8f --- /dev/null +++ b/Source/server/rewolf/monster_human_unarmed.cpp @@ -0,0 +1,10 @@ +class monster_human_unarmed:CBaseMonster +{ + void() monster_human_unarmed; +}; + +void monster_human_unarmed::monster_human_unarmed(void) +{ + model = "models/gunmantrooper.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/Source/server/scihunt.src b/Source/server/scihunt.src index 11af5042..0f298c1e 100755 --- a/Source/server/scihunt.src +++ b/Source/server/scihunt.src @@ -57,6 +57,7 @@ valve/item_healthkit.cpp scihunt/shdata_parse.c spawn.c +vox.c scihunt/client.c client.c @@ -66,7 +67,6 @@ server.c valve/damage.c traceattack.c -vox.c footsteps.c flashlight.c diff --git a/Source/server/scihunt/client.c b/Source/server/scihunt/client.c index 5229853b..89a72eee 100644 --- a/Source/server/scihunt/client.c +++ b/Source/server/scihunt/client.c @@ -104,6 +104,7 @@ void Game_PutClientInServer(void) pl.vDeath = Player_Death; pl.iBleeds = TRUE; forceinfokey(pl, "*spec", "0"); + forceinfokey(self, "*deaths", ftos(self.deaths)); if (cvar("sv_playerslots") == 1) { Game_DecodeChangeParms(); diff --git a/Source/server/scihunt/monster_scientist.cpp b/Source/server/scihunt/monster_scientist.cpp index afa7d6e9..e66f2030 100644 --- a/Source/server/scihunt/monster_scientist.cpp +++ b/Source/server/scihunt/monster_scientist.cpp @@ -279,6 +279,7 @@ class monster_scientist:CBaseEntity entity m_eRescuer; float m_flScreamTime; + float m_flPainTime; float m_flChangePath; float m_flTraceTime; float m_flPitch; @@ -424,19 +425,23 @@ void monster_scientist::Physics(void) } } - 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; movetype = MOVETYPE_WALK; + + 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; + } + } runstandardplayerphysics(this); Footsteps_Update(); @@ -488,13 +493,24 @@ void monster_scientist::PlayerUse(void) void monster_scientist::vPain(int iHitBody) { + + WarnOthers(); + + if (m_flPainTime > time) { + return; + } + + if (random() < 0.75f) { + return; + } + int rand = floor(random(0,sci_sndpain.length)); sound(this, CHAN_VOICE, sci_sndpain[rand], 1.0, ATTN_NORM, m_flPitch); frame = SCIA_FLINCH + floor(random(0, 5)); m_iFlags |= SCIF_FEAR; - WarnOthers(); + m_flPainTime = time + 1.0f; } void monster_scientist::vDeath(int iHitBody) @@ -519,7 +535,7 @@ void monster_scientist::vDeath(int iHitBody) solid = SOLID_CORPSE; //takedamage = DAMAGE_NO; - + if (style != SCI_DEAD) { frame = SCIA_DIE_SIMPLE + floor(random(0, 6)); style = SCI_DEAD; @@ -606,3 +622,5 @@ void monster_scientist::monster_scientist(void) m_flPitch = 100; // Slick } } + +CLASSEXPORT(qreate_arcade, monster_scientist) diff --git a/Source/server/valve.src b/Source/server/valve.src index 7cfce342..ebcb7b69 100755 --- a/Source/server/valve.src +++ b/Source/server/valve.src @@ -16,6 +16,7 @@ defs.h ../gs-entbase/server.src valve/monster_rat.cpp +valve/monster_scientist.cpp valve/monster_scientist_dead.cpp ../shared/decals.c @@ -47,11 +48,14 @@ valve/items.cpp valve/item_longjump.cpp valve/item_suit.cpp valve/item_healthkit.cpp +valve/item_battery.cpp +valve/world_items.cpp valve/ammo.cpp ../shared/valve/weapons.c ../shared/valve/weapon_common.c spawn.c +vox.c valve/client.c client.c @@ -61,7 +65,6 @@ server.c valve/damage.c traceattack.c -vox.c footsteps.c flashlight.c diff --git a/Source/server/valve/client.c b/Source/server/valve/client.c index 734e4b7a..93b75769 100644 --- a/Source/server/valve/client.c +++ b/Source/server/valve/client.c @@ -12,10 +12,12 @@ void Game_ClientConnect(void) { bprint(PRINT_HIGH, sprintf("%s connected\n", self.netname)); } + void Game_ClientDisconnect(void) { bprint(PRINT_HIGH, sprintf("%s disconnected\n", self.netname)); } + void Game_ClientKill(void) { @@ -84,7 +86,6 @@ void Game_PutClientInServer(void) player pl = (player)self; entity spot; - pl.classname = "player"; pl.health = self.max_health = 100; //forceinfokey(self, "*dead", "0"); @@ -104,10 +105,13 @@ void Game_PutClientInServer(void) pl.vDeath = Player_Death; pl.iBleeds = TRUE; forceinfokey(pl, "*spec", "0"); + forceinfokey(self, "*deaths", ftos(self.deaths)); if (cvar("sv_playerslots") == 1) { Game_DecodeChangeParms(); - if (startspot) { + + if (startspot != "") { + print(sprintf("[LEVEL] Startspot is \"%s\"\n", startspot)); setorigin(pl, Landmark_GetSpot()); } else { spot = find(world, classname, "info_player_start"); @@ -146,24 +150,22 @@ void Game_ParseClientCommand(string cmd) { tokenize(cmd); - /*if (argv(1) == "timeleft") { + if (argv(1) == "timeleft") { float fTimeLeft = cvar("mp_timelimit") - (time / 60); Vox_Singlecast(self, sprintf("we have %s minutes remaining", Vox_TimeToString(fTimeLeft))); return; - }*/ - - string chat = substring(cmd, 4, strlen(cmd) - 4); + } // Players talk to players, spectators to spectators. if (argv(0) == "say") { - localcmd(sprintf("echo %s: %s\n", self.netname, chat)); - SV_SendChat(self, chat, world, 0); + localcmd(sprintf("echo [SERVER] %s: %s\n", self.netname, argv(1))); + SV_SendChat(self, argv(1), world, 0); return; } else if (argv(0) == "say_team") { - localcmd(sprintf("echo [TEAM %d] %s: %s\n", self.team, self.netname, chat)); + localcmd(sprintf("echo [TEAM %d] %s: %s\n", self.team, self.netname, argv(1))); for (entity eFind = world; (eFind = find(eFind, classname, "player"));) { if (eFind.team == self.team) { - SV_SendChat(self, chat, eFind, 1); + SV_SendChat(self, argv(1), eFind, 1); } } return; diff --git a/Source/server/valve/damage.c b/Source/server/valve/damage.c index be9818e3..21621027 100644 --- a/Source/server/valve/damage.c +++ b/Source/server/valve/damage.c @@ -36,7 +36,7 @@ Generic function that applies damage, pain and suffering void Damage_Apply(entity eTarget, entity eAttacker, float fDamage, vector vHitPos, int a) { // Apply the damage finally - if (eTarget.armor) { + if (eTarget.armor && fDamage > 0) { float flArmor; float flNewDamage; @@ -56,18 +56,27 @@ void Damage_Apply(entity eTarget, entity eAttacker, float fDamage, vector vHitPo fDamage = rint(fDamage); eTarget.health -= fDamage; - eTarget.dmg_take = fDamage; - eTarget.dmg_inflictor = eAttacker; + + if (fDamage > 0) { + eTarget.dmg_take = fDamage; + eTarget.dmg_inflictor = eAttacker; + } else if (eTarget.max_health && eTarget.health > eTarget.max_health) { + eTarget.health = eTarget.max_health; + } // Target is dead and a client.... if (eTarget.health <= 0) { if (eTarget.flags & FL_CLIENT) { - //eTarget.fDeaths++; - //forceinfokey(eTarget, "*deaths", ftos(eTarget.fDeaths)); + eTarget.deaths++; + forceinfokey(eTarget, "*deaths", ftos(eTarget.deaths)); } if ((eTarget.flags & FL_CLIENT) && (eAttacker.flags & FL_CLIENT)) { - eAttacker.frags++; + if (eTarget == eAttacker) { + eAttacker.frags--; + } else { + eAttacker.frags++; + } //Damage_CastOrbituary(eAttacker, eTarget, eAttacker.weapon); } } @@ -80,8 +89,8 @@ void Damage_Apply(entity eTarget, entity eAttacker, float fDamage, vector vHitPo } else { self.vPain(trace_surface_id); } - - if (self.iBleeds == TRUE) { + + if (self.iBleeds == TRUE && fDamage > 0) { Effect_CreateBlood(vHitPos, [0,0,0]); } @@ -157,11 +166,6 @@ void Damage_Radius(vector org, entity eAttacker, float fDamage, float fRadius, i if (fDiff > 0) { Damage_Apply(c, eAttacker, fDamage, vecRealPos, 0); - /*if (c.movetype != MOVETYPE_NONE) { - vPush = vectoangles(vecRealPos - org); - makevectors(vPush); - c.velocity += (v_forward * fDamage * 5) + (v_up * fDamage * 2.5); - }*/ } } diff --git a/Source/server/valve/input.c b/Source/server/valve/input.c index 9194567f..b3d763db 100644 --- a/Source/server/valve/input.c +++ b/Source/server/valve/input.c @@ -38,6 +38,8 @@ void Game_Input(void) if (cvar("sv_cheats") == 1) { player pl = (player)self; if (self.impulse == 101) { + pl.health = 100; + pl.armor = 100; Weapons_AddItem(pl, WEAPON_CROWBAR); Weapons_AddItem(pl, WEAPON_GLOCK); Weapons_AddItem(pl, WEAPON_PYTHON); diff --git a/Source/server/valve/item_battery.cpp b/Source/server/valve/item_battery.cpp new file mode 100644 index 00000000..0a3c24f2 --- /dev/null +++ b/Source/server/valve/item_battery.cpp @@ -0,0 +1,60 @@ +/*** +* +* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved. +* +* See the file LICENSE attached with the sources for usage details. +* +****/ + +class item_battery:CBaseEntity +{ + void() item_battery; + virtual void() Respawn; + virtual void() touch; +}; + +void item_battery::touch(void) +{ + if (other.classname == "player") { + if (other.armor >= 100) { + return; + } + /* Move this somewhere else? */ + other.armor += 15; + if (other.armor > 100) { + other.armor = 100; + } + + sound(other, CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM); + + if (cvar("sv_playerslots") == 1) { + remove(self); + } else { + Hide(); + think = Respawn; + nextthink = time + 20.0f; + } + } +} + +void item_battery::Respawn(void) +{ + solid = SOLID_TRIGGER; + movetype = MOVETYPE_TOSS; + setmodel(this, m_oldModel); + + setsize(this, [-8,-8,0], [8,8,48]); + setorigin(this, m_oldOrigin); + + think = __NULL__; + nextthink = -1; + sound(this, CHAN_ITEM, "items/suitchargeok1.wav", 1, ATTN_NORM, 150); + droptofloor(); +} + +void item_battery::item_battery(void) +{ + model = "models/w_battery.mdl"; + CBaseEntity::CBaseEntity(); + item_healthkit::Respawn(); +} diff --git a/Source/server/valve/item_healthkit.cpp b/Source/server/valve/item_healthkit.cpp index f8647a5a..11a47cfd 100644 --- a/Source/server/valve/item_healthkit.cpp +++ b/Source/server/valve/item_healthkit.cpp @@ -8,5 +8,51 @@ class item_healthkit:CBaseEntity { - + void() item_healthkit; + virtual void() Respawn; + virtual void() touch; }; + +void item_healthkit::touch(void) +{ + if (other.classname == "player") { + if (other.health >= other.max_health) { + return; + } + Damage_Apply(other, this, -20, this.origin, TRUE); + sound(this, CHAN_ITEM, "items/smallmedkit1.wav", 1, ATTN_NORM); + + if (cvar("sv_playerslots") == 1) { + remove(self); + } else { + Hide(); + think = Respawn; + nextthink = time + 20.0f; + } + } +} + +void item_healthkit::Respawn(void) +{ + solid = SOLID_TRIGGER; + movetype = MOVETYPE_TOSS; + setmodel(this, m_oldModel); + + + setsize(this, [-8,-8,0], [8,8,48]); + setorigin(this, m_oldOrigin); + + think = __NULL__; + nextthink = -1; + sound(this, CHAN_ITEM, "items/suitchargeok1.wav", 1, ATTN_NORM, 150); + droptofloor(); +} + +void item_healthkit::item_healthkit(void) +{ + precache_sound("items/smallmedkit1.wav"); + precache_sound("items/suitchargeok1.wav"); + model = "models/w_medkit.mdl"; + CBaseEntity::CBaseEntity(); + item_healthkit::Respawn(); +} diff --git a/Source/server/valve/monster_scientist.cpp b/Source/server/valve/monster_scientist.cpp new file mode 100644 index 00000000..37275e3a --- /dev/null +++ b/Source/server/valve/monster_scientist.cpp @@ -0,0 +1,18 @@ +/*** +* +* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved. +* +* See the file LICENSE attached with the sources for usage details. +* +****/ + +class monster_scientist:CBaseMonster +{ + void() monster_scientist; +}; + +void monster_scientist::monster_scientist(void) +{ + model = "models/scientist.mdl"; + CBaseMonster::CBaseMonster(); +} diff --git a/Source/server/valve/player.c b/Source/server/valve/player.c index 28da6ac9..4796928a 100644 --- a/Source/server/valve/player.c +++ b/Source/server/valve/player.c @@ -6,15 +6,17 @@ * ****/ -void Player_Pain(void) +void Player_Pain(int hit) { } -void Player_Death(void) +void Player_Death(int hit) { player pl = (player)self; pl.movetype = MOVETYPE_NONE; + pl.solid = SOLID_NOT; + pl.takedamage = DAMAGE_NO; pl.health = pl.armor = pl.activeweapon = pl.g_items = 0; PutClientInServer(); } diff --git a/Source/server/valve/world_items.cpp b/Source/server/valve/world_items.cpp new file mode 100644 index 00000000..3dadd0ce --- /dev/null +++ b/Source/server/valve/world_items.cpp @@ -0,0 +1,35 @@ +/*** +* +* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved. +* +* See the file LICENSE attached with the sources for usage details. +* +****/ + +/* This is one of those leftovers from trying to get a game out in time */ +class world_items:CBaseTrigger +{ + void() world_items; +}; + +void world_items::world_items(void) +{ + int nfields = tokenize(__fullspawndata); + for (int i = 1; i < (nfields - 1); i += 2) { + switch (argv(i)) { + case "type": + float type = stof(argv(i+1)); + switch (type) { + case 44: + spawnfunc_item_battery(); + break; + case 45: + spawnfunc_item_suit(); + break; + default: + } + default: + break; + } + } +} diff --git a/Source/shared/decals.c b/Source/shared/decals.c index 2b946239..2540b468 100644 --- a/Source/shared/decals.c +++ b/Source/shared/decals.c @@ -6,6 +6,8 @@ * ****/ +var int autocvar_cl_decals = TRUE; + #include "decals.h" #define DECALS_MAX 30 @@ -14,6 +16,9 @@ entity g_decals; void Decals_Init(void) { + if (serverkeyfloat("*bspversion") != 30) { + return; + } entity nextdecal = spawn(); g_decals = nextdecal; for (int i = 0; i <= DECALS_MAX; i++) { @@ -47,6 +52,9 @@ entity Decals_Next(vector pos) void Decals_PlaceSmall(vector pos) { + if (serverkeyfloat("*bspversion") != 30) { + return; + } #ifdef CSQC // TODO #else @@ -60,6 +68,9 @@ void Decals_PlaceSmall(vector pos) void Decals_PlaceBig(vector pos) { + if (serverkeyfloat("*bspversion") != 30) { + return; + } #ifdef CSQC // TODO #else @@ -73,6 +84,9 @@ void Decals_PlaceBig(vector pos) void Decals_PlaceGlass(vector pos) { + if (serverkeyfloat("*bspversion") != 30) { + return; + } #ifdef CSQC // TODO #else @@ -86,6 +100,9 @@ void Decals_PlaceGlass(vector pos) void Decals_PlaceScorch(vector pos) { + if (serverkeyfloat("*bspversion") != 30) { + return; + } #ifdef CSQC // TODO #else @@ -121,6 +138,10 @@ const string g_decalshader_add = \ float Decal_PreDraw(void) { + if (!autocvar_cl_decals) { + return PREDRAW_NEXT; + } + adddecal(self.classname, self.origin, self.mins, self.maxs, self.color, 1.0f); addentity(self); return PREDRAW_NEXT; diff --git a/Source/shared/scihunt/player.cpp b/Source/shared/scihunt/player.cpp index 828d3264..f654a9da 100644 --- a/Source/shared/scihunt/player.cpp +++ b/Source/shared/scihunt/player.cpp @@ -31,6 +31,7 @@ class player int shotgun_mag; int crossbow_mag; int rpg_mag; + int satchel_chg; int cannon_mag; #ifdef CSQC diff --git a/Source/shared/valve/player.cpp b/Source/shared/valve/player.cpp index f31a8915..60eba47d 100644 --- a/Source/shared/valve/player.cpp +++ b/Source/shared/valve/player.cpp @@ -31,6 +31,7 @@ class player int shotgun_mag; int crossbow_mag; int rpg_mag; + int satchel_chg; #ifdef CSQC /* External model */ diff --git a/Source/shared/valve/w_crossbow.c b/Source/shared/valve/w_crossbow.c index bb055509..7be7363f 100644 --- a/Source/shared/valve/w_crossbow.c +++ b/Source/shared/valve/w_crossbow.c @@ -24,10 +24,8 @@ enum void w_crossbow_precache(void) { -#ifdef CSQC - precache_model("models/v_crossbow.mdl"); precache_model("models/crossbow_bolt.mdl"); -#else + precache_model("models/v_crossbow.mdl"); precache_model("models/w_crossbow.mdl"); precache_model("models/p_crossbow.mdl"); precache_sound("weapons/xbow_reload1.wav"); @@ -35,7 +33,6 @@ void w_crossbow_precache(void) precache_sound("weapons/xbow_hit1.wav"); precache_sound("weapons/xbow_hitbod1.wav"); precache_sound("weapons/xbow_hitbod2.wav"); -#endif } string w_crossbow_vmodel(void) { @@ -90,23 +87,12 @@ void w_crossbow_holster(void) void w_crossbow_primary(void) { player pl = (player)self; - if (pl.w_attack_next > 0.0) { + if (pl.w_attack_next) { return; } -#ifdef CSQC - if (pl.a_ammo1) { - Weapons_ViewAnimation(CROSSBOW_FIRE1); - Weapons_PlaySound(pl, CHAN_ITEM, "weapons/xbow_reload1.wav", 1, ATTN_NORM); - } else { - Weapons_ViewAnimation(CROSSBOW_FIRE3); - } - - Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/xbow_fire1.wav", 1, ATTN_NORM); -#endif - - static void Crossbolt_Touch(void) { #ifdef SSQC + static void Crossbolt_Touch(void) { Effect_CreateSpark(self.origin, trace_plane_normal); if (other.takedamage == DAMAGE_YES) { @@ -119,46 +105,49 @@ void w_crossbow_primary(void) } else { Weapons_PlaySound(self, CHAN_WEAPON, "weapons/xbow_hit1.wav", 1, ATTN_NORM); } -#endif remove(self); } Weapons_MakeVectors(); entity bolt = spawn(); - -#ifdef SSQC - static float bolt_nosend(entity pvsent, float fl) { - return FALSE; - } - bolt.SendEntity = bolt_nosend; - bolt.SendFlags = 1; -#else setmodel(bolt, "models/crossbow_bolt.mdl"); - bolt.drawmask = MASK_ENGINE; -#endif setorigin(bolt, Weapons_GetCameraPos() + (v_forward * 16)); bolt.owner = self; bolt.velocity = v_forward * 2000; bolt.movetype = MOVETYPE_FLY; bolt.solid = SOLID_BBOX; + //bolt.flags |= FL_LAGGEDMOVE; bolt.gravity = 0.5f; bolt.angles = vectoangles(bolt.velocity); bolt.avelocity[2] = 10; bolt.touch = Crossbolt_Touch; setsize(bolt, [0,0,0], [0,0,0]); + if (pl.crossbow_mag) { + Weapons_PlaySound(pl, CHAN_ITEM, "weapons/xbow_reload1.wav", 1, ATTN_NORM); + } + + Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/xbow_fire1.wav", 1, ATTN_NORM); +#else + if (pl.a_ammo1) { + Weapons_ViewAnimation(CROSSBOW_FIRE1); + } else { + Weapons_ViewAnimation(CROSSBOW_FIRE3); + } Weapons_ViewPunchAngle([-2,0,0]); +#endif + pl.w_attack_next = 0.75f; pl.w_idle_next = 10.0f; } void w_crossbow_secondary(void) { player pl = (player)self; - if (pl.w_attack_next > 0.0) { + if (pl.w_attack_next) { return; } /* Simple toggle of fovs */ if (pl.viewzoom == 1.0f) { - pl.viewzoom = 0.2; + pl.viewzoom = 0.2f; } else { pl.viewzoom = 1.0f; } diff --git a/Source/shared/valve/w_glock.c b/Source/shared/valve/w_glock.c index ffe7f88d..57e2eab1 100644 --- a/Source/shared/valve/w_glock.c +++ b/Source/shared/valve/w_glock.c @@ -62,7 +62,7 @@ void w_glock_draw(void) } void w_glock_holster(void) { -#ifdef SSQC +#ifdef CSQC Weapons_ViewAnimation(GLOCK_HOLSTER); #endif } diff --git a/Source/shared/valve/w_hornetgun.c b/Source/shared/valve/w_hornetgun.c index 1286d1f9..eeefdbdc 100644 --- a/Source/shared/valve/w_hornetgun.c +++ b/Source/shared/valve/w_hornetgun.c @@ -69,21 +69,29 @@ void w_hornetgun_primary(void) if (pl.w_attack_next > 0.0) { return; } - + +#ifdef SSQC Weapons_PlaySound(pl, CHAN_WEAPON, sprintf("agrunt/ag_fire%d.wav", floor(random(1,4))), 1, ATTN_NORM); +#else Weapons_ViewAnimation(HORNETGUN_SHOOT); +#endif + pl.w_attack_next = 0.25; pl.w_idle_next = 2.5f; } void w_hornetgun_secondary(void) { player pl = (player)self; - if (pl.w_attack_next > 0.0) { + if (pl.w_attack_next) { return; } - + +#ifdef SSQC Weapons_PlaySound(pl, CHAN_WEAPON, sprintf("agrunt/ag_fire%d.wav", floor(random(1,4))), 1, ATTN_NORM); +#else Weapons_ViewAnimation(HORNETGUN_SHOOT); +#endif + pl.w_attack_next = 0.1; pl.w_idle_next = 2.5f; } @@ -93,6 +101,7 @@ void w_hornetgun_reload(void) } void w_hornetgun_release(void) { +#ifdef CSQC int r; player pl = (player)self; if (pl.w_idle_next > 0.0) { @@ -115,6 +124,7 @@ void w_hornetgun_release(void) pl.w_idle_next = 2.2f; break; } +#endif } void w_hornetgun_crosshair(void) { diff --git a/Source/shared/valve/w_mp5.c b/Source/shared/valve/w_mp5.c index 9abdde42..275302a4 100644 --- a/Source/shared/valve/w_mp5.c +++ b/Source/shared/valve/w_mp5.c @@ -67,7 +67,9 @@ void w_mp5_draw(void) void w_mp5_holster(void) { +#ifdef CSQC Weapons_ViewAnimation(MP5_DRAW); +#endif } void w_mp5_primary(void) @@ -119,7 +121,7 @@ void w_mp5_secondary(void) static void Grenade_ExplodeTouch(void) { Effect_CreateExplosion( self.origin ); - Damage_Radius( self.origin, self, 100, 256, TRUE ); + Damage_Radius( self.origin, self.owner, 100, 100 * 2.5f, TRUE ); sound( self, CHAN_WEAPON, sprintf( "weapons/explode%d.wav", floor( random() * 2 ) + 3 ), 1, ATTN_NORM ); remove(self); } diff --git a/Source/shared/valve/w_python.c b/Source/shared/valve/w_python.c index 13c2f545..ff0e27b7 100644 --- a/Source/shared/valve/w_python.c +++ b/Source/shared/valve/w_python.c @@ -23,7 +23,7 @@ void w_python_precache(void) precache_model("models/v_357.mdl"); precache_model("models/w_357.mdl"); precache_model("models/p_357.mdl"); - + precache_sound("weapons/357_shot1.wav"); precache_sound("weapons/357_shot2.wav"); } @@ -62,7 +62,9 @@ void w_python_draw(void) void w_python_holster(void) { +#ifdef CSQC Weapons_ViewAnimation(PYTHON_HOLSTER); +#endif } void w_python_primary(void) { @@ -73,17 +75,17 @@ void w_python_primary(void) #ifdef SSQC TraceAttack_FireBullets(1, pl.origin + pl.view_ofs, 40, [0.00873, 0.00873]); -#endif - - Weapons_ViewAnimation(PYTHON_FIRE1); - Weapons_ViewPunchAngle([-10,0,0]); if (random() < 0.5) { Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/357_shot1.wav", 1, ATTN_NORM); } else { Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/357_shot2.wav", 1, ATTN_NORM); } - +#else + Weapons_ViewAnimation(PYTHON_FIRE1); + Weapons_ViewPunchAngle([-10,0,0]); +#endif + pl.w_attack_next = 0.75f; pl.w_idle_next = 10.0f; } @@ -107,19 +109,24 @@ void w_python_reload(void) if (pl.w_attack_next > 0.0) { return; } + +#ifdef CSQC Weapons_ViewAnimation(PYTHON_RELOAD); +#endif + pl.w_attack_next = 3.25f; pl.w_idle_next = 10.0f; } void w_python_release(void) { + +#ifdef CSQC player pl = (player)self; if (pl.w_idle_next > Math_Time()) { return; } int r = floor(random(0,3)); - switch (r) { case 0: Weapons_ViewAnimation(PYTHON_IDLE1); @@ -133,6 +140,7 @@ void w_python_release(void) } pl.w_idle_next = Math_Time() + 15.0f; +#endif } void w_python_crosshair(void) { diff --git a/Source/shared/valve/w_satchel.c b/Source/shared/valve/w_satchel.c index f697ba0a..ae32352d 100644 --- a/Source/shared/valve/w_satchel.c +++ b/Source/shared/valve/w_satchel.c @@ -23,43 +23,9 @@ enum RADIO_HOLSTER }; -void w_satchel_draw(void) -{ -#ifdef CSQC - Weapons_ViewAnimation(SATCHEL_DRAW); -#else - player pl = (player)self; - Weapons_UpdateAmmo(pl, __NULL__, pl.ammo_satchel, __NULL__); -#endif -} - -void w_satchel_holster(void) -{ - -} -void w_satchel_primary(void) -{ - -} -void w_satchel_secondary(void) -{ - -} -void w_satchel_reload(void) -{ - -} -void w_satchel_release(void) -{ - -} -void w_satchel_precache(void) -{ - -} string w_satchel_vmodel(void) { - return "models/v_satchel.mdl"; + return "models/v_satchel_radio.mdl"; } string w_satchel_wmodel(void) { @@ -73,6 +39,130 @@ string w_satchel_deathmsg(void) { return ""; } +void w_satchel_precache(void) +{ + precache_model("models/w_satchel.mdl"); + precache_model("models/v_satchel.mdl"); + precache_model("models/v_satchel_radio.mdl"); + precache_model("models/p_satchel.mdl"); +} + +void w_satchel_draw(void) +{ +#ifdef CSQC + Weapons_ViewAnimation(SATCHEL_DRAW); +#else + player pl = (player)self; + Weapons_UpdateAmmo(pl, pl.satchel_chg, pl.ammo_satchel, __NULL__); +#endif +} + +void w_satchel_holster(void) +{ + +} + +#ifdef SSQC +void s_satchel_drop(entity master, vector src, vector vel) +{ + entity satch; + satch = spawn(); + satch.owner = master; + satch.classname = "satchel"; + satch.movetype = MOVETYPE_BOUNCE; + satch.solid = SOLID_BBOX; + satch.frame = 1; + satch.gravity = 0.5f; + satch.friction = 0.8f; + satch.velocity = vel; + satch.avelocity = [0,400,0]; + setmodel(satch, "models/w_satchel.mdl"); + setsize(satch, [-4,-4,-4], [4,4,4]); + setorigin(satch, src); +} +void s_satchel_detonate(entity master) +{ + for (entity b = world; (b = find(b, ::classname, "satchel"));) { + if (b.owner == master) { + Effect_CreateExplosion(b.origin); + Damage_Radius(b.origin, master, 150, 150 * 2.5f, TRUE); + sound(b, CHAN_WEAPON, sprintf( "weapons/explode%d.wav", floor( random() * 2 ) + 3 ), 1, ATTN_NORM); + remove(b); + } + } +} +#endif + +void w_satchel_primary(void) +{ + player pl = (player)self; + + if (pl.w_attack_next) { + return; + } + +#ifdef SSQC + if (!pl.satchel_chg) { + vector throw; + + Weapons_MakeVectors(); + throw = pl.velocity + (v_forward * 274); + s_satchel_drop(self, pl.origin, throw); + pl.satchel_chg++; + } else { + s_satchel_detonate(pl); + pl.satchel_chg = 0; + } + Weapons_UpdateAmmo(pl, pl.satchel_chg, pl.ammo_satchel, __NULL__); +#else + if (!pl.a_ammo1) { + Weapons_ViewAnimation(RADIO_DRAW); + } else { + Weapons_ViewAnimation(RADIO_USE); + } +#endif + + pl.w_attack_next = 1.0f; + pl.w_idle_next = 2.5f; +} +void w_satchel_secondary(void) +{ + player pl = (player)self; + + if (pl.w_attack_next) { + return; + } + +#ifdef SSQC + vector throw; + Weapons_MakeVectors(); + throw = pl.velocity + (v_forward * 274); + s_satchel_drop(self, pl.origin, throw); + pl.satchel_chg++; + Weapons_UpdateAmmo(pl, pl.satchel_chg, pl.ammo_satchel, __NULL__); +#else + Weapons_ViewAnimation(RADIO_DRAW); +#endif + + pl.w_attack_next = 1.0f; + pl.w_idle_next = 2.5f; +} +void w_satchel_reload(void) +{ + +} +void w_satchel_release(void) +{ +#ifdef CSQC + player pl = (player)self; + if (pl.w_idle_next) { + return; + } + + Weapons_ViewAnimation(RADIO_FIDGET); + pl.w_idle_next = 15.0f; +#endif +} void w_satchel_hudpic(int s, vector pos) { @@ -85,7 +175,6 @@ void w_satchel_hudpic(int s, vector pos) #endif } - weapon_t w_satchel = { ITEM_SATCHEL, diff --git a/Source/shared/valve/w_shotgun.c b/Source/shared/valve/w_shotgun.c index 426f9fda..f175cc2f 100644 --- a/Source/shared/valve/w_shotgun.c +++ b/Source/shared/valve/w_shotgun.c @@ -57,19 +57,17 @@ void w_shotgun_draw(void) void w_shotgun_holster(void) { +#ifdef CSQC Weapons_ViewAnimation(SHOTGUN_HOLSTER); +#endif } void w_shotgun_primary(void) { player pl = (player)self; - if (pl.w_attack_next > 0.0) { + if (pl.w_attack_next) { return; } - Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/sbarrel1.wav", 1, ATTN_NORM); - Weapons_ViewAnimation(SHOTGUN_FIRE1); - Weapons_ViewPunchAngle([-5,0,0]); - #ifdef SSQC /* Singleplayer is more accurate */ if (cvar("sv_playerslots") == 1) { @@ -77,15 +75,19 @@ void w_shotgun_primary(void) } else { TraceAttack_FireBullets(4, pl.origin + pl.view_ofs, 5, [0.08716,0.04362]); } + Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/sbarrel1.wav", 1, ATTN_NORM); +#else + Weapons_ViewAnimation(SHOTGUN_FIRE1); + Weapons_ViewPunchAngle([-5,0,0]); #endif - pl.w_attack_next = Math_Time() + 0.75; - pl.w_idle_next = Math_Time() + 2.5f; + pl.w_attack_next = 0.75; + pl.w_idle_next = 2.5f; } void w_shotgun_secondary(void) { player pl = (player)self; - if (pl.w_attack_next > 0.0) { + if (pl.w_attack_next) { return; } @@ -96,11 +98,12 @@ void w_shotgun_secondary(void) } else { TraceAttack_FireBullets(8, pl.origin + pl.view_ofs, 5, [0.17365,0.04362]); } -#endif - Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/dbarrel1.wav", 1, ATTN_NORM); +#else Weapons_ViewAnimation(SHOTGUN_FIRE2); Weapons_ViewPunchAngle([-10,0,0]); +#endif + pl.w_attack_next = 1.5f; pl.w_idle_next = 2.5f; } @@ -110,8 +113,9 @@ void w_shotgun_reload(void) } void w_shotgun_release(void) { +#ifdef CSQC player pl = (player)self; - if (pl.w_idle_next > 0.0) { + if (pl.w_idle_next) { return; } @@ -129,6 +133,7 @@ void w_shotgun_release(void) } pl.w_idle_next = 15.0f; +#endif } void w_shotgun_crosshair(void) { diff --git a/cstrike/data.pk3dir/csprogs.dat b/cstrike/data.pk3dir/csprogs.dat index d7b54dfb..b6545f10 100644 Binary files a/cstrike/data.pk3dir/csprogs.dat and b/cstrike/data.pk3dir/csprogs.dat differ diff --git a/cstrike/data.pk3dir/progs.dat b/cstrike/data.pk3dir/progs.dat index f3764ba6..3056ff0b 100644 Binary files a/cstrike/data.pk3dir/progs.dat and b/cstrike/data.pk3dir/progs.dat differ diff --git a/rewolf/data.pk3dir/csprogs.dat b/rewolf/data.pk3dir/csprogs.dat index 957af656..834b6ec7 100644 Binary files a/rewolf/data.pk3dir/csprogs.dat and b/rewolf/data.pk3dir/csprogs.dat differ diff --git a/rewolf/data.pk3dir/progs.dat b/rewolf/data.pk3dir/progs.dat index 8b61e54e..ec09db8a 100644 Binary files a/rewolf/data.pk3dir/progs.dat and b/rewolf/data.pk3dir/progs.dat differ diff --git a/scihunt/data.pk3dir/csprogs.dat b/scihunt/data.pk3dir/csprogs.dat index d3e1a724..d959bbd8 100644 Binary files a/scihunt/data.pk3dir/csprogs.dat and b/scihunt/data.pk3dir/csprogs.dat differ diff --git a/scihunt/data.pk3dir/progs.dat b/scihunt/data.pk3dir/progs.dat index 88243139..f405e036 100644 Binary files a/scihunt/data.pk3dir/progs.dat and b/scihunt/data.pk3dir/progs.dat differ diff --git a/valve/data.pk3dir/csprogs.dat b/valve/data.pk3dir/csprogs.dat index 09604928..60ac2854 100644 Binary files a/valve/data.pk3dir/csprogs.dat and b/valve/data.pk3dir/csprogs.dat differ diff --git a/valve/data.pk3dir/glsl/defaultsky.glsl b/valve/data.pk3dir/glsl/defaultsky.glsl deleted file mode 100644 index f6492899..00000000 --- a/valve/data.pk3dir/glsl/defaultsky.glsl +++ /dev/null @@ -1,15 +0,0 @@ -!!ver 110 - -#ifdef VERTEX_SHADER -void main () -{ - gl_Position = ftetransform(); -} -#endif - -#ifdef FRAGMENT_SHADER -void main () -{ - discard; -} -#endif diff --git a/valve/data.pk3dir/glsl/defaultwall.glsl b/valve/data.pk3dir/glsl/defaultwall.glsl index db923341..247c80e2 100644 --- a/valve/data.pk3dir/glsl/defaultwall.glsl +++ b/valve/data.pk3dir/glsl/defaultwall.glsl @@ -48,7 +48,6 @@ varying vec2 lm_c; float m = (diffuse_f.r + diffuse_f.g + diffuse_f.b) / 3.0f; diffuse_f.rgb = vec3(m,m,m); #endif - gl_FragColor = diffuse_f; } diff --git a/valve/data.pk3dir/menu.dat b/valve/data.pk3dir/menu.dat index 8e6c82d1..3b03243f 100644 Binary files a/valve/data.pk3dir/menu.dat and b/valve/data.pk3dir/menu.dat differ diff --git a/valve/data.pk3dir/progs.dat b/valve/data.pk3dir/progs.dat index 3957abc4..090bc0f1 100644 Binary files a/valve/data.pk3dir/progs.dat and b/valve/data.pk3dir/progs.dat differ