diff --git a/src/client/cstrike/defs.h b/src/client/cstrike/defs.h index ceeffc3b..53a30a6f 100644 --- a/src/client/cstrike/defs.h +++ b/src/client/cstrike/defs.h @@ -74,7 +74,7 @@ struct entity eMuzzleflash; float fNumBones; float fEjectBone; - vector vPunchAngle; + vector punchangle; float fLastWeapon; float fBobTime; float fBob; diff --git a/src/client/damage.c b/src/client/damage.c index 53b015c4..069af3b9 100644 --- a/src/client/damage.c +++ b/src/client/damage.c @@ -80,7 +80,7 @@ CSQC_Parse_Damage(float save, float take, vector abs_pos) pSeat->damage_alpha = 1.0f; } - View_AddPunchAngle([take,0,0]); + //View_AddPunchAngle([take,0,0]); return TRUE; } diff --git a/src/client/defs.h b/src/client/defs.h index aa7e39d0..b45cb6f7 100644 --- a/src/client/defs.h +++ b/src/client/defs.h @@ -72,6 +72,5 @@ float clframetime; /* prototypes */ void View_SetMuzzleflash(int); void View_UpdateWeapon(entity, entity); -void View_AddPunchAngle(vector); void View_PlayAnimation(int); void Game_Input(void); diff --git a/src/client/entry.c b/src/client/entry.c index c9243843..7ad93e28 100644 --- a/src/client/entry.c +++ b/src/client/entry.c @@ -242,7 +242,7 @@ CSQC_UpdateView(float w, float h, float focus) addentities(MASK_ENGINE); setproperty(VF_MIN, video_mins); setproperty(VF_SIZE, video_res); - setproperty(VF_ANGLES, view_angles + pSeat->vPunchAngle); + setproperty(VF_ANGLES, view_angles + pl.punchangle); setproperty(VF_DRAWWORLD, 1); if (g_skyscale != 0 && g_skypos) { @@ -270,7 +270,6 @@ CSQC_UpdateView(float w, float h, float focus) pf.postdraw(); } - View_DropPunchAngle(); Fade_Update((int)video_mins[0],(int)video_mins[1], (int)w, (int)h); #ifdef CSTRIKE diff --git a/src/client/predict.c b/src/client/predict.c index 9a18bec6..b19042f8 100644 --- a/src/client/predict.c +++ b/src/client/predict.c @@ -31,6 +31,7 @@ void Predict_PreFrame(player pl) pl.net_jumptime = pl.jumptime; pl.net_teleport_time = pl.teleport_time; pl.net_viewzoom = pl.viewzoom; + pl.net_punchangle = pl.punchangle; #ifdef VALVE pl.net_w_attack_next = pl.w_attack_next; @@ -82,6 +83,8 @@ void Predict_PostFrame(player pl) pl.jumptime = pl.net_jumptime; pl.teleport_time = pl.net_teleport_time; pl.viewzoom = pl.net_viewzoom; + pl.punchangle = pl.net_punchangle; + //pl.hook.origin = pl.net_hookpos; #ifdef VALVE pl.w_attack_next = pl.net_w_attack_next; diff --git a/src/client/rewolf/hud_weaponselect.c b/src/client/rewolf/hud_weaponselect.c new file mode 100644 index 00000000..fd5588d4 --- /dev/null +++ b/src/client/rewolf/hud_weaponselect.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +vector vHUDSlotNumPos[6] = +{ + [168 / 256, 72 / 128], + [188 / 256, 72 / 128], + [208 / 256, 72 / 128], + [168 / 256, 92 / 128], + [188 / 256, 92 / 128], + [208 / 256, 92 / 128] +}; + +void HUD_DrawWeaponSelect_Forward(void) +{ + player pl = (player)pSeat->ePlayer; + + if (!pl.activeweapon) { + return; + } + + if (Weapons_InputForward(pl) == FALSE) { + return; + } + + if (pSeat->fHUDWeaponSelectTime < time) { + pSeat->fHUDWeaponSelected = pl.activeweapon; + sound(pSeat->ePlayer, CHAN_ITEM, "common/wpn_hudon.wav", 0.5, ATTN_NONE); + } else { + sound(pSeat->ePlayer, CHAN_ITEM, "common/wpn_moveselect.wav", 0.5, ATTN_NONE); + pSeat->fHUDWeaponSelected--; + if (pSeat->fHUDWeaponSelected <= 0) { + pSeat->fHUDWeaponSelected = g_weapons.length - 1; + } + } + + pSeat->fHUDWeaponSelectTime = time + 3; + + if not (pl.g_items & g_weapons[pSeat->fHUDWeaponSelected].id) { + HUD_DrawWeaponSelect_Forward(); + } +} + +void HUD_DrawWeaponSelect_Back(void) +{ + player pl = (player)pSeat->ePlayer; + + if (!pl.activeweapon) { + return; + } + + if (Weapons_InputBack(pl) == FALSE) { + return; + } + + if (pSeat->fHUDWeaponSelectTime < time) { + pSeat->fHUDWeaponSelected = pl.activeweapon; + sound(pSeat->ePlayer, CHAN_ITEM, "common/wpn_hudon.wav", 0.5, ATTN_NONE); + } else { + sound(pSeat->ePlayer, CHAN_ITEM, "common/wpn_moveselect.wav", 0.5, ATTN_NONE); + pSeat->fHUDWeaponSelected++; + if (pSeat->fHUDWeaponSelected >= g_weapons.length) { + pSeat->fHUDWeaponSelected = 1; + } + } + + pSeat->fHUDWeaponSelectTime = time + 3; + + if not (pl.g_items & g_weapons[pSeat->fHUDWeaponSelected].id) { + HUD_DrawWeaponSelect_Back(); + } +} + +void HUD_DrawWeaponSelect_Trigger(void) +{ + player pl = (player)pSeat->ePlayer; + pl.activeweapon = pSeat->fHUDWeaponSelected; + sendevent("PlayerSwitchWeapon", "f", pSeat->fHUDWeaponSelected); + sound(pSeat->ePlayer, CHAN_ITEM, "common/wpn_select.wav", 0.5f, ATTN_NONE); + pSeat->fHUDWeaponSelected = pSeat->fHUDWeaponSelectTime = 0; +} + +void HUD_DrawWeaponSelect_Last(void) +{ + +} + +void HUD_DrawWeaponSelect_Num(vector vPos, float fValue) +{ + drawsubpic(vPos, [20,20], "sprites/640hud7.spr_0.tga", vHUDSlotNumPos[fValue], [20/256, 20/128], g_hud_color, 1, DRAWFLAG_ADDITIVE); +} + +int HUD_InSlotPos(int slot, int pos) +{ + player pl = (player)pSeat->ePlayer; + for (int i = 1; i < g_weapons.length; i++) { + if (g_weapons[i].slot == slot && g_weapons[i].slot_pos == pos) { + if (pl.g_items & g_weapons[i].id) { + return i; + } else { + return -1; + } + } + } + return -1; +} + +void HUD_DrawWeaponSelect(void) +{ + player pl = (player)pSeat->ePlayer; + if (!pl.activeweapon) { + return; + } + if (pSeat->fHUDWeaponSelectTime < time) { + if (pSeat->fHUDWeaponSelected) { + sound(pSeat->ePlayer, CHAN_ITEM, "common/wpn_hudoff.wav", 0.5, ATTN_NONE); + pSeat->fHUDWeaponSelected = 0; + } + return; + } + + vector vecPos = video_mins + [16,16]; + + int b; + int wantslot = g_weapons[pSeat->fHUDWeaponSelected].slot; + int wantpos = g_weapons[pSeat->fHUDWeaponSelected].slot_pos; + for (int i = 0; i < 5; i++) { + int slot_selected = 0; + vecPos[1] = video_mins[1] + 16; + HUD_DrawWeaponSelect_Num(vecPos, i); + vecPos[1] += 20; + for (int x = 0; x < 32; x++) { + if (i == wantslot) { + slot_selected = TRUE; + if (x == wantpos) { + // Selected Sprite + Weapons_HUDPic(pSeat->fHUDWeaponSelected, 1, vecPos); + drawsubpic(vecPos, [170,45], "sprites/640hud3.spr_0.tga", + [0,180/256], [170/256,45/256], g_hud_color, 1, DRAWFLAG_ADDITIVE); + vecPos[1] += 50; + } else if ((b=HUD_InSlotPos(i, x)) != -1) { + // Unselected Sprite + Weapons_HUDPic(b, 0, vecPos); + vecPos[1] += 50; + } + } else if (HUD_InSlotPos(i, x) != -1) { + HUD_DrawWeaponSelect_Num(vecPos, 5); + vecPos[1] += 25; + } + } + + if (slot_selected == TRUE) { + vecPos[0] += 175; + } else { + vecPos[0] += 25; + } + } +} diff --git a/src/client/rewolf/init.c b/src/client/rewolf/init.c index a480a7ab..5d1af388 100644 --- a/src/client/rewolf/init.c +++ b/src/client/rewolf/init.c @@ -29,6 +29,8 @@ void Client_Init(float apilevel, string enginename, float engineversion) precache_model("sprites/640hud4.spr"); precache_model("sprites/640hud5.spr"); precache_model("sprites/640hud6.spr"); + + BEAM_TRIPMINE = particleeffectnum("beam_tripmine"); } void Client_InitDone(void) diff --git a/src/client/rewolf/progs.src b/src/client/rewolf/progs.src index e830d9bb..a683fa6c 100755 --- a/src/client/rewolf/progs.src +++ b/src/client/rewolf/progs.src @@ -38,7 +38,7 @@ decore.cpp ../../shared/valve/animations.h ../../shared/valve/animations.c -../../shared/valve/player.cpp +../../shared/rewolf/player.cpp ../player.c ../../shared/pmove.c ../predict.c @@ -52,6 +52,8 @@ decore.cpp ../../shared/rewolf/weapons.h ../../shared/rewolf/w_fists.c ../../shared/rewolf/w_gausspistol.c +../../shared/rewolf/w_grenade.c +../../shared/rewolf/w_shotgun.c ../../shared/rewolf/w_beamgun.c ../../shared/rewolf/w_chemicalgun.c ../../shared/rewolf/w_dml.c @@ -75,7 +77,7 @@ entities.c ../vgui.cpp hud.c -../valve/hud_weaponselect.c +hud_weaponselect.c ../valve/scoreboard.c ../valve/input.c diff --git a/src/client/valve/defs.h b/src/client/valve/defs.h index a6ab0827..d5353599 100644 --- a/src/client/valve/defs.h +++ b/src/client/valve/defs.h @@ -18,12 +18,11 @@ vector g_hud_color; struct { -//Viewmodel stuff + /* viewmodel stuff */ entity eViewModel; entity eMuzzleflash; float fNumBones; float fEjectBone; - vector vPunchAngle; float fLastWeapon; float fBobTime; float fBob; @@ -33,20 +32,23 @@ struct int iZoomed; float flZoomTime; -//Player fields + /* player fields */ entity ePlayer; vector vPlayerOrigin; vector vPlayerOriginOld; vector vPlayerVelocity; float fPlayerFlags; -// Camera Fields - //entity ePlayerEnt; + /* camera fields */ vector vCameraPos; vector vCameraAngle; float fCameraTime; + + /* punchangle */ + vector punchangle; + vector net_punchangle; -/* hud.c */ + /* hud.c */ float health_old; float health_alpha; float armor_old; @@ -58,10 +60,9 @@ struct float ammo3_old; float ammo3_alpha; -//UI fields - int iShowScores; // This is seperated from the other VGUI stuff so we can check scores while buying and whatnot - - // We can only carry one item per slot, so this is hacking around the last one + /* This is seperated from the other VGUI stuff so we can check scores + * while buying and whatnot */ + int iShowScores; float fHUDWeaponSelected; float fHUDWeaponSelectTime; diff --git a/src/client/view.c b/src/client/view.c index d1f691d8..f2fdcc90 100644 --- a/src/client/view.c +++ b/src/client/view.c @@ -119,32 +119,6 @@ View_CalcRoll(void) return autocvar_v_camroll ? roll : 0; } -/* -==================== -View_DropPunchAngle - -Quickly lerp to the original viewposition -==================== -*/ -void View_DropPunchAngle(void) -{ - float lerp; - lerp = 1.0f - (clframetime * 4); - pSeat->vPunchAngle *= lerp; -} - -/* -==================== -View_AddPunchAngle - -Gives the angle a bit of an offset/punch/kick -==================== -*/ -void View_AddPunchAngle(vector add) -{ - pSeat->vPunchAngle = add; -} - /* ==================== View_DrawViewModel @@ -208,8 +182,11 @@ void View_DrawViewModel(void) makevectors(getproperty(VF_ANGLES)); eMuzzleflash.origin = gettaginfo(eViewModel, eMuzzleflash.skin); dynamiclight_add(pSeat->vPlayerOrigin + (v_forward * 32), 400 * eMuzzleflash.alpha, [1,0.45,0]); + + setorigin(eMuzzleflash, eMuzzleflash.origin); addentity(eMuzzleflash); } + setorigin(eViewModel, eViewModel.origin); addentity(eViewModel); } diff --git a/src/gs-entbase/server/func_ladder.cpp b/src/gs-entbase/server/func_ladder.cpp index 69c3cd50..f68404ae 100644 --- a/src/gs-entbase/server/func_ladder.cpp +++ b/src/gs-entbase/server/func_ladder.cpp @@ -52,6 +52,7 @@ void func_ladder :: func_ladder ( void ) #endif #else Init(); + setorigin(this, origin); #endif } @@ -61,4 +62,5 @@ void func_ladder :: Initialized (void) movetype = MOVETYPE_NONE; skin = CONTENT_LADDER; solid = SOLID_BSP; + setorigin(this, origin); } diff --git a/src/server/rewolf/input.c b/src/server/rewolf/input.c index 48d9c881..7b29ee1c 100644 --- a/src/server/rewolf/input.c +++ b/src/server/rewolf/input.c @@ -42,6 +42,15 @@ Game_Input(void) if (self.impulse == 101) { pl.health = 100; pl.armor = 100; + Weapons_AddItem(pl, WEAPON_FISTS); + Weapons_AddItem(pl, WEAPON_GAUSSPISTOL); + Weapons_AddItem(pl, WEAPON_BEAMGUN); + Weapons_AddItem(pl, WEAPON_CHEMICALGUN); + Weapons_AddItem(pl, WEAPON_DML); + Weapons_AddItem(pl, WEAPON_MINIGUN); + Weapons_AddItem(pl, WEAPON_AICORE); + Weapons_AddItem(pl, WEAPON_SHOTGUN); + Weapons_AddItem(pl, WEAPON_GRENADE); } if (self.impulse == 102) { diff --git a/src/server/rewolf/progs.src b/src/server/rewolf/progs.src index 90062e01..27c8b58f 100755 --- a/src/server/rewolf/progs.src +++ b/src/server/rewolf/progs.src @@ -29,7 +29,7 @@ monster_human_unarmed.cpp ../../shared/decals.c ../../shared/effects.c ../../shared/spraylogo.cpp -../../shared/valve/player.cpp +../../shared/rewolf/player.cpp ../valve/player.c ../../shared/pmove.c ../valve/spectator.c @@ -38,6 +38,8 @@ monster_human_unarmed.cpp ../../shared/rewolf/weapons.h ../../shared/rewolf/w_fists.c ../../shared/rewolf/w_gausspistol.c +../../shared/rewolf/w_grenade.c +../../shared/rewolf/w_shotgun.c ../../shared/rewolf/w_beamgun.c ../../shared/rewolf/w_chemicalgun.c ../../shared/rewolf/w_dml.c diff --git a/src/shared/cstrike/basegun.c b/src/shared/cstrike/basegun.c index 0bf23f01..10bb5179 100644 --- a/src/shared/cstrike/basegun.c +++ b/src/shared/cstrike/basegun.c @@ -74,7 +74,8 @@ void BaseGun_ShotMultiplierHandle( float fShots ) { vPunch[0] = -2 * ( pSeat->iShotMultiplier / 6 ); vPunch[1] = random( -1, 1 ); - View_AddPunchAngle( vPunch ); + /*player pl = (player)self; + pl.punchangle += vPunch;*/ #endif } diff --git a/src/shared/gearbox/player.cpp b/src/shared/gearbox/player.cpp index bcea18cb..9e298baf 100644 --- a/src/shared/gearbox/player.cpp +++ b/src/shared/gearbox/player.cpp @@ -39,10 +39,11 @@ class player float activeweapon; float viewzoom; + vector punchangle; vector view_ofs; float weapontime; - /* special for opfor */ + /* any mods that use hooks */ entity hook; /* Weapon specific */ @@ -76,6 +77,8 @@ class player float net_teleport_time; float net_weapontime; float net_viewzoom; + vector net_punchangle; + vector net_hookpos; int net_ammo1; int net_ammo2; int net_ammo3; diff --git a/src/shared/gearbox/w_displacer.c b/src/shared/gearbox/w_displacer.c index 8e89333d..ee86c3e4 100644 --- a/src/shared/gearbox/w_displacer.c +++ b/src/shared/gearbox/w_displacer.c @@ -43,6 +43,7 @@ w_displacer_precache(void) precache_model("models/v_displacer.mdl"); precache_model("models/w_displacer.mdl"); precache_model("models/p_displacer.mdl"); + precache_model("sprites/exit1.spr"); } void diff --git a/src/shared/pmove.c b/src/shared/pmove.c index af42f7b4..45ae24c0 100644 --- a/src/shared/pmove.c +++ b/src/shared/pmove.c @@ -675,6 +675,7 @@ PMove_Run_Move(void) void PMove_Run(void) { + float punch; player pl = (player)self; #ifdef VALVE self.maxspeed = (self.flags & FL_CROUCHING) ? 135 : 270; @@ -697,12 +698,10 @@ PMove_Run(void) } /* grappling hook stuff */ -#ifdef GEARBOX if (pl.hook.skin == 1) { pl.velocity = (pl.hook.origin - pl.origin); pl.velocity = (pl.velocity * (1 / (vlen(pl.velocity) / 1000))); } -#endif /* call accelerate before and after the actual move, * with half the move each time. this reduces framerate dependence. @@ -723,5 +722,11 @@ PMove_Run(void) pl.w_idle_next = max(0, pl.w_idle_next - input_timelength); #endif pl.weapontime += input_timelength; + + punch = max(0, 1.0f - (input_timelength * 4)); + pl.punchangle[0] *= punch; + pl.punchangle[1] *= punch; + pl.punchangle[2] *= punch; + Game_Input(); } diff --git a/src/shared/rewolf/items.h b/src/shared/rewolf/items.h index b8221ccd..a4aa1a87 100644 --- a/src/shared/rewolf/items.h +++ b/src/shared/rewolf/items.h @@ -21,10 +21,10 @@ #define ITEM_DML 0x00000010i #define ITEM_MINIGUN 0x00000020i #define ITEM_AICORE 0x00000040i -#define ITEM_UNUSED8 0x00000080i +#define ITEM_GRENADE 0x00000080i -#define ITEM_UNUSED9 0x00000100i -#define ITEM_UNUSED10 0x00000200i +#define ITEM_SHOTGUN 0x00000100i +#define ITEM_GAUSSADDON 0x00000200i #define ITEM_UNUSED11 0x00000400i #define ITEM_UNUSED12 0x00000800i #define ITEM_UNUSED13 0x00001000i diff --git a/src/shared/rewolf/player.cpp b/src/shared/rewolf/player.cpp new file mode 100644 index 00000000..99c549a3 --- /dev/null +++ b/src/shared/rewolf/player.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +int input_sequence; +class player +{ + float health; + float armor; + + /* When the weapon is done firing */ + float w_attack_next; + /* When to play the next idle animation */ + float w_idle_next; + + /* Magazine/Clip */ + int a_ammo1; + /* Rest in the inventory */ + int a_ammo2; + /* Special ammo */ + int a_ammo3; + + /* We can't use the default .items field, because FTE will assume + * effects of some bits. Such as invisibility, quad, etc. + * also, modders probably want 32 bits for items. */ + int g_items; + + float activeweapon; + float viewzoom; + vector punchangle; + vector view_ofs; + float weapontime; + + /* any mods that use hooks */ + entity hook; + +#ifdef CSQC + /* External model */ + entity p_model; + int p_hand_bone; + int p_model_bone; + float pitch; + float lastweapon; + + /* Prediction */ + vector net_origin; + vector net_velocity; + float net_flags; + float net_w_attack_next; + float net_w_idle_next; + float net_jumptime; + float net_teleport_time; + float net_weapontime; + float net_viewzoom; + vector net_punchangle; + int net_ammo1; + int net_ammo2; + int net_ammo3; + int sequence; + + virtual void() gun_offset; + virtual void() draw; + virtual float() predraw; + virtual void() postdraw; +#else + int ammo_battery; // beamgun + int ammo_chem; // chemicalgun + int ammo_rocket; // dml / grenades + int ammo_gauss; // gauspistol + int ammo_minigun; // minigun + int ammo_buckshot; // shotgun + + int fist_mode; // knife/fists + int gauss_mode; + int shotgun_shells; + int shotgun_spread; + + int dml_launch; /* when fired, when targeted */ + int dml_flightpath; /* guided, homing, spiral */ + int dml_detonate; /* on impact, in proximity, timed, when tripped */ + int dml_payload; /* explosive, cluster */ + + int chem_acid; + int chem_neutral; + int chem_base; + int chem_pressure; + + int beam_range; /* TOUCH TAZER, SHORT TAZER, MEDIUM BEAM, LONG BEAM */ + int beam_poweracc; /* LOW HIGHEST, MEDIUM HIGH, HIGH MEDIUM, HIGHEST LOW */ + int beam_lightning; /* BEAM, CHAIN, BALL */ + + int gren_detonate; /* when tripped (tripmine), timed, on impact */ + int gren_payload; /* cluster, explosive */ + + /* conditional networking */ + int old_modelindex; + vector old_origin; + vector old_angles; + vector old_velocity; + int old_flags; + int old_activeweapon; + int old_items; + int old_health; + int old_armor; + int old_movetype; + float old_viewofs; + int old_baseframe; + int old_frame; + int old_a_ammo1; + int old_a_ammo2; + int old_a_ammo3; +#endif +}; + diff --git a/src/shared/rewolf/w_aicore.c b/src/shared/rewolf/w_aicore.c index 9b0cd0ca..cf2ac992 100644 --- a/src/shared/rewolf/w_aicore.c +++ b/src/shared/rewolf/w_aicore.c @@ -1,2 +1,153 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ -weapon_t w_aicore = {}; +enum { + AIC_IDLE, // 1.777778f + AIC_PLUGIN, // 1.066667f + AIC_DRAW // 1.7f +}; + +void +w_aicore_draw(void) +{ + Weapons_SetModel("models/v_aicore.mdl"); + Weapons_SetGeomset("geomset 1 1\n"); + Weapons_ViewAnimation(AIC_DRAW); +} + +void +w_aicore_holster(void) +{ +} + +void +w_aicore_primary(void) +{ + vector src; + player pl = (player)self; + if (pl.w_attack_next) { + return; + } + + src = Weapons_GetCameraPos(); + +#ifdef CSQC + //Weapons_ViewAnimation(GP_FIRESINGLE); +#endif + + pl.w_attack_next = 0.15f; + pl.w_idle_next = 2.5f; +} + +void +w_aicore_release(void) +{ + player pl = (player)self; + + pl.flags |= FL_SEMI_TOGGLED; + + if (pl.w_idle_next) { + return; + } + + Weapons_ViewAnimation(AIC_IDLE); + pl.w_idle_next = 1.777778f; +} + +void +w_aicore_updateammo(player pl) +{ + +} + +string +w_aicore_wmodel(void) +{ + return ""; +} + +string +w_aicore_pmodel(void) +{ + return ""; +} + +string +w_aicore_deathmsg(void) +{ + return ""; +} + +float +w_aicore_aimanim(void) +{ + return 0; +} + +void +w_aicore_hudpic(int selected, vector pos) +{ +#ifdef CSQC + drawpic( + pos, + "gfx/vgui/640_weapon_aicore0.tga", + [170,43], + [1,1,1], + 1.0f, + DRAWFLAG_NORMAL + ); +#endif +} + +void +w_aicore_precache(void) +{ + precache_model("models/v_aicore.mdl"); +} + +weapon_t w_aicore = +{ + .id = ITEM_AICORE, + .slot = 0, + .slot_pos = 1, + .ki_spr = "sprites/640hud1.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [192,0], + .draw = w_aicore_draw, + .holster = w_aicore_holster, + .primary = w_aicore_primary, + .secondary = __NULL__, + .reload = __NULL__, + .release = w_aicore_release, + .crosshair = __NULL__, + .precache = w_aicore_precache, + .pickup = __NULL__, + .updateammo = w_aicore_updateammo, + .wmodel = w_aicore_wmodel, + .pmodel = w_aicore_pmodel, + .deathmsg = w_aicore_deathmsg, + .aimanim = w_aicore_aimanim, + .hudpic = w_aicore_hudpic +}; + +/* entity definitions for pickups */ +#ifdef SSQC +void +weapon_aicore(void) +{ + Weapons_InitItem(WEAPON_AICORE); +} +#endif diff --git a/src/shared/rewolf/w_beamgun.c b/src/shared/rewolf/w_beamgun.c index 2cb9182e..72f217b0 100644 --- a/src/shared/rewolf/w_beamgun.c +++ b/src/shared/rewolf/w_beamgun.c @@ -1,2 +1,353 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ -weapon_t w_beamgun = {}; +enum { + BEAMGUN_DRAW, + BEAMGUN_IDLE, // 2.6f + BEAMGUN_FIDGET1, // 2.4f + BEAMGUN_FIDGET2, // 2.08f + BEAMGUN_FIRE, // 0.333333f + BEAMGUN_FIRESINGLE, // 0.333333f + BEAMGUN_CONFIG, // 2.26087f + BEAMGUN_CHARGE // 1.3f +}; + +void +w_beamgun_draw(void) +{ + Weapons_SetModel("models/v_beam.mdl"); + Weapons_SetGeomset("geomset 1 1\n"); + Weapons_ViewAnimation(BEAMGUN_DRAW); +} + +void +w_beamgun_holster(void) +{ +} + +void +w_beamgun_release(void) +{ + player pl = (player)self; + + pl.flags |= FL_SEMI_TOGGLED; + + if (pl.w_idle_next) { + return; + } + + Weapons_ViewAnimation(BEAMGUN_IDLE); + pl.w_idle_next = 2.6f; +} + +void +w_beamgun_primary(void) +{ + vector src; + player pl = (player)self; + + if not (pl.flags & FL_SEMI_TOGGLED) { + return; + } + + if (pl.a_ammo1 > 0) { + pl.a_ammo1 = 0; + pl.flags &= ~FL_SEMI_TOGGLED; + Weapons_ViewAnimation(BEAMGUN_CONFIG); + pl.w_attack_next = 2.26087f; + pl.w_idle_next = 2.26087f; + return; + } + + if (pl.w_attack_next) { + return; + } + + src = Weapons_GetCameraPos(); + +#ifdef CSQC + //Weapons_ViewAnimation(GP_FIRESINGLE); +#endif + + pl.w_attack_next = 0.15f; + pl.w_idle_next = 2.5f; +} + +void +w_beamgun_secondary(void) +{ + player pl = (player)self; + + if not (pl.flags & FL_SEMI_TOGGLED) { + return; + } + + pl.flags &= ~FL_SEMI_TOGGLED; + + if (pl.w_attack_next) { + return; + } + + /* activate menu */ + if (pl.a_ammo1 <= 0 || pl.a_ammo1 == 3) { + pl.a_ammo1 = 1; + } else { + pl.a_ammo1 = bound(1, pl.a_ammo1 + 1, 3); + } +} + +void +w_beamgun_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, -1, pl.ammo_battery, -1); +#endif +} + +string +w_beamgun_wmodel(void) +{ + return ""; +} + +string +w_beamgun_pmodel(void) +{ + return ""; +} + +string +w_beamgun_deathmsg(void) +{ + return ""; +} + +float +w_beamgun_aimanim(void) +{ + return 0; +} + +void +w_beamgun_hud(void) +{ +#ifdef CSQC + static string rmodes[] = { + "TOUCH TAZER", + "SHORT TAZER", + "MEDIUM BEAM", + "LONG BEAM" + }; + static string pmodes[] = { + "LOW", + "MEDIUM", + "HIGH", + "HIGHEST" + }; + static string amodes[] = { + "HIGHEST", + "HIGH", + "MEDIUM", + "LOW" + }; + static string lmodes[] = { + "BEAM", + "CHAIN", + "BALL" + }; + vector pos; + player pl = (player)self; + + /* menu */ + if (pl.a_ammo1 > 0) { + vector col1, col2, col3; + string txt1, txt2, txt3, txt4; + + col1 = col2 = col3 = [1,1,1]; + switch (pl.a_ammo1) { + case 1: + col1 = [0,1,0]; + break; + case 2: + col2 = [0,1,0]; + break; + case 3: + col3 = [0,1,0]; + break; + } + + txt1 = sprintf("RANGE: %s", rmodes[getstati(46)]); + txt2 = sprintf("POWER: %s", pmodes[getstati(47)]); + txt3 = sprintf("ACCURACY: %s", amodes[getstati(47)]); + txt4 = sprintf("LIGHTNING: %s", lmodes[getstati(48)]); + pos = video_mins + (video_res / 2) + [-80,-48]; + + drawfont = FONT_20; + drawstring(pos, txt1, [20,20], col1, 1.0f, + DRAWFLAG_ADDITIVE); + pos[1] += 24; + drawstring(pos, txt2, [20,20], col2, 1.0f, + DRAWFLAG_ADDITIVE); + pos[1] += 24; + drawstring(pos, txt3, [20,20], col2, 1.0f, + DRAWFLAG_ADDITIVE); + pos[1] += 24; + drawstring(pos, txt4, [20,20], col3, 1.0f, + DRAWFLAG_ADDITIVE); + return; + } + + pos = video_mins + (video_res / 2) + [-15,-15]; + drawsubpic( + pos, + [31,31], + "sprites/crosshairs.spr_0.tga", + [116/256,1/128], + [31/256, 31/128], + [1,1,1], + 1.0f, + DRAWFLAG_NORMAL + ); + + HUD_DrawAmmo2(); +#endif +} + +void +w_beamgun_hudpic(int selected, vector pos) +{ +#ifdef CSQC + drawpic( + pos, + "gfx/vgui/640_weapon_beamgun0.tga", + [170,43], + [1,1,1], + 1.0f, + DRAWFLAG_NORMAL + ); +#endif +} + +void +w_beamgun_precache(void) +{ + precache_model("models/v_beam.mdl"); + +#ifdef SSQC + clientstat(46, EV_INTEGER, player::beam_range); + clientstat(47, EV_INTEGER, player::beam_poweracc); + clientstat(48, EV_INTEGER, player::beam_lightning); +#endif +} + +weapon_t w_beamgun = +{ + .id = ITEM_BEAMGUN, + .slot = 3, + .slot_pos = 0, + .ki_spr = "sprites/640hud1.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [192,0], + .draw = w_beamgun_draw, + .holster = w_beamgun_holster, + .primary = w_beamgun_primary, + .secondary = w_beamgun_secondary, + .reload = __NULL__, + .release = w_beamgun_release, + .crosshair = w_beamgun_hud, + .precache = w_beamgun_precache, + .pickup = __NULL__, + .updateammo = w_beamgun_updateammo, + .wmodel = w_beamgun_wmodel, + .pmodel = w_beamgun_pmodel, + .deathmsg = w_beamgun_deathmsg, + .aimanim = w_beamgun_aimanim, + .hudpic = w_beamgun_hudpic +}; + +/* entity definitions for pickups */ +#ifdef SSQC +void +weapon_beamgun(void) +{ + Weapons_InitItem(WEAPON_BEAMGUN); +} +#endif + +#ifdef CSQC +int +w_beamgun_hudforward(player pl) +{ + if (pl.a_ammo1 <= 0) { + return TRUE; + } + + switch (pl.a_ammo1) { + case 1: + sendevent("w_beamgun_range", "i", 1i); + break; + case 2: + sendevent("w_beamgun_power", "i", 1i); + break; + case 3: + sendevent("w_beamgun_light", "i", 1i); + break; + } + return FALSE; +} + +int +w_beamgun_hudback(player pl) +{ + if (pl.a_ammo1 <= 0) { + return TRUE; + } + + switch (pl.a_ammo1) { + case 1: + sendevent("w_beamgun_range", "i", -1i); + break; + case 2: + sendevent("w_beamgun_power", "i", -1i); + break; + case 3: + sendevent("w_beamgun_light", "i", -1i); + break; + } + return FALSE; +} +#else +void +CSEv_w_beamgun_range_i(int f) +{ + player pl = (player)self; + pl.beam_range = bound(0, pl.beam_range + f, 3); +} + +void +CSEv_w_beamgun_power_i(int f) +{ + player pl = (player)self; + pl.beam_poweracc = bound(0, pl.beam_poweracc + f, 3); +} + +void +CSEv_w_beamgun_light_i(int f) +{ + player pl = (player)self; + pl.beam_lightning = bound(0, pl.beam_lightning + f, 2); +} +#endif diff --git a/src/shared/rewolf/w_chemicalgun.c b/src/shared/rewolf/w_chemicalgun.c index b7e8caa7..bad965de 100644 --- a/src/shared/rewolf/w_chemicalgun.c +++ b/src/shared/rewolf/w_chemicalgun.c @@ -1,2 +1,468 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ -weapon_t w_chemicalgun = {}; +enum { + CHEMGUN_DRAW, // 1.2f + CHEMGUN_HOLSTER, // 1.2f + CHEMGUN_IDLE, // 2.08f + CHEMGUN_FIDGET, // 2.08f + CHEMGUN_CONFIG, // 2.08f + CHEMGUN_SHOOT // 0.535714 +}; + +void +w_chemicalgun_draw(void) +{ + Weapons_SetModel("models/v_chemgun.mdl"); + Weapons_SetGeomset("geomset 1 1\n"); + Weapons_ViewAnimation(CHEMGUN_DRAW); +} + +void +w_chemicalgun_holster(void) +{ +} + +void +w_chemicalgun_primary(void) +{ + vector src; + player pl = (player)self; + + if not (pl.flags & FL_SEMI_TOGGLED) { + return; + } + + if (pl.a_ammo1 > 0) { + pl.a_ammo1 = 0; + pl.flags &= ~FL_SEMI_TOGGLED; + Weapons_ViewAnimation(CHEMGUN_CONFIG); + pl.w_attack_next = 2.08f; + pl.w_idle_next = pl.w_attack_next; + return; + } + + if (pl.w_attack_next) { + return; + } + + src = Weapons_GetCameraPos(); + +#ifdef CSQC + //Weapons_ViewAnimation(GP_FIRESINGLE); +#endif + + pl.w_attack_next = 0.15f; + pl.w_idle_next = 2.5f; +} + +void +w_chemicalgun_secondary(void) +{ + player pl = (player)self; + + if not (pl.flags & FL_SEMI_TOGGLED) { + return; + } + + pl.flags &= ~FL_SEMI_TOGGLED; + + if (pl.w_attack_next) { + return; + } + + /* activate menu */ + if (pl.a_ammo1 <= 0 || pl.a_ammo1 == 4) { + pl.a_ammo1 = 1; + } else { + pl.a_ammo1 = bound(1, pl.a_ammo1 + 1, 4); + } +} + +void +w_chemicalgun_release(void) +{ + player pl = (player)self; + + pl.flags |= FL_SEMI_TOGGLED; + + if (pl.w_idle_next) { + return; + } + + Weapons_ViewAnimation(CHEMGUN_IDLE); + pl.w_idle_next = 2.08f; +} + +void +w_chemicalgun_updateammo(player pl) +{ + +} + +string +w_chemicalgun_wmodel(void) +{ + return ""; +} + +string +w_chemicalgun_pmodel(void) +{ + return ""; +} + +string +w_chemicalgun_deathmsg(void) +{ + return ""; +} + +float +w_chemicalgun_aimanim(void) +{ + return 0; +} + +int +w_chemicalgun_pickup(int new) +{ +#ifdef SSQC + player pl = (player)self; + + if (new) { + pl.chem_acid = 5; + pl.chem_neutral = 2; + pl.chem_base = 4; + pl.chem_pressure = 3; + } + + if (pl.ammo_chem < 50) { + pl.ammo_chem = bound(0, pl.ammo_chem + 10, 50); + } else { + return FALSE; + } +#endif + return TRUE; +} + +#ifdef CSQC +void +w_chemgun_drawvial(vector pos, int length, vector col) +{ + int i; + vector npos; + const string parts[] = { + "sprites/vial_el.spr_0.tga", + "sprites/vial_ec.spr_0.tga", + "sprites/vial_ec.spr_0.tga", + "sprites/vial_ec.spr_0.tga", + "sprites/vial_er.spr_0.tga" + }; + + pos[0] += 96; + npos = pos; + + /* empty */ + for (i = 0; i < 5; i++) { + if (i >= length) { + drawpic( + pos, + parts[i], + [32,32], + [1,1,1], + 1.0f, + DRAWFLAG_ADDITIVE + ); + } + pos[0] += 32; + } + + /* full */ + for (i = 0; i < length; i++) { + drawpic( + npos, + parts[i], + [32,32], + col, + 1.0f, + DRAWFLAG_ADDITIVE + ); + npos[0] += 32; + } +} +void +w_chemgun_drawpressure(vector pos, int length, vector col) +{ + int i; + const string parts[] = { + "sprites/hud_pntr.spr_0.tga", + "sprites/vial_ec.spr_0.tga", + "sprites/vial_ec.spr_0.tga", + "sprites/vial_ec.spr_0.tga", + "sprites/vial_er.spr_0.tga" + }; + + pos[0] += 96; + + /* full */ + for (i = 0; i < 5; i++) { + if (i == length) { + drawpic( + pos, + "sprites/hud_pntr.spr_0.tga", + [32,32], + col, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } else { + drawpic( + pos, + "sprites/hud_rule.spr_0.tga", + [32,32], + col, + 1.0f, + DRAWFLAG_ADDITIVE + ); + } + pos[0] += 32; + } +} +#endif + +void +w_chemicalgun_hud(void) +{ +#ifdef CSQC + vector pos; + player pl = (player)self; + + pos = video_mins + [video_res[0] - 125, video_res[1] - 42]; + for (int i = 0; i < 3; i++) { + drawpic( + pos, + "gfx/vgui/640_ammo_chem.tga", + [32,16], + [1,1,1], + 1.0f, + DRAWFLAG_NORMAL + ); + pos[1] += 8; + } + + HUD_DrawAmmo2(); + + /* menu */ + if (pl.a_ammo1 > 0) { + vector col1, col2, col3, col4; + string txt1, txt2, txt3, txt4; + + col1 = col2 = col3 = col4 = [1,1,1]; + switch (pl.a_ammo1) { + case 1: + col1 = [0,1,0]; + break; + case 2: + col2 = [0,1,0]; + break; + case 3: + col3 = [0,1,0]; + break; + case 4: + col4 = [0,1,0]; + break; + } + + txt1 = "ACID:"; + txt2 = "NEUTRAL:"; + txt3 = "BASE:"; + txt4 = "PRESSURE:"; + pos = video_mins + (video_res / 2) + [-128,-96]; + + drawfont = FONT_20; + drawstring(pos + [0,8], txt1, [20,20], col1, 1.0f, + DRAWFLAG_ADDITIVE); + w_chemgun_drawvial(pos, getstati(51), [0,1,0]); + pos[1] += 48; + drawstring(pos + [0,8], txt2, [20,20], col2, 1.0f, + DRAWFLAG_ADDITIVE); + w_chemgun_drawvial(pos, getstati(52), [0.25,0.25,1]); + pos[1] += 48; + drawstring(pos + [0,8], txt3, [20,20], col3, 1.0f, + DRAWFLAG_ADDITIVE); + w_chemgun_drawvial(pos, getstati(53), [1,0,0]); + pos[1] += 48; + drawstring(pos + [0,8], txt4, [20,20], col4, 1.0f, + DRAWFLAG_ADDITIVE); + w_chemgun_drawpressure(pos, getstati(54), [1,0.5,0.25]); + return; + } +#endif +} + +void +w_chemicalgun_hudpic(int selected, vector pos) +{ +#ifdef CSQC + drawpic( + pos, + "gfx/vgui/640_weapon_SPchemicalgun0.tga", + [170,43], + [1,1,1], + 1.0f, + DRAWFLAG_NORMAL + ); +#endif +} + +void +w_chemicalgun_precache(void) +{ + precache_model("models/v_chemgun.mdl"); + + /* empty */ + precache_model("sprites/vial_el.spr"); /* 32x32 */ + precache_model("sprites/vial_ec.spr"); + precache_model("sprites/vial_er.spr"); + + /* full */ + precache_model("sprites/vial_fl.spr"); + precache_model("sprites/vial_fc.spr"); + precache_model("sprites/vial_fr.spr"); + + precache_model("sprites/hud_pntr.spr"); + precache_model("sprites/hud_rule.spr"); + +#ifdef SSQC + clientstat(51, EV_INTEGER, player::chem_acid); + clientstat(52, EV_INTEGER, player::chem_neutral); + clientstat(53, EV_INTEGER, player::chem_base); + clientstat(54, EV_INTEGER, player::chem_pressure); +#endif +} + +weapon_t w_chemicalgun = +{ + .id = ITEM_CHEMICALGUN, + .slot = 4, + .slot_pos = 1, + .ki_spr = "sprites/640hud1.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [192,0], + .draw = w_chemicalgun_draw, + .holster = w_chemicalgun_holster, + .primary = w_chemicalgun_primary, + .secondary = w_chemicalgun_secondary, + .reload = __NULL__, + .release = w_chemicalgun_release, + .crosshair = w_chemicalgun_hud, + .precache = w_chemicalgun_precache, + .pickup = w_chemicalgun_pickup, + .updateammo = w_chemicalgun_updateammo, + .wmodel = w_chemicalgun_wmodel, + .pmodel = w_chemicalgun_pmodel, + .deathmsg = w_chemicalgun_deathmsg, + .aimanim = w_chemicalgun_aimanim, + .hudpic = w_chemicalgun_hudpic +}; + +/* entity definitions for pickups */ +#ifdef SSQC +void +weapon_chemgun(void) +{ + Weapons_InitItem(WEAPON_CHEMICALGUN); +} +#endif + +#ifdef CSQC +int +w_chemgun_hudforward(player pl) +{ + if (pl.a_ammo1 <= 0) { + return TRUE; + } + + switch (pl.a_ammo1) { + case 1: + sendevent("w_chem_a", "i", 1i); + break; + case 2: + sendevent("w_chem_n", "i", 1i); + break; + case 3: + sendevent("w_chem_b", "i", 1i); + break; + case 4: + sendevent("w_chem_p", "i", 1i); + break; + } + return FALSE; +} + +int +w_chemgun_hudback(player pl) +{ + if (pl.a_ammo1 <= 0) { + return TRUE; + } + + switch (pl.a_ammo1) { + case 1: + sendevent("w_chem_a", "i", -1i); + break; + case 2: + sendevent("w_chem_n", "i", -1i); + break; + case 3: + sendevent("w_chem_b", "i", -1i); + break; + case 4: + sendevent("w_chem_p", "i", -1i); + break; + } + return FALSE; +} +#else +void +CSEv_w_chem_a_i(int f) +{ + player pl = (player)self; + pl.chem_acid = bound(0, pl.chem_acid + f, 5); +} + +void +CSEv_w_chem_n_i(int f) +{ + player pl = (player)self; + pl.chem_neutral = bound(0, pl.chem_neutral + f, 5); +} + +void +CSEv_w_chem_b_i(int f) +{ + player pl = (player)self; + pl.chem_base = bound(0, pl.chem_base + f, 5); +} + +void +CSEv_w_chem_p_i(int f) +{ + player pl = (player)self; + pl.chem_pressure = bound(0, pl.chem_pressure + f, 4); +} +#endif diff --git a/src/shared/rewolf/w_dml.c b/src/shared/rewolf/w_dml.c index da771706..de9c70cd 100644 --- a/src/shared/rewolf/w_dml.c +++ b/src/shared/rewolf/w_dml.c @@ -1,2 +1,476 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ -weapon_t w_dml = {}; +/* the rocket launcher */ + +enum { + DML_IDLE, // 2.5f + DML_FIDGET, // 2.0f + DML_RELOADBOTH, // 1.6f + DML_RELOADLEFT, // 1.6f + DML_RELOADRIGHT, // 1.6f + DML_FIRE, // 1.222222f + DML_CUSTOMIZE, // 4.0f + DML_DRAW // 1.222222f +}; + +enum { + DS_FULL, + DS_RELOADING +}; + +enum { + DMENU_NONE, + DMENU_LAUNCH, + DMENU_FLIGHTPATH, + DMENU_DETONATE, + DMENU_PAYLOAD +}; + +/* customizable states */ +enum { + LAUNCH_FIRED, + LAUNCH_TARGETED +}; + +enum { + FLIGHTPATH_GUIDED, + FLIGHTPATH_HOMING, + FLIGHTPATH_SPIRAL +} ; + +enum { + DETONATE_IMPACT, + DETONATE_PROXIMITY, + DETONATE_TIMED, + DETONATE_TRIPPED +}; + +enum { + PAYLOAD_EXPLOSIVE, + PAYLOAD_CLUSTER +}; + +/* functions */ +void +w_dml_draw(void) +{ + Weapons_SetModel("models/v_dml.mdl"); + Weapons_SetGeomset("geomset 1 1\n"); + Weapons_ViewAnimation(DML_DRAW); +} + +void +w_dml_holster(void) +{ + +} + +void +w_dml_release(void) +{ + player pl = (player)self; + pl.flags |= FL_SEMI_TOGGLED; + if (pl.w_idle_next) { + return; + } + + if (pl.a_ammo3 == DS_RELOADING) { + if (pl.a_ammo1 == 1) { + Weapons_ViewAnimation(DML_RELOADRIGHT); + } else { + Weapons_ViewAnimation(DML_RELOADLEFT); + } + + sound(pl, CHAN_WEAPON, "weapons/dml_reload.wav", 1.0f, ATTN_NORM); + pl.w_attack_next = 1.6f; + pl.w_idle_next = pl.w_attack_next; + pl.a_ammo3 = DS_FULL; + return; + } + + int r = (float)input_sequence % 5; + switch (r) { + case 0: + case 1: + case 2: + case 3: + Weapons_ViewAnimation(DML_IDLE); + pl.w_idle_next = 10.0f; + break; + default: + Weapons_ViewAnimation(DML_FIDGET); + pl.w_idle_next = 2.0f; + } +} + +void +w_dml_primary(void) +{ + vector src; + player pl = (player)self; + + if not (pl.flags & FL_SEMI_TOGGLED) { + return; + } + + if (pl.a_ammo1 > 0) { + pl.a_ammo1 = 0; + pl.flags &= ~FL_SEMI_TOGGLED; + Weapons_ViewAnimation(DML_CUSTOMIZE); + sound(pl, 8, "weapons/dml_customize.wav", 1.0f, ATTN_NORM); + pl.w_attack_next = 4.0f; + pl.w_idle_next = 5.0f; + return; + } + + if (pl.w_attack_next) { + return; + } + + if (pl.a_ammo3 == DS_RELOADING) { + w_dml_release(); + return; + } + + src = Weapons_GetCameraPos(); + +#ifdef SSQC + sound(pl, CHAN_WEAPON, "weapons/dml_fire.wav", 1.0f, ATTN_NORM); +#endif + + Weapons_ViewAnimation(DML_FIRE); + pl.w_attack_next = 1.222222f; + pl.w_idle_next = 1.222222f; + pl.a_ammo3 = DS_RELOADING; +} + +void +w_dml_secondary(void) +{ + player pl = (player)self; + + if not (pl.flags & FL_SEMI_TOGGLED) { + return; + } + + pl.flags &= ~FL_SEMI_TOGGLED; + + if (pl.w_attack_next) { + return; + } + + /* activate menu */ + if (pl.a_ammo1 <= 0 || pl.a_ammo1 == DMENU_PAYLOAD) { + pl.a_ammo1 = 1; + } else { + pl.a_ammo1 = bound(DMENU_LAUNCH, pl.a_ammo1 + 1, DMENU_PAYLOAD); + } +} + +void +w_dml_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, -1, pl.ammo_rockets, -1); +#endif +} + +string +w_dml_wmodel(void) +{ + return ""; +} + +string +w_dml_pmodel(void) +{ + return ""; +} + +string +w_dml_deathmsg(void) +{ + return ""; +} + +float +w_dml_aimanim(void) +{ + return 0; +} + +int +w_dml_pickup(int new) +{ +#ifdef SSQC + player pl = (player)self; + + if (pl.ammo_rocket < 100) { + pl.ammo_rocket = bound(0, pl.ammo_rocket + 2, 100); + } else { + return FALSE; + } +#endif + return TRUE; +} + +void +w_dml_hud(void) +{ +#ifdef CSQC + static string lmodes[] = { + "WHEN FIRED", + "WHEN TARGETED" + }; + static string fmodes[] = { + "GUIDED", + "HOMING", + "SPIRAL" + }; + static string dmodes[] = { + "ON IMPACT", + "IN PROXIMITY", + "TIMED", + "WHEN TRIPPED" + }; + static string pmodes[] = { + "EXPLOSIVE", + "CLUSTER" + }; + vector pos; + vector jitter; + float lerp; + player pl = (player)self; + + /* laser */ + Weapons_MakeVectors(); + vector src = Weapons_GetCameraPos(); + traceline(src, src + (v_forward * 256), FALSE, pl); + lerp = Math_Lerp(18,6, trace_fraction); + jitter[0] = (random(0,2) - 2) * (1 - trace_fraction); + jitter[1] = (random(0,2) - 2) * (1 - trace_fraction); + pos = (video_res / 2) + ([-lerp,-lerp] / 2); + drawsubpic( + pos + jitter, + [lerp,lerp], + "sprites/laserdot.spr_0.tga", + [0,0], + [1.0, 1.0], + [1,1,1], + 1.0f, + DRAWFLAG_ADDITIVE + ); + + /* menu */ + if (pl.a_ammo1 > 0) { + vector col1, col2, col3, col4; + string txt1, txt2, txt3, txt4; + + col1 = col2 = col3 = col4 = [1,1,1]; + switch (pl.a_ammo1) { + case DMENU_LAUNCH: + col1 = [0,1,0]; + break; + case DMENU_FLIGHTPATH: + col2 = [0,1,0]; + break; + case DMENU_DETONATE: + col3 = [0,1,0]; + break; + case DMENU_PAYLOAD: + col4 = [0,1,0]; + break; + } + + txt1 = sprintf("LAUNCH: %s", lmodes[getstati(42)]); + txt2 = sprintf("FLIGHTPATH: %s", fmodes[getstati(43)]); + txt3 = sprintf("DETONATE: %s", dmodes[getstati(44)]); + txt4 = sprintf("PAYLOAD: %s", pmodes[getstati(45)]); + pos = video_mins + (video_res / 2) + [-80,-48]; + + drawfont = FONT_20; + drawstring(pos, txt1, [20,20], col1, 1.0f, + DRAWFLAG_ADDITIVE); + pos[1] += 24; + drawstring(pos, txt2, [20,20], col2, 1.0f, + DRAWFLAG_ADDITIVE); + pos[1] += 24; + drawstring(pos, txt3, [20,20], col3, 1.0f, + DRAWFLAG_ADDITIVE); + pos[1] += 24; + drawstring(pos, txt4, [20,20], col4, 1.0f, + DRAWFLAG_ADDITIVE); + return; + } + + pos = video_mins + (video_res / 2) + [-32,-15]; + drawsubpic( + pos, + [63,31], + "sprites/crosshairs.spr_0.tga", + [149/256,1/128], + [63/256, 31/128], + [1,1,1], + 1.0f, + DRAWFLAG_NORMAL + ); + + HUD_DrawAmmo2(); +#endif +} + +void +w_dml_hudpic(int selected, vector pos) +{ +#ifdef CSQC + drawpic( + pos, + "gfx/vgui/640_weapon_dml0.tga", + [170,43], + [1,1,1], + 1.0f, + DRAWFLAG_NORMAL + ); +#endif +} + +void +w_dml_precache(void) +{ + precache_model("models/v_dml.mdl"); + precache_model("sprites/laserdot.spr"); + precache_sound("weapons/dml_reload.wav"); + precache_sound("weapons/dml_customize.wav"); + precache_sound("weapons/dml_fire.wav"); + +#ifdef SSQC + clientstat(42, EV_INTEGER, player::dml_launch); + clientstat(43, EV_INTEGER, player::dml_flightpath); + clientstat(44, EV_INTEGER, player::dml_detonate); + clientstat(45, EV_INTEGER, player::dml_payload); +#endif +} + +weapon_t w_dml = +{ + .id = ITEM_DML, + .slot = 3, + .slot_pos = 1, + .ki_spr = "sprites/640hud1.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [192,0], + .draw = w_dml_draw, + .holster = w_dml_holster, + .primary = w_dml_primary, + .secondary = w_dml_secondary, + .reload = __NULL__, + .release = w_dml_release, + .crosshair = w_dml_hud, + .precache = w_dml_precache, + .pickup = w_dml_pickup, + .updateammo = w_dml_updateammo, + .wmodel = w_dml_wmodel, + .pmodel = w_dml_pmodel, + .deathmsg = w_dml_deathmsg, + .aimanim = w_dml_aimanim, + .hudpic = w_dml_hudpic +}; + +/* entity definitions for pickups */ +#ifdef SSQC +void +weapon_dml(void) +{ + Weapons_InitItem(WEAPON_DML); +} +#endif + +#ifdef CSQC +int +w_dml_hudforward(player pl) +{ + if (pl.a_ammo1 <= 0) { + return TRUE; + } + + switch (pl.a_ammo1) { + case DMENU_LAUNCH: + sendevent("w_dml_launch", "i", 1i); + break; + case DMENU_FLIGHTPATH: + sendevent("w_dml_path", "i", 1i); + break; + case DMENU_DETONATE: + sendevent("w_dml_det", "i", 1i); + break; + case DMENU_PAYLOAD: + sendevent("w_dml_pay", "i", 1i); + break; + } + return FALSE; +} +int +w_dml_hudback(player pl) +{ + if (pl.a_ammo1 <= 0) { + return TRUE; + } + + switch (pl.a_ammo1) { + case DMENU_LAUNCH: + sendevent("w_dml_launch", "i", -1i); + break; + case DMENU_FLIGHTPATH: + sendevent("w_dml_path", "i", -1i); + break; + case DMENU_DETONATE: + sendevent("w_dml_det", "i", -1i); + break; + case DMENU_PAYLOAD: + sendevent("w_dml_pay", "i", -1i); + break; + } + return FALSE; +} +#else +void +CSEv_w_dml_launch_i(int f) +{ + player pl = (player)self; + pl.dml_launch = bound(0, pl.dml_launch + f, 1); +} + +void +CSEv_w_dml_path_i(int f) +{ + player pl = (player)self; + pl.dml_flightpath = bound(0, pl.dml_flightpath + f, 2); +} +void +CSEv_w_dml_det_i(int f) +{ + player pl = (player)self; + pl.dml_detonate = bound(0, pl.dml_detonate + f, 3); +} + +void +CSEv_w_dml_pay_i(int f) +{ + player pl = (player)self; + pl.dml_payload = bound(0, pl.dml_payload + f, 1); +} +#endif diff --git a/src/shared/rewolf/w_fists.c b/src/shared/rewolf/w_fists.c index a0d8fd83..488f5c57 100644 --- a/src/shared/rewolf/w_fists.c +++ b/src/shared/rewolf/w_fists.c @@ -1,2 +1,324 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ -weapon_t w_fists = {}; +enum { + FISTS_IDLE, // 2.0f + FISTS_FIDGET1, // 3.0f + FISTS_FIDGET2, // 2.333333f + FISTS_RIGHT, // 0.419355f + FISTS_LEFT, // 0.419355f + FISTS_DOUBLE, // 0.739130f + FISTS_DRAW, // 1.4f + FISTS_HOLSTER, // 0.7f + KNIFE_DRAW, // 0.75f + KNIFE_HOLSTER, // 0.75f + KNIFE_IDLE, // 2.0f + KNIFE_FIDGET, // 2.0f + KNIFE_ATTACK1, // 0.789474f + KNIFE_ATTACK2, // 0.421053f + HANDS_PUSHBUTTON, // 8.0f +}; + +enum { + HS_KNIFE, + HS_KNIFE_TO_FISTS, + HS_FISTS, + HS_FISTS_TO_KNIFE +}; + +void +w_fists_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, -1, -1, pl.fist_mode); +#endif +} + +void +w_fists_draw(void) +{ + player pl = (player)self; + Weapons_SetModel("models/v_hands.mdl"); + Weapons_SetGeomset("geomset 1 2\n"); + Weapons_ViewAnimation(KNIFE_DRAW); + sound(pl, CHAN_WEAPON, "weapons/KnifeDraw.wav", 1.0f, ATTN_NORM); +} + +void +w_fists_holster(void) +{ + Weapons_ViewAnimation(KNIFE_HOLSTER); +} + +void +w_fists_release(void) +{ + int r; + player pl = (player)self; + + if (pl.w_idle_next) { + return; + } + + if (pl.a_ammo3 == HS_FISTS_TO_KNIFE) { + Weapons_ViewAnimation(KNIFE_DRAW); + Weapons_SetGeomset("geomset 1 2\n"); + sound(pl, CHAN_WEAPON, "weapons/KnifeDraw.wav", 1.0f, ATTN_NORM); + pl.a_ammo3 = HS_KNIFE; + pl.w_attack_next = 0.75f; + pl.w_idle_next = pl.w_attack_next; + return; + } else if (pl.a_ammo3 == HS_KNIFE_TO_FISTS) { + Weapons_ViewAnimation(FISTS_DRAW); + Weapons_SetGeomset("geomset 1 1\n"); + pl.a_ammo3 = HS_FISTS; + pl.w_attack_next = 1.4f; + pl.w_idle_next = pl.w_attack_next; + return; + } + + if (pl.a_ammo3 == HS_KNIFE) { + r = (float)input_sequence % 5; + switch (r) { + case 0: + case 1: + case 2: + case 3: + Weapons_ViewAnimation(KNIFE_IDLE); + pl.w_idle_next = 10.0f; + break; + default: + Weapons_ViewAnimation(KNIFE_FIDGET); + pl.w_idle_next = 2.0f; + } + } else { + r = (float)input_sequence % 5; + switch (r) { + case 0: + case 1: + case 2: + Weapons_ViewAnimation(FISTS_IDLE); + pl.w_idle_next = 10.0f; + break; + case 3: + Weapons_ViewAnimation(FISTS_FIDGET1); + pl.w_idle_next = 3.0f; + break; + default: + Weapons_ViewAnimation(FISTS_FIDGET2); + pl.w_idle_next = 2.333333f; + } + } +} + +void +w_fists_leftsound(void) +{ + player pl = (player)self; + int r; + r = (float)input_sequence % 3; + + switch (r) { + case 0: + sound(pl, CHAN_WEAPON, "weapons/LeftPunch.wav", 1.0f, ATTN_NORM); + break; + case 1: + sound(pl, CHAN_WEAPON, "weapons/LeftPunch2.wav", 1.0f, ATTN_NORM); + break; + default: + sound(pl, CHAN_WEAPON, "weapons/LeftPunch3.wav", 1.0f, ATTN_NORM); + } +} + +void +w_fists_rightsound(void) +{ + player pl = (player)self; + int r; + r = (float)input_sequence % 3; + switch (r) { + case 0: + sound(pl, CHAN_WEAPON, "weapons/RightPunch.wav", 1.0f, ATTN_NORM); + break; + case 1: + sound(pl, CHAN_WEAPON, "weapons/RightPunch2.wav", 1.0f, ATTN_NORM); + break; + default: + sound(pl, CHAN_WEAPON, "weapons/RightPunch3.wav", 1.0f, ATTN_NORM); + } +} + +void +w_fists_misssound(void) +{ + player pl = (player)self; + int r; + r = (float)input_sequence % 2; + switch (r) { + case 0: + sound(pl, CHAN_WEAPON, "weapons/cbar_miss1.wav", 1.0f, ATTN_NORM); + break; + default: + sound(pl, CHAN_WEAPON, "weapons/cbar_miss2.wav", 1.0f, ATTN_NORM); + } +} + +void +w_fists_primary(void) +{ + player pl = (player)self; + if (pl.w_attack_next) { + return; + } + + pl.a_ammo1 = 1 - pl.a_ammo1; + w_fists_misssound(); + + if (pl.a_ammo3 == HS_KNIFE) { + if (pl.a_ammo1 == 1) { + Weapons_ViewAnimation(KNIFE_ATTACK1); + } else { + Weapons_ViewAnimation(KNIFE_ATTACK2); + } + pl.w_attack_next = 0.5f; + pl.w_idle_next = pl.w_attack_next; + } else { + if (pl.a_ammo1 == 1) { + Weapons_ViewAnimation(FISTS_RIGHT); + } else { + Weapons_ViewAnimation(FISTS_LEFT); + } + pl.w_attack_next = 0.25f; + pl.w_idle_next = pl.w_attack_next; + } +} + +void +w_fists_secondary(void) +{ + player pl = (player)self; + + if (pl.w_attack_next) { + w_fists_release(); + return; + } + + if (pl.a_ammo3 == HS_KNIFE) { + Weapons_ViewAnimation(KNIFE_HOLSTER); + pl.a_ammo3 = HS_KNIFE_TO_FISTS; + pl.w_attack_next = 0.75f; + pl.w_idle_next = pl.w_attack_next; + } else if (pl.a_ammo3 == HS_FISTS) { + Weapons_ViewAnimation(FISTS_HOLSTER); + pl.a_ammo3 = HS_FISTS_TO_KNIFE; + pl.w_attack_next = 0.7f; + pl.w_idle_next = pl.w_attack_next; + } +} + +string +w_fists_wmodel(void) +{ + return ""; +} + +string +w_fists_pmodel(void) +{ + return ""; +} + +string +w_fists_deathmsg(void) +{ + return "%s killed %s with his knife."; +} + +float +w_fists_aimanim(void) +{ + return 0; +} + +int +w_fists_pickup(int new) +{ +#ifdef SSQC + player pl = (player)self; + + if (pl.ammo_minigun < 100) { + pl.ammo_minigun = bound(0, pl.ammo_minigun + 30, 100); + } else { + return FALSE; + } +#endif + return TRUE; +} + +void +w_fists_hudpic(int selected, vector pos) +{ +#ifdef CSQC + drawpic( + pos, + "gfx/vgui/640_weapon_fists0.tga", + [170,43], + [1,1,1], + 1.0f, + DRAWFLAG_NORMAL + ); +#endif +} + +void +w_fists_precache(void) +{ + precache_model("models/v_hands.mdl"); + precache_sound("weapons/KnifeDraw.wav"); + precache_sound("weapons/LeftPunch.wav"); + precache_sound("weapons/LeftPunch2.wav"); + precache_sound("weapons/LeftPunch3.wav"); + precache_sound("weapons/RightPunch.wav"); + precache_sound("weapons/RightPunch2.wav"); + precache_sound("weapons/RightPunch3.wav"); + precache_sound("weapons/cbar_miss1.wav"); + precache_sound("weapons/cbar_miss2.wav"); +} + +weapon_t w_fists = +{ + .id = ITEM_FISTS, + .slot = 0, + .slot_pos = 0, + .ki_spr = "sprites/640hud1.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [192,0], + .draw = w_fists_draw, + .holster = w_fists_holster, + .primary = w_fists_primary, + .secondary = w_fists_secondary, + .reload = __NULL__, + .release = w_fists_release, + .crosshair = __NULL__, + .precache = w_fists_precache, + .pickup = __NULL__, + .updateammo = w_fists_updateammo, + .wmodel = __NULL__, + .pmodel = __NULL__, + .deathmsg = w_fists_deathmsg, + .aimanim = w_fists_aimanim, + .hudpic = w_fists_hudpic +}; diff --git a/src/shared/rewolf/w_gausspistol.c b/src/shared/rewolf/w_gausspistol.c index 75ea67c0..e021e479 100644 --- a/src/shared/rewolf/w_gausspistol.c +++ b/src/shared/rewolf/w_gausspistol.c @@ -1,2 +1,426 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ -weapon_t w_gausspistol = {}; +enum { + GP_IDLE1, // 3.75f + GP_IDLE2, // 3.0f + GP_FIRESINGLE, // 0.727273f + GP_FIREFAST, // 0.2f + GP_FIRECHARGE, // 3.0f + GP_DRAW, // 1.071429f + GP_HOLSTER, // 0.9375f + SNIPER_IDLE1, // 3.0f + SNIPER_IDLE2, // 3.0f + SNIPER_FIDGET, // 3.0f + SNIPER_SHOOT, // 0.357143 + SNIPER_DRAW, // 0.937500 + SNIPER_HOLSTER // 1.666667f +}; + +enum { + GM_SINGLE, + GM_CHARGE, + GM_FAST, + GM_SNIPER +}; + +void +w_gausspistol_draw(void) +{ + Weapons_SetModel("models/v_guasspistol.mdl"); + Weapons_SetGeomset("geomset 1 1\n"); + Weapons_ViewAnimation(GP_DRAW); +} + +void +w_gausspistol_holster(void) +{ + Weapons_ViewAnimation(GP_HOLSTER); +} + +void +w_gausspistol_release(void) +{ + player pl = (player)self; + + pl.flags |= FL_SEMI_TOGGLED; + + if (pl.w_idle_next) { + return; + } + + int r = (float)input_sequence % 5; + switch (r) { + case 0: + case 1: + case 2: + case 3: + Weapons_ViewAnimation(GP_IDLE1); + pl.w_idle_next = 3.75f; + break; + default: + Weapons_ViewAnimation(GP_IDLE2); + pl.w_idle_next = 3.0f; + } +} + +void +w_gausspistol_primary(void) +{ + vector src; + int take = 1; + player pl = (player)self; + + if not (pl.flags & FL_SEMI_TOGGLED) { + return; + } + + if (pl.a_ammo1 > 0) { + pl.a_ammo1 = 0; + pl.flags &= ~FL_SEMI_TOGGLED; + return; + } + + if (pl.w_attack_next > 0) { + return; + } + + /* ammo check */ + if (pl.a_ammo2 <= 0) { + return; + } + + if (pl.a_ammo3 == GM_CHARGE && pl.a_ammo2 < 10) { + return; + } + + switch (pl.a_ammo3) { + case GM_FAST: + Weapons_ViewAnimation(GP_FIREFAST); +#ifdef SSQC + sound(self, CHAN_WEAPON, "weapons/gauss_fire4.wav", 1, ATTN_NORM); +#endif + pl.w_attack_next = 0.15f; + pl.w_idle_next = 2.5f; + break; + case GM_CHARGE: + take = 10; + Weapons_ViewAnimation(GP_FIRECHARGE); +#ifdef SSQC + sound(self, CHAN_WEAPON, "weapons/gauss_fire2.wav", 1, ATTN_NORM); + sound(self, 8, "weapons/gauss_charge.wav", 1, ATTN_NORM); +#endif + pl.w_attack_next = 2.0f; + pl.w_idle_next = 5.0f; + break; + default: + pl.flags &= ~FL_SEMI_TOGGLED; + Weapons_ViewAnimation(GP_FIRESINGLE); +#ifdef SSQC + sound(self, CHAN_WEAPON, "weapons/gauss_fire1.wav", 1, ATTN_NORM); +#endif + pl.w_attack_next = 0.15f; + pl.w_idle_next = 2.5f; + break; + } + + src = Weapons_GetCameraPos(); + +#ifdef SSQC + pl.ammo_gauss -= take; +#else + pl.a_ammo2 -= take; + View_SetMuzzleflash(MUZZLE_SMALL); + Weapons_ViewPunchAngle([-5,0,0]); +#endif +} + +void +w_gausspistol_secondary(void) +{ + player pl = (player)self; + + if not (pl.flags & FL_SEMI_TOGGLED) { + return; + } + + pl.flags &= ~FL_SEMI_TOGGLED; + + /* activate menu */ + pl.a_ammo1 = 1; + w_gausspistol_release(); +} + +void +w_gausspistol_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, -1, pl.ammo_gauss, pl.gauss_mode); +#endif +} + +string +w_gausspistol_wmodel(void) +{ + return "models/w_gauss.mdl"; +} + +string +w_gausspistol_pmodel(void) +{ + return "models/p_gauss.mdl"; +} + +string +w_gausspistol_deathmsg(void) +{ + return "%s kills %s with his Gauss-Pistol"; +} + +float +w_gausspistol_aimanim(void) +{ + return 0; +} + +int +w_gausspistol_pickup(int new) +{ +#ifdef SSQC + player pl = (player)self; + + if (pl.ammo_gauss < 150) { + pl.ammo_gauss = bound(0, pl.ammo_gauss + 35, 150); + } else { + return FALSE; + } +#endif + return TRUE; +} + +void +w_gausspistol_hud(void) +{ +#ifdef CSQC + vector pos; + player pl = (player)self; + + pos = video_mins + [video_res[0] - 125, video_res[1] - 42]; + for (int i = 0; i < 3; i++) { + drawpic( + pos, + "gfx/vgui/640_ammo_gauss.tga", + [32,16], + [1,1,1], + 1.0f, + DRAWFLAG_NORMAL + ); + pos[1] += 8; + } + + HUD_DrawAmmo2(); + + /* menu */ + if (pl.a_ammo1 > 0) { + pos = video_mins + (video_res / 2) + [-96,-72]; + + /* far left */ + if (pl.a_ammo3 == GM_SINGLE) { + drawsubpic( + pos, + [64,144], + "sprites/gausshud2.spr_0.tga", + [0/192,0/144], + [64/192, 144/144], + [1,1,1], + 1.0f, + DRAWFLAG_ADDITIVE + ); + drawsubpic( + pos + [64,0], + [128,144], + "sprites/gausshud1.spr_0.tga", + [64/192,0/144], + [128/192, 144/144], + [1,1,1], + 1.0f, + DRAWFLAG_ADDITIVE + ); + } + if (pl.a_ammo3 == GM_CHARGE) { + drawsubpic( + pos, + [64,144], + "sprites/gausshud1.spr_0.tga", + [0/192,0/144], + [64/192, 144/144], + [1,1,1], + 1.0f, + DRAWFLAG_ADDITIVE + ); + drawsubpic( + pos + [64,0], + [64,144], + "sprites/gausshud2.spr_0.tga", + [64/192,0/144], + [64/192, 144/144], + [1,1,1], + 1.0f, + DRAWFLAG_ADDITIVE + ); + drawsubpic( + pos + [128,0], + [64,144], + "sprites/gausshud1.spr_0.tga", + [128/192,0/144], + [64/192, 144/144], + [1,1,1], + 1.0f, + DRAWFLAG_ADDITIVE + ); + } + if (pl.a_ammo3 == GM_FAST) { + drawsubpic( + pos, + [128,144], + "sprites/gausshud1.spr_0.tga", + [0/192,0/144], + [128/192, 144/144], + [1,1,1], + 1.0f, + DRAWFLAG_ADDITIVE + ); + drawsubpic( + pos + [128,0], + [64,144], + "sprites/gausshud2.spr_0.tga", + [128/192,0/144], + [64/192, 144/144], + [1,1,1], + 1.0f, + DRAWFLAG_ADDITIVE + ); + } + return; + } + + pos = video_mins + (video_res / 2) + [-15,-15]; + drawsubpic( + pos, + [31,31], + "sprites/crosshairs.spr_0.tga", + [1/256,1/128], + [31/256, 31/128], + [1,1,1], + 1.0f, + DRAWFLAG_NORMAL + ); +#endif +} + +void +w_gausspistol_hudpic(int selected, vector pos) +{ +#ifdef CSQC + drawpic( + pos, + "gfx/vgui/640_weapon_gaussPistol0.tga", + [170,43], + [1,1,1], + 1.0f, + DRAWFLAG_NORMAL + ); +#endif +} + +void +w_gausspistol_precache(void) +{ + precache_model("models/v_guasspistol.mdl"); + precache_model("sprites/gausshud1.spr"); + precache_model("sprites/gausshud2.spr"); + precache_sound("weapons/gauss_fire4.wav"); + precache_sound("weapons/gauss_fire2.wav"); + precache_sound("weapons/gauss_fire1.wav"); + precache_sound("weapons/gauss_charge.wav"); +} + +weapon_t w_gausspistol = +{ + .id = ITEM_GAUSSPISTOL, + .slot = 1, + .slot_pos = 0, + .ki_spr = "sprites/640hud1.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [192,0], + .draw = w_gausspistol_draw, + .holster = w_gausspistol_holster, + .primary = w_gausspistol_primary, + .secondary = w_gausspistol_secondary, + .reload = __NULL__, + .release = w_gausspistol_release, + .crosshair = w_gausspistol_hud, + .precache = w_gausspistol_precache, + .pickup = w_gausspistol_pickup, + .updateammo = w_gausspistol_updateammo, + .wmodel = w_gausspistol_wmodel, + .pmodel = w_gausspistol_pmodel, + .deathmsg = w_gausspistol_deathmsg, + .aimanim = w_gausspistol_aimanim, + .hudpic = w_gausspistol_hudpic +}; + +/* entity definitions for pickups */ +#ifdef SSQC +void +weapon_gausspistol(void) +{ + Weapons_InitItem(WEAPON_GAUSSPISTOL); +} +#endif + +#ifdef CSQC +int +w_gausspistol_hudforward(player pl) +{ + if (pl.a_ammo1 <= 0) { + return TRUE; + } + + pl.a_ammo3 = bound(GM_SINGLE, pl.a_ammo3 - 1, GM_FAST); + sendevent("w_gp_setmode", "i", pl.a_ammo3); + return FALSE; +} + +int +w_gausspistol_hudback(player pl) +{ + if (pl.a_ammo1 <= 0) { + return TRUE; + } + + pl.a_ammo3 = bound(GM_SINGLE, pl.a_ammo3 + 1, GM_FAST); + sendevent("w_gp_setmode", "i", pl.a_ammo3); + return FALSE; +} +#else +void CSEv_w_gp_setmode_i(int f) +{ + player pl = (player)self; + pl.a_ammo3 = f; + pl.gauss_mode = f; +} +#endif diff --git a/src/shared/rewolf/w_grenade.c b/src/shared/rewolf/w_grenade.c new file mode 100644 index 00000000..512ac577 --- /dev/null +++ b/src/shared/rewolf/w_grenade.c @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +enum { + GREN_IDLE1, // 2.0f + GREN_IDLE2, // 2.0f + GREN_FIDGET, // 1.2f + GREN_RELOAD, // 1.6f + GREN_ARM, // 1.2f + GREN_THROW, // 0.5f + GREN_TRIPMINE, // 1.33333f + GREN_DRAW // 0.588235f +}; + +void +w_grenade_draw(void) +{ + Weapons_SetModel("models/v_grenade.mdl"); + Weapons_SetGeomset("geomset 1 1\n"); + Weapons_ViewAnimation(GREN_DRAW); +} + +void +w_grenade_holster(void) +{ +} + +void +w_grenade_primary(void) +{ + vector src; + player pl = (player)self; + + if not (pl.flags & FL_SEMI_TOGGLED) { + return; + } + + if (pl.a_ammo1 > 0) { + pl.a_ammo1 = 0; + pl.flags &= ~FL_SEMI_TOGGLED; + Weapons_ViewAnimation(GREN_FIDGET); + pl.w_attack_next = 1.2f; + pl.w_idle_next = pl.w_attack_next; + return; + } + + if (pl.w_attack_next) { + return; + } + + src = Weapons_GetCameraPos(); + +#ifdef CSQC + //Weapons_ViewAnimation(GP_FIRESINGLE); +#endif + + pl.w_attack_next = 0.15f; + pl.w_idle_next = 2.5f; +} + +void +w_grenade_secondary(void) +{ + player pl = (player)self; + + if not (pl.flags & FL_SEMI_TOGGLED) { + return; + } + + pl.flags &= ~FL_SEMI_TOGGLED; + + if (pl.w_attack_next) { + return; + } + + /* activate menu */ + if (pl.a_ammo1 <= 0) { + pl.a_ammo1 = 1; + } else { + if (pl.a_ammo1 == 1) { + pl.a_ammo1 = 2; + } else { + pl.a_ammo1 = 1; + } + } +} + +void +w_grenade_release(void) +{ + player pl = (player)self; + + pl.flags |= FL_SEMI_TOGGLED; + + if (pl.w_idle_next) { + return; + } + + Weapons_ViewAnimation(GREN_IDLE1); + pl.w_idle_next = 1.777778f; +} + +void +w_grenade_updateammo(player pl) +{ + +} + +string +w_grenade_wmodel(void) +{ + return ""; +} + +string +w_grenade_pmodel(void) +{ + return ""; +} + +string +w_grenade_deathmsg(void) +{ + return ""; +} + +float +w_grenade_aimanim(void) +{ + return 0; +} + +void +w_grenade_hud(void) +{ +#ifdef CSQC + vector pos; + player pl = (player)self; + + static string dmodes[] = { + "WHEN TRIPPED", + "TIMED", + "ON IMPACT" + }; + static string pmodes[] = { + "CLUSTER", + "EXPLOSIVE" + }; + + HUD_DrawAmmo2(); + + /* menu */ + if (pl.a_ammo1 > 0) { + vector col1, col2; + string txt1, txt2; + + col1 = col2 = [1,1,1]; + switch (pl.a_ammo1) { + case 1: + col1 = [0,1,0]; + break; + case 2: + col2 = [0,1,0]; + break; + } + + txt1 = sprintf("DETONATE: %s", dmodes[getstati(49)]); + txt2 = sprintf("PAYLOAD: %s", pmodes[getstati(50)]); + pos = video_mins + (video_res / 2) + [-48,-16]; + + drawfont = FONT_20; + drawstring(pos, txt1, [20,20], col1, 1.0f, + DRAWFLAG_ADDITIVE); + drawstring(pos + [0,24], txt2, [20,20], col2, 1.0f, + DRAWFLAG_ADDITIVE); + return; + } +#endif +} + +void +w_grenade_hudpic(int selected, vector pos) +{ +#ifdef CSQC + drawpic( + pos, + "gfx/vgui/640_weapon_dmlGrenade0.tga", + [170,43], + [1,1,1], + 1.0f, + DRAWFLAG_NORMAL + ); +#endif +} + +void +w_grenade_precache(void) +{ + precache_model("models/v_grenade.mdl"); + +#ifdef SSQC + clientstat(49, EV_INTEGER, player::gren_detonate); + clientstat(50, EV_INTEGER, player::gren_payload); +#endif +} + +weapon_t w_grenade = +{ + .id = ITEM_GRENADE, + .slot = 4, + .slot_pos = 0, + .ki_spr = "sprites/640hud1.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [192,0], + .draw = w_grenade_draw, + .holster = w_grenade_holster, + .primary = w_grenade_primary, + .secondary = w_grenade_secondary, + .reload = __NULL__, + .release = w_grenade_release, + .crosshair = w_grenade_hud, + .precache = w_grenade_precache, + .pickup = __NULL__, + .updateammo = w_grenade_updateammo, + .wmodel = w_grenade_wmodel, + .pmodel = w_grenade_pmodel, + .deathmsg = w_grenade_deathmsg, + .aimanim = w_grenade_aimanim, + .hudpic = w_grenade_hudpic +}; + +/* entity definitions for pickups */ +#ifdef SSQC +void +weapon_grenade(void) +{ + Weapons_InitItem(WEAPON_GRENADE); +} +#endif + +#ifdef CSQC +int +w_grenade_hudforward(player pl) +{ + if (pl.a_ammo1 <= 0) { + return TRUE; + } + + switch (pl.a_ammo1) { + case 1: + sendevent("w_gren_det", "i", 1i); + break; + case 2: + sendevent("w_gren_pay", "i", 1i); + break; + } + return FALSE; +} + +int +w_grenade_hudback(player pl) +{ + if (pl.a_ammo1 <= 0) { + return TRUE; + } + + switch (pl.a_ammo1) { + case 1: + sendevent("w_gren_det", "i", -1i); + break; + case 2: + sendevent("w_gren_pay", "i", -1i); + break; + } + return FALSE; +} +#else +void +CSEv_w_gren_det_i(int f) +{ + player pl = (player)self; + pl.gren_detonate = bound(0, pl.gren_detonate + f, 2); +} + +void +CSEv_w_gren_pay_i(int f) +{ + player pl = (player)self; + pl.gren_payload = bound(0, pl.gren_payload + f, 1); +} +#endif diff --git a/src/shared/rewolf/w_minigun.c b/src/shared/rewolf/w_minigun.c index d2e075bc..d7c9826b 100644 --- a/src/shared/rewolf/w_minigun.c +++ b/src/shared/rewolf/w_minigun.c @@ -1,2 +1,306 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ -weapon_t w_minigun = {}; +enum { + MG_IDLE, // 2.0f + MG_FIDGET, // 2.6f + MG_FIRE, // 0.333333f + MG_SPINUP, // 2.0f + MG_FIRELOOP, // 0.666667f + MG_SPINDOWN, // 2.0f + MG_DRAW, // 1.5f + MG_IDLELOOP, // 0.666667f + MG_HOLSTER // 1.5f +}; + +void +w_minigun_draw(void) +{ + Weapons_SetModel("models/v_mechagun.mdl"); + Weapons_SetGeomset("geomset 1 1\n"); + Weapons_ViewAnimation(MG_DRAW); +} + +void +w_minigun_holster(void) +{ + Weapons_ViewAnimation(MG_DRAW); +} + +void +w_minigun_release(void) +{ + player pl = (player)self; + if (pl.w_idle_next) { + return; + } + + if (pl.a_ammo3 == 1) { + Weapons_ViewAnimation(MG_IDLELOOP); + pl.w_idle_next = 0.666667f; + return; + } + + int r = (float)input_sequence % 5; + switch (r) { + case 0: + case 1: + case 2: + case 3: + Weapons_ViewAnimation(MG_IDLE); + pl.w_idle_next = 10.0f; + break; + default: + Weapons_ViewAnimation(MG_FIDGET); + pl.w_idle_next = 2.0f; + } +} + +void +w_minigun_primary(void) +{ + vector src; + player pl = (player)self; + if (pl.w_attack_next) { + return; + } + +#ifdef CSQC + if (pl.a_ammo2 <= 0) { + w_minigun_release(); + return; + } +#else + if (pl.ammo_minigun <= 0) { + w_minigun_release(); + return; + } +#endif + + src = Weapons_GetCameraPos(); + +#ifdef SSQC + int r = floor(random(0,3)); + switch (r) { + case 0: + sound(pl, CHAN_WEAPON, "weapons/hks1.wav", 1.0f, ATTN_NORM); + break; + case 1: + sound(pl, CHAN_WEAPON, "weapons/hks2.wav", 1.0f, ATTN_NORM); + break; + default: + sound(pl, CHAN_WEAPON, "weapons/hks3.wav", 1.0f, ATTN_NORM); + } +#else + View_SetMuzzleflash(MUZZLE_RIFLE); + Weapons_ViewPunchAngle([-2,0,0]); +#endif + +#ifdef CSQC + pl.a_ammo2--; +#else + pl.ammo_minigun--; +#endif + + if (pl.a_ammo3 == 1) { +#ifdef CSQC + Weapons_ViewAnimation(MG_FIRELOOP); +#else + TraceAttack_FireBullets(1, src, 8, [0.1,0.1], WEAPON_MINIGUN); +#endif + pl.w_attack_next = 0.1f; + pl.w_idle_next = 0.1f; + } else { + +#ifdef CSQC + Weapons_ViewAnimation(MG_FIRE); +#else + TraceAttack_FireBullets(1, src, 8, [0.05,0.05], WEAPON_MINIGUN); +#endif + pl.w_attack_next = 0.25f; + pl.w_idle_next = 2.5f; + } +} + +void +w_minigun_secondary(void) +{ + player pl = (player)self; + if (pl.w_attack_next) { + return; + } + +#ifdef SSQC + if (pl.a_ammo3 == 0) { + sound(pl, 8, "weapons/MechaSpinUp.wav", 1.0f, ATTN_NORM); + } else { + sound(pl, 8, "weapons/MechaSpinDown.wav", 1.0f, ATTN_NORM); + } +#else + if (pl.a_ammo3 == 0) { + Weapons_ViewAnimation(MG_SPINUP); + } else { + Weapons_ViewAnimation(MG_SPINDOWN); + } +#endif + pl.a_ammo3 = 1 - pl.a_ammo3; + + pl.w_attack_next = 2.0f; + pl.w_idle_next = 2.0f; +} + +void +w_minigun_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, -1, pl.ammo_minigun, -1); +#endif +} + +string +w_minigun_wmodel(void) +{ + return "models/w_mechagun.mdl"; +} + +string +w_minigun_pmodel(void) +{ + return "models/p_9mmar.mdl"; +} + +string +w_minigun_deathmsg(void) +{ + return ""; +} + +float +w_minigun_aimanim(void) +{ + return 0; +} + +int +w_minigun_pickup(int new) +{ +#ifdef SSQC + player pl = (player)self; + + if (pl.ammo_minigun < 100) { + pl.ammo_minigun = bound(0, pl.ammo_minigun + 30, 100); + } else { + return FALSE; + } +#endif + return TRUE; +} + +void +w_minigun_hud(void) +{ +#ifdef CSQC + vector pos; + pos = video_mins + (video_res / 2) + [-23,-15]; + + drawsubpic( + pos, + [47,31], + "sprites/crosshairs.spr_0.tga", + [67/256,1/128], + [47/256, 31/128], + [1,1,1], + 1.0f, + DRAWFLAG_NORMAL + ); + + pos = video_mins + [video_res[0] - 125, video_res[1] - 42]; + for (int i = 0; i < 3; i++) { + drawpic( + pos, + "gfx/vgui/640_ammo_minigun.tga", + [32,16], + [1,1,1], + 1.0f, + DRAWFLAG_NORMAL + ); + pos[1] += 8; + } + HUD_DrawAmmo2(); +#endif +} + +void +w_minigun_hudpic(int selected, vector pos) +{ +#ifdef CSQC + drawpic( + pos, + "gfx/vgui/640_weapon_minigun0.tga", + [170,43], + [1,1,1], + 1.0f, + DRAWFLAG_NORMAL + ); +#endif +} + +void +w_minigun_precache(void) +{ + precache_model("models/v_mechagun.mdl"); + precache_model("models/w_mechagun.mdl"); + precache_model("models/p_9mmar.mdl"); + precache_sound("weapons/MechaSpinDown.wav"); + precache_sound("weapons/MechaSpinUp.wav"); + precache_sound("weapons/hks1.wav"); + precache_sound("weapons/hks2.wav"); + precache_sound("weapons/hks3.wav"); +} + +weapon_t w_minigun = +{ + .id = ITEM_MINIGUN, + .slot = 2, + .slot_pos = 1, + .ki_spr = "sprites/640hud1.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [192,0], + .draw = w_minigun_draw, + .holster = w_minigun_holster, + .primary = w_minigun_primary, + .secondary = w_minigun_secondary, + .reload = __NULL__, + .release = w_minigun_release, + .crosshair = w_minigun_hud, + .precache = w_minigun_precache, + .pickup = w_minigun_pickup, + .updateammo = w_minigun_updateammo, + .wmodel = w_minigun_wmodel, + .pmodel = w_minigun_pmodel, + .deathmsg = w_minigun_deathmsg, + .aimanim = w_minigun_aimanim, + .hudpic = w_minigun_hudpic +}; + +/* entity definitions for pickups */ +#ifdef SSQC +void +weapon_minigun(void) +{ + Weapons_InitItem(WEAPON_MINIGUN); +} +#endif diff --git a/src/shared/rewolf/w_shotgun.c b/src/shared/rewolf/w_shotgun.c new file mode 100644 index 00000000..8c99a296 --- /dev/null +++ b/src/shared/rewolf/w_shotgun.c @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2016-2019 Marco Hladik + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +enum { + SHOTGUN_DRAW, // 0.909091f + SHOTGUN_IDLE, // 2.0f + SHOTGUN_FIDGET, // 2.0f + SHOTGUN_SHOOT1, // 0.846154f + SHOTGUN_SHOOT2, // 0.846154f + SHOTGUN_SHOOT3, // 0.846154f + SHOTGUN_SHOOT4, // 0.846154f + SHOTGUN_CUSTOMIZE // 2.25f +}; + +enum { + SMENU_NONE, + SMENU_SHELLS, + SMENU_SPREAD +}; + +enum { + SPREAD_RIOT, + SPREAD_SHOT, + SPREAD_RIFLE +}; + +#ifdef CSQC +string gsmodes[] = { + "RIOTGUN", + "SHOTGUN", + "RIFLE" +}; +#endif + +void +w_shotgun_draw(void) +{ + Weapons_SetModel("models/v_shotgun.mdl"); + Weapons_SetGeomset("geomset 1 1\n"); + Weapons_ViewAnimation(SHOTGUN_DRAW); +} + +void +w_shotgun_holster(void) +{ + Weapons_ViewAnimation(SHOTGUN_DRAW); +} + +void +w_shotgun_primary(void) +{ + vector src; + player pl = (player)self; + + if not (pl.flags & FL_SEMI_TOGGLED) { + return; + } + + if (pl.a_ammo1 > 0) { + pl.a_ammo1 = 0; + pl.flags &= ~FL_SEMI_TOGGLED; + Weapons_ViewAnimation(SHOTGUN_CUSTOMIZE); + pl.w_attack_next = 2.25f; + pl.w_idle_next = 2.25f; + return; + } + + if (pl.w_attack_next) { + return; + } + + src = Weapons_GetCameraPos(); + + pl.velocity += v_forward * -128; + +#ifdef SSQC + vector spread = [0.1,0.05]; + int pellets; + + switch (pl.shotgun_spread) { + case SPREAD_RIOT: + spread = [0.1,0.1]; + break; + case SPREAD_RIFLE: + spread = [0.05,0.05]; + break; + default: + spread = [0.1,0.05]; + } + + pellets = pl.shotgun_shells * 4; + + TraceAttack_FireBullets(pellets, src, 5, spread, WEAPON_SHOTGUN); + sound(self, CHAN_WEAPON, "weapons/sbarrel1.wav", 1, ATTN_NORM); +#else + View_SetMuzzleflash(MUZZLE_SMALL); + Weapons_ViewPunchAngle([-5,0,0]); + + int r = (float)input_sequence % 4; + switch (r) { + case 0: + Weapons_ViewAnimation(SHOTGUN_SHOOT1); + break; + case 1: + Weapons_ViewAnimation(SHOTGUN_SHOOT2); + break; + case 2: + Weapons_ViewAnimation(SHOTGUN_SHOOT3); + break; + default: + Weapons_ViewAnimation(SHOTGUN_SHOOT4); + } +#endif + + pl.w_attack_next = 0.846154f; + pl.w_idle_next = 2.5f; +} + +void +w_shotgun_secondary(void) +{ + player pl = (player)self; + + if not (pl.flags & FL_SEMI_TOGGLED) { + return; + } + + pl.flags &= ~FL_SEMI_TOGGLED; + + if (pl.w_attack_next) { + return; + } + + /* activate menu */ + if (pl.a_ammo1 <= 0) { + pl.a_ammo1 = 1; + } else { + if (pl.a_ammo1 == 1) { + pl.a_ammo1 = 2; + } else { + pl.a_ammo1 = 1; + } + } +} + +void +w_shotgun_release(void) +{ + player pl = (player)self; + pl.flags |= FL_SEMI_TOGGLED; + + if (pl.w_idle_next) { + return; + } + + int r = (float)input_sequence % 5; + switch (r) { + case 0: + case 1: + case 2: + case 3: + Weapons_ViewAnimation(SHOTGUN_IDLE); + pl.w_idle_next = 10.0f; + break; + default: + Weapons_ViewAnimation(SHOTGUN_FIDGET); + pl.w_idle_next = 2.0f; + } +} + +void +w_shotgun_updateammo(player pl) +{ +#ifdef SSQC + Weapons_UpdateAmmo(pl, -1, pl.ammo_buckshot, -1); +#endif +} + +string +w_shotgun_wmodel(void) +{ + return ""; +} + +string +w_shotgun_pmodel(void) +{ + return ""; +} + +string +w_shotgun_deathmsg(void) +{ + return ""; +} + +float +w_shotgun_aimanim(void) +{ + return 0; +} + +int +w_shotgun_pickup(int new) +{ +#ifdef SSQC + player pl = (player)self; + + if (new) { + pl.shotgun_shells = 2; + pl.shotgun_spread = SPREAD_SHOT; + } + + if (pl.ammo_buckshot < 90) { + pl.ammo_buckshot = bound(0, pl.ammo_buckshot + 16, 90); + } else { + return FALSE; + } +#endif + return TRUE; +} + +void +w_shotgun_hud(void) +{ +#ifdef CSQC + vector pos; + player pl = (player)self; + + pos = video_mins + [video_res[0] - 125, video_res[1] - 42]; + for (int i = 0; i < 3; i++) { + drawpic( + pos, + "gfx/vgui/640_ammo_buckshot.tga", + [32,16], + [1,1,1], + 1.0f, + DRAWFLAG_NORMAL + ); + pos[1] += 8; + } + + HUD_DrawAmmo2(); + + /* menu */ + if (pl.a_ammo1 > 0) { + vector col1, col2; + string shellstr, spreadstr; + + col1 = col2 = [1,1,1]; + switch (pl.a_ammo1) { + case SMENU_SHELLS: + col1 = [0,1,0]; + break; + case SMENU_SPREAD: + col2 = [0,1,0]; + break; + } + + shellstr = sprintf("SHELLS: %i", getstati(40)); + spreadstr = sprintf("SPREAD: %s", gsmodes[getstati(41)]); + pos = video_mins + (video_res / 2) + [-48,-16]; + + drawfont = FONT_20; + drawstring(pos, shellstr, [20,20], col1, 1.0f, + DRAWFLAG_ADDITIVE); + drawstring(pos + [0,24], spreadstr, [20,20], col2, 1.0f, + DRAWFLAG_ADDITIVE); + return; + } + + /* crosshair */ + pos = video_mins + (video_res / 2) + [-15,-15]; + drawsubpic( + pos, + [31,31], + "sprites/crosshairs.spr_0.tga", + [34/256,1/128], + [31/256, 31/128], + [1,1,1], + 1.0f, + DRAWFLAG_NORMAL + ); +#endif +} + +void +w_shotgun_hudpic(int selected, vector pos) +{ +#ifdef CSQC + drawpic( + pos, + "gfx/vgui/640_weapon_shotgun0.tga", + [170,43], + [1,1,1], + 1.0f, + DRAWFLAG_NORMAL + ); +#endif +} + +void +w_shotgun_precache(void) +{ + precache_model("models/v_shotgun.mdl"); + precache_model("models/w_shotgun.mdl"); + precache_model("models/p_shotgun.mdl"); + precache_sound("weapons/sbarrel1.wav"); + +#ifdef SSQC + clientstat(40, EV_INTEGER, player::shotgun_shells); + clientstat(41, EV_INTEGER, player::shotgun_spread); +#endif +} + +weapon_t w_shotgun = +{ + .id = ITEM_SHOTGUN, + .slot = 2, + .slot_pos = 0, + .ki_spr = "sprites/640hud1.spr_0.tga", + .ki_size = [48,16], + .ki_xy = [192,0], + .draw = w_shotgun_draw, + .holster = w_shotgun_holster, + .primary = w_shotgun_primary, + .secondary = w_shotgun_secondary, + .reload = __NULL__, + .release = w_shotgun_release, + .crosshair = w_shotgun_hud, + .precache = w_shotgun_precache, + .pickup = w_shotgun_pickup, + .updateammo = w_shotgun_updateammo, + .wmodel = w_shotgun_wmodel, + .pmodel = w_shotgun_pmodel, + .deathmsg = w_shotgun_deathmsg, + .aimanim = w_shotgun_aimanim, + .hudpic = w_shotgun_hudpic +}; + +/* entity definitions for pickups */ +#ifdef SSQC +void +weapon_shotgun(void) +{ + Weapons_InitItem(WEAPON_SHOTGUN); +} +#endif + +#ifdef CSQC +int +w_shotgun_hudforward(player pl) +{ + if (pl.a_ammo1 <= 0) { + return TRUE; + } + + switch (pl.a_ammo1) { + case SMENU_SHELLS: + sendevent("w_shot_shell", "i", 1i); + break; + case SMENU_SPREAD: + sendevent("w_shot_spread", "i", 1i); + break; + } + return FALSE; +} + +int +w_shotgun_hudback(player pl) +{ + if (pl.a_ammo1 <= 0) { + return TRUE; + } + + switch (pl.a_ammo1) { + case SMENU_SHELLS: + sendevent("w_shot_shell", "i", -1i); + break; + case SMENU_SPREAD: + sendevent("w_shot_spread", "i", -1i); + break; + } + return FALSE; +} +#else +void +CSEv_w_shot_shell_i(int f) +{ + player pl = (player)self; + pl.shotgun_shells = bound(1, pl.shotgun_shells + f, 4); +} + +void +CSEv_w_shot_spread_i(int f) +{ + player pl = (player)self; + pl.shotgun_spread = bound(SPREAD_RIOT, pl.shotgun_spread + f, SPREAD_RIFLE); +} +#endif diff --git a/src/shared/rewolf/weapons.c b/src/shared/rewolf/weapons.c index 7fa19f6f..23e8deb8 100644 --- a/src/shared/rewolf/weapons.c +++ b/src/shared/rewolf/weapons.c @@ -15,13 +15,60 @@ */ weapon_t w_null = {}; + weapon_t g_weapons[] = { w_null, w_fists, + w_aicore, w_gausspistol, - w_beamgun, - w_chemicalgun, - w_dml, + w_shotgun, w_minigun, - w_aicore + w_beamgun, + w_dml, + w_grenade, + w_chemicalgun }; + +#ifdef CSQC +int(player) gp_inputforward[] = { + __NULL__, + __NULL__, + __NULL__, + w_gausspistol_hudforward, + w_shotgun_hudforward, + __NULL__, + w_beamgun_hudforward, + w_dml_hudforward, + w_grenade_hudforward, + w_chemgun_hudforward +} + +int(player) gp_inputback[] = { + __NULL__, + __NULL__, + __NULL__, + w_gausspistol_hudback, + w_shotgun_hudback, + __NULL__, + w_beamgun_hudback, + w_dml_hudback, + w_grenade_hudback, + w_chemgun_hudback +} + +int Weapons_InputForward(player pl) +{ + if (gp_inputforward[pl.activeweapon] != __NULL__) { + return gp_inputforward[pl.activeweapon](pl); + } + return TRUE; +} + +int Weapons_InputBack(player pl) +{ + if (gp_inputback[pl.activeweapon] != __NULL__) { + return gp_inputback[pl.activeweapon](pl); + } + return TRUE; +} +#endif diff --git a/src/shared/rewolf/weapons.h b/src/shared/rewolf/weapons.h index e3e7b5c5..cfefa588 100644 --- a/src/shared/rewolf/weapons.h +++ b/src/shared/rewolf/weapons.h @@ -18,11 +18,13 @@ enum { WEAPON_NONE, - WEAPON_FISTS, - WEAPON_GAUSSPISTOL, - WEAPON_BEAMGUN, - WEAPON_CHEMICALGUN, - WEAPON_DML, - WEAPON_MINIGUN, - WEAPON_AICORE + WEAPON_FISTS, // 0 + WEAPON_AICORE, + WEAPON_GAUSSPISTOL, // 1 + WEAPON_SHOTGUN, // 2 + WEAPON_MINIGUN, // 2 + WEAPON_BEAMGUN, // 3 + WEAPON_DML, // 3 + WEAPON_GRENADE, + WEAPON_CHEMICALGUN }; diff --git a/src/shared/scihunt/player.cpp b/src/shared/scihunt/player.cpp index 09b24a3d..85f3212c 100644 --- a/src/shared/scihunt/player.cpp +++ b/src/shared/scihunt/player.cpp @@ -38,9 +38,13 @@ class player float activeweapon; float viewzoom; + vector punchangle; vector view_ofs; float weapontime; + /* any mods that use hooks */ + entity hook; + /* Weapon specific */ int glock_mag; int mp5_mag; @@ -70,6 +74,7 @@ class player float net_teleport_time; float net_weapontime; float net_viewzoom; + vector net_punchangle; int net_ammo1; int net_ammo2; int net_ammo3; diff --git a/src/shared/valve/player.cpp b/src/shared/valve/player.cpp index 13c9e770..b305d99a 100644 --- a/src/shared/valve/player.cpp +++ b/src/shared/valve/player.cpp @@ -39,9 +39,13 @@ class player float activeweapon; float viewzoom; + vector punchangle; vector view_ofs; float weapontime; + /* any mods that use hooks */ + entity hook; + /* Weapon specific */ int glock_mag; int mp5_mag; @@ -69,6 +73,7 @@ class player float net_teleport_time; float net_weapontime; float net_viewzoom; + vector net_punchangle; int net_ammo1; int net_ammo2; int net_ammo3; diff --git a/src/shared/valve/w_mp5.c b/src/shared/valve/w_mp5.c index f8ceb2db..f6989132 100644 --- a/src/shared/valve/w_mp5.c +++ b/src/shared/valve/w_mp5.c @@ -131,7 +131,8 @@ w_mp5_primary(void) pl.a_ammo1--; View_SetMuzzleflash(MUZZLE_RIFLE); - Weapons_ViewPunchAngle([random(-2, 2),0,0]); + int r = (float)input_sequence % 4; + Weapons_ViewPunchAngle([r-2,0,0]); #else /* singleplayer is more accurate */ if (cvar("sv_playerslots") == 1) { diff --git a/src/shared/valve/w_python.c b/src/shared/valve/w_python.c index 2edcaf23..d968e83a 100644 --- a/src/shared/valve/w_python.c +++ b/src/shared/valve/w_python.c @@ -88,6 +88,13 @@ w_python_draw(void) { #ifdef CSQC Weapons_SetModel("models/v_357.mdl"); + + /* singleplayer doesn't do scope */ + if (cvar("sv_playerslots") == 1) { + Weapons_SetGeomset("geomset 4 1\n"); + } else { + Weapons_SetGeomset("geomset 4 2\n"); + } Weapons_ViewAnimation(PYTHON_DRAW); #endif } @@ -150,6 +157,11 @@ w_python_secondary(void) return; } + /* singleplayer doesn't do scope */ + if (cvar("sv_playerslots") == 1) { + return; + } + /* Simple toggle of fovs */ if (pl.viewzoom == 1.0f) { pl.viewzoom = 0.5f; diff --git a/src/shared/valve/w_shotgun.c b/src/shared/valve/w_shotgun.c index 3479f17b..4c6d2fa1 100644 --- a/src/shared/valve/w_shotgun.c +++ b/src/shared/valve/w_shotgun.c @@ -87,10 +87,6 @@ void w_shotgun_draw(void) { Weapons_SetModel("models/v_shotgun.mdl"); Weapons_ViewAnimation(SHOTGUN_DRAW); -#ifdef SSQC - player pl = (player)self; - Weapons_UpdateAmmo(pl, pl.shotgun_mag, pl.ammo_buckshot, __NULL__); -#endif } void w_shotgun_holster(void) @@ -128,7 +124,6 @@ void w_shotgun_primary(void) } Weapons_PlaySound(pl, CHAN_WEAPON, "weapons/sbarrel1.wav", 1, ATTN_NORM); pl.shotgun_mag--; - Weapons_UpdateAmmo(pl, pl.shotgun_mag, pl.ammo_buckshot, __NULL__); #else View_SetMuzzleflash(MUZZLE_WEIRD); Weapons_ViewPunchAngle([-5,0,0]); diff --git a/src/shared/valve/weapon_common.c b/src/shared/valve/weapon_common.c index 8d920cf3..1c42c86d 100644 --- a/src/shared/valve/weapon_common.c +++ b/src/shared/valve/weapon_common.c @@ -31,7 +31,14 @@ void Weapons_SetModel(string mdl) { #ifdef CSQC setmodel(pSeat->eViewModel, mdl); -#endif +#endif +} + +void Weapons_SetGeomset(string set) +{ +#ifdef CSQC + setcustomskin(pSeat->eViewModel, "", set); +#endif } void Weapons_Draw(void) @@ -213,8 +220,8 @@ int Weapons_GetAnimation(void) void Weapons_ViewPunchAngle(vector add) { #ifdef CSQC - View_AddPunchAngle(add); - + player pl = (player)self; + pl.punchangle += add; #endif } diff --git a/src/shared/valve/weapon_common.h b/src/shared/valve/weapon_common.h index 73032a7e..e5d22f45 100644 --- a/src/shared/valve/weapon_common.h +++ b/src/shared/valve/weapon_common.h @@ -51,6 +51,7 @@ 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 SSQC void Weapons_RefreshAmmo(player); void Weapons_InitItem(int);