Skip to content
1 change: 1 addition & 0 deletions code/__DEFINES/keybinding.dm
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@
#define COMSIG_KB_XENO_PURCHASE_STRAIN "keybinding_purchase_strain"
#define COMSIG_KB_XENO_RESET_STRAIN "keybinding_reset_strain"
#define COMSIG_KB_XENO_BECOME_SEETHROUGH "keybinding_become_seethrough"
#define COMSIG_KB_XENO_RIP_LIMB "keybinding_rip_limb"

// Yautja

Expand Down
14 changes: 14 additions & 0 deletions code/datums/keybinding/xenomorph.dm
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,17 @@
current_xeno.toggle_seethrough()
return TRUE

/datum/keybinding/xenomorph/rip_limb
hotkey_keys = list("Unbound")
classic_keys = list("Unbound")
name = "rip_limb"
full_name = "Rip Limb"
keybind_signal = COMSIG_KB_XENO_RIP_LIMB

/datum/keybinding/xenomorph/rip_limb/down(client/user)
. = ..()
if(.)
return

var/mob/living/carbon/xenomorph/current_xeno = user?.mob
current_xeno.rip_limb()
14 changes: 14 additions & 0 deletions code/modules/cm_aliens/structures/fruit.dm
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,20 @@
// Need to do it here because baseline initialize override the icon through config.
icon = 'icons/mob/xenos/fruits.dmi'

/obj/effect/alien/resin/fruit/clicked(mob/user, list/mods)
var/mob/living/carbon/xenomorph/xeno = user
if(mods[ALT_CLICK])
if(!istype(xeno) || !Adjacent(xeno) || xeno != usr || xeno.is_mob_incapacitated() || xeno.body_position == LYING_DOWN)
return
xeno.pickup_fruit(src)
return TRUE
..()

/obj/effect/alien/resin/fruit/get_examine_text(mob/user)
. = ..()
if(isxeno(user) || isobserver(user))
. += "[SPAN_HELPFUL("Press Alt + Click to pick up fruit.")]"

/obj/effect/alien/resin/fruit/proc/on_weed_expire()
SIGNAL_HANDLER
qdel(src)
Expand Down
36 changes: 35 additions & 1 deletion code/modules/mob/living/carbon/xenomorph/XenoProcs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,41 @@

/// Called when pulling something and attacking yourself wth the pull (Z hotkey) override for caste specific behaviour
/mob/living/carbon/xenomorph/proc/pull_power(mob/mob)
return
var/mob/living/carbon/pulled = src.pulling
if(!istype(pulled))
return
if(isxeno(pulled) || issynth(pulled))
to_chat(src, SPAN_WARNING("That wouldn't serve a purpose."))
return
if(pulled.buckled)
to_chat(src, SPAN_WARNING("[pulled] is buckled to something."))
return
if(pulled.stat == DEAD && !pulled.chestburst)
to_chat(src, SPAN_WARNING("Ew, [pulled] is already starting to rot."))
return
if(src.hauled_mob?.resolve()) // We can't carry more than one mob
to_chat(src, SPAN_WARNING("You already are carrying something, there's no way that will work."))
return
if(HAS_TRAIT(pulled, TRAIT_HAULED))
to_chat(src, SPAN_WARNING("They are already being hauled by someone else."))
return
if(src.action_busy)
to_chat(src, SPAN_WARNING("We are already busy with something."))
return
SEND_SIGNAL(src, COMSIG_MOB_EFFECT_CLOAK_CANCEL)
src.visible_message(SPAN_DANGER("[src] starts to restrain [pulled]!"),
SPAN_DANGER("We start restraining [pulled]!"), null, 5)
if(HAS_TRAIT(src, TRAIT_CLOAKED)) //cloaked don't show the visible message, so we gotta work around
to_chat(pulled, FONT_SIZE_HUGE(SPAN_DANGER("[src] is trying to restrain you!")))
if(do_after(src, 50, INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE))
if((isxeno(pulled.loc) && !src.hauled_mob) || HAS_TRAIT(pulled, TRAIT_HAULED))
to_chat(src, SPAN_WARNING("Someone already took \the [pulled]."))
return
if(src.pulling == pulled && !pulled.buckled && (pulled.stat != DEAD || pulled.chestburst) && !src.hauled_mob?.resolve()) //make sure you've still got them in your claws, and alive
if(SEND_SIGNAL(pulled, COMSIG_MOB_HAULED, src) & COMPONENT_CANCEL_HAUL)
return FALSE
src.haul(pulled)
src.stop_pulling()

