diff --git a/src/client/draw.qc b/src/client/draw.qc new file mode 100644 index 0000000..d30148a --- /dev/null +++ b/src/client/draw.qc @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016-2022 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +void +ClientGame_PreDraw(void) +{ + +} + +void +ClientGame_PostDraw(void) +{ + +} diff --git a/src/client/modelevent.qc b/src/client/modelevent.qc new file mode 100644 index 0000000..cd659ea --- /dev/null +++ b/src/client/modelevent.qc @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2016-2022 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +void +ClientGame_ModelEvent(float flTimeStamp, int iCode, string strData) +{ + switch (iCode) { + default: + Event_ProcessModel(flTimeStamp, iCode, strData); + } +} diff --git a/src/client/progs.src b/src/client/progs.src index 6531b81..1778181 100644 --- a/src/client/progs.src +++ b/src/client/progs.src @@ -19,7 +19,7 @@ defs.h ../../../src/gs-entbase/shared.src ../shared/include.src -../../../base/src/client/draw.qc +draw.qc damage.qc init.qc @@ -37,7 +37,7 @@ hud_ammonotify.qc hud.qc hud_weaponselect.qc scoreboard.qc -../../../base/src/client/modelevent.qc +modelevent.qc ../../../src/client/include.src ../../../src/shared/include.src diff --git a/src/server/damage.qc b/src/server/damage.qc new file mode 100644 index 0000000..cca3ce6 --- /dev/null +++ b/src/server/damage.qc @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2016-2022 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ diff --git a/src/server/item_armorvest.qc b/src/server/item_armorvest.qc new file mode 100644 index 0000000..ef0a342 --- /dev/null +++ b/src/server/item_armorvest.qc @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2016-2020 Marco Cawthorne + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/*QUAKED item_armorvest (0 0 0.8) (-16 -16 0) (16 16 36) SUIT_LONGINTRO + +HALF-LIFE (1998) ENTITY + +HEV Suit +Provides the player with armor, a flashlight and a Heads-Up-Display. + +When SUIT_LONGINTRO is set, the intro dialog will be longer. + +*/ + +class item_armorvest:NSRenderableEntity +{ + string m_strOnPlayerTouch; + + void(void) item_armorvest; + + virtual void(void) Spawned; + virtual void(entity) Touch; + virtual void(void) Respawn; + virtual void(string, string) SpawnKey; +}; + +void +item_armorvest::Touch(entity eToucher) +{ + if (other.classname != "player") { + return; + } + + player pl = (player)other; + if (pl.g_items & ITEM_SUIT) { + return; + } + + Logging_Pickup(other, this, __NULL__); + pl.g_items |= ITEM_SUIT; + m_iValue = TRUE; + + if (!target) { + UseOutput(other, m_strOnPlayerTouch); + } else { + UseTargets(other, TRIG_TOGGLE, m_flDelay); + } + + if (real_owner || cvar("sv_playerslots") == 1) { + Destroy(); + } else { + Disappear(); + ScheduleThink(Respawn, 30.0f); + } +} + +void +item_armorvest::Respawn(void) +{ + SetSolid(SOLID_TRIGGER); + SetMovetype(MOVETYPE_TOSS); + SetOrigin(GetSpawnOrigin()); + SetModel(GetSpawnModel()); + SetSize(VEC_HULL_MIN + [0,0,36], VEC_HULL_MAX + [0,0,36]); + m_iValue = FALSE; + + ReleaseThink(); + + if (!real_owner && time > 30.0f) + Sound_Play(this, CHAN_ITEM, "item.respawn"); + + DropToFloor(); +} + +void +item_armorvest::SpawnKey(string strKey, string strValue) +{ + switch (strKey) { + case "OnPlayerTouch": + strValue = strreplace(",", ",_", strValue); + m_strOnPlayerTouch = strcat(m_strOnPlayerTouch, ",_", strValue); + break; + default: + super::SpawnKey(strKey, strValue); + break; + } +} + +void +item_armorvest::Spawned(void) +{ + super::Spawned(); + + precache_model(model); + + if (m_strOnPlayerTouch) + m_strOnPlayerTouch = CreateOutput(m_strOnPlayerTouch); +} + +void +item_armorvest::item_armorvest(void) +{ + model = "models/barney_vest.mdl"; +} diff --git a/src/server/item_helmet.qc b/src/server/item_helmet.qc new file mode 100644 index 0000000..e69de29 diff --git a/src/server/modelevent.qc b/src/server/modelevent.qc new file mode 100644 index 0000000..1052cff --- /dev/null +++ b/src/server/modelevent.qc @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2016-2022 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +void +Game_ServerModelEvent(float flTimeStamp, int iCode, string strData) +{ + switch (iCode) { + default: + Event_ServerModelEvent(flTimeStamp, iCode, strData); + break; + } +} diff --git a/src/server/progs.src b/src/server/progs.src index 6e48f3e..a656296 100644 --- a/src/server/progs.src +++ b/src/server/progs.src @@ -75,9 +75,9 @@ gamerules.qc gamerules_singleplayer.qc gamerules_multiplayer.qc server.qc -../../../base/src/server/damage.qc +damage.qc flashlight.qc -../../../base/src/server/modelevent.qc +modelevent.qc spawn.qc diff --git a/src/shared/fx_corpse.qc b/src/shared/fx_corpse.qc new file mode 100644 index 0000000..0231ba2 --- /dev/null +++ b/src/shared/fx_corpse.qc @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016-2022 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifdef SERVER +#define CORPSES_MAX 16 +entity g_bodies; + +void +FX_Corpse_Init(void) +{ + entity next = spawn(NSRenderableEntity); + g_bodies = next; + + for ( int i = 0; i <= CORPSES_MAX; i++ ) { + next.classname = "corpse"; + next.owner = spawn(NSRenderableEntity); + + if ( i == CORPSES_MAX ) { + next.owner = g_bodies; + } else { + next = next.owner; + } + } +} + +entity +FX_Corpse_Next(void) +{ + entity r = g_bodies; + g_bodies = g_bodies.owner; + return r; +} + +entity +FX_Corpse_Spawn(player pl, float anim) +{ + NSRenderableEntity body_next = (NSRenderableEntity)FX_Corpse_Next(); + setorigin(body_next, pl.origin + [0,0,32]); + body_next.SetMovetype(MOVETYPE_TOSS); + body_next.SetSolid(SOLID_CORPSE); + setmodel(body_next, pl.model); + setsize(body_next, VEC_HULL_MIN, VEC_HULL_MAX); + body_next.SetModelindex(pl.modelindex); + body_next.SetAngles(pl.angles); + body_next.velocity = (pl.velocity) + [0,0,120]; + body_next.colormap = pl.colormap; + body_next.SetFrame(anim); + return (entity)body_next; +} +#endif diff --git a/src/shared/fx_spark.qc b/src/shared/fx_spark.qc new file mode 100644 index 0000000..62a2a52 --- /dev/null +++ b/src/shared/fx_spark.qc @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016-2022 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifdef CLIENT +var float PARTICLE_SPARK; + +void +FX_Spark_Init(void) +{ + Sound_Precache("env_spark.sfx"); + PARTICLE_SPARK = particleeffectnum("fx_spark.effect"); +} +#endif + +void +FX_Spark(vector pos, vector ang) +{ +#ifdef SERVER + WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); + WriteByte(MSG_MULTICAST, EV_SPARK); + WriteCoord(MSG_MULTICAST, pos[0]); + WriteCoord(MSG_MULTICAST, pos[1]); + WriteCoord(MSG_MULTICAST, pos[2]); + WriteCoord(MSG_MULTICAST, ang[0]); + WriteCoord(MSG_MULTICAST, ang[1]); + WriteCoord(MSG_MULTICAST, ang[2]); + msg_entity = self; + multicast(pos, MULTICAST_PVS); +#else + pointparticles(PARTICLE_SPARK, pos, ang, 1); + Sound_PlayAt(pos, "env_spark.sfx"); +#endif +} diff --git a/src/shared/include.src b/src/shared/include.src index eeee887..85afb85 100644 --- a/src/shared/include.src +++ b/src/shared/include.src @@ -3,7 +3,7 @@ entities.h events.h flags.h player.qc -../../../base/src/shared/weapon_common.h +weapon_common.h animations.h animations.qc pmove.qc @@ -13,8 +13,8 @@ fx_gaussbeam.qc fx_breakmodel.qc fx_explosion.qc fx_gibhuman.qc -../../../base/src/shared/fx_spark.qc -../../../base/src/shared/fx_corpse.qc +fx_spark.qc +fx_corpse.qc fx_impact.qc items.h @@ -34,5 +34,5 @@ w_shotgun.qc w_snark.qc w_tripmine.qc weapons.qc -../../../base/src/shared/weapon_common.qc +weapon_common.qc #endlist diff --git a/src/shared/weapon_common.h b/src/shared/weapon_common.h new file mode 100644 index 0000000..1aac488 --- /dev/null +++ b/src/shared/weapon_common.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2016-2022 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef NEW_INVENTORY +/* for AI identification purposes */ +typedef enum +{ + WPNTYPE_INVALID, /* no logic */ + WPNTYPE_RANGED, /* will want to keep their distance mostly */ + WPNTYPE_THROW, /* has to keep some distance, but not too far */ + WPNTYPE_CLOSE, /* have to get really close */ + WPNTYPE_FULLAUTO, /* for things that need to be held down */ + WPNTYPE_SEMI /* semi automatic */ +} weapontype_t; + +typedef struct +{ + string name; + int id; /* bitflag id */ + int slot; + int slot_pos; + int allow_drop; + int weight; /* required for bestweapon */ + void(void) precache; + string() wmodel; + string() deathmsg; + + /* player specific */ + string(player) pmodel; + float(player) aimanim; + weapontype_t(player) type; /* required for bot-AI */ + void(player) draw; + void(player) holster; + void(player) primary; + void(player) secondary; + void(player) reload; + void(player) release; + int(player, int, int) pickup; + void(player) updateammo; + + void(player, int) predraw; /* predraw... */ + void(player) postdraw; /* postdraw... */ + + int(player) isempty; /* kinda handy */ + void(player, int, vector, float) hudpic; +} weapon_t; + +void Weapons_Holster(player pl); +void Weapons_Primary(player pl); +void Weapons_Secondary(player pl); +void Weapons_Reload(player pl); +void Weapons_Release(player pl); +void Weapons_PreDraw(player pl, int); + +float Weapons_GetAim(player, int); +int Weapons_IsEmpty(player, int); +void Weapons_DrawCrosshair(player pl); +void Weapons_MakeVectors(player pl); +vector Weapons_GetCameraPos(player pl); +void Weapons_ViewAnimation(player pl, int); +void Weapons_ViewPunchAngle(player pl, vector); +int Weapons_IsPresent(player, int); +void Weapons_UpdateAmmo(player, int, int, int); +int Weapons_GetAnimation(player pl); +void Weapons_EnableModel(void); +void Weapons_DisableModel(void); +weapontype_t Weapons_GetType(player, int); + +void Weapons_SetLeftModel(string); +void Weapons_SetRightModel(string); + +void Weapons_SetRightGeomset(string); +void Weapons_SetLeftGeomset(string); + +/* compat */ +void Weapons_SetGeomset(string); +void Weapons_SetModel(string); + +void Weapons_Sound(entity, float, string); + +#ifdef CLIENT +string Weapons_GetPlayermodel(player, int); +void Weapons_HUDPic(player, int, int, vector, float); +#endif +#else +#endif \ No newline at end of file diff --git a/src/shared/weapon_common.qc b/src/shared/weapon_common.qc new file mode 100644 index 0000000..154aba0 --- /dev/null +++ b/src/shared/weapon_common.qc @@ -0,0 +1,478 @@ +/* + * Copyright (c) 2016-2022 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef NEW_INVENTORY +var int g_weapon_weights[g_weapons.length]; + +#ifdef CLIENT +var int g_weapon_order[g_weapons.length]; +#endif + +void +Weapons_Init(void) +{ + /* in the future we'll have no internal weapon table, then this will fill + * one up... */ + /*searchhandle sh; + filestream fh; + string line; + sh = search_begin("scripts/weapon_*.txt", TRUE, TRUE); + for (int i = 0; i < search_getsize(sh); i++) { + fh = fopen(search_getfilename(sh, i), FILE_READ); + if (fh < 0) { + continue; + } + + while ((line = fgets(fh))) { + int w = tokenize(line); + switch (argv(0)) { + case "name": + break; + case "slot": + break; + case "slot_pos": + break; + } + } + fclose(fh); + }*/ + + for (int i = 0; i < g_weapons.length; i++) + if (g_weapons[i].precache != __NULL__) + g_weapons[i].precache(); + + /* check our weapon weights */ + int max = 0; + for (int i = 0; i < g_weapons.length; i++) + if (g_weapons[i].weight > max) + max = g_weapons[i].weight; + + /* don't bother building the list if we've got no weights */ + if (max <= 0) + return; + + /* position in the weight array */ + int w = 0; + + /* loop through all weights */ + for (int b = 0; b <= max; b++) { + /* loop through all weapons */ + for (int i = 0; i < g_weapons.length; i++) { + /* if we've found a valid weight, add the weapon to the list */ + if (g_weapons[i].weight == b) { + g_weapon_weights[w] = i; + w++; + } + } + } + +#if 0 + for (int i = 0; i < g_weapons.length; i++) + print(sprintf("Weapon-Weight order: %s, %i\n", g_weapons[g_weapon_weights[i]].name, i)); +#endif + +#ifdef CLIENT + /* build our slot-order table */ + int st = 0; + + int max_slots = 0; + for (int i = 0; i < g_weapons.length; i++) + if (g_weapons[i].slot > max_slots) + max_slots = g_weapons[i].slot; + int max_pos = 0; + for (int i = 0; i < g_weapons.length; i++) + if (g_weapons[i].slot_pos > max_pos) + max_pos = g_weapons[i].slot_pos; + + /* loop through all slots */ + for (int s = 0; s <= max_slots; s++) { + /* loop through all positions */ + for (int p = 0; p < max_pos; p++) { + /* loop through all the weapons */ + for (int i = 0; i < g_weapons.length; i++) { + if (g_weapons[i].slot == s && g_weapons[i].slot_pos == p) { + g_weapon_order[st] = i; + st++; + } + } + } + } +#if 0 + for (int i = 0; i < g_weapons.length; i++) + print(sprintf("Weapon-List order: %s, %i\n", g_weapons[g_weapon_order[i]].name, i)); +#endif +#endif +} + +void +Weapons_SetLeftModel(string mdl) +{ +#ifdef CLIENT + setmodel(pSeat->m_eViewModelL, mdl); + setsize(pSeat->m_eViewModelL, [0,0,0], [0,0,0]); + pSeat->m_eViewModelL.effects |= EF_NOSHADOW; +#endif +} +void +Weapons_SetRightModel(string mdl) +{ +#ifdef CLIENT + setmodel(pSeat->m_eViewModel, mdl); + setsize(pSeat->m_eViewModel, [0,0,0], [0,0,0]); + pSeat->m_eViewModel.effects |= EF_NOSHADOW; +#endif +} + +void +Weapons_SetModel(string mdl) +{ + Weapons_SetRightModel(mdl); + Weapons_SetLeftModel(""); +} + +void +Weapons_SetRightGeomset(string set) +{ +#ifdef CLIENT + setcustomskin(pSeat->m_eViewModel, "", set); +#endif +} +void +Weapons_SetLeftGeomset(string set) +{ +#ifdef CLIENT + setcustomskin(pSeat->m_eViewModelL, "", set); +#endif +} + +void +Weapons_SetGeomset(string set) +{ + Weapons_SetRightGeomset(set); +} + +void +Weapons_Draw(player pl) +{ + int i = pl.activeweapon; + + /* In case the previous weapon hid the model */ + Weapons_EnableModel(); + + pl.w_attack_next = 0.5f; + pl.w_idle_next = 2.5f; + pl.viewzoom = 1.0f; + + /* we're meant to respawn when we're dead, don't unset! */ + if (pl.health > 0) { + pl.think = __NULL__; + pl.nextthink = 0.0f; + } + + /* make sure this is all wiped */ + pl.a_ammo1 = pl.a_ammo2 = pl.a_ammo3 = 0; + + if (g_weapons[i].draw != __NULL__) + g_weapons[i].draw(pl); + + if (g_weapons[i].updateammo != __NULL__) + g_weapons[i].updateammo(pl); + + pl.gflags |= GF_SEMI_TOGGLED; +} + +void +Weapons_Holster(player pl) +{ + int i = pl.activeweapon; + + if (g_weapons[i].holster != __NULL__) + g_weapons[i].holster(pl); +} + +void +Weapons_Primary(player pl) +{ + int i = pl.activeweapon; + + if (pl.gflags & GF_SEMI_TOGGLED) + return; + + if (g_weapons[i].primary != __NULL__) + g_weapons[i].primary(pl); + + if (g_weapons[i].updateammo != __NULL__) + g_weapons[i].updateammo(pl); +} + +void +Weapons_AmmoUpdate(entity target) +{ + player pl = (player)target; + int i = pl.activeweapon; + + if (g_weapons[i].updateammo != __NULL__) + g_weapons[i].updateammo(pl); + +} + +void +Weapons_Secondary(player pl) +{ + int i = pl.activeweapon; + + if (g_weapons[i].secondary != __NULL__) + g_weapons[i].secondary(pl); + + if (g_weapons[i].updateammo != __NULL__) + g_weapons[i].updateammo(pl); +} + +void +Weapons_Reload(player pl) +{ + int i = pl.activeweapon; + + if (g_weapons[i].reload != __NULL__) + g_weapons[i].reload(pl); + + if (g_weapons[i].updateammo != __NULL__) + g_weapons[i].updateammo(pl); +} + +void +Weapons_Release(player pl) +{ + int i = pl.activeweapon; + + if (g_weapons[i].release != __NULL__) + g_weapons[i].release(pl); + + pl.gflags &= ~GF_SEMI_TOGGLED; +} + +void +Weapons_PreDraw(player pl, int thirdperson) +{ + int i = pl.activeweapon; + + if (g_weapons[i].predraw != __NULL__) + g_weapons[i].predraw(pl, thirdperson); +} + +int +Weapons_IsEmpty(player pl, int w) +{ + int r = 0; + + entity oself = self; + self = pl; + + if (g_weapons[w].isempty != __NULL__) + r = g_weapons[w].isempty(pl); + + self = oself; + + return (r); +} + + +weapontype_t +Weapons_GetType(player pl, int w) +{ + weapontype_t r = WPNTYPE_INVALID; + + entity oself = self; + self = pl; + + if (g_weapons[w].type != __NULL__) + r = g_weapons[w].type(pl); + + self = oself; + + return (r); +} + +void +Weapons_DrawCrosshair(player pl) +{ + int i = pl.activeweapon; + + if (g_weapons[i].postdraw != __NULL__) + g_weapons[i].postdraw(pl); +} + +string +Weapons_GetWorldmodel(int id) +{ + if (g_weapons[id].wmodel != __NULL__) + return g_weapons[id].wmodel(); + + return ""; +} + +string +Weapons_GetPlayermodel(player pl, int id) +{ + if (g_weapons[id].pmodel != __NULL__) + return g_weapons[id].pmodel(pl); + + return ""; +} + +string +Weapons_GetDeathmessage(int id) +{ + if (g_weapons[id].deathmsg != __NULL__) + return g_weapons[id].deathmsg(); + + return ""; +} + +float +Weapons_GetAim(player pl, int id) +{ + if (g_weapons[id].aimanim != __NULL__) + return g_weapons[id].aimanim(pl); + + return (0); +} + +#ifdef CLIENT +void +Weapons_HUDPic(player pl, int id, int s, vector pos, float a) +{ + if (g_weapons[id].hudpic != __NULL__) + g_weapons[id].hudpic(pl, s, pos, a); +} +#endif + +void +Weapons_MakeVectors(player pl) +{ +#ifdef SERVER + makevectors(pl.v_angle); +#else + makevectors(view_angles); +#endif +} + +vector +Weapons_GetCameraPos(player pl) +{ +#ifdef SERVER + return (pl.origin + pl.view_ofs); +#else + return getproperty(VF_ORIGIN); +#endif +} + +void +Weapons_ViewAnimation(player pl, int i) +{ +#if 0 + View_PlayAnimation(i); +#endif + pl.weaponframe = i; + pl.weapontime = 0.0f; +} + +#ifdef CLIENT +int View_GetAnimation(void); +#endif + +int +Weapons_GetAnimation(player pl) +{ + return pl.weaponframe; +} + +void +Weapons_ViewPunchAngle(player pl, vector add) +{ + pl.punchangle += add; +} + +int +Weapons_IsPresent(player pl, int w) +{ + if (pl.g_items & g_weapons[w].id) { + return (1); + } else { + return (0); + } +} + +void +Weapons_EnableModel(void) +{ +#ifdef CLIENT + View_EnableViewmodel(); +#endif +} + +void +Weapons_DisableModel(void) +{ +#ifdef CLIENT + View_DisableViewmodel(); +#endif +} + +/* +================= +Weapons_UpdateAmmo + +Sets .a_ammoX fields and clamps them so they can be networked as a single byte. +================= +*/ +void +Weapons_UpdateAmmo(player pl, int a1, int a2, int a3) +{ + /* no change */ + if (a1 == -1) + a1 = pl.a_ammo1; + if (a2 == -1) + a2 = pl.a_ammo2; + if (a3 == -1) + a3 = pl.a_ammo3; + + /* networked as bytes, since we don't need more. Clamp to avoid errors */ + pl.a_ammo1 = a1; + pl.a_ammo2 = a2; + pl.a_ammo3 = a3; +} + +void +Weapons_Sound(entity pl, float channel, string snd) +{ +#if 0 +#ifdef SERVER + float prev = pl.dimension_see; + pl.dimension_see=0; + Sound_Play(pl, channel, snd); + pl.dimension_see = prev; +#else + /* client side == immediately */ + Sound_Play(pl, channel, snd); +#endif +#else + #ifdef SERVER + Sound_Play(pl, channel, snd); + #endif +#endif +} +#endif \ No newline at end of file