diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 1eb555fceaf7..514c3a220112 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -254,7 +254,7 @@ return 1 if("Use unique action") - var/obj/item/weapon/gun/held_item = user.get_held_item() + var/obj/item/weapon/held_item = user.get_held_item() if(istype(held_item)) held_item.use_unique_action() return 1 diff --git a/code/datums/keybinding/human_combat.dm b/code/datums/keybinding/human_combat.dm index d30414d68563..5517f42c41ea 100644 --- a/code/datums/keybinding/human_combat.dm +++ b/code/datums/keybinding/human_combat.dm @@ -6,7 +6,7 @@ if(!.) return var/mob/user_mob = user.mob - return isgun(user_mob.get_held_item()) + return isweapon(user_mob.get_held_item()) /datum/keybinding/human/combat/field_strip_weapon hotkey_keys = list("Unbound") @@ -101,7 +101,7 @@ if(.) return var/mob/living/carbon/human/human = user.mob - var/obj/item/weapon/gun/held_item = human.get_held_item() + var/obj/item/weapon/held_item = human.get_held_item() held_item.use_unique_action() return TRUE diff --git a/code/game/objects/items/weapons/weapon.dm b/code/game/objects/items/weapons/weapon.dm index 3d53dfb86b73..34d04b9cff65 100644 --- a/code/game/objects/items/weapons/weapon.dm +++ b/code/game/objects/items/weapons/weapon.dm @@ -3,6 +3,12 @@ name = "weapon" icon = 'icons/obj/items/weapons/weapons.dmi' hitsound = "swing_hit" + var/has_unique_action = FALSE + +/obj/item/weapon/Initialize(mapload, ...) + . = ..() + if(!has_unique_action) + verbs -= /obj/item/weapon/verb/use_unique_action /obj/item/get_examine_text(mob/user) . = ..() diff --git a/code/modules/cm_preds/smartdisc.dm b/code/modules/cm_preds/smartdisc.dm index f0262f5f140a..7925e7193269 100644 --- a/code/modules/cm_preds/smartdisc.dm +++ b/code/modules/cm_preds/smartdisc.dm @@ -17,8 +17,8 @@ unacidable = TRUE embeddable = FALSE - force = 15 - throwforce = 25 + force = MELEE_FORCE_WEAK + throwforce = MELEE_FORCE_NORMAL /obj/item/explosive/grenade/spawnergrenade/smartdisc/launch_towards(datum/launch_metadata/LM) ..() diff --git a/code/modules/cm_preds/yaut_weapons.dm b/code/modules/cm_preds/yaut_weapons.dm index 9cb8a8bef3fc..818153e10192 100644 --- a/code/modules/cm_preds/yaut_weapons.dm +++ b/code/modules/cm_preds/yaut_weapons.dm @@ -2,6 +2,20 @@ #define FLAY_STAGE_STRIP 2 #define FLAY_STAGE_SKIN 3 +#define ABILITY_COST_DEFAULT 1 +#define ABILITY_COST_CHAIN 0 +#define ABILITY_COST_SCYTHE 5 +#define ABILITY_COST_SWORD 0 +#define ABILITY_COST_GLAIVE 0 + +#define ABILITY_CHARGE_SMALL 0.5 +#define ABILITY_CHARGE_NORMAL 1 +#define ABILITY_CHARGE_LARGE 2 + +#define ABILITY_MAX_SMALL 1 +#define ABILITY_MAX_DEFAULT 2 +#define ABILITY_MAX_LARGE 5 + /*######################################### ########### Weapon Reused Procs ########### #########################################*/ @@ -127,7 +141,7 @@ item_state = "scim" attack_speed = 5 attack_verb = list("sliced", "slashed", "jabbed", "torn", "gored") - force = MELEE_FORCE_TIER_5 + force = MELEE_FORCE_TIER_6 has_speed_bonus = FALSE /*######################################### @@ -141,6 +155,45 @@ WEAR_R_HAND = 'icons/mob/humans/onmob/hunter/items_righthand.dmi' ) var/human_adapted = FALSE + ///The amount this weapon interrupts hivemind link on Xenomorphs. + var/xeno_interfere_amount = 30 + + ///The amount of charges towards use of special abilities. + var/ability_charge = 0 + var/ability_charge_max = ABILITY_MAX_DEFAULT + var/ability_charge_rate = ABILITY_CHARGE_NORMAL + var/ability_cost = ABILITY_COST_DEFAULT + ///Whether the ability is ready to trigger + var/ability_primed = FALSE + + +/obj/item/weapon/yautja/dropped() + if(ability_primed) + ability_primed = FALSE + ..() + +/obj/item/weapon/yautja/attack(mob/living/target, mob/living/carbon/human/user) + . = ..() + if(!.) + return + if((human_adapted || isspeciesyautja(user)) && isxeno(target)) + var/mob/living/carbon/xenomorph/xenomorph = target + xenomorph.interference = xeno_interfere_amount + + if(target == user || target.stat == DEAD || isanimal(target)) + to_chat(user, SPAN_DANGER("You think you're smart?")) //very funny + return + + if(ability_charge < ability_charge_max) + ability_charge += ability_charge_rate + +/obj/item/weapon/yautja/unique_action(mob/user) + if(user.get_active_hand() != src) + return FALSE + if(ability_charge < ability_cost) + to_chat(user, SPAN_WARNING("The blood reservoir is not full enough to do this!")) + return FALSE + return TRUE /obj/item/weapon/yautja/chain name = "chainwhip" @@ -153,8 +206,8 @@ embeddable = FALSE w_class = SIZE_MEDIUM unacidable = TRUE - force = MELEE_FORCE_TIER_6 - throwforce = MELEE_FORCE_TIER_5 + force = MELEE_FORCE_TIER_7 + throwforce = MELEE_FORCE_TIER_4 sharp = IS_SHARP_ITEM_SIMPLE edge = TRUE attack_verb = list("whipped", "slashed","sliced","diced","shredded") @@ -164,9 +217,6 @@ /obj/item/weapon/yautja/chain/attack(mob/target, mob/living/user) . = ..() - if((human_adapted || isyautja(user)) && isxeno(target)) - var/mob/living/carbon/xenomorph/xenomorph = target - xenomorph.interference = 30 /obj/item/weapon/yautja/sword name = "clan sword" @@ -186,12 +236,6 @@ attack_speed = 1 SECONDS unacidable = TRUE -/obj/item/weapon/yautja/sword/attack(mob/target, mob/living/user) - . = ..() - if((human_adapted || isyautja(user)) && isxeno(target)) - var/mob/living/carbon/xenomorph/xenomorph = target - xenomorph.interference = 30 - /obj/item/weapon/yautja/scythe name = "dual war scythe" desc = "A huge, incredibly sharp dual blade used for hunting dangerous prey. This weapon is commonly carried by Yautja who wish to disable and slice apart their foes." @@ -200,7 +244,7 @@ flags_atom = FPRINT|CONDUCT flags_item = ITEM_PREDATOR flags_equip_slot = SLOT_WAIST - force = MELEE_FORCE_TIER_6 + force = MELEE_FORCE_TIER_7 throwforce = MELEE_FORCE_TIER_5 sharp = IS_SHARP_ITEM_SIMPLE edge = TRUE @@ -209,19 +253,59 @@ hitsound = 'sound/weapons/bladeslice.ogg' attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") unacidable = TRUE + has_unique_action = TRUE + + ability_cost = ABILITY_COST_SCYTHE + ability_charge_max = ABILITY_COST_SCYTHE + ability_charge_rate = ABILITY_CHARGE_NORMAL /obj/item/weapon/yautja/scythe/attack(mob/living/target as mob, mob/living/carbon/human/user as mob) ..() - if((human_adapted || isyautja(user)) && isxeno(target)) - var/mob/living/carbon/xenomorph/xenomorph = target - xenomorph.interference = 15 + if(ability_charge >= ability_cost) + var/color = BLOOD_COLOR_HUMAN + var/alpha = 70 + color += num2text(alpha, 2, 16) + add_filter("scythe_ready", 1, list("type" = "outline", "color" = color, "size" = 2)) - if(prob(15)) - user.visible_message(SPAN_DANGER("An opening in combat presents itself!"),SPAN_DANGER("You manage to strike at your foe once more!")) - user.spin(5, 1) - ..() //Do it again! CRIT! This will be replaced by a bleed effect. +/obj/item/weapon/yautja/scythe/attack_self(mob/user) + ..() + ability_primed = !ability_primed + var/message = "You tighten your grip on [src], preparing to whirl it in a spin." + if(!ability_primed) + message = "You relax your grip on [src]." + to_chat(user, SPAN_WARNING(message)) - return +/obj/item/weapon/yautja/scythe/unique_action(mob/user) + . = ..() + if(!.) + return + if(!ability_primed) + to_chat(user, SPAN_WARNING("You need a stronger grip for this!")) + return FALSE + user.spin_circle(2) + for(var/mob/living/carbon/target in orange(1, user)) + if(!isxeno_human(target) || isyautja(target)) + continue + + if(target.stat == DEAD) + continue + + if(!check_clear_path_to_target(user, target)) + continue + + user.visible_message(SPAN_HIGHDANGER("[user] slices open the guts of [target]!"), SPAN_HIGHDANGER("You slice open the guts of [target]!")) + target.spawn_gibs() + playsound(get_turf(target), 'sound/effects/gibbed.ogg', 30, 1) + target.apply_effect(get_xeno_stun_duration(target, 1), WEAKEN) + target.apply_armoured_damage(get_xeno_damage_slash(target, (force * 1.5)), ARMOR_MELEE, BRUTE, "chest", 40) + + user.attack_log += text("\[[time_stamp()]\] [key_name(user)] sliced [key_name(target)] with their whirling scythe.") + target.attack_log += text("\[[time_stamp()]\] [key_name(target)] was sliced by [key_name(user)] whirling their scythe.") + log_attack("[key_name(target)] was sliced by [key_name(user)] whirling their scythe.") + + ability_charge -= ability_cost + remove_filter("scythe_ready") + return TRUE /obj/item/weapon/yautja/scythe/alt name = "double war scythe" @@ -234,6 +318,7 @@ name = "combi-stick" desc = "A compact yet deadly personal weapon. Can be concealed when folded. Functions well as a throwing weapon or defensive tool. A common sight in Yautja packs due to its versatility." icon_state = "combistick" + has_unique_action = TRUE flags_atom = FPRINT|CONDUCT flags_equip_slot = SLOT_BACK flags_item = TWOHANDED|ITEM_PREDATOR @@ -243,14 +328,17 @@ throw_range = 4 unacidable = TRUE force = MELEE_FORCE_TIER_6 - throwforce = MELEE_FORCE_TIER_6 + throwforce = MELEE_FORCE_TIER_7 sharp = IS_SHARP_ITEM_SIMPLE edge = TRUE hitsound = 'sound/weapons/bladeslice.ogg' attack_verb = list("speared", "stabbed", "impaled") + ability_cost = ABILITY_COST_DEFAULT + ability_charge_max = ABILITY_MAX_DEFAULT + ability_charge_rate = ABILITY_CHARGE_SMALL + var/on = TRUE - var/charged = FALSE var/force_wielded = MELEE_FORCE_TIER_6 var/force_unwielded = MELEE_FORCE_TIER_2 @@ -270,11 +358,12 @@ setup_chain(user) /obj/item/weapon/yautja/combistick/try_to_throw(mob/living/user) - if(!charged) + if(ability_charge < ability_cost) to_chat(user, SPAN_WARNING("Your combistick refuses to leave your hand. You must charge it with blood from prey before throwing it.")) return FALSE - charged = FALSE - remove_filter("combistick_charge") + ability_charge -= ability_cost + if(ability_charge < ability_cost) + remove_filter("combistick_charge") unwield(user) //Otherwise stays wielded even when thrown return TRUE @@ -400,7 +489,6 @@ flags_item |= TWOHANDED w_class = SIZE_LARGE force = force_unwielded - throwforce = MELEE_FORCE_TIER_6 attack_verb = list("speared", "stabbed", "impaled") if(blood_overlay && blood_color) @@ -417,7 +505,6 @@ flags_item &= ~TWOHANDED w_class = SIZE_TINY force = force_storage - throwforce = MELEE_FORCE_TIER_6 attack_verb = list("thwacked", "smacked") overlays.Cut() on = FALSE @@ -436,23 +523,16 @@ . = ..() if(!.) return - if((human_adapted || isspeciesyautja(user)) && isxeno(target)) - var/mob/living/carbon/xenomorph/xenomorph = target - xenomorph.interference = 30 - if(target == user || target.stat == DEAD) - to_chat(user, SPAN_DANGER("You think you're smart?")) //very funny - return - if(isanimal(target)) - return - - if(!charged) - to_chat(user, SPAN_DANGER("Your combistick's reservoir fills up with your opponent's blood! You may now throw it!")) - charged = TRUE - var/color = target.get_blood_color() - var/alpha = 70 - color += num2text(alpha, 2, 16) - add_filter("combistick_charge", 1, list("type" = "outline", "color" = color, "size" = 2)) + if((ability_charge < ability_charge_max)) + to_chat(user, SPAN_DANGER("Your combistick's reservoir fills up with your opponent's blood!")) + ability_charge += ability_charge_rate + if(ability_charge >= ability_cost) + to_chat(user, SPAN_DANGER("You may now throw your combistick!")) + var/color = target.get_blood_color() + var/alpha = 70 + color += num2text(alpha, 2, 16) + add_filter("combistick_charge", 1, list("type" = "outline", "color" = color, "size" = 2)) /obj/item/weapon/yautja/combistick/attack_hand(mob/user) //Prevents marines from instantly picking it up via pickup macros. if(!human_adapted && !HAS_TRAIT(user, TRAIT_SUPER_STRONG)) @@ -700,7 +780,7 @@ icon_state = "spearhunter" item_state = "spearhunter" flags_item = NOSHIELD|TWOHANDED - force = MELEE_FORCE_TIER_3 + force = MELEE_FORCE_TIER_4 force_wielded = MELEE_FORCE_TIER_7 sharp = IS_SHARP_ITEM_SIMPLE attack_verb = list("attacked", "stabbed", "jabbed", "torn", "gored") @@ -755,7 +835,7 @@ icon_state = "glaive" item_state = "glaive" force = MELEE_FORCE_TIER_3 - force_wielded = MELEE_FORCE_TIER_9 + force_wielded = MELEE_FORCE_TIER_10 throwforce = MELEE_FORCE_TIER_3 embeddable = FALSE //so predators don't lose their glaive when thrown. sharp = IS_SHARP_ITEM_BIG @@ -763,14 +843,6 @@ attack_verb = list("sliced", "slashed", "carved", "diced", "gored") attack_speed = 14 //Default is 7. -/obj/item/weapon/twohanded/yautja/glaive/attack(mob/living/target, mob/living/carbon/human/user) - . = ..() - if(!.) - return - if((human_adapted || isyautja(user)) && isxeno(target)) - var/mob/living/carbon/xenomorph/xenomorph = target - xenomorph.interference = 30 - /obj/item/weapon/twohanded/yautja/glaive/alt icon_state = "glaive_alt" item_state = "glaive_alt" @@ -817,6 +889,7 @@ var/last_regen flags_gun_features = GUN_UNUSUAL_DESIGN flags_item = ITEM_PREDATOR|TWOHANDED + has_unique_action = FALSE /obj/item/weapon/gun/launcher/spike/process() if(spikes < max_spikes && world.time > last_regen + 100 && prob(70)) @@ -832,7 +905,6 @@ verbs -= /obj/item/weapon/gun/verb/field_strip verbs -= /obj/item/weapon/gun/verb/use_toggle_burst verbs -= /obj/item/weapon/gun/verb/empty_mag - verbs -= /obj/item/weapon/gun/verb/use_unique_action /obj/item/weapon/gun/launcher/spike/set_gun_config_values() ..() @@ -916,6 +988,8 @@ var/last_regen = 0 flags_gun_features = GUN_UNUSUAL_DESIGN flags_item = ITEM_PREDATOR|TWOHANDED + has_unique_action = FALSE + flags_item = ITEM_PREDATOR|TWOHANDED /obj/item/weapon/gun/energy/yautja/plasmarifle/Initialize(mapload, spawn_empty) . = ..() @@ -926,7 +1000,6 @@ verbs -= /obj/item/weapon/gun/verb/field_strip verbs -= /obj/item/weapon/gun/verb/use_toggle_burst verbs -= /obj/item/weapon/gun/verb/empty_mag - verbs -= /obj/item/weapon/gun/verb/use_unique_action /obj/item/weapon/gun/energy/yautja/plasmarifle/process() if(charge_time < 100) @@ -1024,7 +1097,6 @@ verbs -= /obj/item/weapon/gun/verb/empty_mag - /obj/item/weapon/gun/energy/yautja/plasmapistol/Destroy() . = ..() STOP_PROCESSING(SSobj, src) @@ -1037,7 +1109,6 @@ if(ismob(loc)) to_chat(loc, SPAN_NOTICE("[src] hums as it achieves maximum charge.")) - /obj/item/weapon/gun/energy/yautja/plasmapistol/set_gun_config_values() ..() set_fire_delay(FIRE_DELAY_TIER_7) @@ -1091,7 +1162,7 @@ log_debug("Plasma Pistol refunded shot.") return TRUE -/obj/item/weapon/gun/energy/yautja/plasmapistol/use_unique_action() +/obj/item/weapon/gun/energy/yautja/plasmapistol/unique_action() switch(mode) if(FIRE_MODE_STANDARD) mode = FIRE_MODE_INCENDIARY @@ -1214,7 +1285,7 @@ to_chat(user, SPAN_NOTICE("[src] will now fire [strength].")) ammo = GLOB.ammo_list[/datum/ammo/energy/yautja/caster/bolt] -/obj/item/weapon/gun/energy/yautja/plasma_caster/use_unique_action() +/obj/item/weapon/gun/energy/yautja/plasma_caster/unique_action() switch(mode) if("stun") mode = "lethal" diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 21af882376eb..7bc6be190590 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -95,7 +95,7 @@ Contains most of the procs that are called when a mob is attacked by something /mob/living/carbon/human/proc/check_shields(damage = 0, attack_text = "the attack", combistick=0) if(l_hand && istype(l_hand, /obj/item/weapon))//Current base is the prob(50-d/3) - if(combistick && istype(l_hand,/obj/item/weapon/yautja/combistick) && prob(66)) + if(combistick && istype(l_hand,/obj/item/weapon/yautja/combistick) && prob(33)) var/obj/item/weapon/yautja/combistick/C = l_hand if(C.on) return TRUE @@ -120,7 +120,7 @@ Contains most of the procs that are called when a mob is attacked by something return TRUE if(r_hand && istype(r_hand, /obj/item/weapon)) - if(combistick && istype(r_hand,/obj/item/weapon/yautja/combistick) && prob(66)) + if(combistick && istype(r_hand,/obj/item/weapon/yautja/combistick) && prob(33)) var/obj/item/weapon/yautja/combistick/C = r_hand if(C.on) return TRUE diff --git a/code/modules/mob/living/carbon/xenomorph/attack_alien.dm b/code/modules/mob/living/carbon/xenomorph/attack_alien.dm index 2aefff19c684..dcbb3d8fa81f 100644 --- a/code/modules/mob/living/carbon/xenomorph/attack_alien.dm +++ b/code/modules/mob/living/carbon/xenomorph/attack_alien.dm @@ -107,7 +107,8 @@ knock_chance += 2 * M.frenzy_aura if(M.caste && M.caste.is_intelligent) knock_chance += 2 - knock_chance += min(round(damage * 0.25), 10) //Maximum of 15% chance. + knock_chance += min(round(damage * 0.25), 10) + knock_chance = min(knock_chance, 15)//Maximum of 15% chance. if(prob(knock_chance)) playsound(loc, "alien_claw_metal", 25, 1) M.visible_message(SPAN_DANGER("[M] smashes off [src]'s [wear_mask.name]!"), \ diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 3f7533f26620..a2efc89bafdb 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -7,6 +7,7 @@ icon = 'icons/obj/items/weapons/guns/guns_by_faction/uscm.dmi' icon_state = "" item_state = "gun" + has_unique_action = TRUE pickup_sound = "gunequip" drop_sound = "gunrustle" pickupvol = 7 diff --git a/code/modules/projectiles/gun_helpers.dm b/code/modules/projectiles/gun_helpers.dm index 66e3a65f2f77..e2e7a0da86bb 100644 --- a/code/modules/projectiles/gun_helpers.dm +++ b/code/modules/projectiles/gun_helpers.dm @@ -749,19 +749,21 @@ DEFINES in setup.dm, referenced here. unload(user, FALSE, drop_to_ground) //We want to drop the mag on the ground. -/obj/item/weapon/gun/verb/use_unique_action() +/obj/item/weapon/verb/use_unique_action() set category = "Weapons" set name = "Unique Action" - set desc = "Use anything unique your firearm is capable of. Includes pumping a shotgun or spinning a revolver. If you have an active attachment, this will activate on the attachment instead." - set src = usr.contents + set desc = "Use anything unique your weapon is capable of. Includes pumping a shotgun or spinning a revolver. If you have an active gun attachment, this will activate on the attachment instead." - var/obj/item/weapon/gun/active_firearm = get_active_firearm(usr) - if(!active_firearm) + var/obj/item/weapon/current_weapon = usr.get_held_item() + if(!current_weapon) + to_chat(usr, SPAN_WARNING("Your weapon must be in your hand to do that.")) return - if(active_firearm.active_attachable) - src = active_firearm.active_attachable - else - src = active_firearm + if(isgun(current_weapon)) + var/obj/item/weapon/gun/firearm = current_weapon + if(firearm.active_attachable) + src = firearm.active_attachable + else + src = firearm unique_action(usr)