// Vent Crawl
/mob/living/carbon/xenomorph/proc/vent_crawl()
Expand Down
3 changes: 2 additions & 1 deletion code/modules/mob/living/carbon/xenomorph/Xenomorph.dm
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,6 @@
var/crest_defense = FALSE
/// 0/FALSE - upright, 1/TRUE - all fours
var/agility = FALSE
var/ripping_limb = FALSE
/// For drones/hivelords. Extends the maximum build range they have
var/extra_build_dist = 0
/// tiles from self you can plant eggs.
Expand Down Expand Up @@ -403,6 +402,8 @@
wound_icon_holder = new(null, src)
vis_contents += wound_icon_holder

AddComponent(/datum/component/seethrough_mob)

///Handle transferring things from the old Xeno if we have one in the case of evolve, devolve etc.
AddComponent(/datum/component/deevolve_cooldown, old_xeno)
if(old_xeno)
Expand Down
1 change: 1 addition & 0 deletions code/modules/mob/living/carbon/xenomorph/castes/Boiler.dm
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
var/datum/effect_system/smoke_spread/xeno_acid/smoke

base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/onclick/release_haul,
/datum/action/xeno_action/watch_xeno,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
organ_value = 1500

base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/onclick/release_haul,
/datum/action/xeno_action/watch_xeno,
Expand Down
1 change: 1 addition & 0 deletions code/modules/mob/living/carbon/xenomorph/castes/Carrier.dm
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
organ_value = 1000

base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/onclick/release_haul,
/datum/action/xeno_action/watch_xeno,
Expand Down
1 change: 1 addition & 0 deletions code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
rebounds = FALSE // no more fucking pinball crooshers
organ_value = 3000
base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/onclick/release_haul,
/datum/action/xeno_action/watch_xeno,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
organ_value = 1000

base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/onclick/release_haul,
/datum/action/xeno_action/watch_xeno,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
organ_value = 3000

base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/onclick/release_haul,
/datum/action/xeno_action/watch_xeno,
Expand Down
1 change: 1 addition & 0 deletions code/modules/mob/living/carbon/xenomorph/castes/Drone.dm
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
old_x = -12
xenonid_pixel_x = -8
base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/onclick/release_haul,
/datum/action/xeno_action/watch_xeno,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
can_hivemind_speak = FALSE

base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/watch_xeno,
/datum/action/xeno_action/onclick/xenohide,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
organ_value = 1500

base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/onclick/release_haul,
/datum/action/xeno_action/watch_xeno,
Expand Down
1 change: 1 addition & 0 deletions code/modules/mob/living/carbon/xenomorph/castes/King.dm
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
fire_immunity = FIRE_IMMUNITY_NO_DAMAGE

base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/onclick/release_haul,
/datum/action/xeno_action/watch_xeno,
Expand Down
1 change: 1 addition & 0 deletions code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
tier = 2
organ_value = 2000
base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/onclick/release_haul,
/datum/action/xeno_action/watch_xeno,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
organ_value = 3000

base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/onclick/release_haul,
/datum/action/xeno_action/watch_xeno,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
small_explosives_stun = FALSE

base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/onclick/release_haul,
/datum/action/xeno_action/watch_xeno,
Expand Down
1 change: 0 additions & 1 deletion code/modules/mob/living/carbon/xenomorph/castes/Queen.dm
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,6 @@
make_combat_effective()

