/* * Copyright (c) 2016-2020 Marco Cawthorne * Copyright (c) 2019-2020 Gethyn ThomasQuail * * 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 { MACHETTE_IDLE1, MACHETTE_IDLE2, MACHETTE_IDLE3, MACHETTE_THROW, MACHETTE_DRAW, MACHETTE_HOLSTER }; void w_machette_precache(void) { #ifdef SERVER Sound_Precache("weapon_crowbar.hit"); Sound_Precache("weapon_crowbar.miss"); Sound_Precache("weapon_crowbar.hitbody"); precache_model("models/machette.mdl"); precache_model("models/rune_stalker.mdl"); #else precache_model("models/v_machette.mdl"); precache_model("models/p_machette.mdl"); #endif } void w_machette_updateammo(player pl) { w_broom_updateammo(pl); } string w_machette_wmodel(void) { return "models/w_machette.mdl"; } string w_machette_pmodel(player pl) { return "models/p_machette.mdl"; } string w_machette_deathmsg(void) { return ""; } int w_machette_pickup(player pl, int new, int startammo) { #ifdef SERVER /* Broadcast a message and sound upon picking up Rune */ Sound_Play(self, CHAN_ITEM, "weapon_machette.pickup"); env_message_single(self, "Activating Rune STALKER!"); #endif return (1); } void w_machette_draw(player pl) { Weapons_SetModel("models/v_machette.mdl"); Weapons_ViewAnimation(pl, MACHETTE_DRAW); } void w_machette_holster(player pl) { Weapons_ViewAnimation(pl, MACHETTE_HOLSTER); } void w_machette_primary(player pl) { int anim = 0; vector src; if (pl.w_attack_next) { return; } Weapons_MakeVectors(pl); src = pl.origin + pl.view_ofs; traceline(src, src + (v_forward * 32), FALSE, pl); pl.w_attack_next = 0.4f; pl.w_idle_next = 2.5f; Weapons_ViewAnimation(pl, MACHETTE_THROW); if (pl.flags & FL_CROUCHING) { Animation_PlayerTop(pl, ANIM_SHOOTCROWBAR, 0.5f); } else { Animation_PlayerTop(pl, ANIM_CR_SHOOTCROWBAR, 0.42f); } #ifdef SERVER if (trace_fraction >= 1.0) { return; } /* don't bother with decals, we got squibs */ if (trace_ent.iBleeds) { FX_Blood(trace_endpos, [1,0,0]); } else { SurfData_Impact(trace_ent, trace_endpos, trace_plane_normal); } if (trace_ent.takedamage) { Damage_Apply(trace_ent, pl, 5, WEAPON_MACHETTE, DMG_BLUNT); if (trace_ent.iBleeds) { Sound_Play(self, CHAN_WEAPON, "weapon_machette.hitbody"); } } else { Sound_Play(self, CHAN_WEAPON, "weapon_machette.hit"); } #endif } #ifdef SERVER void w_machette_throw(player pl) { static void Machette_Touch(void) { setmodel(self, "models/machette.mdl"); /* squibs */ if (trace_ent.iBleeds) { FX_Blood(trace_endpos, [1,0,0]); remove(self); } else { SurfData_Impact(trace_ent, trace_endpos, trace_plane_normal); } if (other.takedamage == DAMAGE_YES) { Damage_Apply(other, self.owner, 15, WEAPON_MACHETTE, DMG_GENERIC); Sound_Play(self, CHAN_WEAPON, "weapon_machette.hitbody"); } else { Sound_Play(self, CHAN_WEAPON, "weapon_machette.stick"); } self.movetype = MOVETYPE_NONE; } Weapons_MakeVectors(pl); entity machette = spawn(); setmodel(machette, "models/machette.mdl"); setorigin(machette, Weapons_GetCameraPos(pl) + (v_forward * 16)); machette.owner = self; machette.velocity = v_forward * 2000; machette.movetype = MOVETYPE_FLY; machette.solid = SOLID_BBOX; machette.angles = vectoangles(machette.velocity); machette.avelocity[2] = 10; machette.touch = Machette_Touch; setsize(machette, [0,0,0], [0,0,0]); } #endif void w_machette_secondary(player pl) { if (pl.w_attack_next > 0.0) { return; } /* Actual firing */ #ifdef SERVER w_machette_throw(pl); Sound_Play(pl, CHAN_WEAPON, "weapon_machette.throw"); #endif Weapons_ViewPunchAngle(pl, [-2,0,0]); Weapons_ViewAnimation(pl, MACHETTE_THROW); if (self.flags & FL_CROUCHING) Animation_PlayerTop(pl, ANIM_SHOOT1HAND, 0.45f); else Animation_PlayerTop(pl, ANIM_CR_SHOOT1HAND, 0.45f); pl.w_attack_next = 0.5f; pl.w_idle_next = 5.0f; } void w_machette_release(player pl) { if (pl.w_idle_next > 0.0) { return; } int r; r = (float)input_sequence % 3; switch (r) { case 1: Weapons_ViewAnimation(pl, MACHETTE_IDLE1); pl.w_idle_next = 1.3f; break; case 2: Weapons_ViewAnimation(pl, MACHETTE_IDLE2); pl.w_idle_next = 3.0f; break; default: Weapons_ViewAnimation(pl, MACHETTE_IDLE3); pl.w_idle_next = 1.285f; } } float w_machette_aimanim(player pl) { return w_broom_aimanim(pl); } void w_machette_hudpic(player pl, int selected, vector pos, float a) { #ifdef CLIENT if (selected) { drawsubpic( pos, [170,45], "sprites/tfchud04.spr_0.tga", [0,135/256], [170/256,45/256], g_hud_color, a, DRAWFLAG_ADDITIVE ); } else { drawsubpic( pos, [170,45], "sprites/tfchud03.spr_0.tga", [0,90/256], [170/256,45/256], g_hud_color, a, DRAWFLAG_ADDITIVE ); } #endif } int w_machette_isempty(player pl) { return 0; } weapontype_t w_machette_type(player pl) { return WPNTYPE_RANGED; } weapon_t w_machette = { .name = "machette", .id = ITEM_MACHETTE, .slot = 1, .slot_pos = 1, .draw = w_machette_draw, .holster = w_machette_holster, .primary = w_machette_primary, .secondary = w_machette_secondary, .reload = __NULL__, .release = w_machette_release, .postdraw = __NULL__, .precache = w_machette_precache, .pickup = w_machette_pickup, .updateammo = w_machette_updateammo, .wmodel = w_machette_wmodel, .pmodel = w_machette_pmodel, .deathmsg = w_machette_deathmsg, .aimanim = w_machette_aimanim, .hudpic = w_machette_hudpic, .weight = -1, .isempty = w_machette_isempty, .type = w_machette_type }; /* entity definitions for pickups */ #ifdef SERVER void rune_stalker(void) { Weapons_InitItem(WEAPON_MACHETTE); } #endif