/* * 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. */ /*QUAKED weapon_hairspray (0 0 1) (-16 -16 0) (16 16 32) "model" "models/w_knife.mdl" Household DEATH! (2003) ENTITY Flamethrower Hairspray Weapon */ enum { HAIRSPRAY_IDLE, HAIRSPRAY_FIRE, HAIRSPRAY_DRAW, HAIRSPRAY_HOLSTER }; void w_hairspray_precache(void) { #ifdef SERVER Sound_Precache("weapon_hairspray.fire"); precache_model("models/w_hairspray.mdl"); precache_model("sprites/flame.spr"); #else precache_model("sprites/hud_haircan.spr"); precache_model("models/v_hairspray.mdl"); precache_model("models/p_hairspray.mdl"); #endif } void w_hairspray_updateammo(player pl) { Weapons_UpdateAmmo(pl, -1, pl.ammo_spray, -1); } string w_hairspray_wmodel(void) { return "models/w_hairspray.mdl"; } string w_hairspray_pmodel(player pl) { return "models/p_hairspray.mdl"; } string w_hairspray_deathmsg(void) { return ""; } int w_hairspray_pickup(player pl, int new, int startammo) { #ifdef SERVER if (pl.ammo_spray < MAX_A_SPRAY) { pl.ammo_spray = bound(0, pl.ammo_spray + 20, MAX_A_SPRAY); } else { return (0); } #endif return (1); } void w_hairspray_draw(player pl) { Weapons_SetModel("models/v_hairspray.mdl"); Weapons_ViewAnimation(pl, HAIRSPRAY_DRAW); } void w_hairspray_holster(player pl) { Weapons_ViewAnimation(pl, HAIRSPRAY_HOLSTER); } #ifdef SERVER void Flame_Touch(void) { if (other.takedamage != DAMAGE_YES) { remove(self); return; } /* anything else that can take damage */ Damage_Apply(other, self.owner, 40, WEAPON_HAIRSPRAY, DMG_BURN); remove(self); } #endif void w_hairspray_primary(player pl) { if (pl.w_attack_next > 0.0) { return; } /* Ammo check */ if (pl.ammo_spray <= 0) { return; } Weapons_ViewAnimation(pl, HAIRSPRAY_FIRE); pl.ammo_spray--; /* Actual firing */ #ifdef SERVER static void w_flamer_die(void) { NSEntity::Destroy(); } static void w_flamer_touch(entity target, entity source) { NSEntity me = (NSEntity)source; if (target.takedamage == DAMAGE_YES) { NSSurfacePropEntity m = (NSSurfacePropEntity)target; m.Ignite(source, 5.0f, WEAPON_HAIRSPRAY); } } Sound_Play(pl, CHAN_WEAPON, "weapon_hairspray.fire"); NSProjectile ball = spawn(NSProjectile); ball.SetModel("sprites/flame.spr"); ball.SetRenderMode(RM_ADDITIVE); ball.SetRenderColor([1,1,1]); ball.SetRenderAmt(1.0); ball.SetOwner(pl); ball.SetImpact(w_flamer_touch); ball.AnimateOnce(0, 28, 0.1f); // To be added to spec // ball.Animate(0,15); // ball.effects |= EF_BRIGHTLIGHT; // Also will need check for water contents (so projectile will die underwater) Weapons_MakeVectors(pl); ball.SetOrigin(Weapons_GetCameraPos(pl) + (v_forward * 16)); ball.SetVelocity(v_forward * 300); /* Remove weapon if we run out of ammo */ if (pl.ammo_spray <= 0) { Weapons_RemoveItem(pl, WEAPON_HAIRSPRAY); return; } #endif pl.w_attack_next = 0.1f; pl.w_idle_next = 2.5f; } void w_hairspray_release(player pl) { if (pl.w_idle_next) { return; } sound(pl, CHAN_WEAPON, "", 1.0, ATTN_NORM); Weapons_ViewAnimation(pl, HAIRSPRAY_IDLE); pl.w_idle_next = 2.0f; } void w_hairspray_crosshair(player pl) { #ifdef CLIENT static vector cross_pos; cross_pos = g_hudmins + (g_hudres / 2) + [-12,-12]; drawsubpic( cross_pos, [32,32], g_crossSoda, [0,0], [1, 1], [1,0,0], 1, DRAWFLAG_NORMAL ); HUD_DrawAmmo2(); vector aicon_pos = g_hudmins + [g_hudres[0] - 42, g_hudres[1] - 64]; drawpic( aicon_pos, "sprites/hud_haircan.spr_0.tga", [32,64], [1,1,1], pSeatLocal->m_flAmmo2Alpha, 0 ); #endif } float w_hairspray_aimanim(player pl) { return self.flags & FL_CROUCHING ? ANIM_CR_AIMBOW : ANIM_AIMBOW; } int w_hairspray_isempty(player pl) { return 0; } void w_hairspray_hudpic(player pl, int selected, vector pos, float a) { #ifdef CLIENT if (w_hairspray_isempty(pl)) { drawsubpic( pos, [80,40], g_sprWeapons, [160/256,40/256], [80/256,40/256], [1,1,1], a, DRAWFLAG_NORMAL ); } else { drawsubpic( pos, [80,40], g_sprWeapons, [160/256,0], [80/256,40/256], [1,1,1], a, DRAWFLAG_NORMAL ); } #endif } weapontype_t w_hairspray_type(player pl) { return WPNTYPE_CLOSE; } weapon_t w_hairspray = { .name = "flame", .id = ITEM_HAIRSPRAY, .slot = 0, .slot_pos = 6, .draw = w_hairspray_draw, .holster = w_hairspray_holster, .primary = w_hairspray_primary, .secondary = __NULL__, .reload = __NULL__, .release = w_hairspray_release, .postdraw = w_hairspray_crosshair, .precache = w_hairspray_precache, .pickup = w_hairspray_pickup, .updateammo = w_hairspray_updateammo, .wmodel = w_hairspray_wmodel, .pmodel = w_hairspray_pmodel, .deathmsg = w_hairspray_deathmsg, .aimanim = w_hairspray_aimanim, .hudpic = w_hairspray_hudpic, .weight = 8, .isempty = w_hairspray_isempty, .type = w_hairspray_type }; #ifdef SERVER void weapon_hairspray(void) { Weapons_InitItem(WEAPON_HAIRSPRAY); /*item_pickup item = (item_pickup)self; item.SetRenderMode(RM_FULLBRIGHT); item.SetRenderAmt(1.0f);*/ } #endif