AddComponent(/datum/component/footstep, 2 , 35, 11, 4, "alien_footstep_large")
AddComponent(/datum/component/seethrough_mob)
if(hive.hivenumber == XENO_HIVE_NORMAL)
AddComponent(/datum/component/tacmap, has_drawing_tools=TRUE, minimap_flag=get_minimap_flag_for_faction(hive.hivenumber), has_update=TRUE, drawing=TRUE)
RegisterSignal(src, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(check_block))
Expand Down
1 change: 1 addition & 0 deletions code/modules/mob/living/carbon/xenomorph/castes/Ravager.dm
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
fire_immunity = FIRE_IMMUNITY_NO_DAMAGE|FIRE_IMMUNITY_XENO_FRENZY

base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/onclick/release_haul,
/datum/action/xeno_action/watch_xeno,
Expand Down
1 change: 1 addition & 0 deletions code/modules/mob/living/carbon/xenomorph/castes/Runner.dm
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
mob_size = MOB_SIZE_XENO_SMALL

base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/onclick/release_haul,
/datum/action/xeno_action/watch_xeno,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
tier = 1
organ_value = 800
base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/onclick/release_haul,
/datum/action/xeno_action/watch_xeno,
Expand Down
1 change: 1 addition & 0 deletions code/modules/mob/living/carbon/xenomorph/castes/Spitter.dm
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
organ_value = 2000
tier = 2
base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/onclick/release_haul,
/datum/action/xeno_action/watch_xeno,
Expand Down
85 changes: 1 addition & 84 deletions code/modules/mob/living/carbon/xenomorph/castes/Warrior.dm
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
pull_speed = 2 // about what it was before, slightly faster
organ_value = 2000
base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/onclick/release_haul,
/datum/action/xeno_action/watch_xeno,
Expand Down Expand Up @@ -181,90 +182,6 @@
bound_xeno.remove_filter("empower_rage")


/// Warrior specific behaviour for increasing pull power, limb rip.
/mob/living/carbon/xenomorph/warrior/pull_power(mob/mob)
if(!ripping_limb && mob.stat != DEAD)
if(mob.status_flags & XENO_HOST)
to_chat(src, SPAN_XENOWARNING("This would harm the embryo!"))
return
ripping_limb = TRUE
if(rip_limb(mob))
stop_pulling()
ripping_limb = FALSE


/// Warrior Rip Limb - called by pull_power()
/mob/living/carbon/xenomorph/warrior/proc/rip_limb(mob/mob)
if(!istype(mob, /mob/living/carbon/human))
return FALSE

if(action_busy) //can't stack the attempts
return FALSE

var/mob/living/carbon/human/human = mob
var/obj/limb/limb = human.get_limb(check_zone(zone_selected))

if(can_not_harm(human))
to_chat(src, SPAN_XENOWARNING("We can't harm this host!"))
return

if(!limb || limb.body_part == BODY_FLAG_CHEST || limb.body_part == BODY_FLAG_GROIN || (limb.status & LIMB_DESTROYED)) //Only limbs and head.
to_chat(src, SPAN_XENOWARNING("We can't rip off that limb."))
return FALSE

var/limb_time = rand(40,60)
if(limb.body_part == BODY_FLAG_HEAD)
limb_time = rand(90,110)

visible_message(SPAN_XENOWARNING("[src] begins pulling on [mob]'s [limb.display_name] with incredible strength!"),
SPAN_XENOWARNING("We begin to pull on [mob]'s [limb.display_name] with incredible strength!"))

if(!do_after(src, limb_time, INTERRUPT_ALL|INTERRUPT_DIFF_SELECT_ZONE, BUSY_ICON_HOSTILE) || mob.stat == DEAD || mob.status_flags & XENO_HOST)
to_chat(src, SPAN_NOTICE("We stop ripping off the limb."))
return FALSE

if(mob.status_flags & XENO_HOST)
to_chat(src, SPAN_NOTICE("We detect an embryo inside [mob] which overwhelms our instinct to rip."))
return FALSE

if(limb.status & LIMB_DESTROYED)
return FALSE

