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 5dd98bfa5708..bca2156f831a 100644
--- a/code/game/objects/items/weapons/weapon.dm
+++ b/code/game/objects/items/weapons/weapon.dm
@@ -4,6 +4,12 @@
icon = 'icons/obj/items/weapons/weapons.dmi'
hitsound = "swing_hit"
flags_atom = FPRINT|QUICK_DRAWABLE
+ 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_hudprocs.dm b/code/modules/cm_preds/yaut_hudprocs.dm
index 460cad894c6d..93fb98f1c304 100644
--- a/code/modules/cm_preds/yaut_hudprocs.dm
+++ b/code/modules/cm_preds/yaut_hudprocs.dm
@@ -85,7 +85,7 @@
// List all possible preys
// We only target living humans and xenos
var/list/target_list = list()
- for(var/mob/living/prey in view(7, usr.client))
+ for(var/mob/living/prey in view(7, usr.client.eye))
if((ishuman_strict(prey) || isxeno(prey)) && prey.stat != DEAD)
target_list += prey
@@ -149,7 +149,7 @@
return
var/list/target_list = list()
- for(var/mob/living/carbon/target in view(7, usr.client))
+ for(var/mob/living/carbon/target in view(7, usr.client.eye))
if(ishuman_strict(target) && (target.stat != DEAD))
target_list += target
@@ -186,7 +186,7 @@
return
var/list/target_list = list()
- for(var/mob/living/carbon/target in view(7, usr.client))
+ for(var/mob/living/carbon/target in view(7, usr.client.eye))
if(ishuman_strict(target) && (target.stat != DEAD))
if(target.hunter_data.honored)
target_list += target
@@ -223,7 +223,7 @@
return
var/list/target_list = list()
- for(var/mob/living/carbon/target in view(7, usr.client))
+ for(var/mob/living/carbon/target in view(7, usr.client.eye))
if((ishuman_strict(target) || isxeno(target)) && target.stat != DEAD)
target_list += target
@@ -263,7 +263,7 @@
return
var/list/target_list = list()
- for(var/mob/living/carbon/target in view(7, usr.client))
+ for(var/mob/living/carbon/target in view(7, usr.client.eye))
if((ishuman_strict(target) || isxeno(target)) && target.stat != DEAD)
if(target.job != "Predalien" && target.job != "Predalien Larva")
if(target.hunter_data.dishonored)
@@ -304,7 +304,7 @@
return
var/list/target_list = list()
- for(var/mob/living/carbon/target in view(7, usr.client))
+ for(var/mob/living/carbon/target in view(7, usr.client.eye))
if((ishuman_strict(target) && target.stat != DEAD))
target_list += target
@@ -335,7 +335,7 @@
return
var/list/target_list = list()
- for(var/mob/living/carbon/target in view(7, usr.client))
+ for(var/mob/living/carbon/target in view(7, usr.client.eye))
if((ishuman_strict(target) && target.stat != DEAD))
if(target.hunter_data.gear)
target_list += target
@@ -376,7 +376,7 @@
// List all possible targets
// We only target living humans
var/list/target_list = list()
- for(var/mob/living/carbon/target in view(7, usr.client))
+ for(var/mob/living/carbon/target in view(7, usr.client.eye))
if(ishuman_strict(target) && target.stat != DEAD)
target_list += target
@@ -415,7 +415,7 @@
// List all possible targets
// We only target living humans
var/list/target_list = list()
- for(var/mob/living/carbon/target in view(7, usr.client))
+ for(var/mob/living/carbon/target in view(7, usr.client.eye))
if(ishuman_strict(target) && target.stat != DEAD)
if(target.hunter_data.thralled)
target_list += target
diff --git a/code/modules/cm_preds/yaut_weapons.dm b/code/modules/cm_preds/yaut_weapons.dm
index 55e1d427eca2..02f437dd75f8 100644
--- a/code/modules/cm_preds/yaut_weapons.dm
+++ b/code/modules/cm_preds/yaut_weapons.dm
@@ -2,6 +2,23 @@
#define FLAY_STAGE_STRIP 2
#define FLAY_STAGE_SKIN 3
+#define ABILITY_COST_COMBI 1
+#define ABILITY_COST_CHAIN 3
+#define ABILITY_COST_SCYTHE 5
+#define ABILITY_COST_SWORD 0
+#define ABILITY_COST_GLAIVE 0
+#define ABILITY_COST_NO_ABILITY 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
+
+#define ABILITY_FILTER_NAME "ability_charge"
+
/*#########################################
########### Weapon Reused Procs ###########
#########################################*/
@@ -34,7 +51,7 @@
attack_verb = list("jabbed","stabbed","ripped", "skewered")
throw_range = 4
unacidable = TRUE
- edge = 1
+ edge = TRUE
hitsound = 'sound/weapons/bladeslice.ogg'
sharp = IS_SHARP_ITEM_BIG
@@ -127,7 +144,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
/obj/item/weapon/wristblades/scimitar/alt
@@ -150,88 +167,254 @@
WEAR_L_HAND = 'icons/mob/humans/onmob/hunter/items_lefthand.dmi',
WEAR_R_HAND = 'icons/mob/humans/onmob/hunter/items_righthand.dmi'
)
+
+ flags_atom = FPRINT|QUICK_DRAWABLE|CONDUCT
+ flags_item = ITEM_PREDATOR
+ unacidable = TRUE
+ edge = TRUE
+ w_class = SIZE_LARGE
+ embeddable = FALSE
+
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_NO_ABILITY
+ ///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.AddComponent(/datum/component/status_effect/interference, xeno_interfere_amount, xeno_interfere_amount)
+
+ if(!ability_cost || !(HAS_TRAIT(user, TRAIT_YAUTJA_TECH)))
+ return
+
+ progress_ability(target, user)
+
+/obj/item/weapon/yautja/proc/progress_ability(mob/living/target, mob/living/carbon/human/user)
+ if(target == user || target.stat == DEAD || isanimal(target))
+ to_chat(user, SPAN_DANGER("You think you're smart?")) //very funny
+ return FALSE
+
+ if(ability_charge < ability_charge_max)
+ ability_charge = min(ability_charge_max, ability_charge + ability_charge_rate)
+ to_chat(user, SPAN_DANGER("[src]'s reservoir fills up with your opponent's blood!"))
+
+ if(ability_charge >= ability_cost)
+ ready_ability(target, user)
+ return TRUE
+
+/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/get_examine_text(mob/user)
+ . = ..()
+ if(isyautja(user) && ability_cost)
+ . += SPAN_WARNING("It currently has [ability_charge]/[ability_charge_max] blood charge(s).")
+ . += SPAN_ORANGE("It requires [ability_cost] blood charge(s) to use its ability.")
+
+/obj/item/weapon/yautja/proc/ready_ability(mob/living/target as mob, mob/living/carbon/human/user as mob)
+ if(ability_charge >= ability_cost)
+ var/color = target.get_blood_color()
+ var/alpha = 70
+ color += num2text(alpha, 2, 16)
+ add_filter(ABILITY_FILTER_NAME, 1, list("type" = "outline", "color" = color, "size" = 2))
+ return TRUE
+ return FALSE
/obj/item/weapon/yautja/chain
name = "chainwhip"
desc = "A segmented, lightweight whip made of durable, acid-resistant metal. Not very common among Yautja Hunters, but still a dangerous weapon capable of shredding prey."
icon_state = "whip"
item_state = "whip"
- flags_atom = FPRINT|QUICK_DRAWABLE|CONDUCT
flags_item = ITEM_PREDATOR
flags_equip_slot = SLOT_WAIST
- 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")
attack_speed = 0.8 SECONDS
hitsound = 'sound/weapons/chain_whip.ogg'
+ ability_cost = ABILITY_COST_CHAIN
+ ability_charge_max = ABILITY_COST_CHAIN
-/obj/item/weapon/yautja/chain/attack(mob/target, mob/living/user)
+ var/chain_range = 3
+ var/chain_duration = 30 SECONDS
+ var/mob/trapped_mob
+ var/datum/effects/tethering/tether_effect
+
+/obj/item/weapon/yautja/chain/progress_ability(mob/living/target, mob/living/carbon/human/user)
+ if(trapped_mob)
+ return FALSE//No recharging ability while a mob is already captured.
+ ..()
+
+/obj/item/weapon/yautja/chain/attack_self(mob/user)
+ ..()
+ if(trapped_mob)
+ var/choice = tgui_alert(user, "Do you wish to release your captive?", "Confirmation", list("Yes", "No"))
+ if(choice != "Yes")
+ return FALSE
+ release_capture(user)
+ reset_tether()
+ return TRUE
+ if(!(ability_charge >= ability_cost))
+ return FALSE
+ ability_primed = !ability_primed
+ var/message = "You tighten your grip on [src], preparing to whirl it around your target."
+ if(!ability_primed)
+ message = "You relax your grip on [src]."
+ to_chat(user, SPAN_WARNING(message))
+ return TRUE
+
+/obj/item/weapon/yautja/chain/attack(mob/living/target, mob/living/carbon/human/user)
. = ..()
- if((human_adapted || isyautja(user)) && isxeno(target))
- var/mob/living/carbon/xenomorph/xenomorph = target
- xenomorph.AddComponent(/datum/component/status_effect/interference, 30, 30)
+ if(!.)
+ return
+ if(ability_primed)
+ capture_target(user, target)
+
+/obj/item/weapon/yautja/chain/proc/capture_target(mob/living/user, mob/living/target)
+ var/real_chain_duration = chain_duration
+ var/real_chain_range = chain_range
+ if(target.mob_size >= MOB_SIZE_BIG)
+ real_chain_duration = (chain_duration / 2)
+ real_chain_range = (chain_range / 2)
+
+ var/list/tether_effects = apply_tether(user, target, range = real_chain_range, resistable = TRUE)
+ tether_effect = tether_effects["tetherer_tether"]
+ RegisterSignal(tether_effect, COMSIG_PARENT_QDELETING, PROC_REF(reset_tether))
+ RegisterSignal(target, COMSIG_MOB_DEATH, PROC_REF(reset_tether))
+ addtimer(CALLBACK(src, PROC_REF(reset_tether), user), real_chain_duration)
+ trapped_mob = target
+ ability_primed = FALSE
+ ability_charge = max(ability_charge - ability_cost, 0)
+
+/obj/item/weapon/yautja/chain/dropped(mob/user)
+ if(trapped_mob || tether_effect)
+ release_capture(user)
+ reset_tether()
+ . = ..()
+
+/obj/item/weapon/yautja/chain/proc/release_capture(mob/user)
+ SIGNAL_HANDLER
+ if(user)
+ to_chat(user, SPAN_WARNING("[src] is no longer wrapped around [trapped_mob]!"))
+ //user.attack_log += text("\[[time_stamp()]\] [key_name(user)] has disarmed \the [src] at [get_location_in_text(user)].")
+ //log_attack("[key_name(user)] has disarmed \a [src] at [get_location_in_text(user)].")
+ if(trapped_mob)
+ //if(isxeno(trapped_mob))
+ // var/mob/living/carbon/xenomorph/xeno = trapped_mob
+ // UnregisterSignal(xeno, COMSIG_XENO_PRE_HEAL)
+ UnregisterSignal(trapped_mob, COMSIG_MOB_DEATH)
+ trapped_mob = null
+ remove_filter(ABILITY_FILTER_NAME)
+
+/obj/item/weapon/yautja/chain/Destroy()
+ release_capture()
+ reset_tether()
+ . = ..()
+
+/obj/item/weapon/yautja/chain/proc/reset_tether()
+ SIGNAL_HANDLER
+ if(trapped_mob)
+ release_capture()
+ if(tether_effect)
+ UnregisterSignal(tether_effect, COMSIG_PARENT_QDELETING)
+ if(!QDESTROYING(tether_effect))
+ qdel(tether_effect)
+ tether_effect = null
/obj/item/weapon/yautja/sword
name = "clan sword"
desc = "An expertly crafted Yautja blade carried by hunters who wish to fight up close. Razor sharp and capable of cutting flesh into ribbons. Commonly carried by aggressive and lethal hunters."
icon_state = "clansword"
- flags_atom = FPRINT|QUICK_DRAWABLE|CONDUCT
- flags_item = ITEM_PREDATOR
flags_equip_slot = SLOT_BACK
force = MELEE_FORCE_TIER_7
throwforce = MELEE_FORCE_TIER_5
sharp = IS_SHARP_ITEM_ACCURATE
- edge = TRUE
- embeddable = FALSE
- w_class = SIZE_LARGE
- hitsound = "clan_sword_hit"
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
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.AddComponent(/datum/component/status_effect/interference, 30, 30)
+ hitsound = "clan_sword_hit"
+ ability_cost = ABILITY_COST_SWORD
/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."
icon_state = "predscythe"
item_state = "scythe_dual"
- flags_atom = FPRINT|QUICK_DRAWABLE|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
- embeddable = FALSE
- w_class = SIZE_LARGE
- hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
- unacidable = TRUE
+ hitsound = 'sound/weapons/bladeslice.ogg'
+ has_unique_action = TRUE
-/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.AddComponent(/datum/component/status_effect/interference, 15, 15)
+ ability_cost = ABILITY_COST_SCYTHE
+ ability_charge_max = ABILITY_COST_SCYTHE
+ ability_charge_rate = ABILITY_CHARGE_NORMAL
- 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.Slow(get_xeno_stun_duration(target, 3))
+ target.apply_armoured_damage(get_xeno_damage_slash(target, (force * 1.25)), ARMOR_MELEE, BRUTE, "chest", 25)
+
+ 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
+ if(ability_charge < ability_cost)
+ remove_filter(ABILITY_FILTER_NAME)
+ return TRUE
/obj/item/weapon/yautja/scythe/alt
name = "double war scythe"
@@ -244,23 +427,23 @@
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"
- flags_atom = FPRINT|QUICK_DRAWABLE|CONDUCT
+ has_unique_action = TRUE
flags_equip_slot = SLOT_BACK
flags_item = TWOHANDED|ITEM_PREDATOR
- w_class = SIZE_LARGE
embeddable = FALSE //It shouldn't embed so that the Yautja can actually use the yank combi verb, and so that it's not useless upon throwing it at someone.
throw_speed = SPEED_VERY_FAST
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")
+ hitsound = 'sound/weapons/bladeslice.ogg'
+
+ ability_cost = ABILITY_COST_COMBI
+ 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
@@ -280,11 +463,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(ABILITY_FILTER_NAME)
unwield(user) //Otherwise stays wielded even when thrown
return TRUE
@@ -410,7 +594,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)
@@ -427,7 +610,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
@@ -442,28 +624,6 @@
return
-/obj/item/weapon/yautja/combistick/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.AddComponent(/datum/component/status_effect/interference, 30, 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))
-
/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))
user.visible_message(SPAN_DANGER("[user] starts to untangle the chain on \the [src]..."), SPAN_NOTICE("You start to untangle the chain on \the [src]..."))
@@ -485,7 +645,6 @@
desc = "A viciously sharp dagger inscribed with ancient Yautja markings. Smells thickly of blood. Carried by some hunters."
icon_state = "predknife"
item_state = "knife"
- flags_atom = FPRINT|QUICK_DRAWABLE|CONDUCT
flags_item = ITEM_PREDATOR|CAN_DIG_SHRAPNEL
flags_equip_slot = SLOT_STORE
sharp = IS_SHARP_ITEM_ACCURATE
@@ -695,6 +854,7 @@
)
flags_item = NOSHIELD|TWOHANDED|ITEM_PREDATOR
+ flags_atom = FPRINT|QUICK_DRAWABLE|CONDUCT
unacidable = TRUE
flags_equip_slot = SLOT_BACK
w_class = SIZE_LARGE
@@ -702,6 +862,65 @@
edge = TRUE
hitsound = 'sound/weapons/bladeslice.ogg'
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_NO_ABILITY
+ ///Whether the ability is ready to trigger
+ var/ability_primed = FALSE
+
+/obj/item/weapon/twohanded/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.AddComponent(/datum/component/status_effect/interference, xeno_interfere_amount, xeno_interfere_amount)
+
+ if(!ability_cost || !(HAS_TRAIT(user, TRAIT_YAUTJA_TECH)))
+ return
+
+ progress_ability(target, user)
+
+/obj/item/weapon/twohanded/yautja/proc/progress_ability(mob/living/target, mob/living/carbon/human/user)
+ if(target == user || target.stat == DEAD || isanimal(target))
+ to_chat(user, SPAN_DANGER("You think you're smart?")) //very funny
+ return FALSE
+
+ if(ability_charge < ability_charge_max)
+ ability_charge = min(ability_charge_max, ability_charge + ability_charge_rate)
+ to_chat(user, SPAN_DANGER("[src]'s reservoir fills up with your opponent's blood!"))
+
+ if(ability_charge >= ability_cost)
+ ready_ability(target, user)
+ return TRUE
+
+/obj/item/weapon/twohanded/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/twohanded/yautja/get_examine_text(mob/user)
+ . = ..()
+ if(isyautja(user) && ability_cost)
+ . += SPAN_WARNING("It currently has [ability_charge]/[ability_charge_max] blood charge(s).")
+ . += SPAN_ORANGE("It requires [ability_cost] blood charge(s) to use its ability.")
+
+/obj/item/weapon/twohanded/yautja/proc/ready_ability(mob/living/target as mob, mob/living/carbon/human/user as mob)
+ if(ability_charge >= ability_cost)
+ var/color = target.get_blood_color()
+ var/alpha = 70
+ color += num2text(alpha, 2, 16)
+ add_filter(ABILITY_FILTER_NAME, 1, list("type" = "outline", "color" = color, "size" = 2))
+ return TRUE
+ return FALSE
/obj/item/weapon/twohanded/yautja/spear
name = "hunter spear"
@@ -709,7 +928,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")
@@ -764,21 +983,12 @@
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
- flags_atom = FPRINT|QUICK_DRAWABLE|CONDUCT
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.AddComponent(/datum/component/status_effect/interference, 30, 30)
+ ability_cost = ABILITY_COST_GLAIVE
/obj/item/weapon/twohanded/yautja/glaive/alt
icon_state = "glaive_alt"
@@ -826,6 +1036,8 @@
var/last_regen
flags_gun_features = GUN_UNUSUAL_DESIGN
flags_item = ITEM_PREDATOR|TWOHANDED
+ flags_atom = FPRINT|QUICK_DRAWABLE|CONDUCT
+ has_unique_action = FALSE
/obj/item/weapon/gun/launcher/spike/process()
if(spikes < max_spikes && world.time > last_regen + 100 && prob(70))
@@ -841,7 +1053,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()
..()
@@ -910,6 +1121,7 @@
WEAR_L_HAND = 'icons/mob/humans/onmob/hunter/items_lefthand.dmi',
WEAR_R_HAND = 'icons/mob/humans/onmob/hunter/items_righthand.dmi'
)
+ flags_atom = FPRINT|QUICK_DRAWABLE|CONDUCT
/obj/item/weapon/gun/energy/yautja/plasmarifle
name = "plasma rifle"
@@ -926,6 +1138,7 @@
var/last_regen = 0
flags_gun_features = GUN_UNUSUAL_DESIGN
flags_item = ITEM_PREDATOR|TWOHANDED
+ has_unique_action = FALSE
/obj/item/weapon/gun/energy/yautja/plasmarifle/Initialize(mapload, spawn_empty)
. = ..()
@@ -936,7 +1149,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)
@@ -1036,7 +1248,6 @@
verbs -= /obj/item/weapon/gun/verb/empty_mag
-
/obj/item/weapon/gun/energy/yautja/plasmapistol/Destroy()
. = ..()
STOP_PROCESSING(SSobj, src)
@@ -1049,7 +1260,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)
@@ -1103,7 +1313,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
@@ -1145,7 +1355,6 @@
w_class = SIZE_HUGE
force = 0
fire_delay = 3
- flags_atom = FPRINT|QUICK_DRAWABLE|CONDUCT
flags_item = NOBLUDGEON|DELONDROP|IGNITING_ITEM //Can't bludgeon with this.
flags_gun_features = GUN_UNUSUAL_DESIGN
has_empty_icon = FALSE
@@ -1227,7 +1436,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 09ce5bb9c149..61a610102097 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 2c69f984d884..dcb56f61ffda 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 * attacking_xeno.frenzy_aura
if(attacking_xeno.caste && attacking_xeno.caste.is_intelligent)
knock_chance += 2
- knock_chance += min(floor(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)
attacking_xeno.visible_message(SPAN_DANGER("[attacking_xeno] smashes off [src]'s [wear_mask.name]!"), \
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 80fce329e8cf..7e914e5d5eb5 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 51a5988f2fd0..51afb04bf0ae 100644
--- a/code/modules/projectiles/gun_helpers.dm
+++ b/code/modules/projectiles/gun_helpers.dm
@@ -776,19 +776,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)