diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/reaper/reaper_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/reaper/reaper_abilities.dm index 31c374f5b2c1..ff19d979f6db 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/reaper/reaper_abilities.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/reaper/reaper_abilities.dm @@ -1,7 +1,7 @@ /datum/action/xeno_action/activable/flesh_harvest name = "Flesh Harvest" ability_name = "flesh harvest" - action_icon_state = "gut" + action_icon_state = "flesh_harvest" macro_path = /datum/action/xeno_action/verb/verb_flesh_harvest action_type = XENO_ACTION_CLICK ability_primacy = XENO_PRIMARY_ACTION_1 @@ -21,7 +21,7 @@ /datum/action/xeno_action/onclick/raise_servant name = "Raise Servant" ability_name = "raise servant" - action_icon_state = "empower" + action_icon_state = "unburrow" macro_path = /datum/action/xeno_action/verb/verb_raise_servant action_type = XENO_ACTION_CLICK ability_primacy = XENO_PRIMARY_ACTION_3 @@ -29,13 +29,12 @@ plasma_cost = 100 var/resin_cost = 200 var/creattime = 20 SECONDS - var/making_servant = FALSE // So we can't make multiple at once /datum/action/xeno_action/activable/command_servants name = "Command Servants" ability_name = "command servants" - action_icon_state = "empower" + action_icon_state = "mark_rally" action_type = XENO_ACTION_CLICK ability_primacy = XENO_PRIMARY_ACTION_4 diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/reaper/reaper_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/reaper/reaper_powers.dm index 45ba83820e6f..74b0fe903014 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/reaper/reaper_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/reaper/reaper_powers.dm @@ -23,7 +23,10 @@ if(!xeno.Adjacent(carbon)) return - if(reaper.harvesting) + if(reaper.making_servant == TRUE) + return + + if(reaper.harvesting == TRUE) to_chat(xeno, SPAN_XENOWARNING("We are already harvesting!")) return @@ -56,7 +59,9 @@ reaper.harvesting = TRUE if(victim.has_limb("r_leg")) - do_after(xeno, 1 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE) + if(!do_after(xeno, 1 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE)) + reaper.harvesting = FALSE + return limb = victim.get_limb("r_leg") if(limb.status & (LIMB_ROBOT|LIMB_SYNTHSKIN)) to_chat(xeno, SPAN_XENOWARNING("This limb is fake!")) @@ -64,7 +69,9 @@ else playsound(carbon, limb_remove_start, 50, TRUE) xeno.visible_message(SPAN_XENONOTICE("[xeno] grabs [carbon]'s [limb.display_name] and starts twisting and pulling!")) - do_after(xeno, 3 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE) + if(!do_after(xeno, 3 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE)) + reaper.harvesting = FALSE + return limb.droplimb(FALSE, TRUE, "flesh harvest") xeno.visible_message(SPAN_XENOWARNING("With a final violent motion, [xeno] wrenches off [carbon]'s [limb.display_name] and consumes it!"), \ SPAN_XENOWARNING("We harvest the [limb.display_name]!")) @@ -73,7 +80,9 @@ playsound(xeno, limb_remove_end, 25, TRUE) if(victim.has_limb("l_leg")) - do_after(xeno, 1 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE) + if(!do_after(xeno, 1 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE)) + reaper.harvesting = FALSE + return limb = victim.get_limb("l_leg") if(limb.status & (LIMB_ROBOT|LIMB_SYNTHSKIN)) to_chat(xeno, SPAN_XENOWARNING("This limb is fake!")) @@ -81,7 +90,9 @@ else playsound(carbon, limb_remove_start, 50, TRUE) xeno.visible_message(SPAN_XENONOTICE("[xeno] grabs [carbon]'s [limb.display_name] and starts twisting and pulling!")) - do_after(xeno, 3 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE) + if(!do_after(xeno, 3 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE)) + reaper.harvesting = FALSE + return limb.droplimb(FALSE, TRUE, "flesh harvest") xeno.visible_message(SPAN_XENOWARNING("With a final violent motion, [xeno] wrenches off [carbon]'s [limb.display_name] and consumes it!"), \ SPAN_XENOWARNING("We harvest the [limb.display_name]!")) @@ -90,7 +101,9 @@ playsound(xeno, limb_remove_end, 25, TRUE) if(victim.has_limb("r_arm")) - do_after(xeno, 1 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE) + if(!do_after(xeno, 1 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE)) + reaper.harvesting = FALSE + return limb = victim.get_limb("r_arm") if(limb.status & (LIMB_ROBOT|LIMB_SYNTHSKIN)) to_chat(xeno, SPAN_XENOWARNING("This limb is fake!")) @@ -98,7 +111,9 @@ else playsound(carbon, limb_remove_start, 50, TRUE) xeno.visible_message(SPAN_XENONOTICE("[xeno] grabs [carbon]'s [limb.display_name] and starts twisting and pulling!")) - do_after(xeno, 3 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE) + if(!do_after(xeno, 3 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE)) + reaper.harvesting = FALSE + return limb.droplimb(FALSE, TRUE, "flesh harvest") xeno.visible_message(SPAN_XENOWARNING("With a final violent motion, [xeno] wrenches off [carbon]'s [limb.display_name] and consumes it!"), \ SPAN_XENOWARNING("We harvest the [limb.display_name]!")) @@ -107,7 +122,9 @@ playsound(xeno, limb_remove_end, 25, TRUE) if(victim.has_limb("l_arm")) - do_after(xeno, 1 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE) + if(!do_after(xeno, 1 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE)) + reaper.harvesting = FALSE + return limb = victim.get_limb("l_arm") if(limb.status & (LIMB_ROBOT|LIMB_SYNTHSKIN)) to_chat(xeno, SPAN_XENOWARNING("This limb is fake!")) @@ -115,7 +132,9 @@ else playsound(carbon, limb_remove_start, 50, TRUE) xeno.visible_message(SPAN_XENONOTICE("[xeno] grabs [carbon]'s [limb.display_name] and starts twisting and pulling!")) - do_after(xeno, 3 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE) + if(!do_after(xeno, 3 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE)) + reaper.harvesting = FALSE + return limb.droplimb(FALSE, TRUE, "flesh harvest") xeno.visible_message(SPAN_XENOWARNING("With a final violent motion, [xeno] wrenches off [carbon]'s [limb.display_name] and consumes it!"), \ SPAN_XENOWARNING("We harvest the [limb.display_name]!")) @@ -123,15 +142,19 @@ cooldown_mult += 1 playsound(xeno, limb_remove_end, 25, TRUE) - if(fake_count == 4) // Let's be real, this isn't going to happen naturally, but this is fucking funny. + if(fake_count == 4) // Let's be real, this isn't going to happen naturally, but it would be fucking funny. xeno.emote("hiss") + reaper.harvesting = FALSE xeno.visible_message(SPAN_XENONOTICE("After inspecting [carbon]'s corpse, [xeno] rises angrily."), SPAN_XENOWARNING("It was all fake! Infuriating!")) return if(limb == null) - do_after(xeno, 4 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE) + if(!do_after(xeno, 4 SECONDS, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_HOSTILE)) + reaper.harvesting = FALSE + return xeno.emote("hiss") - xeno.visible_message(SPAN_XENONOTICE("After inspecting [carbon]'s corpse, [xeno] rises frustratedly."), SPAN_XENOWARNING("...But they have nothing to harvest. Frustrating.")) + reaper.harvesting = FALSE + xeno.visible_message(SPAN_XENONOTICE("After inspecting [carbon]'s corpse, [xeno] rises, visibly frustrated."), SPAN_XENOWARNING("...But they have nothing to harvest. Frustrating.")) return xeno.visible_message(SPAN_XENONOTICE("[xeno] rises from [carbon]'s corpse."), SPAN_XENOWARNING("We finish our harvest, digesting the harvested limbs into flesh resin!")) @@ -199,9 +222,6 @@ if(ishuman(carbon)) var/mob/living/carbon/human/victim = carbon - to_chat(victim, SPAN_XENOWARNING("As [xeno]'s wing-like claws rip into your [target_limb ? target_limb.display_name : "chest"], your wounds suddenly start hurting badly!")) - victim.apply_effect(5, AGONY) - victim.emote("pain") if(victim.getToxLoss() >= 20) victim.vomit() if(reaper.flesh_resin > 0) @@ -219,7 +239,10 @@ if(!action_cooldown_check()) return - if(making_servant == TRUE) + if(reaper.harvesting == TRUE) + return + + if(reaper.making_servant == TRUE) to_chat(xeno, SPAN_XENOWARNING("We are already making a servant!")) return @@ -240,6 +263,7 @@ /datum/action/xeno_action/onclick/raise_servant/proc/create_servant(datum/action/xeno_action/onclick/raise_servant/action_def, atom/target) var/mob/living/carbon/xenomorph/xeno = owner + var/datum/behavior_delegate/base_reaper/reaper = xeno.behavior_delegate if(!xeno.check_state()) return @@ -248,10 +272,10 @@ xeno.visible_message(SPAN_XENOWARNING("[xeno] bends over and starts spewing large amounts of rancid ooze at it's feet, grasping at it as it cascades down!"), \ SPAN_XENOWARNING("We regurgitate a mix of plasma and flesh resin, moulding it into a loyal servant!")) - making_servant = TRUE + reaper.making_servant = TRUE if(!do_after(xeno, creattime, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, ACTION_PURPLE_POWER_UP)) - making_servant = FALSE + reaper.making_servant = FALSE return xeno.visible_message(SPAN_XENOWARNING("As [xeno] rises, the lump of decomposing sludge shudders and grows, animating into a melting, odd-looking Drone!"), \ @@ -259,7 +283,7 @@ var/mob/living/simple_animal/hostile/alien/rotdrone/rotxeno = new(xeno.loc, xeno) servant_rise(rotxeno) new_servant(rotxeno) - making_servant = FALSE + reaper.making_servant = FALSE /datum/action/xeno_action/onclick/raise_servant/proc/servant_rise(mob/living/simple_animal/hostile/alien/rotdrone/servant) if(!istype(servant)) @@ -330,7 +354,6 @@ servant.got_orders = TRUE servant.target_mob = target servant.is_fighting = TRUE - servant.fighting_override = TRUE /datum/action/xeno_action/activable/command_servants/proc/servant_escort(mob/living/simple_animal/hostile/alien/rotdrone/servant, mob/living/carbon/target) if(!istype(servant)) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Reaper.dm b/code/modules/mob/living/carbon/xenomorph/castes/Reaper.dm index dae0c8e40d22..eed5971917bd 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Reaper.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Reaper.dm @@ -89,6 +89,7 @@ var/flesh_resin = 0 var/flesh_resin_max = 1000 var/harvesting = FALSE // So you can't harvest multiple corpses at once + var/making_servant = FALSE // So we can't make multiple at once var/list/mob/living/simple_animal/hostile/alien/rotdrone/servants = list() // List of active rotdrones var/servant_max = 3 // How many rotdrones one Reaper can have at once diff --git a/code/modules/mob/living/simple_animal/hostile/rotdrone.dm b/code/modules/mob/living/simple_animal/hostile/rotdrone.dm index f2c470d0804e..453210e65822 100644 --- a/code/modules/mob/living/simple_animal/hostile/rotdrone.dm +++ b/code/modules/mob/living/simple_animal/hostile/rotdrone.dm @@ -1,12 +1,12 @@ /mob/living/simple_animal/hostile/alien/rotdrone - name = "Drone" + name = "Rotdrone" desc = "A rotting... thing vaguely reminiscent of a drone. Smells absolutely awful." - icon = 'icons/mob/xenos/drone.dmi' + icon = 'icons/mob/xenos/rotdrone.dmi' icon_gib = null speed = XENO_SPEED_TIER_2 harm_intent_damage = 5 melee_damage_lower = XENO_DAMAGE_TIER_1 - melee_damage_upper = XENO_DAMAGE_TIER_2 + melee_damage_upper = XENO_DAMAGE_TIER_1 move_to_delay = 5 meat_type = null unsuitable_atoms_damage = 5 @@ -62,23 +62,26 @@ /mob/living/simple_animal/hostile/alien/rotdrone/Life() . = ..() - if(escort && escort.stat == DEAD) - escorting = FALSE - if(get_dist(src, xeno_master) > 3) + if(!xeno_master || xeno_master.stat == DEAD) + xeno_master = null + adjustBruteLoss(15) + return + if(get_dist(src, xeno_master) > 4) adjustBruteLoss(5) if(is_fighting == FALSE) - if(escort == TRUE && escorting == TRUE && get_dist(src, escort) > 3) + if(escort && escorting == TRUE && get_dist(src, escort) > 3) walk_to(src, escort, rand(1, 2), 4) if(got_orders == FALSE && get_dist(src, xeno_master) > 3) walk_to(src, xeno_master, rand(1, 2), 4) + if(escort && escort.stat == DEAD) + escorting = FALSE if(escorting == FALSE) escort = null - if(got_orders == FALSE) - fighting_override = FALSE - if(fighting_override == TRUE || stance == HOSTILE_STANCE_ATTACKING) + + if(stance == HOSTILE_STANCE_ATTACKING) is_fighting = TRUE - else if(fighting_override == FALSE) + else is_fighting = FALSE /mob/living/simple_animal/hostile/alien/rotdrone/death(cause, gibbed, deathmessage = "screeches and collapses as it's body melts back into an inert, rotting ooze...") diff --git a/icons/mob/hud/actions_xeno.dmi b/icons/mob/hud/actions_xeno.dmi index fc5560fba069..b60db3332efa 100644 Binary files a/icons/mob/hud/actions_xeno.dmi and b/icons/mob/hud/actions_xeno.dmi differ diff --git a/icons/mob/xenos/drone.dmi b/icons/mob/xenos/drone.dmi index 94b8a9b3bee4..a918d6fb95ab 100644 Binary files a/icons/mob/xenos/drone.dmi and b/icons/mob/xenos/drone.dmi differ diff --git a/icons/mob/xenos/radial_xenos.dmi b/icons/mob/xenos/radial_xenos.dmi index 2832f42fda33..ed3eccfbeb39 100644 Binary files a/icons/mob/xenos/radial_xenos.dmi and b/icons/mob/xenos/radial_xenos.dmi differ diff --git a/icons/mob/xenos/rotdrone.dmi b/icons/mob/xenos/rotdrone.dmi new file mode 100644 index 000000000000..7b845a70b7e2 Binary files /dev/null and b/icons/mob/xenos/rotdrone.dmi differ diff --git a/icons/mob/xenos/wounds.dmi b/icons/mob/xenos/wounds.dmi index 804ba9396fab..ce74cb436408 100644 Binary files a/icons/mob/xenos/wounds.dmi and b/icons/mob/xenos/wounds.dmi differ