From 86daed3eecfda4135695468eb59748967aef37fc Mon Sep 17 00:00:00 2001 From: Marco Hladik Date: Tue, 22 Dec 2020 01:56:44 +0100 Subject: [PATCH] Added a stripped down base game tree, which should pose as a decent entry-point for starters into the SDK --- build_engine.sh | 14 +- default.fmf | 31 +++ src/Makefile | 15 +- src/client/base/Makefile | 5 + src/client/base/cmds.c | 27 ++ src/client/base/defs.h | 105 ++++++++ src/client/base/entities.c | 26 ++ src/client/base/game_event.c | 36 +++ src/client/base/hud.c | 34 +++ src/client/base/hud_weaponselect.c | 50 ++++ src/client/base/init.c | 37 +++ src/client/base/input.c | 29 +++ src/client/base/player.c | 149 +++++++++++ src/client/base/predict.c | 25 ++ src/client/base/progs.src | 35 +++ src/client/base/scoreboard.c | 168 ++++++++++++ src/client/base/view.c | 51 ++++ src/gs-entbase/client/sky_camera.cpp | 1 - src/server/base/Makefile | 5 + src/server/base/client.c | 75 ++++++ src/server/base/damage.c | 166 ++++++++++++ src/server/base/defs.h | 18 ++ src/server/base/flashlight.c | 42 +++ src/server/base/gamerules.cpp | 197 ++++++++++++++ src/server/base/gamerules.h | 47 ++++ src/server/base/gamerules_multiplayer.cpp | 116 +++++++++ src/server/base/gamerules_singleplayer.cpp | 74 ++++++ src/server/base/input.c | 71 ++++++ src/server/base/items.cpp | 82 ++++++ src/server/base/items.h | 30 +++ src/server/base/player.c | 180 +++++++++++++ src/server/base/progs.src | 40 +++ src/server/base/rules.c | 20 ++ src/server/base/server.c | 33 +++ src/server/base/spawn.c | 37 +++ src/server/base/spectator.c | 28 ++ src/shared/base/animations.c | 47 ++++ src/shared/base/animations.h | 18 ++ src/shared/base/flags.h | 40 +++ src/shared/base/fx_blood.c | 48 ++++ src/shared/base/fx_breakmodel.c | 28 ++ src/shared/base/fx_explosion.c | 29 +++ src/shared/base/fx_gibhuman.c | 30 +++ src/shared/base/fx_impact.c | 30 +++ src/shared/base/fx_spark.c | 44 ++++ src/shared/base/include.src | 21 ++ src/shared/base/items.h | 16 ++ src/shared/base/player.cpp | 34 +++ src/shared/base/pmove.c | 69 +++++ src/shared/base/pmove_water.c | 78 ++++++ src/shared/base/weapon_common.c | 283 +++++++++++++++++++++ src/shared/base/weapon_common.h | 57 +++++ src/shared/base/weapons.c | 20 ++ src/shared/base/weapons.h | 21 ++ src/shared/sound.c | 8 +- 55 files changed, 3006 insertions(+), 14 deletions(-) create mode 100644 default.fmf create mode 100644 src/client/base/Makefile create mode 100644 src/client/base/cmds.c create mode 100644 src/client/base/defs.h create mode 100644 src/client/base/entities.c create mode 100644 src/client/base/game_event.c create mode 100644 src/client/base/hud.c create mode 100644 src/client/base/hud_weaponselect.c create mode 100644 src/client/base/init.c create mode 100644 src/client/base/input.c create mode 100644 src/client/base/player.c create mode 100644 src/client/base/predict.c create mode 100755 src/client/base/progs.src create mode 100644 src/client/base/scoreboard.c create mode 100644 src/client/base/view.c create mode 100644 src/server/base/Makefile create mode 100644 src/server/base/client.c create mode 100644 src/server/base/damage.c create mode 100644 src/server/base/defs.h create mode 100644 src/server/base/flashlight.c create mode 100644 src/server/base/gamerules.cpp create mode 100644 src/server/base/gamerules.h create mode 100644 src/server/base/gamerules_multiplayer.cpp create mode 100644 src/server/base/gamerules_singleplayer.cpp create mode 100644 src/server/base/input.c create mode 100644 src/server/base/items.cpp create mode 100644 src/server/base/items.h create mode 100644 src/server/base/player.c create mode 100755 src/server/base/progs.src create mode 100644 src/server/base/rules.c create mode 100644 src/server/base/server.c create mode 100644 src/server/base/spawn.c create mode 100644 src/server/base/spectator.c create mode 100755 src/shared/base/animations.c create mode 100644 src/shared/base/animations.h create mode 100644 src/shared/base/flags.h create mode 100644 src/shared/base/fx_blood.c create mode 100644 src/shared/base/fx_breakmodel.c create mode 100755 src/shared/base/fx_explosion.c create mode 100644 src/shared/base/fx_gibhuman.c create mode 100644 src/shared/base/fx_impact.c create mode 100644 src/shared/base/fx_spark.c create mode 100644 src/shared/base/include.src create mode 100644 src/shared/base/items.h create mode 100644 src/shared/base/player.cpp create mode 100644 src/shared/base/pmove.c create mode 100644 src/shared/base/pmove_water.c create mode 100644 src/shared/base/weapon_common.c create mode 100644 src/shared/base/weapon_common.h create mode 100644 src/shared/base/weapons.c create mode 100644 src/shared/base/weapons.h diff --git a/build_engine.sh b/build_engine.sh index a41441e2..fe72a778 100755 --- a/build_engine.sh +++ b/build_engine.sh @@ -2,6 +2,7 @@ set -e FTE_MAKEFILE=./src/engine/engine/Makefile +BUILD_SDL2=0 mkdir -p ./bin @@ -17,9 +18,16 @@ else cd ./engine/engine fi -make -j $(nproc) makelibs FTE_TARGET=SDL2 -make -j $(nproc) m-rel FTE_TARGET=SDL2 -cp -v ./release/fteqw-sdl2 ../../../bin/fteqw +if [ "$BUILD_SDL2" -eq 1 ]; then + make -j $(nproc) makelibs FTE_TARGET=SDL2 + make -j $(nproc) m-rel FTE_TARGET=SDL2 + cp -v ./release/fteqw-sdl2 ../../../bin/fteqw +else + make -j $(nproc) makelibs + make -j $(nproc) m-rel + cp -v ./release/fteqw ../../../bin/fteqw +fi + make -j $(nproc) sv-rel cp -v ./release/fteqw-sv ../../../bin/fteqw-sv make -j $(nproc) qcc-rel diff --git a/default.fmf b/default.fmf new file mode 100644 index 00000000..5ca634c4 --- /dev/null +++ b/default.fmf @@ -0,0 +1,31 @@ +FTEMANIFEST 1 +GAME base +NAME "Nuclide" +BASEGAME platform +BASEGAME logos +BASEGAME base + +// custom game menu variables +-set gameinfo_game "Nuclide Base" +-set gameinfo_gamedir "base" +-set gameinfo_fallback_dir "" +-set gameinfo_mpentity "info_player_deathmatch" +-set gameinfo_size "1000080" +-set gameinfo_url_info "www.vera-visions.com" +-set gameinfo_version "1.0" +-set gameinfo_url_dl "" +-set gameinfo_type "Both" +-set gameinfo_nomodels 0 +-set gameinfo_gamedll "progs.dat" +-set gameinfo_startmap "c0a0" +-set gameinfo_trainingmap "map t0a0" +-set gameinfo_cldll 1 +-set gameinfo_hlversion "1110" +-set gameinfo_svonly "0" +-set gameinfo_menutrack "" +-set gameinfo_chatroom "lobby" + +// you don't really want to change these +RTCBROKER master.frag-net.com:27950 +PROTOCOLNAME "Nuclide" +MAINCONFIG nuclide.cfg diff --git a/src/Makefile b/src/Makefile index a26bb5ba..0fe6d9de 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,12 +1,20 @@ all: make menu + make base + make plugs make games make mods - make plugs menu: cd menu-fn && $(MAKE) +base: + cd client/base && $(MAKE) + cd server/base && $(MAKE) + +plugs: + cd plugins && $(MAKE) + games: cd client/valve && $(MAKE) cd server/valve && $(MAKE) @@ -16,8 +24,6 @@ games: cd server/rewolf && $(MAKE) cd client/gearbox && $(MAKE) cd server/gearbox && $(MAKE) - #cd client/wastes && $(MAKE) - #cd server/wastes && $(MAKE) mods: cd client/cstrike && $(MAKE) @@ -28,6 +34,3 @@ mods: cd server/poke646 && $(MAKE) cd client/hunger && $(MAKE) cd server/hunger && $(MAKE) - -plugs: - cd plugins && $(MAKE) diff --git a/src/client/base/Makefile b/src/client/base/Makefile new file mode 100644 index 00000000..f06fc8c2 --- /dev/null +++ b/src/client/base/Makefile @@ -0,0 +1,5 @@ +CC=fteqcc + +all: + mkdir -p ../../../base/data.pk3dir + $(CC) progs.src diff --git a/src/client/base/cmds.c b/src/client/base/cmds.c new file mode 100644 index 00000000..1b013af8 --- /dev/null +++ b/src/client/base/cmds.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* This is where custom game-specific commands go! + * You'll also inherit all the commands defined in entry.c */ +int +Game_ConsoleCommand(void) +{ + switch(argv(0)) { + default: + return FALSE; + } + return TRUE; +} diff --git a/src/client/base/defs.h b/src/client/base/defs.h new file mode 100644 index 00000000..698af0af --- /dev/null +++ b/src/client/base/defs.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +vector g_hud_color; +vector g_hudmins; +vector g_hudres; + +struct +{ + /* viewmodel stuff */ + entity m_eViewModel; + entity m_eMuzzleflash; + int m_iVMBones; + int m_iVMEjectBone; + int m_iLastWeapon; + int m_iOldWeapon; + float m_flBobTime; + float m_flBob; + + /* damage overlay */ + float m_flDamageAlpha; + vector m_vecDamagePos; + + /* +zoomin cmd */ + int m_iZoomed; + float m_flZoomTime; + + /* player fields */ + entity m_ePlayer; + vector m_vecPredictedOrigin; + vector m_vecPredictedOriginOld; + vector m_vecPredictedVelocity; + float m_flPredictedFlags; + + /* camera fields */ + vector m_vecCameraOrigin; + vector m_vecCameraAngle; + float m_flCameraTime; + + /* hud.c */ + int m_iHealthOld; + float m_flHealthAlpha; + int m_iArmorOld; + float m_flArmorAlpha; + int m_iAmmo1Old; + float m_flAmmo1Alpha; + int m_iAmmo2Old; + float m_flAmmo2Alpha; + int m_iAmmo3Old; + float m_flAmmo3Alpha; + int m_iPickupWeapon; + float m_flPickupAlpha; + + int m_iScoresVisible; + int m_iHUDWeaponSelected; + float m_flHUDWeaponSelectTime; + + /* centerprint related */ + float m_flCenterprintAlpha; + float m_flCenterprintTime; + float m_iCenterprintLines; + string m_strCenterprintBuffer[18]; + + /* chat related */ + float m_flPrintTime; + string m_strPrintBuffer[5]; + int m_iPrintLines; + + int m_iInputAttack2; + int m_iInputReload; + int m_iInputUse; + int m_iInputDuck; + float m_flInputBlockTime; + + /* fading */ + float m_flFadeDuration; + float m_flFadeHold; + float m_flFadeMaxAlpha; + float m_flFadeStyle; + float m_flFadeAlpha; + float m_flFadeTime; + vector m_vecFadeColor; + int m_iFadeActive; + + /* shake */ + float m_flShakeFreq; + float m_flShakeDuration; + float m_flShakeTime; + float m_flShakeAmp; + + entity m_pWeaponFX; +} g_seats[4], *pSeat; diff --git a/src/client/base/entities.c b/src/client/base/entities.c new file mode 100644 index 00000000..5c4f4a57 --- /dev/null +++ b/src/client/base/entities.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +int +Game_Entity_Update(float id, float new) +{ + switch (id) { + default: + return FALSE; + } + + return TRUE; +} diff --git a/src/client/base/game_event.c b/src/client/base/game_event.c new file mode 100644 index 00000000..df7a786f --- /dev/null +++ b/src/client/base/game_event.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +void +Game_Parse_Event(float fHeader) +{ + switch (fHeader) { + case EV_CHAT: + float fSender = readbyte(); + float fTeam = readbyte(); + string sMessage = readstring(); + + CSQC_Parse_Print(sprintf("%s: %s", getplayerkeyvalue(fSender, "name"), sMessage), PRINT_CHAT); + break; + case EV_CHAT_TEAM: + float fSender2 = readbyte(); + float fTeam2 = readbyte(); + string sMessage2 = readstring(); + + CSQC_Parse_Print(sprintf("[TEAM] %s: %s", getplayerkeyvalue(fSender2, "name"), sMessage2), PRINT_CHAT); + break; + } +} diff --git a/src/client/base/hud.c b/src/client/base/hud.c new file mode 100644 index 00000000..6723aec5 --- /dev/null +++ b/src/client/base/hud.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* main entry */ +void +HUD_Init(void) +{ +} + +/* main entry */ +void +HUD_Draw(void) +{ +} + +/* specatator main entry */ +void +HUD_DrawSpectator(void) +{ + // FIXME +} diff --git a/src/client/base/hud_weaponselect.c b/src/client/base/hud_weaponselect.c new file mode 100644 index 00000000..f79e20ff --- /dev/null +++ b/src/client/base/hud_weaponselect.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +void +HUD_DrawWeaponSelect_Forward(void) +{ + +} + +void +HUD_DrawWeaponSelect_Back(void) +{ + +} + +void +HUD_DrawWeaponSelect_Trigger(void) +{ +} + +void +HUD_DrawWeaponSelect_Last(void) +{ + +} + +void +HUD_SlotSelect(int slot) +{ + +} + +void +HUD_DrawWeaponSelect(void) +{ + +} diff --git a/src/client/base/init.c b/src/client/base/init.c new file mode 100644 index 00000000..9fcd7217 --- /dev/null +++ b/src/client/base/init.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* +================= +Client_Init + +Comparable to worldspawn in SSQC in that it's mostly used for precaches +================= +*/ +void +Client_Init(float apilevel, string enginename, float engineversion) +{ +} + +void +Client_InitDone(void) +{ +} + +void +Game_RendererRestarted(string rstr) +{ +} diff --git a/src/client/base/input.c b/src/client/base/input.c new file mode 100644 index 00000000..63e1d2d0 --- /dev/null +++ b/src/client/base/input.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +void +Game_Input(void) +{ + if (input_buttons & INPUT_BUTTON0) { + Weapons_Primary(); + } else if (input_buttons & INPUT_BUTTON4) { + Weapons_Reload(); + } else if (input_buttons & INPUT_BUTTON3) { + Weapons_Secondary(); + } else { + Weapons_Release(); + } +} diff --git a/src/client/base/player.c b/src/client/base/player.c new file mode 100644 index 00000000..e970f1c4 --- /dev/null +++ b/src/client/base/player.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +void +Player_PreDraw(base_player pl, int thirdperson) +{ + /* Handle the flashlights... */ + if (pl.gflags & GF_FLASHLIGHT) { + vector src; + vector ang; + + if (pl.entnum != player_localentnum) { + src = pl.origin + pl.view_ofs; + ang = [pl.pitch, pl.angles[1], pl.angles[2]]; + } else { + src = pSeat->m_vecPredictedOrigin + [0,0,-8]; + ang = view_angles; + } + + makevectors(ang); + traceline(src, src + (v_forward * 8096), MOVE_NORMAL, pl); + + if (serverkeyfloat("*bspversion") == BSPVER_HL) { + dynamiclight_add(trace_endpos + (v_forward * -2), 128, [1,1,1]); + } else { + float p = dynamiclight_add(src, 512, [1,1,1], 0, "textures/flashlight"); + dynamiclight_set(p, LFIELD_ANGLES, ang); + dynamiclight_set(p, LFIELD_FLAGS, 3); + } + } +} + +void +Player_ReceiveEntity(float new) +{ + float fl; + player pl = (player)self; + + if (new == TRUE) { + spawnfunc_player(); + pl.classname = "player"; + pl.solid = SOLID_SLIDEBOX; + pl.drawmask = MASK_ENGINE; + pl.customphysics = Empty; + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + } else { + /* Go through all the physics code between the last received frame + * and the newest frame and keep the changes this time around instead + * of rolling back, because we'll apply the new server-verified values + * right after anyway. */ + /* FIXME: splitscreen */ + if (pl.entnum == player_localentnum) { + /* FIXME: splitscreen */ + pSeat = &g_seats[0]; + + for (int i = pl.sequence+1; i <= servercommandframe; i++) { + /* ...maybe the input state is too old? */ + if (!getinputstate(i)) { + break; + } + input_sequence = i; + PMove_Run(); + } + + /* any differences in things that are read below are now + * officially from prediction misses. */ + } + } + + /* seed for our prediction table */ + pl.sequence = servercommandframe; + + fl = readfloat(); + + /* HACK: we need to make this more reliable */ + if (fl == UPDATE_ALL) { + /* we respawned */ + pl.gravity = __NULL__; + } + + if (fl & PLAYER_MODELINDEX) + pl.modelindex = readshort(); + + if (fl & PLAYER_ORIGIN) { + pl.origin[0] = readcoord(); + pl.origin[1] = readcoord(); + } + + if (fl & PLAYER_ORIGIN_Z) + pl.origin[2] = readcoord(); + if (fl & PLAYER_ANGLES_X) + pl.pitch = readfloat(); + if (fl & PLAYER_ANGLES_Y) + pl.angles[1] = readfloat(); + if (fl & PLAYER_ANGLES_Z) + pl.angles[2] = readfloat(); + + if (fl & PLAYER_VELOCITY) { + pl.velocity[0] = readcoord(); + pl.velocity[1] = readcoord(); + } + + if (fl & PLAYER_VELOCITY_Z) + pl.velocity[2] = readcoord(); + if (fl & PLAYER_FLAGS) { + pl.flags = readfloat(); + pl.gflags = readfloat(); + } + if (fl & PLAYER_WEAPON) + pl.activeweapon = readbyte(); + if (fl & PLAYER_ITEMS) + pl.g_items = (__variant)readfloat(); + if (fl & PLAYER_HEALTH) + pl.health = readbyte(); + if (fl & PLAYER_ARMOR) + pl.armor = readbyte(); + if (fl & PLAYER_MOVETYPE) + pl.movetype = readbyte(); + if (fl & PLAYER_VIEWOFS) + pl.view_ofs[2] = readfloat(); + if (fl & PLAYER_BASEFRAME) + pl.baseframe = readbyte(); + if (fl & PLAYER_FRAME) { + pl.frame = readbyte(); + pl.frame1time = 0.0f; + pl.frame2time = 0.0f; + } + if (fl & PLAYER_AMMO1) + pl.a_ammo1 = readbyte(); + if (fl & PLAYER_AMMO2) + pl.a_ammo2 = readbyte(); + if (fl & PLAYER_AMMO3) + pl.a_ammo3 = readbyte(); + + setorigin(pl, pl.origin); +} diff --git a/src/client/base/predict.c b/src/client/base/predict.c new file mode 100644 index 00000000..5aea1382 --- /dev/null +++ b/src/client/base/predict.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +void +GamePredict_PreFrame(player pl) +{ +} + +void +GamePredict_PostFrame(player pl) +{ +} diff --git a/src/client/base/progs.src b/src/client/base/progs.src new file mode 100755 index 00000000..c42c335b --- /dev/null +++ b/src/client/base/progs.src @@ -0,0 +1,35 @@ +#pragma target fte +#pragma progs_dat "../../../base/data.pk3dir/csprogs.dat" + +#define CSQC +#define CLIENT +#define CLASSIC_VGUI +#define GS_RENDERFX + +#includelist +../../shared/fteextensions.qc +../../shared/defs.h +../base/defs.h +../defs.h + +../../vgui/include.src + +../../gs-entbase/client.src +../../gs-entbase/shared.src +../../shared/base/include.src + +../base/predict.c +../base/init.c +../base/player.c +../base/entities.c +../base/cmds.c +../base/game_event.c +../base/view.c +../base/hud.c +../base/hud_weaponselect.c +../base/scoreboard.c +../base/input.c + +../include.src +../../shared/include.src +#endlist diff --git a/src/client/base/scoreboard.c b/src/client/base/scoreboard.c new file mode 100644 index 00000000..57b23dca --- /dev/null +++ b/src/client/base/scoreboard.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define SCORE_HEADER_C [255/255,156/255,0] +#define SCORE_LINE_C [255/255,200/255,0] + +var int autocvar_cl_centerscores = FALSE; +var int g_scores_teamplay = 0; + +void +Scores_Init(void) +{ + g_scores_teamplay = (int)serverkeyfloat("teamplay"); +} + +void +Scores_DrawTeam(player pl, vector pos) +{ + drawfill(pos, [290, 1], SCORE_LINE_C, 1.0f, DRAWFLAG_ADDITIVE); + + drawfont = FONT_20; + drawstring(pos + [0,-18], "Teams", [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 t = 1; t <= serverkeyfloat("teams"); t++) { + float l; + string temp; + drawstring(pos, serverkey(sprintf("team_%i", t)), [20,20], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE); + temp = serverkey(sprintf("teamscore_%i", t)); + l = stringwidth(temp, FALSE, [20,20]); + drawstring(pos + [150-l, 0], temp, [20,20], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE); + drawstring(pos + [158, 0], "wins", [20,20], SCORE_HEADER_C, 1.0f, DRAWFLAG_ADDITIVE); + pos[1] += 16; + + for (int i = -1; i > -32; i--) { + if (getplayerkeyfloat(i, "*team") != t) { + continue; + } + + temp = getplayerkeyvalue(i, "name"); + + /* Out of players */ + if (!temp) { + break; + } else if (temp == getplayerkeyvalue(pl.entnum-1, "name")) { + drawfill(pos, [290, 13], [0,0,1], 0.5f, DRAWFLAG_ADDITIVE); + } + + drawstring(pos + [24,0], 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 */ + temp = getplayerkeyvalue(i, "frags"); + l = stringwidth(temp, FALSE, [20,20]); + drawstring(pos + [150 - l,0], temp, [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE); + + /* Deaths are right to left aligned */ + temp = getplayerkeyvalue(i, "*deaths"); + drawstring(pos + [165,0], temp, [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE); + + /* Get the latency and align it left to right */ + temp = getplayerkeyvalue(i, "ping"); + l = stringwidth(temp, FALSE, [20,20]); + + drawstring(pos + [290 - l,0], temp, [20,20], [1,1,1], 1.0f, DRAWFLAG_ADDITIVE); + pos[1] += 20; + } + pos[1] += 12; + } + + drawfont = FONT_CON; +} + +void +Scores_DrawNormal(player pl, vector pos) +{ + 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; +} + +void +Scores_Draw(void) +{ + vector pos; + player pl; + + pl = (player)pSeat->m_ePlayer; + + if (autocvar_cl_centerscores) { + int c = 10; + + /* calculate all valid entries */ + for (int i = -1; i > -32; i--) { + if (getplayerkeyvalue(i, "name")) { + break; + } + c += 10; + } + pos = video_mins + [(video_res[0] / 2) - 145, (video_res[1] / 2) - c]; + } else { + pos = video_mins + [(video_res[0] / 2) - 145, 30]; + } + + if (serverkeyfloat("teams") > 0) { + Scores_DrawTeam(pl, pos); + } else { + Scores_DrawNormal(pl, pos); + } +} diff --git a/src/client/base/view.c b/src/client/base/view.c new file mode 100644 index 00000000..55921816 --- /dev/null +++ b/src/client/base/view.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +void +View_UpdateWeapon(entity vm, entity mflash) +{ + player pl = (player)pSeat->m_ePlayer; + + /* only bother upon change */ + if (pSeat->m_iLastWeapon == pl.activeweapon) { + return; + } + pSeat->m_iOldWeapon = pSeat->m_iLastWeapon; + pSeat->m_iLastWeapon = pl.activeweapon; + + if (!pl.activeweapon) { + return; + } + + /* hack, we changed the wep, move this into Game_Input/PMove */ + Weapons_Draw(); + + /* we forced a weapon call outside the prediction, + * thus we need to update all the net variables to + * make sure these updates are recognized. this is + * vile but it'll have to do for now */ + pl.net_w_attack_next = pl.w_attack_next; + pl.net_w_idle_next = pl.w_idle_next; + pl.net_viewzoom = pl.viewzoom; + pl.net_weapontime = pl.weapontime; + + /* figure out when the attachments start. in FTE attachments for + * HLMDL are treated as bones. they start at numbones + 1 */ + skel_delete(mflash.skeletonindex); + mflash.skeletonindex = skel_create(vm.modelindex); + pSeat->m_iVMBones = skel_get_numbones(mflash.skeletonindex) + 1; + pSeat->m_iVMEjectBone = pSeat->m_iVMBones + 1; +} diff --git a/src/gs-entbase/client/sky_camera.cpp b/src/gs-entbase/client/sky_camera.cpp index 9cc74b38..47486485 100644 --- a/src/gs-entbase/client/sky_camera.cpp +++ b/src/gs-entbase/client/sky_camera.cpp @@ -65,7 +65,6 @@ void SkyCamera_Setup(vector org) { if (g_skyscale != 0 && g_skypos) { - vector porg; vector realpos; if (autocvar_dev_skyscale) { diff --git a/src/server/base/Makefile b/src/server/base/Makefile new file mode 100644 index 00000000..f06fc8c2 --- /dev/null +++ b/src/server/base/Makefile @@ -0,0 +1,5 @@ +CC=fteqcc + +all: + mkdir -p ../../../base/data.pk3dir + $(CC) progs.src diff --git a/src/server/base/client.c b/src/server/base/client.c new file mode 100644 index 00000000..2a81dca8 --- /dev/null +++ b/src/server/base/client.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* called every input frame */ +void +Game_RunClientCommand(void) +{ + Footsteps_Update(); + PMove_Run(); +} + +/* custom chat packet */ +void +SV_SendChat(entity sender, string msg, entity eEnt, float fType) +{ + WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); + WriteByte(MSG_MULTICAST, fType == 0 ? EV_CHAT:EV_CHAT_TEAM); + WriteByte(MSG_MULTICAST, num_for_edict(sender) - 1); + WriteByte(MSG_MULTICAST, sender.team); + WriteString(MSG_MULTICAST, msg); + if (eEnt) { + msg_entity = eEnt; + multicast([0,0,0], MULTICAST_ONE); + } else { + multicast([0,0,0], MULTICAST_ALL); + } + + localcmd(sprintf("echo [SERVER] %s: %s\n", sender.netname, msg)); +} + +/* client cmd overrides happen here */ +void +Game_ParseClientCommand(string cmd) +{ + tokenize(cmd); + + if (argv(1) == "timeleft") { + string msg; + string timestring; + float timeleft; + timeleft = cvar("mp_timelimit") - (time / 60); + timestring = Vox_TimeToString(timeleft); + msg = sprintf("we have %s minutes remaining", timestring); + Vox_Singlecast(self, msg); + return; + } + + if (argv(0) == "say") { + SV_SendChat(self, argv(1), world, 0); + return; + } else if (argv(0) == "say_team") { + entity a; + for (a = world; (a = find(a, ::classname, "player"));) { + if (a.team == self.team) { + SV_SendChat(self, argv(1), a, 1); + } + } + return; + } + + clientcommand(self, cmd); +} diff --git a/src/server/base/damage.c b/src/server/base/damage.c new file mode 100644 index 00000000..73cd3804 --- /dev/null +++ b/src/server/base/damage.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* generic function that applies damage, pain and suffering */ +void +Damage_Apply(entity t, entity c, float dmg, int w, int type) +{ + base_player tp = (base_player)t; + + CGameRules rules = (CGameRules)g_grMode; + if (t.flags & FL_GODMODE) { + return; + } + + /* already dead, please avoid recursion */ + if (t.health <= 0) { + return; + } + + /* skip armor */ + if not (type & DMG_SKIP_ARMOR) + if (tp.armor && dmg > 0) { + float flArmor; + float flNewDamage; + + flNewDamage = dmg * 0.2; + flArmor = (dmg - flNewDamage) * 0.5; + + if (flArmor > tp.armor) { + flArmor = tp.armor; + flArmor *= (1/0.5); + flNewDamage = dmg - flArmor; + tp.armor = 0; + } else { + tp.armor -= flArmor; + } + dmg = flNewDamage; + } + + dmg = rint(dmg); + t.health -= dmg; + + /* the globals... */ + g_dmg_eAttacker = c; + g_dmg_eTarget = t; + g_dmg_iDamage = dmg; + g_dmg_iHitBody = trace_surface_id; + g_dmg_iFlags = type; + g_dmg_iWeapon = w; + + if (dmg > 0) { + t.dmg_take = dmg; + t.dmg_inflictor = c; + } else if (t.max_health && t.health > t.max_health) { + t.health = t.max_health; + } + + /* set this global in case we need it later */ + g_eAttacker = c; + + CBaseEntity s = (CBaseEntity)t; + + if (s.health <= 0) { + if (s.flags & FL_CLIENT) { + rules.PlayerDeath((player)s); + } else { + s.Death(); + } + } else { + if (s.flags & FL_CLIENT) { + rules.PlayerPain((player)s); + } else { + s.Pain(); + } + } +} + +/* physical check of whether or not we can trace important parts of an ent */ +float +Damage_CheckTrace(entity t, vector vecHitPos) +{ + /* We're lazy. Who cares */ + if (t.solid == SOLID_BSP) { + return TRUE; + } + + traceline(vecHitPos, t.origin, 1, self); + if (trace_fraction == 1) { + return TRUE; + } + traceline(vecHitPos, t.origin + [15,15,0], 1, self); + if (trace_fraction == 1) { + return TRUE; + } + traceline(vecHitPos, t.origin + [-15,-15,0], 1, self); + if (trace_fraction == 1) { + return TRUE; + } + traceline(vecHitPos, t.origin + [-15,15,0], 1, self); + if (trace_fraction == 1) { + return TRUE; + } + traceline(vecHitPos, t.origin + [15,-15,0], 1, self); + if (trace_fraction == 1) { + return TRUE; + } + + return FALSE; +} + +/* even more pain and suffering, mostly used for explosives */ +void +Damage_Radius(vector org, entity attacker, float dmg, float r, int check, int w) +{ + float new_dmg; + float dist; + float diff; + vector pos; + + for (entity e = world; (e = findfloat(e, ::takedamage, DAMAGE_YES));) { + pos[0] = e.absmin[0] + (0.5 * (e.absmax[0] - e.absmin[0])); + pos[1] = e.absmin[1] + (0.5 * (e.absmax[1] - e.absmin[1])); + pos[2] = e.absmin[2] + (0.5 * (e.absmax[2] - e.absmin[2])); + + /* don't bother if it's not anywhere near us */ + dist = vlen(org - pos); + if (dist > r) { + continue; + } + + /* can we physically hit this thing? */ + if (Damage_CheckTrace(e, org) == FALSE) { + if (check == TRUE) { + continue; + } + } + + /* calculate new damage values */ + diff = vlen(org - pos); + diff = (r - diff) / r; + new_dmg = rint(dmg * diff); + + if (diff > 0) { + Damage_Apply(e, attacker, new_dmg, w, DMG_EXPLODE); + + /* approximate, feel free to tweak */ + if (e.movetype == MOVETYPE_WALK) { + makevectors(vectoangles(e.origin - org)); + e.velocity += v_forward * (new_dmg * 5); + } + } + } +} diff --git a/src/server/base/defs.h b/src/server/base/defs.h new file mode 100644 index 00000000..88c34489 --- /dev/null +++ b/src/server/base/defs.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "gamerules.h" +#include "items.h" diff --git a/src/server/base/flashlight.c b/src/server/base/flashlight.c new file mode 100644 index 00000000..fbdf8278 --- /dev/null +++ b/src/server/base/flashlight.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +void Flashlight_Toggle(void) +{ + if (cvar("sv_playerslots") != 1) { + if (cvar("mp_flashlight") != 1) { + return; + } + } + +#ifdef VALVE + player pl = (player)self; + if (!(pl.g_items & ITEM_SUIT)) { + return; + } +#endif + + if (self.health <= 0) { + return; + } + + if (self.gflags & GF_FLASHLIGHT) { + self.gflags &= ~GF_FLASHLIGHT; + } else { + self.gflags |= GF_FLASHLIGHT; + } + sound(self, CHAN_ITEM, "items/flashlight1.wav", 1, ATTN_IDLE); +} diff --git a/src/server/base/gamerules.cpp b/src/server/base/gamerules.cpp new file mode 100644 index 00000000..c1f8dc4c --- /dev/null +++ b/src/server/base/gamerules.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +var int autocvar_sv_playerkeepalive = TRUE; + +void +GameRules::LevelDecodeParms(base_player pp) +{ + player pl = (player)pp; + g_landmarkpos[0] = parm1; + g_landmarkpos[1] = parm2; + g_landmarkpos[2] = parm3; + pl.angles[0] = parm4; + pl.angles[1] = parm5; + pl.angles[2] = parm6; + pl.velocity[0] = parm7; + pl.velocity[1] = parm8; + pl.velocity[2] = parm9; + pl.g_items = parm10; + pl.activeweapon = parm11; + pl.flags = parm64; + + if (pl.flags & FL_CROUCHING) { + setsize(pl, VEC_CHULL_MIN, VEC_CHULL_MAX); + } else { + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + } +} + +void +GameRules::LevelChangeParms(base_player pp) +{ + player pl = (player)pp; + parm1 = g_landmarkpos[0]; + parm2 = g_landmarkpos[1]; + parm3 = g_landmarkpos[2]; + parm4 = pl.angles[0]; + parm5 = pl.angles[1]; + parm6 = pl.angles[2]; + parm7 = pl.velocity[0]; + parm8 = pl.velocity[1]; + parm9 = pl.velocity[2]; + parm64 = pl.flags; + parm10 = pl.g_items; + parm11 = pl.activeweapon; +} + +void +GameRules::LevelNewParms(void) +{ + parm1 = parm2 = parm3 = parm4 = parm5 = parm6 = parm7 = + parm8 = parm9 = parm10 = parm11 = parm12 = parm13 = parm14 = + parm15 = parm16 = parm17 = parm18 = parm19 = parm20 = parm21 = + parm22 = parm23 = parm24 = parm25 = parm26 = parm27 = parm28 = + parm29 = parm30 = 0; + parm64 = FL_CLIENT; +} + +/* we check what fields have changed over the course of the frame and network + * only the ones that have actually changed */ +void +GameRules::PlayerPostFrame(base_player pl) +{ + Animation_PlayerUpdate(); + + if (autocvar_sv_playerkeepalive) + pl.SendFlags |= PLAYER_KEEPALIVE; + + if (pl.old_modelindex != pl.modelindex) + pl.SendFlags |= PLAYER_MODELINDEX; + + if (pl.old_origin[0] != pl.origin[0]) + pl.SendFlags |= PLAYER_ORIGIN; + + if (pl.old_origin[1] != pl.origin[1]) + pl.SendFlags |= PLAYER_ORIGIN; + + if (pl.old_origin[2] != pl.origin[2]) + pl.SendFlags |= PLAYER_ORIGIN_Z; + + if (pl.old_angles[0] != pl.v_angle[0]) + pl.SendFlags |= PLAYER_ANGLES_X; + + if (pl.old_angles[1] != pl.angles[1]) + pl.SendFlags |= PLAYER_ANGLES_Y; + + if (pl.old_angles[2] != pl.angles[2]) + pl.SendFlags |= PLAYER_ANGLES_Z; + + if (pl.old_velocity[0] != pl.velocity[0]) + pl.SendFlags |= PLAYER_VELOCITY; + + if (pl.old_velocity[1] != pl.velocity[1]) + pl.SendFlags |= PLAYER_VELOCITY; + + if (pl.old_velocity[2] != pl.velocity[2]) + pl.SendFlags |= PLAYER_VELOCITY_Z; + + if (pl.old_flags != pl.flags) + pl.SendFlags |= PLAYER_FLAGS; + + if (pl.old_gflags != pl.gflags) + pl.SendFlags |= PLAYER_FLAGS; + + if (pl.old_activeweapon != pl.activeweapon) + pl.SendFlags |= PLAYER_WEAPON; + + if (pl.old_items != pl.g_items) + pl.SendFlags |= PLAYER_ITEMS; + + if (pl.old_health != pl.health) + pl.SendFlags |= PLAYER_HEALTH; + + if (pl.old_armor != pl.armor) + pl.SendFlags |= PLAYER_ARMOR; + + if (pl.old_movetype != pl.movetype) + pl.SendFlags |= PLAYER_MOVETYPE; + + if (pl.old_viewofs != pl.view_ofs[2]) + pl.SendFlags |= PLAYER_VIEWOFS; + + if (pl.old_baseframe != pl.baseframe) + pl.SendFlags |= PLAYER_BASEFRAME; + + if (pl.old_frame != pl.frame) + pl.SendFlags |= PLAYER_FRAME; + + if (pl.old_a_ammo1 != pl.a_ammo1) + pl.SendFlags |= PLAYER_AMMO1; + + if (pl.old_a_ammo2 != pl.a_ammo2) + pl.SendFlags |= PLAYER_AMMO2; + + if (pl.old_a_ammo3 != pl.a_ammo3) + pl.SendFlags |= PLAYER_AMMO3; + + pl.old_modelindex = pl.modelindex; + pl.old_origin = pl.origin; + pl.old_angles = pl.angles; + pl.old_angles[0] = pl.v_angle[0]; + pl.old_velocity = pl.velocity; + pl.old_flags = pl.flags; + pl.old_gflags = pl.gflags; + pl.old_activeweapon = pl.activeweapon; + pl.old_items = pl.g_items; + pl.old_health = pl.health; + pl.old_armor = pl.armor; + pl.old_movetype = pl.movetype; + pl.old_viewofs = pl.view_ofs[2]; + pl.old_baseframe = pl.baseframe; + pl.old_frame = pl.frame; + pl.old_a_ammo1 = pl.a_ammo1; + pl.old_a_ammo2 = pl.a_ammo2; + pl.old_a_ammo3 = pl.a_ammo3; +} + +void +GameRules::PlayerConnect(base_player pl) +{ + if (Plugin_PlayerConnect(pl) == FALSE) + bprint(PRINT_HIGH, sprintf("%s connected\n", pl.netname)); +} + +void +GameRules::PlayerDisconnect(base_player pl) +{ + if (Plugin_PlayerDisconnect(pl) == FALSE) + bprint(PRINT_HIGH, sprintf("%s disconnected\n", pl.netname)); + + /* Make this unusable */ + pl.solid = SOLID_NOT; + pl.movetype = MOVETYPE_NONE; + pl.modelindex = 0; + pl.health = 0; + pl.takedamage = 0; + pl.SendFlags = -1; +} + +void +GameRules::PlayerKill(base_player pl) +{ + Damage_Apply(pl, pl, pl.health, WEAPON_NONE, DMG_SKIP_ARMOR); +} diff --git a/src/server/base/gamerules.h b/src/server/base/gamerules.h new file mode 100644 index 00000000..9e943db0 --- /dev/null +++ b/src/server/base/gamerules.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +class GameRules:CGameRules +{ + virtual void(base_player) PlayerConnect; + virtual void(base_player) PlayerDisconnect; + virtual void(base_player) PlayerKill; + virtual void(base_player) PlayerPostFrame; + + virtual void(base_player) LevelDecodeParms; + virtual void(base_player) LevelChangeParms; + virtual void(void) LevelNewParms; +}; + +class SingleplayerRules:GameRules +{ + /* client */ + virtual void(base_player) PlayerSpawn; + virtual void(base_player) PlayerDeath; +}; + +class MultiplayerRules:GameRules +{ + int m_iIntermission; + int m_iIntermissionTime; + + virtual void(void) FrameStart; + + /* client */ + virtual void(base_player) PlayerSpawn; + virtual void(base_player) PlayerDeath; + virtual float(base_player, string) ConsoleCommand; +}; diff --git a/src/server/base/gamerules_multiplayer.cpp b/src/server/base/gamerules_multiplayer.cpp new file mode 100644 index 00000000..6897d386 --- /dev/null +++ b/src/server/base/gamerules_multiplayer.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +void +MultiplayerRules::FrameStart(void) +{ + if (cvar("mp_timelimit")) + if (time >= (cvar("mp_timelimit") * 60)) { + IntermissionStart(); + } + + IntermissionCycle(); +} + +void +MultiplayerRules::PlayerDeath(base_player pl) +{ + Plugin_PlayerObituary(g_dmg_eAttacker, g_dmg_eTarget, g_dmg_iWeapon, g_dmg_iHitBody, g_dmg_iDamage); + + /* death-counter */ + pl.deaths++; + forceinfokey(pl, "*deaths", ftos(pl.deaths)); + + /* update score-counter */ + if (pl.flags & FL_CLIENT || pl.flags & FL_MONSTER) + if (g_dmg_eAttacker.flags & FL_CLIENT) { + if (pl == g_dmg_eAttacker) + g_dmg_eAttacker.frags--; + else + g_dmg_eAttacker.frags++; + } + + /* in DM we only care about the frags */ + if (cvar("mp_fraglimit")) + if (g_dmg_eAttacker.frags >= cvar("mp_fraglimit")) { + IntermissionStart(); + } + + pl.movetype = MOVETYPE_NONE; + pl.solid = SOLID_NOT; + pl.takedamage = DAMAGE_NO; + pl.gflags &= ~GF_FLASHLIGHT; + pl.armor = pl.activeweapon = pl.g_items = 0; + + pl.think = PutClientInServer; + pl.nextthink = time + 4.0f; +} + +void +MultiplayerRules::PlayerSpawn(base_player pp) +{ + player pl = (player)pp; + /* this is where the mods want to deviate */ + entity spot; + + pl.classname = "player"; + pl.health = pl.max_health = 100; + pl.takedamage = DAMAGE_YES; + pl.solid = SOLID_SLIDEBOX; + pl.movetype = MOVETYPE_WALK; + pl.flags = FL_CLIENT; + pl.viewzoom = 1.0; + pl.model = "models/player.mdl"; + setmodel(pl, pl.model); + + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + pl.view_ofs = VEC_PLAYER_VIEWPOS; + pl.velocity = [0,0,0]; + pl.gravity = __NULL__; + pl.frame = 1; + pl.SendEntity = Player_SendEntity; + pl.SendFlags = UPDATE_ALL; + pl.customphysics = Empty; + pl.iBleeds = TRUE; + forceinfokey(pl, "*spec", "0"); + forceinfokey(pl, "*deaths", ftos(pl.deaths)); + + LevelNewParms(); + LevelDecodeParms(pl); + + spot = Spawn_SelectRandom("info_player_deathmatch"); + setorigin(pl, spot.origin); + pl.angles = spot.angles; + Weapons_RefreshAmmo(pl); + + Client_FixAngle(pl, pl.angles); +} + +float +MultiplayerRules::ConsoleCommand(base_player pp, string cmd) +{ + tokenize(cmd); + + switch (argv(0)) { + case "bot_add": + Bot_AddQuick(); + break; + default: + return FALSE; + } + + return TRUE; +} diff --git a/src/server/base/gamerules_singleplayer.cpp b/src/server/base/gamerules_singleplayer.cpp new file mode 100644 index 00000000..1869779a --- /dev/null +++ b/src/server/base/gamerules_singleplayer.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +void +SingleplayerRules::PlayerDeath(base_player pl) +{ + pl.movetype = MOVETYPE_NONE; + pl.solid = SOLID_NOT; + pl.takedamage = DAMAGE_NO; + pl.gflags &= ~GF_FLASHLIGHT; + pl.armor = pl.activeweapon = pl.g_items = pl.weapon = 0; + pl.health = 0; + + if (cvar("coop") == 1) { + pl.think = PutClientInServer; + pl.nextthink = time + 4.0f; + } +} + +void +SingleplayerRules::PlayerSpawn(base_player pl) +{ + pl.classname = "player"; + pl.health = pl.max_health = 100; + pl.takedamage = DAMAGE_YES; + pl.solid = SOLID_SLIDEBOX; + pl.movetype = MOVETYPE_WALK; + pl.flags = FL_CLIENT; + pl.viewzoom = 1.0; + pl.model = "models/player.mdl"; + setmodel(pl, pl.model); + + setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX); + pl.view_ofs = VEC_PLAYER_VIEWPOS; + pl.velocity = [0,0,0]; + pl.gravity = __NULL__; + pl.frame = 1; + pl.SendEntity = Player_SendEntity; + pl.SendFlags = UPDATE_ALL; + pl.customphysics = Empty; + pl.iBleeds = TRUE; + forceinfokey(pl, "*spec", "0"); + forceinfokey(pl, "*deaths", ftos(pl.deaths)); + + /* this is where the mods want to deviate */ + entity spot; + + if (startspot != "") { + dprint(sprintf("^3Gamerules_Spawn^7: Startspot is %s\n", startspot)); + LevelDecodeParms(pl); + setorigin(pl, Landmark_GetSpot()); + } else { + LevelNewParms(); + spot = find(world, ::classname, "info_player_start"); + setorigin(pl, spot.origin); + pl.angles = spot.angles; + } + + Weapons_RefreshAmmo(pl); + Client_FixAngle(pl, pl.angles); +} diff --git a/src/server/base/input.c b/src/server/base/input.c new file mode 100644 index 00000000..89d37cc5 --- /dev/null +++ b/src/server/base/input.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* +================= +Input_Handle + +Handles impulse and whatnot +================= +*/ +void Game_Input(void) +{ + CGameRules rules = (CGameRules)g_grMode; + + if (rules.m_iIntermission) { + rules.IntermissionEnd(); + return; + } + + if (input_buttons & INPUT_BUTTON0) { + Weapons_Primary(); + } else if (input_buttons & INPUT_BUTTON4) { + Weapons_Reload(); + } else if (input_buttons & INPUT_BUTTON3) { + Weapons_Secondary(); + } else { + Weapons_Release(); + } + + if (input_buttons & INPUT_BUTTON5) { + Player_UseDown(); + } else { + Player_UseUp(); + } + + if (self.impulse == 100) { + Flashlight_Toggle(); + } + + if (cvar("sv_cheats") == 1) { + player pl = (player)self; + if (self.impulse == 101) { + pl.health = 100; + pl.armor = 100; + } + + if (self.impulse == 102) { + // Respawn all the entities + for (entity a = world; (a = findfloat(a, ::identity, 1));) { + CBaseEntity caw = (CBaseEntity)a; + caw.Respawn(); + } + bprint(PRINT_HIGH, "Respawning all map entities...\n"); + } + } + + self.impulse = 0; +} diff --git a/src/server/base/items.cpp b/src/server/base/items.cpp new file mode 100644 index 00000000..566b32a2 --- /dev/null +++ b/src/server/base/items.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +void item_pickup::touch(void) +{ + if (other.classname != "player") { + return; + } + + /* don't remove if AddItem fails */ + if (Weapons_AddItem((player)other, id, m_iClip) == FALSE) { + return; + } + + Logging_Pickup(other, this, __NULL__); + + UseTargets(other, TRIG_TOGGLE, m_flDelay); + + if (real_owner || m_iWasDropped == 1 || cvar("sv_playerslots") == 1) { + remove(self); + } else { + Hide(); + think = Respawn; + nextthink = time + 30.0f; + } +} + +void item_pickup::SetItem(int i) +{ + id = i; + m_oldModel = Weapons_GetWorldmodel(id); + SetModel(m_oldModel); +} + +void item_pickup::SetFloating(int i) +{ + m_bFloating = rint(bound(0, m_bFloating, 1)); +} + +void item_pickup::Respawn(void) +{ + SetSolid(SOLID_TRIGGER); + SetOrigin(m_oldOrigin); + + /* At some points, the item id might not yet be set */ + if (m_oldModel) { + SetModel(m_oldModel); + } + + SetSize([-16,-16,0], [16,16,16]); + + think = __NULL__; + nextthink = -1; + + if (!m_iWasDropped && cvar("sv_playerslots") > 1) { + m_iClip = -1; + } + + if (!m_bFloating) { + droptofloor(); + SetMovetype(MOVETYPE_TOSS); + } +} + +void item_pickup::item_pickup(void) +{ + CBaseTrigger::CBaseTrigger(); + Respawn(); +} diff --git a/src/server/base/items.h b/src/server/base/items.h new file mode 100644 index 00000000..dee59bd3 --- /dev/null +++ b/src/server/base/items.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* PICKUP ITEMS */ +class item_pickup:CBaseTrigger +{ + int m_bFloating; + int m_iClip; + int m_iWasDropped; + int id; + void(void) item_pickup; + + virtual void(void) touch; + virtual void(int i) SetItem; + virtual void(void) Respawn; + virtual void(int) SetFloating; +}; diff --git a/src/server/base/player.c b/src/server/base/player.c new file mode 100644 index 00000000..a11d2638 --- /dev/null +++ b/src/server/base/player.c @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* +==================== +UseWorkaround +==================== +*/ +void UseWorkaround(entity eTarget) +{ + eActivator = self; + entity eOldSelf = self; + self = eTarget; + self.PlayerUse(); + self = eOldSelf; +} + +/* +==================== +Player_UseDown +==================== +*/ +void Player_UseDown(void) +{ + vector vecSrc; + + if (self.health <= 0) { + return; + } else if (!(self.flags & FL_USE_RELEASED)) { + return; + } + + makevectors(self.v_angle); + vecSrc = self.origin + self.view_ofs; + + self.hitcontentsmaski = CONTENTBITS_POINTSOLID; + traceline(vecSrc, vecSrc + (v_forward * 64), MOVE_HITMODEL, self); + + + if (trace_ent.PlayerUse) { + self.flags &= ~FL_USE_RELEASED; + + UseWorkaround(trace_ent); + + /* Some entities want to support Use spamming */ + if (!(self.flags & FL_USE_RELEASED)) { + sound(self, CHAN_ITEM, "common/wpn_select.wav", 0.25, ATTN_IDLE); + } + } else { + sound(self, CHAN_ITEM, "common/wpn_denyselect.wav", 0.25, ATTN_IDLE); + self.flags &= ~FL_USE_RELEASED; + } +} + +/* +==================== +Player_UseUp +==================== +*/ +void Player_UseUp(void) { + if (!(self.flags & FL_USE_RELEASED)) { + self.flags |= FL_USE_RELEASED; + } +} + +/* +================= +Player_SendEntity +================= +*/ +float Player_SendEntity(entity ePEnt, float fChanged) +{ + player pl = (player)self; + + if (pl.health <= 0 && ePEnt != pl) { + return FALSE; + } + + WriteByte(MSG_ENTITY, ENT_PLAYER); + WriteFloat(MSG_ENTITY, fChanged); + + /* really trying to get our moneys worth with 23 bits of mantissa */ + if (fChanged & PLAYER_MODELINDEX) { + WriteShort(MSG_ENTITY, pl.modelindex); + } + if (fChanged & PLAYER_ORIGIN) { + WriteCoord(MSG_ENTITY, pl.origin[0]); + WriteCoord(MSG_ENTITY, pl.origin[1]); + } + if (fChanged & PLAYER_ORIGIN_Z) { + WriteCoord(MSG_ENTITY, pl.origin[2]); + } + if (fChanged & PLAYER_ANGLES_X) { + WriteFloat(MSG_ENTITY, pl.v_angle[0]); + } + if (fChanged & PLAYER_ANGLES_Y) { + WriteFloat(MSG_ENTITY, pl.angles[1]); + } + if (fChanged & PLAYER_ANGLES_Z) { + WriteFloat(MSG_ENTITY, pl.angles[2]); + } + if (fChanged & PLAYER_VELOCITY) { + WriteCoord(MSG_ENTITY, pl.velocity[0]); + WriteCoord(MSG_ENTITY, pl.velocity[1]); + } + if (fChanged & PLAYER_VELOCITY_Z) { + WriteCoord(MSG_ENTITY, pl.velocity[2]); + } + if (fChanged & PLAYER_FLAGS) { + WriteFloat(MSG_ENTITY, pl.flags); + WriteFloat(MSG_ENTITY, pl.gflags); + } + if (fChanged & PLAYER_WEAPON) { + WriteByte(MSG_ENTITY, pl.activeweapon); + } + if (fChanged & PLAYER_ITEMS) { + WriteFloat(MSG_ENTITY, (__variant)pl.g_items); + } + if (fChanged & PLAYER_HEALTH) { + WriteByte(MSG_ENTITY, pl.health); + } + if (fChanged & PLAYER_ARMOR) { + WriteByte(MSG_ENTITY, pl.armor); + } + if (fChanged & PLAYER_MOVETYPE) { + WriteByte(MSG_ENTITY, pl.movetype); + } + if (fChanged & PLAYER_VIEWOFS) { + WriteFloat(MSG_ENTITY, pl.view_ofs[2]); + } + if (fChanged & PLAYER_BASEFRAME) { + WriteByte(MSG_ENTITY, pl.baseframe); + } + if (fChanged & PLAYER_FRAME) { + WriteByte(MSG_ENTITY, pl.frame); + } + if (fChanged & PLAYER_AMMO1) { + WriteByte(MSG_ENTITY, pl.a_ammo1); + } + if (fChanged & PLAYER_AMMO2) { + WriteByte(MSG_ENTITY, pl.a_ammo2); + } + if (fChanged & PLAYER_AMMO3) { + WriteByte(MSG_ENTITY, pl.a_ammo3); + } + + return TRUE; +} + +void Weapons_Draw(void); +void CSEv_PlayerSwitchWeapon_i(int w) +{ + player pl = (player)self; + pl.activeweapon = w; + Weapons_Draw(); +} + +void +Player_Precache(void) +{ + searchhandle pm; + pm = search_begin("models/player/*/*.mdl", TRUE, TRUE); + for (int i = 0; i < search_getsize(pm); i++) { + precache_model(search_getfilename(pm, i)); + } + search_end(pm); +} diff --git a/src/server/base/progs.src b/src/server/base/progs.src new file mode 100755 index 00000000..6a2a6721 --- /dev/null +++ b/src/server/base/progs.src @@ -0,0 +1,40 @@ +#pragma target fte +#pragma progs_dat "../../../base/data.pk3dir/progs.dat" + +#define QWSSQC +#define SERVER +#define GS_RENDERFX + +#includelist +../../shared/fteextensions.qc +../../gs-entbase/server/defs.h +../../shared/defs.h +../defs.h + +../../gs-entbase/server.src +../../gs-entbase/shared.src +../../shared/base/include.src + +../base/defs.h + +../base/player.c +../base/spectator.c + +../../botlib/include.src + +../base/gamerules.cpp +../base/gamerules_singleplayer.cpp +../base/gamerules_multiplayer.cpp +../base/client.c +../base/server.c +../base/damage.c +../base/items.cpp +../base/rules.c +../base/flashlight.c + +../base/input.c +../base/spawn.c + +../include.src +../../shared/include.src +#endlist diff --git a/src/server/base/rules.c b/src/server/base/rules.c new file mode 100644 index 00000000..e6b76f0a --- /dev/null +++ b/src/server/base/rules.c @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +int Rules_IsTeamPlay(void) +{ + return cvar("teamplay"); +} diff --git a/src/server/base/server.c b/src/server/base/server.c new file mode 100644 index 00000000..61d3550a --- /dev/null +++ b/src/server/base/server.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +void +Game_InitRules(void) +{ + if (cvar("sv_playerslots") == 1 || cvar("coop") == 1) { + g_grMode = spawn(SingleplayerRules); + } else { + g_grMode = spawn(MultiplayerRules); + } +} + +void +Game_Worldspawn(void) +{ + precache_model("models/player.mdl"); + Weapons_Init(); + Player_Precache(); +} diff --git a/src/server/base/spawn.c b/src/server/base/spawn.c new file mode 100644 index 00000000..021bcc54 --- /dev/null +++ b/src/server/base/spawn.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +void info_player_start(void) +{ + self.solid = SOLID_TRIGGER; + setsize(self, VEC_HULL_MIN, VEC_HULL_MAX); +} + +void info_player_deathmatch(void) +{ + self.solid = SOLID_TRIGGER; + setsize(self, VEC_HULL_MIN, VEC_HULL_MAX); +} + +void info_player_team1(void) +{ + self.classname = "info_player_deathmatch"; +} + +void info_player_team2(void) +{ + self.classname = "info_player_deathmatch"; +} diff --git a/src/server/base/spectator.c b/src/server/base/spectator.c new file mode 100644 index 00000000..01ce53fe --- /dev/null +++ b/src/server/base/spectator.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +void Game_SpectatorThink(void) +{ + +} +void Game_SpectatorConnect(void) +{ + +} +void Game_SpectatorDisconnect(void) +{ + +} diff --git a/src/shared/base/animations.c b/src/shared/base/animations.c new file mode 100755 index 00000000..ef19d5b4 --- /dev/null +++ b/src/shared/base/animations.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* +================= +Animation_PlayerUpdate + +Called every frame to update the animation sequences +depending on what the player is doing +================= +*/ +void +Animation_PlayerUpdate(void) +{ + +} + +/* +================= +Animation_PlayerTop + +Changes the animation sequence for the upper body part +================= +*/ +void +Animation_PlayerTop(float fFrame) +{ +} + +void +Animation_PlayerTopTemp(float fFrame, float fTime) +{ + +} diff --git a/src/shared/base/animations.h b/src/shared/base/animations.h new file mode 100644 index 00000000..ab712317 --- /dev/null +++ b/src/shared/base/animations.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +void Animation_PlayerTop(float); +void Animation_PlayerTopTemp(float, float); diff --git a/src/shared/base/flags.h b/src/shared/base/flags.h new file mode 100644 index 00000000..87c3e9af --- /dev/null +++ b/src/shared/base/flags.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* game flags */ +#define GF_SEMI_TOGGLED (1<<0) +#define GF_FLASHLIGHT (1<<1) +#define GF_UNUSED3 (1<<2) +#define GF_UNUSED4 (1<<3) +#define GF_UNUSED5 (1<<4) +#define GF_UNUSED6 (1<<5) +#define GF_UNUSED7 (1<<6) +#define GF_UNUSED8 (1<<7) +#define GF_UNUSED9 (1<<8) +#define GF_UNUSED10 (1<<9) +#define GF_UNUSED11 (1<<10) +#define GF_UNUSED12 (1<<11) +#define GF_UNUSED13 (1<<12) +#define GF_UNUSED14 (1<<14) +#define GF_UNUSED15 (1<<16) +#define GF_UNUSED16 (1<<13) +#define GF_UNUSED17 (1<<17) +#define GF_UNUSED18 (1<<18) +#define GF_UNUSED19 (1<<19) +#define GF_UNUSED20 (1<<20) +#define GF_UNUSED21 (1<<21) +#define GF_UNUSED22 (1<<22) +#define GF_UNUSED23 (1<<23) diff --git a/src/shared/base/fx_blood.c b/src/shared/base/fx_blood.c new file mode 100644 index 00000000..bac57194 --- /dev/null +++ b/src/shared/base/fx_blood.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef CLIENT +var float PARTICLE_BLOOD; + +void +FX_Blood_Init(void) +{ + PARTICLE_BLOOD = particleeffectnum("part_blood"); +} +#endif + +void +FX_Blood(vector pos, vector color) +{ +#ifdef SERVER + WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); + WriteByte(MSG_MULTICAST, EV_BLOOD); + WriteCoord(MSG_MULTICAST, pos[0]); + WriteCoord(MSG_MULTICAST, pos[1]); + WriteCoord(MSG_MULTICAST, pos[2]); + WriteByte(MSG_MULTICAST, color[0] * 255); + WriteByte(MSG_MULTICAST, color[1] * 255); + WriteByte(MSG_MULTICAST, color[2] * 255); + msg_entity = self; + multicast(pos, MULTICAST_PVS); +#else + if (cvar("violence_hblood") <= 0) { + return; + } + + pointparticles(PARTICLE_BLOOD, pos, [0,0,0], 1); +#endif +} diff --git a/src/shared/base/fx_breakmodel.c b/src/shared/base/fx_breakmodel.c new file mode 100644 index 00000000..b213e257 --- /dev/null +++ b/src/shared/base/fx_breakmodel.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef CLIENT +void +FX_BreakModel_Init(void) +{ +} +#endif + +void +FX_BreakModel(int count, vector vMins, vector vMaxs, vector vVel, float fStyle) +{ + +} diff --git a/src/shared/base/fx_explosion.c b/src/shared/base/fx_explosion.c new file mode 100755 index 00000000..fccbda78 --- /dev/null +++ b/src/shared/base/fx_explosion.c @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef CLIENT + +void +FX_Explosion_Init(void) +{ +} +#endif + +void +FX_Explosion(vector vecPos) +{ +} + diff --git a/src/shared/base/fx_gibhuman.c b/src/shared/base/fx_gibhuman.c new file mode 100644 index 00000000..b72b8f4d --- /dev/null +++ b/src/shared/base/fx_gibhuman.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef CLIENT + +void +FX_GibHuman_Init(void) +{ + +} +#endif + +void +FX_GibHuman(vector pos) +{ + +} diff --git a/src/shared/base/fx_impact.c b/src/shared/base/fx_impact.c new file mode 100644 index 00000000..32697644 --- /dev/null +++ b/src/shared/base/fx_impact.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef CLIENT + +void +FX_Impact_Init(void) +{ + +} +#endif + +void +FX_Impact(int iType, vector vecPos, vector vNormal) +{ + +} diff --git a/src/shared/base/fx_spark.c b/src/shared/base/fx_spark.c new file mode 100644 index 00000000..3e9a2735 --- /dev/null +++ b/src/shared/base/fx_spark.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef CLIENT +var float PARTICLE_SPARK; + +void +FX_Spark_Init(void) +{ + 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); +#endif +} diff --git a/src/shared/base/include.src b/src/shared/base/include.src new file mode 100644 index 00000000..669ca8e3 --- /dev/null +++ b/src/shared/base/include.src @@ -0,0 +1,21 @@ + #includelist +../../shared/base/flags.h +../../shared/base/player.cpp +../../shared/base/weapon_common.h +../../shared/base/animations.h +../../shared/base/animations.c +../../shared/base/pmove.c +../../shared/base/pmove_water.c + +../../shared/base/fx_blood.c +../../shared/base/fx_breakmodel.c +../../shared/base/fx_explosion.c +../../shared/base/fx_gibhuman.c +../../shared/base/fx_spark.c +../../shared/base/fx_impact.c + +../../shared/base/items.h +../../shared/base/weapons.h +../../shared/base/weapons.c +../../shared/base/weapon_common.c +#endlist diff --git a/src/shared/base/items.h b/src/shared/base/items.h new file mode 100644 index 00000000..ab888e3c --- /dev/null +++ b/src/shared/base/items.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + diff --git a/src/shared/base/player.cpp b/src/shared/base/player.cpp new file mode 100644 index 00000000..3714e645 --- /dev/null +++ b/src/shared/base/player.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +noref int input_sequence; +class player:base_player +{ +#ifdef CLIENT + /* External model */ + entity p_model; + int p_hand_bone; + int p_model_bone; + float lastweapon; + + virtual void(void) gun_offset; + virtual void(void) draw; + virtual float() predraw; + virtual void(void) postdraw; +#else +#endif +}; + diff --git a/src/shared/base/pmove.c b/src/shared/base/pmove.c new file mode 100644 index 00000000..8e8a44ec --- /dev/null +++ b/src/shared/base/pmove.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define PHY_JUMP_CHAINWINDOW 0.5 +#define PHY_JUMP_CHAIN 100 +#define PHY_JUMP_CHAINDECAY 50 + +.float waterlevel; +.float watertype; + +float GamePMove_Maxspeed(player target) +{ + return (target.flags & FL_CROUCHING) ? 135 : 270; +} + +void GamePMove_Fall(player target, float impactspeed) +{ + if (impactspeed > 580) { +#ifdef SERVER + float fFallDamage = (impactspeed - 580) * (100 / (1024 - 580)); + Damage_Apply(target, world, fFallDamage, 0, DMG_FALL); + Sound_Play(target, CHAN_VOICE, "player.fall"); +#endif + target.punchangle += [15,0,(input_sequence & 1) ? 15 : -15]; + } else if (impactspeed > 400) { + target.punchangle += [15,0,0]; +#ifdef SERVER + Sound_Play(target, CHAN_VOICE, "player.lightfall"); +#endif + } +} + +void GamePMove_Jump(player target) +{ + float flJumptimeDelta; + float flChainBonus; + + if (target.waterlevel >= 2) { + if (target.watertype == CONTENT_WATER) { + target.velocity[2] = 100; + } else if (target.watertype == CONTENT_SLIME) { + target.velocity[2] = 80; + } else { + target.velocity[2] = 50; + } + } else { + target.velocity[2] += 240; + } + + if (target.jumptime > 0) { + flJumptimeDelta = 0 - (target.jumptime - PHY_JUMP_CHAINWINDOW); + flChainBonus = PHY_JUMP_CHAIN - (((PHY_JUMP_CHAINWINDOW - (PHY_JUMP_CHAINWINDOW - flJumptimeDelta)) * 2) * PHY_JUMP_CHAINDECAY); + target.velocity[2] += flChainBonus; + } + target.jumptime = PHY_JUMP_CHAINWINDOW; +} diff --git a/src/shared/base/pmove_water.c b/src/shared/base/pmove_water.c new file mode 100644 index 00000000..cec6cab0 --- /dev/null +++ b/src/shared/base/pmove_water.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +void +GamePMove_WaterMove(player target) +{ + if (target.movetype == MOVETYPE_NOCLIP) { + return; + } + +#ifdef SERVER + if (target.health < 0) { + return; + } + + /* we've just exited water */ + if (target.waterlevel != 3) { + if (target.underwater_time < time) { + Sound_Play(target, CHAN_BODY, "player.gasplight"); + } else if (target.underwater_time < time + 9) { + Sound_Play(target, CHAN_BODY, "player.gaspheavy"); + } + target.underwater_time = time + 12; + } else if (target.underwater_time < time) { + /* we've been underwater... for too long. */ + if (target.pain_time < time) { + Damage_Apply(target, world, 5, DMG_DROWN, 0); + target.pain_time = time + 1; + } + } +#endif + + if (!target.waterlevel){ + if (target.flags & FL_INWATER) { +#ifdef SERVER + Sound_Play(target, CHAN_BODY, "player.waterexit"); +#endif + target.flags &= ~FL_INWATER; + } + return; + } + +#ifdef SERVER + if (target.watertype == CONTENT_LAVA) { + if (target.pain_time < time) { + target.pain_time = time + 0.2; + Damage_Apply(target, world, 10*target.waterlevel, DMG_BURN, 0); + } + } else if (target.watertype == CONTENT_SLIME) { + if (target.pain_time < time) { + target.pain_time = time + 1; + Damage_Apply(target, world, 4*target.waterlevel, DMG_ACID, 0); + } + } +#endif + + if (!(target.flags & FL_INWATER)) { +#ifdef SERVER + Sound_Play(target, CHAN_BODY, "player.waterenter"); + target.pain_time = 0; +#endif + target.flags |= FL_INWATER; + } +} + diff --git a/src/shared/base/weapon_common.c b/src/shared/base/weapon_common.c new file mode 100644 index 00000000..b5fc342e --- /dev/null +++ b/src/shared/base/weapon_common.c @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef SERVER +void Decals_Init(void); +#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(); + } + } +} + +void Weapons_SetModel(string mdl) +{ +#ifdef CLIENT + setmodel(pSeat->m_eViewModel, mdl); +#endif +} + +void Weapons_SetGeomset(string set) +{ +#ifdef CLIENT + setcustomskin(pSeat->m_eViewModel, "", set); +#endif +} + +void Weapons_Draw(void) +{ + player pl = (player)self; + int i = pl.activeweapon; + + pl.w_attack_next = 0.5f; + pl.w_idle_next = 2.5f; + pl.viewzoom = 1.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(); + } +#ifdef SERVER + if (g_weapons[i].updateammo != __NULL__) { + g_weapons[i].updateammo(pl); + } +#endif +} + +void Weapons_Holster(void) +{ + player pl = (player)self; + int i = pl.activeweapon; + if (g_weapons[i].holster != __NULL__) { + g_weapons[i].holster(); + } +} + +void Weapons_Primary(void) +{ + player pl = (player)self; + int i = pl.activeweapon; + + if (pl.flags & FL_NOATTACK) + return; + + if (g_weapons[i].primary != __NULL__) { + g_weapons[i].primary(); + } + +#ifdef SERVER + if (g_weapons[i].updateammo != __NULL__) { + g_weapons[i].updateammo(pl); + } +#endif +} + +void Weapons_Secondary(void) +{ + player pl = (player)self; + int i = pl.activeweapon; + + if (pl.flags & FL_NOATTACK) + return; + + if (g_weapons[i].secondary != __NULL__) { + g_weapons[i].secondary(); + } +#ifdef SERVER + if (g_weapons[i].updateammo != __NULL__) { + g_weapons[i].updateammo(pl); + } +#endif +} + +void Weapons_Reload(void) +{ + player pl = (player)self; + int i = pl.activeweapon; + + if (pl.flags & FL_NOATTACK) + return; + + if (g_weapons[i].reload != __NULL__) { + g_weapons[i].reload(); + } +#ifdef SERVER + if (g_weapons[i].updateammo != __NULL__) { + g_weapons[i].updateammo(pl); + } +#endif +} + +void Weapons_Release(void) +{ + player pl = (player)self; + int i = pl.activeweapon; + if (g_weapons[i].release != __NULL__) { + g_weapons[i].release(); + } + + pl.gflags &= ~GF_SEMI_TOGGLED; +} + +void Weapons_DrawCrosshair(void) +{ + player pl = (player)self; + int i = pl.activeweapon; + if (g_weapons[i].crosshair != __NULL__) { + g_weapons[i].crosshair(); + } +} + +string Weapons_GetWorldmodel(int id) +{ + if (g_weapons[id].wmodel != __NULL__) { + return g_weapons[id].wmodel(); + } + + return ""; +} + +string Weapons_GetPlayermodel(int id) +{ + if (g_weapons[id].pmodel != __NULL__) { + return g_weapons[id].pmodel(); + } + + return ""; +} + +string Weapons_GetDeathmessage(int id) +{ + if (g_weapons[id].deathmsg != __NULL__) { + return g_weapons[id].deathmsg(); + } + + return ""; +} + +#ifdef SERVER +float Weapons_GetAim(int id) +{ + if (g_weapons[id].aimanim != __NULL__) { + return g_weapons[id].aimanim(); + } + + return 0; +} +#endif + +#ifdef CLIENT +void Weapons_HUDPic(int id, int s, vector pos, float a) +{ + if (g_weapons[id].hudpic != __NULL__) { + g_weapons[id].hudpic(s, pos, a); + } +} +#endif + +void Weapons_MakeVectors(void) +{ +#ifdef SERVER + player pl = (player)self; + makevectors(pl.v_angle); +#else + makevectors(view_angles); +#endif +} + +vector Weapons_GetCameraPos(void) +{ +#ifdef SERVER + return self.origin + self.view_ofs; +#else + return getproperty(VF_ORIGIN); +#endif +} + +void Weapons_ViewAnimation(int i) +{ +#ifdef CLIENT + player pl = (player)pSeat->m_ePlayer; + View_PlayAnimation(i); +#else + player pl = (player)self; +#endif + pl.weapontime = 0.0f; +} + +#ifdef CLIENT +int View_GetAnimation(void); +int Weapons_GetAnimation(void) +{ + return View_GetAnimation(); +} +#endif + +void Weapons_ViewPunchAngle(vector add) +{ +#ifdef CLIENT + player pl = (player)self; + pl.punchangle += add; +#endif +} + +void Weapons_PlaySound(entity t, float ch, string s, float vol, float at) +{ +#ifdef SERVER + sound(t, ch, s, vol, at); +#endif +} + +int Weapons_IsPresent(player pl, int w) +{ + if (pl.g_items & g_weapons[w].id) { + return TRUE; + } else { + return FALSE; + } +} diff --git a/src/shared/base/weapon_common.h b/src/shared/base/weapon_common.h new file mode 100644 index 00000000..acb9acbc --- /dev/null +++ b/src/shared/base/weapon_common.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +typedef struct +{ + string name; + int id; /* bitflag id */ + int slot; + int slot_pos; + int allow_drop; + + void(void) draw; + void(void) holster; + void(void) primary; + void(void) secondary; + void(void) reload; + void(void) release; + void(void) crosshair; + + void(void) precache; + int(int, int) pickup; + void(player) updateammo; + string() wmodel; + string() pmodel; + string() deathmsg; + float() aimanim; + void(int, vector, float) hudpic; +} weapon_t; + +void Weapons_DrawCrosshair(void); +void Weapons_MakeVectors(void); +vector Weapons_GetCameraPos(void); +void Weapons_ViewAnimation(int); +void Weapons_ViewPunchAngle(vector); +void Weapons_PlaySound(entity, float, string, float, float); +int Weapons_IsPresent(player, int); +void Weapons_SetModel(string); +void Weapons_SetGeomset(string); + +#ifdef CLIENT +string Weapons_GetPlayermodel(int); +int Weapons_GetAnimation(void); +void Weapons_HUDPic(int, int, vector, float); +#endif diff --git a/src/shared/base/weapons.c b/src/shared/base/weapons.c new file mode 100644 index 00000000..9936c7e8 --- /dev/null +++ b/src/shared/base/weapons.c @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +weapon_t w_null = {}; +weapon_t g_weapons[] = { + w_null +}; diff --git a/src/shared/base/weapons.h b/src/shared/base/weapons.h new file mode 100644 index 00000000..03287c48 --- /dev/null +++ b/src/shared/base/weapons.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2016-2020 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* weapon Indices for the weapon table */ +enum +{ + WEAPON_NONE +}; diff --git a/src/shared/sound.c b/src/shared/sound.c index 82daff3b..2ec82aec 100644 --- a/src/shared/sound.c +++ b/src/shared/sound.c @@ -316,15 +316,15 @@ Sound_Play(entity target, int chan, string shader) if (g_sounds[sample].flags & SNDFL_STEP) { float s = vlen(target.velocity); - if (target.flags & FL_CROUCHING) - s *= 2.0f; + /*if (target.flags & FL_CROUCHING) + s *= 2.0f;*/ if (s < PMOVE_STEP_WALKSPEED) { return; } else if (s < PMOVE_STEP_RUNSPEED) { - volume = 0.35f; + volume *= 0.35f; } else { - volume = 0.75; + volume *= 0.75f; } } #ifdef CLIENT