if(limb.status & (LIMB_ROBOT|LIMB_SYNTHSKIN))
limb.take_damage(rand(30,40), 0, 0) // just do more damage
visible_message(SPAN_XENOWARNING("You hear [mob]'s [limb.display_name] being pulled beyond its load limits!"),
SPAN_XENOWARNING("[mob]'s [limb.display_name] begins to tear apart!"))
else
visible_message(SPAN_XENOWARNING("We hear the bones in [mob]'s [limb.display_name] snap with a sickening crunch!"),
SPAN_XENOWARNING("[mob]'s [limb.display_name] bones snap with a satisfying crunch!"))
limb.take_damage(rand(15,25), 0, 0)
limb.fracture(100)
mob.last_damage_data = create_cause_data(initial(caste_type), src)
src.attack_log += text("\[[time_stamp()]\] <font color='red'>ripped the [limb.display_name] off of [mob.name] ([mob.ckey]) 1/2 progress</font>")
mob.attack_log += text("\[[time_stamp()]\] <font color='orange'>had their [limb.display_name] ripped off by [src.name] ([src.ckey]) 1/2 progress</font>")
log_attack("[src.name] ([src.ckey]) ripped the [limb.display_name] off of [mob.name] ([mob.ckey]) 1/2 progress")

if(!do_after(src, limb_time, INTERRUPT_ALL|INTERRUPT_DIFF_SELECT_ZONE, BUSY_ICON_HOSTILE) || mob.stat == DEAD || iszombie(mob))
to_chat(src, SPAN_NOTICE("We stop ripping off the limb."))
return FALSE

if(mob.status_flags & XENO_HOST)
to_chat(src, SPAN_NOTICE("We detect an embryo inside [mob] which overwhelms our instinct to rip."))
return FALSE

if(limb.status & LIMB_DESTROYED)
return FALSE

visible_message(SPAN_XENOWARNING("[src] rips [mob]'s [limb.display_name] away from their body!"),
SPAN_XENOWARNING("[mob]'s [limb.display_name] rips away from their body!"))
src.attack_log += text("\[[time_stamp()]\] <font color='red'>ripped the [limb.display_name] off of [mob.name] ([mob.ckey]) 2/2 progress</font>")
mob.attack_log += text("\[[time_stamp()]\] <font color='orange'>had their [limb.display_name] ripped off by [src.name] ([src.ckey]) 2/2 progress</font>")
log_attack("[src.name] ([src.ckey]) ripped the [limb.display_name] off of [mob.name] ([mob.ckey]) 2/2 progress")

limb.droplimb(0, 0, initial(name))

return TRUE

/datum/action/xeno_action/activable/lunge/use_ability(atom/affected_atom)
var/mob/living/carbon/xenomorph/lunge_user = owner

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
gib_chance = 100
acid_blood_damage = 15
base_actions = list(
/datum/action/xeno_action/onclick/toggle_seethrough,
/datum/action/xeno_action/onclick/xeno_resting,
/datum/action/xeno_action/onclick/release_haul,
/datum/action/xeno_action/watch_xeno,
Expand Down
8 changes: 8 additions & 0 deletions code/modules/mob/living/carbon/xenomorph/seethrough.dm
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
animate(trickery_image, alpha = target_alpha, time = animation_time)

RegisterSignal(fool, COMSIG_MOB_LOGOUT, PROC_REF(on_client_disconnect))
RegisterSignal(fool, COMSIG_MOB_GHOSTIZE, PROC_REF(on_client_ghost))

///Remove the screen object and make us appear solid to ourselves again
/datum/component/seethrough_mob/proc/untrick_mob()
Expand All @@ -97,6 +98,13 @@
UnregisterSignal(fool, COMSIG_MOB_LOGOUT)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
UnregisterSignal(fool, COMSIG_MOB_LOGOUT)
UnregisterSignal(fool, COMSIG_MOB_GHOSTIZE)
UnregisterSignal(fool, COMSIG_MOB_LOGOUT)

I lied, one more thing.

clear_image(trickery_image, fool.client)

/datum/component/seethrough_mob/proc/on_client_ghost()
SIGNAL_HANDLER

var/mob/fool = parent
UnregisterSignal(fool, COMSIG_MOB_GHOSTIZE)
clear_image(trickery_image, fool.client)

/datum/component/seethrough_mob/proc/toggle_active()
is_active = !is_active
if(is_active)
Expand Down
Loading
Loading