From b8763ca465f313fb0dda2145f133108925b99f64 Mon Sep 17 00:00:00 2001 From: cypress Date: Mon, 16 Oct 2023 10:23:50 -0400 Subject: [PATCH] SERVER: Control crosshair via QuakeC --- source/client/defs/custom.qc | 1 + source/client/hud.qc | 108 ++++++++++++-------- source/client/main.qc | 3 + source/server/clientfuncs.qc | 12 +++ source/server/defs/standard.qc | 1 + source/server/entities/machines.qc | 7 +- source/server/entities/wall_weapon.qc | 3 +- source/server/utilities/weapon_utilities.qc | 10 +- source/server/weapons/bouncing_betty.qc | 2 + source/server/weapons/frames_core.qc | 4 + source/server/weapons/weapon_core.qc | 81 +++++++++++++-- source/shared/defs/custom.qc | 1 + source/shared/weapon_defines.qc | 28 ++++- 13 files changed, 204 insertions(+), 57 deletions(-) diff --git a/source/client/defs/custom.qc b/source/client/defs/custom.qc index 26111a1..1215380 100644 --- a/source/client/defs/custom.qc +++ b/source/client/defs/custom.qc @@ -91,6 +91,7 @@ float scrollheight; float HUD_Change_time; float Hitmark_time; float crosshair_spread_time; +float crosshair_pulse_grenade; float zoom_2_time; float broadcast_time; float broadcast_type; diff --git a/source/client/hud.qc b/source/client/hud.qc index 1532c07..6de907c 100644 --- a/source/client/hud.qc +++ b/source/client/hud.qc @@ -1145,7 +1145,18 @@ void() Draw_Crosshair = drawline(2, [0, 0, 0], [g_width/2, g_height/2, 0], [0, 0, 1], 0.5); } - if (!cvar("crosshair")) + hide_viewmodel = false; + if (getstatf(STAT_WEAPONZOOM) == 2 && zoom_2_time < time) + { + hide_viewmodel = true; + drawfill('0 0 0', [g_width/2 - g_height/2, g_height, 0], '0 0 0', 1, 0); + drawpic([(g_width/2 - g_height/2),0,0], "gfx/hud/scope_nb.tga", [g_height, g_height, 1], [1,1,1], 1); + drawfill([(g_width/2 + g_height/2),0,0], [g_width, g_height, 0], '0 0 0', 1, 0); + return; + } + + float crosshair_value = cvar("crosshair"); + if (!crosshair_value) return; if (!crosshair_opacity) @@ -1184,15 +1195,6 @@ void() Draw_Crosshair = crosshair_color = TEXT_RED; else crosshair_color = [1, 1, 1]; - - hide_viewmodel = false; - if (getstatf(STAT_WEAPONZOOM) == 2 && zoom_2_time < time) - { - hide_viewmodel = true; - drawfill('0 0 0', [g_width/2 - g_height/2, g_height, 0], '0 0 0', 1, 0); - drawpic([(g_width/2 - g_height/2),0,0], "gfx/hud/scope_nb.tga", [g_height, g_height, 1], [1,1,1], 1); - drawfill([(g_width/2 + g_height/2),0,0], [g_width, g_height, 0], '0 0 0', 1, 0); - } if (getstatf(STAT_HEALTH) < 1) return; @@ -1216,41 +1218,61 @@ void() Draw_Crosshair = } } - if (getstatf(STAT_WEAPONZOOM) != 1 && getstatf(STAT_WEAPONZOOM) != 2) { - // 'O' crosshair - if (getstatf(STAT_ACTIVEWEAPON) == W_M2 || getstatf(STAT_ACTIVEWEAPON) == W_FIW || getstatf(STAT_ACTIVEWEAPON) == W_TESLA || getstatf(STAT_ACTIVEWEAPON) == W_DG3) { - float circle_offset = stringwidth("O", 0, [12, 12])/2; - drawstring([g_width/2 - circle_offset, g_height/2 - circle_offset], "O", [12, 12], crosshair_color, 1, 0); + // Standard crosshair (+) + if (crosshair_value == 1) { + int x_value, y_value; + int crosshair_offset; + + crosshair_offset = CrossHairWeapon(getstatf(STAT_ACTIVEWEAPON), getstatf(STAT_PLAYERSTANCE)) + cur_spread; + + if (CrossHairMaxSpread(getstatf(STAT_ACTIVEWEAPON), getstatf(STAT_PLAYERSTANCE)) < crosshair_offset) + crosshair_offset = CrossHairMaxSpread(getstatf(STAT_ACTIVEWEAPON), getstatf(STAT_PLAYERSTANCE)); + + if (perks & P_DEAD) + crosshair_offset *= 0.65; + + crosshair_offset_step += (crosshair_offset - crosshair_offset_step) * 0.5; + + // Creds to heartologic for some actually good crosshair position stuff. + vector crossSize = [1, 5]; + vector screenSize = [g_width, g_height]; + + drawfill(screenSize / 2 - [crossSize.x, +crossSize.y * 2 + crosshair_offset_step], crossSize, crosshair_color, crosshair_opacity, 0); // top + drawfill(screenSize / 2 - [crossSize.x, -crossSize.y * 1 - crosshair_offset_step + 2], crossSize, crosshair_color, crosshair_opacity, 0); // bottom + drawfill(screenSize / 2 - [+crossSize.y * 2 + crosshair_offset_step, crossSize.x], [crossSize.y, crossSize.x], crosshair_color, crosshair_opacity, 0); // right + drawfill(screenSize / 2 - [-crossSize.y * 1 - crosshair_offset_step, crossSize.x], [crossSize.y, crossSize.x], crosshair_color, crosshair_opacity, 0); // left + } + // Area of Effect (o) + else if (crosshair_value == 2) { + float circle_offset = stringwidth("O", 0, [12, 12])/2; + drawstring([g_width/2 - circle_offset, g_height/2 - circle_offset], "O", [12, 12], crosshair_color, 1, 0); + } + // Dot crosshair (.) + else if (crosshair_value == 3) { + vector screenSize2 = [g_width, g_height]; + drawfill(screenSize2 / 2 - [2, 2], [4, 4], crosshair_color, crosshair_opacity, 0); // dot + } + // Grenade crosshair + else if (crosshair_value == 4) { + if (crosshair_pulse_grenade) { + crosshair_offset_step = 0; + cur_spread = 12; } - // '.' crosshair - else if (getstatf(STAT_ACTIVEWEAPON) == W_PANZER || getstatf(STAT_ACTIVEWEAPON) == W_LONGINUS) { - vector screenSize2 = [g_width, g_height]; - drawfill(screenSize2 / 2 - [2, 2], [4, 4], crosshair_color, crosshair_opacity, 0); // dot - } - // Standard crosshair - else { - int x_value, y_value; - int crosshair_offset; - - crosshair_offset = CrossHairWeapon(getstatf(STAT_ACTIVEWEAPON), getstatf(STAT_PLAYERSTANCE)) + cur_spread; - - if (CrossHairMaxSpread(getstatf(STAT_ACTIVEWEAPON), getstatf(STAT_PLAYERSTANCE)) < crosshair_offset) - crosshair_offset = CrossHairMaxSpread(getstatf(STAT_ACTIVEWEAPON), getstatf(STAT_PLAYERSTANCE)); - - if (perks & P_DEAD) - crosshair_offset *= 0.65; - crosshair_offset_step += (crosshair_offset - crosshair_offset_step) * 0.5; + crosshair_pulse_grenade = false; - // Creds to heartologic for some actually good crosshair position stuff. - vector crossSize = [1, 5]; - vector screenSize = [g_width, g_height]; + int crosshair_offset2; + crosshair_offset2 = 3 + cur_spread; + crosshair_offset_step += (crosshair_offset2 - crosshair_offset_step) * 0.05; - drawfill(screenSize / 2 - [crossSize.x, +crossSize.y * 2 + crosshair_offset_step], crossSize, crosshair_color, crosshair_opacity, 0); // top - drawfill(screenSize / 2 - [crossSize.x, -crossSize.y * 1 - crosshair_offset_step], crossSize, crosshair_color, crosshair_opacity, 0); // bottom - drawfill(screenSize / 2 - [+crossSize.y * 2 + crosshair_offset_step, crossSize.x], [crossSize.y, crossSize.x], crosshair_color, crosshair_opacity, 0); // right - drawfill(screenSize / 2 - [-crossSize.y * 1 - crosshair_offset_step, crossSize.x], [crossSize.y, crossSize.x], crosshair_color, crosshair_opacity, 0); // left - } + // Creds to heartologic for some actually good crosshair position stuff. + vector crossSize2 = [1, 5]; + vector screenSize3 = [g_width, g_height]; + + drawfill(screenSize3 / 2 - [crossSize2.x, +crossSize2.y * 2 + crosshair_offset_step], crossSize2, crosshair_color, crosshair_opacity, 0); // top + drawfill(screenSize3 / 2 - [crossSize2.x, -crossSize2.y * 1 - crosshair_offset_step + 2], crossSize2, crosshair_color, crosshair_opacity, 0); // bottom + drawfill(screenSize3 / 2 - [+crossSize2.y * 2 + crosshair_offset_step, crossSize2.x], [crossSize2.y, crossSize2.x], crosshair_color, crosshair_opacity, 0); // right + drawfill(screenSize3 / 2 - [-crossSize2.y * 1 - crosshair_offset_step, crossSize2.x], [crossSize2.y, crossSize2.x], crosshair_color, crosshair_opacity, 0); // left } } @@ -1556,9 +1578,7 @@ void(float width, float height) HUD_Draw = if (!getstatf(STAT_SPECTATING) && (getstatf(STAT_HEALTH) > 1) && !score_show) { - - if (vmodel.model == GetWeaponModel(getstatf(STAT_ACTIVEWEAPON), FALSE) && vmodel.model != "" || getstatf(STAT_WEAPONZOOM) == 2) - Draw_Crosshair(); + Draw_Crosshair(); if (!cvar("waypoint_mode")) { HUD_Health(width, height); diff --git a/source/client/main.qc b/source/client/main.qc index f8de2c4..9c5fdcb 100644 --- a/source/client/main.qc +++ b/source/client/main.qc @@ -1203,6 +1203,9 @@ noref void() CSQC_Parse_Event = case EVENT_PLAYERUPDATE: player_count = readbyte(); break; + case EVENT_GRENADEPULSE: + crosshair_pulse_grenade = true; + break; case EVENT_WEAPONUPDATE: float wepnum = readbyte(); string wepname = readstring(); diff --git a/source/server/clientfuncs.qc b/source/server/clientfuncs.qc index df7a933..9fb85c3 100644 --- a/source/server/clientfuncs.qc +++ b/source/server/clientfuncs.qc @@ -321,6 +321,18 @@ void(float newtime, float newtype, entity change) PromptLevelChange = #endif // FTE } +#ifdef FTE +void(entity who) grenade_pulse = +{ + + WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); + WriteByte(MSG_MULTICAST, EVENT_GRENADEPULSE); + msg_entity = who; + multicast('0 0 0', MULTICAST_ONE); + +} +#endif // FTE + void(entity who) UpdatePunchangle = { #ifdef FTE diff --git a/source/server/defs/standard.qc b/source/server/defs/standard.qc index 21e53a7..ecba72d 100644 --- a/source/server/defs/standard.qc +++ b/source/server/defs/standard.qc @@ -266,6 +266,7 @@ string(float num) // 2001-11-15 DarkPlaces general builtin functions by Lord Havoc end void (string trackname) songegg = #500; void () nzp_maxammo = #501; +void (entity who) grenade_pulse = #502; // // constants diff --git a/source/server/entities/machines.qc b/source/server/entities/machines.qc index 7c98dbd..be4159a 100644 --- a/source/server/entities/machines.qc +++ b/source/server/entities/machines.qc @@ -28,6 +28,7 @@ float backupWepSkin; float sound_perk_delay; void() W_TakeOut; +void(entity person) W_HideCrosshair; // // -------------------- @@ -115,7 +116,7 @@ void GivePerk(optional float p) { self.weaponskin = backupWepSkin; self.perk_delay = self.fire_delay; - Weapon_PlayViewModelAnimation(ANIM_TAKE_OUT, SUB_Null, 0); + Weapon_PlayViewModelAnimation(ANIM_TAKE_OUT, ReturnWeaponModel, 0); SetPerk(self, self.perks); } @@ -143,7 +144,8 @@ void DrinkPerk(float perk) { self.maxspeed *= GetWeaponWalkSpeed(self.perks, self.weapon); - self.knife_delay = self.reload_delay2 = self.fire_delay2 = self.fire_delay = self.reload_delay = 3 + time; + self.knife_delay = self.reload_delay2 = self.fire_delay2 = self.fire_delay = self.reload_delay = 3 + time; + W_HideCrosshair(self); Set_W_Frame (tempe.weapon_animduration, tempe.weapon2_animduration, 2.25, 0, PERK, GivePerk, tempe.weapon2model, true, S_RIGHT); self = tempe; sound(other, CHAN_ITEM, self.oldmodel, 1, ATTN_NORM); @@ -1185,6 +1187,7 @@ void PapUpgrade(entity pap, entity buyer) { pap.weapon = self.weapon; Weapon_RemoveWeapon(0); + W_HideCrosshair(self); Set_W_Frame (0, 39, 2.0, 0, 0, W_PlayTakeOut, "models/machines/v_pap.mdl", true, S_BOTH); self.weapon2model = ""; UpdateV2model(self.weapon2model, 0); diff --git a/source/server/entities/wall_weapon.qc b/source/server/entities/wall_weapon.qc index 4ced924..cea9f04 100644 --- a/source/server/entities/wall_weapon.qc +++ b/source/server/entities/wall_weapon.qc @@ -330,12 +330,13 @@ void () WallWeapon_TouchTrigger = sound(other, 0, "sounds/misc/denybuy.wav", 1, 1); return; } else { + W_HideCrosshair(other); addmoney(other, -self.cost2, FALSE); other.ach_tracker_coll++; entity tempz; tempz = self; self = other; - Set_W_Frame(15, 30, 2.75, 0, 0, ReturnWeaponModel, "models/weapons/knife/v_bowie.mdl", false, S_BOTH); + Set_W_Frame(15, 30, 2.75, 0, 0, W_PlayTakeOut, "models/weapons/knife/v_bowie.mdl", false, S_BOTH); self.bowie = 1; } } diff --git a/source/server/utilities/weapon_utilities.qc b/source/server/utilities/weapon_utilities.qc index b4e6907..b6e806c 100644 --- a/source/server/utilities/weapon_utilities.qc +++ b/source/server/utilities/weapon_utilities.qc @@ -49,6 +49,7 @@ void() W_AimOut; void() ReturnWeaponModel; +void(entity person) W_HideCrosshair; // // Weapon_GetPlayerAmmoInSlot(person, slot) @@ -180,7 +181,7 @@ void (float animation_type, void(optional float t) end_function, float playback_ break; } - self.reload_delay2 = self.fire_delay2 = self.reload_delay = self.fire_delay = self.knife_delay = time + duration; + self.reload_delay2 = self.fire_delay2 = self.reload_delay = self.fire_delay = self.knife_delay = time + duration + 0.2; UpdateVmodel(self.weaponmodel, GetWepSkin(self.weapon)); self.weapon2model = GetWeapon2Model(self.weapon); @@ -242,6 +243,7 @@ void Weapon_SwapWeapons(float play_animation) self.weapon = self.weapons[0].weapon_id; SwitchWeapon(self.weapon); + W_HideCrosshair(self); Weapon_PlayViewModelAnimation(ANIM_TAKE_OUT, ReturnWeaponModel, 0); #ifndef FTE @@ -272,9 +274,9 @@ void Weapon_SetActiveInSlot(float slot, float play_first_raise) SwitchWeapon(self.weapon); if (GetFrame(self.weapon, FIRST_TAKE_START) != 0 && play_first_raise == true) - Weapon_PlayViewModelAnimation(ANIM_FIRST_TAKE, SUB_Null, 0); + Weapon_PlayViewModelAnimation(ANIM_FIRST_TAKE, ReturnWeaponModel, 0); else - Weapon_PlayViewModelAnimation(ANIM_TAKE_OUT, SUB_Null, 0); + Weapon_PlayViewModelAnimation(ANIM_TAKE_OUT, ReturnWeaponModel, 0); #ifndef FTE @@ -328,6 +330,8 @@ void Weapon_AssignWeapon(float weapon_slot, float weapon_id, float weapon_mag, f // void Weapon_GiveWeapon(float weapon_id, float weapon_mag, float weapon_reserve) { + W_HideCrosshair(self); + float should_leave = false; // Find next available weapon slot diff --git a/source/server/weapons/bouncing_betty.qc b/source/server/weapons/bouncing_betty.qc index eac2193..db590a1 100644 --- a/source/server/weapons/bouncing_betty.qc +++ b/source/server/weapons/bouncing_betty.qc @@ -163,6 +163,8 @@ void() W_PrimeBetty = if (self.sprinting) W_SprintStop(); + W_HideCrosshair(self); + // Play the "prime" animation for the betty viewmodel. Set_W_Frame (0, 18, 1, 0, GRENADE, Betty_CheckForRelease, "models/weapons/grenade/v_betty.mdl", true, S_RIGHT); diff --git a/source/server/weapons/frames_core.qc b/source/server/weapons/frames_core.qc index 867734c..3947c10 100644 --- a/source/server/weapons/frames_core.qc +++ b/source/server/weapons/frames_core.qc @@ -25,6 +25,8 @@ */ +void(entity person) W_ShowCrosshair; + void() ContinueRun = { float startframe; @@ -157,6 +159,8 @@ void () W_Frame_Update = } else { + if (self.callfuncat != self.weaponframe) + W_ShowCrosshair(self); self.weaponframe_end = self.weaponframe = GetFrame(self.weapon,BASE_FRAME); self.new_anim_stop = FALSE; self.weapon_anim_type = 0; diff --git a/source/server/weapons/weapon_core.qc b/source/server/weapons/weapon_core.qc index 454c7b9..9a8d369 100644 --- a/source/server/weapons/weapon_core.qc +++ b/source/server/weapons/weapon_core.qc @@ -36,6 +36,48 @@ void() AI_RevertEnemySolidState float() push_away_zombies; #endif // FTE +// +// W_HideCrosshair(person) +// Toggles off the crosshair for provided client. +// This is considered "nasty" by use of stuffcmd, +// however non-FTE has no way of better controlling +// cvars for individual clients. +// +void(entity person) W_HideCrosshair = +{ + if (person == world) + return; + + stuffcmd(person, "crosshair 0\n"); +} + +// +// W_ShowCrosshair(person) +// Toggles on the crosshair for provided client. +// This is considered "nasty" by use of stuffcmd, +// however non-FTE has no way of better controlling +// cvars for individual clients. +// +void(entity person) W_ShowCrosshair = +{ + if (person == world) + return; + + // Grab the type of crosshair + float crosshair_type; + + // Grenades have a special crosshair type that can pulse. + if (person.grenade_delay) { + crosshair_type = 4; + } else + crosshair_type = WepDef_GetWeaponCrosshairType(person.weapon); + + string crosshair_string = "crosshair "; + crosshair_string = strzone(strcat(crosshair_string, ftos(crosshair_type))); + stuffcmd(person, strcat(crosshair_string, "\n")); + strunzone(crosshair_string); +} + void() ReturnWeaponModel = { self.weaponmodel = GetWeaponModel(self.weapon, 0); @@ -57,11 +99,13 @@ void() ReturnWeaponModel = // If the person is swapping, play the sprint anim if they're sprinting after swap. Otherwise it plays idle if (self.sprinting == TRUE) W_SprintStart(); - + + W_ShowCrosshair(self); } void() W_PlayTakeOut = { + W_HideCrosshair(self); Weapon_PlayViewModelAnimation(ANIM_TAKE_OUT, ReturnWeaponModel, 0); } @@ -197,19 +241,25 @@ void() W_PutOut = // We don't hold more than one weapon if (self.weapons[1].weapon_id == 0 || self.downed) return; + + float duration = getWeaponDelay(self.weapon, PUTOUT); W_AimOut(); + W_HideCrosshair(self); if (self.weapon_count != 1 && !self.new_anim_stop) - Weapon_PlayViewModelAnimation(ANIM_PUT_AWAY, W_PutOutHack, 0); + Weapon_PlayViewModelAnimation(ANIM_PUT_AWAY, W_PutOutHack, duration); } void() W_TakeOut = { self.isBuying = false; + float duration = getWeaponDelay(self.weapon, TAKEOUT); + W_AimOut(); - Weapon_PlayViewModelAnimation(ANIM_TAKE_OUT, SUB_Null, 0); + W_HideCrosshair(self); + Weapon_PlayViewModelAnimation(ANIM_TAKE_OUT, ReturnWeaponModel, duration); } @@ -255,6 +305,8 @@ void() ContinueReload = //Special reloads if (self.weapon == W_GUT && self.weapons[0].weapon_magazine == 10) return; + W_HideCrosshair(self); + float delay = 0; string modelname = GetWeaponModel(self.weapon, 0); float startframe = 0; @@ -359,6 +411,7 @@ void(float side) W_Reload = W_AimOut(); W_SprintStop(); + W_HideCrosshair(self); float endframe, startframe, reloadcancelframe, delay; string modelname = ""; @@ -726,7 +779,7 @@ void() LungeKnifeHit = sound (self, CHAN_WEAPON, "sounds/weapons/knife/knife_hitbod.wav", 1, ATTN_NORM); // Calculate melee damage - f_damage = WepDefp_CalculateMeleeDamage(self.weapon, self.bowie); + f_damage = WepDef_CalculateMeleeDamage(self.weapon, self.bowie); if (trace_ent.classname == "ai_zombie_head") { @@ -1178,6 +1231,8 @@ void () W_Knife = if (self.sprinting) { W_SprintStop(); } + + W_HideCrosshair(self); backupSkin = self.weaponskin; self.weaponskin = 0; @@ -1356,6 +1411,8 @@ void() W_ThrowGrenade = float endframe; local entity nade; + W_HideCrosshair(self); + if (self.pri_grenade_state == 0) { nade = spawn (); nade.owner = self; @@ -1425,7 +1482,18 @@ void() checkHold = } else { - self.isBuying = true; + if (self.isBuying == false) { + W_ShowCrosshair(self); + self.isBuying = true; + } + + // Pulse the grenade crosshair every 1 second + float difference = rint(self.grenade_delay - time); + if (difference != self.beingrevived) { + self.beingrevived = difference; + grenade_pulse(self); + } + Set_W_Frame (2, 2, 0, 0, GRENADE, checkHold, "models/weapons/grenade/v_grenade.mdl", true, S_RIGHT); } } @@ -1440,11 +1508,12 @@ void() W_Grenade = if (self.sprinting) W_SprintStop(); + W_HideCrosshair(self); Set_W_Frame (0, 2, 0.6, 0, GRENADE, checkHold, "models/weapons/grenade/v_grenade.mdl", true, S_RIGHT); sound (self, CHAN_WEAPON, "sounds/weapons/grenade/prime.wav", 1, ATTN_NORM); self.primary_grenades -= 1; self.reload_delay2 = self.fire_delay2 = self.throw_delay = self.reload_delay = self.fire_delay = time + 6; - self.grenade_delay = time + 5.6; + self.grenade_delay = time + 5; self.seminade = true; } diff --git a/source/shared/defs/custom.qc b/source/shared/defs/custom.qc index 4c43aa2..fd1c9ad 100644 --- a/source/shared/defs/custom.qc +++ b/source/shared/defs/custom.qc @@ -55,6 +55,7 @@ const float EVENT_REVIVEOFF = 38; const float EVENT_REVIVECHANGE = 39; const float EVENT_WEAPONRECOIL = 40; const float EVENT_SONGPLAY = 41; +const float EVENT_GRENADEPULSE = 42; // Define our FTE platform #ifndef STANDARD diff --git a/source/shared/weapon_defines.qc b/source/shared/weapon_defines.qc index ef9ee96..c7ba6a9 100644 --- a/source/shared/weapon_defines.qc +++ b/source/shared/weapon_defines.qc @@ -4517,7 +4517,7 @@ float(float wep) GetWeaponZoomAmount = // Returns the amount of melee damage the Player can // do given their weapon and Bowie Knife status. // -float(float weapon, float has_bowie) WepDefp_CalculateMeleeDamage = +float(float weapon, float has_bowie) WepDef_CalculateMeleeDamage = { switch(weapon) { case W_BK: @@ -4618,3 +4618,29 @@ float(string weapon) WepDef_GetWeaponIDFromName = } return W_COLT; } + +// +// WepDef_GetWeaponCrosshairType(weapon) +// Returns the type of crosshair used by active +// weapon. +// 0. No crosshair +// 1. Standard crosshair (+) +// 2. Area of Effect (o) +// 3. Dot crosshair (.) (unused). +// 4 is reserved for the grenade, do not use. +// +float WepDef_GetWeaponCrosshairType(float weapon) +{ + switch(weapon) { + case W_M2: + case W_FIW: + case W_TESLA: + case W_DG3: + return 2; + case W_PANZER: + case W_LONGINUS: + return 0; + default: + return 1; + } +} \ No newline at end of file