diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index e73af05c7d6..cab2662a7ec 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -27,6 +27,8 @@
#define isaliensentinel(A) (istype(A, /mob/living/carbon/alien/humanoid/sentinel))
+#define isalienqueen(A) (istype(A, /mob/living/carbon/alien/humanoid/queen))
+
// Simple animals
#define issimple_animal(A) (istype(A, /mob/living/simple_animal))
diff --git a/code/_onclick/hud/alien_hud.dm b/code/_onclick/hud/alien_hud.dm
index 1dd86fe5ce5..a541fca8b57 100644
--- a/code/_onclick/hud/alien_hud.dm
+++ b/code/_onclick/hud/alien_hud.dm
@@ -16,8 +16,21 @@
/obj/screen/alien/nightvision/Click()
var/mob/living/carbon/alien/humanoid/A = usr
- A.nightvisiontoggle()
+ A.night_vision_toggle()
+/mob/living/carbon/alien/proc/night_vision_toggle()
+ if(!nightvision)
+ see_in_dark = 8
+ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
+ nightvision = TRUE
+ hud_used.nightvisionicon.icon_state = "nightvision1"
+ else
+ see_in_dark = initial(see_in_dark)
+ lighting_alpha = initial(lighting_alpha)
+ nightvision = FALSE
+ hud_used.nightvisionicon.icon_state = "nightvision0"
+
+ update_sight()
/obj/screen/alien/plasma_display
icon = 'icons/mob/screen_gen.dmi'
diff --git a/code/datums/beam.dm b/code/datums/beam.dm
index d4005122083..f67b5f2ed4c 100644
--- a/code/datums/beam.dm
+++ b/code/datums/beam.dm
@@ -14,8 +14,9 @@
var/origin_oldloc = null
var/static_beam = FALSE
var/beam_type = /obj/effect/ebeam //must be subtype
+ var/beamcolor
-/datum/beam/New(beam_origin,beam_target,beam_icon='icons/effects/beam.dmi',beam_icon_state="b_beam",time=50,maxdistance=10,btype = /obj/effect/ebeam,beam_sleep_time=3)
+/datum/beam/New(beam_origin, beam_target,beam_icon = 'icons/effects/beam.dmi', beam_icon_state = "b_beam", time = 50, maxdistance = 10, btype = /obj/effect/ebeam, beam_sleep_time = 3, beam_color)
endtime = world.time+time
origin = beam_origin
origin_oldloc = get_turf(origin)
@@ -29,6 +30,7 @@
icon = beam_icon
icon_state = beam_icon_state
beam_type = btype
+ beamcolor = beam_color
/datum/beam/proc/Start()
Draw()
@@ -77,10 +79,12 @@
//cropped by a transparent box of length-N pixel size
if(N+32>length)
var/icon/II = new(icon, icon_state)
- II.DrawBox(null,1,(length-N),32,32)
+ II.DrawBox(null, 1, (length-N), 32, 32)
X.icon = II
else
X.icon = base_icon
+ if(beamcolor)
+ X.color = beamcolor
X.transform = rot_matrix
//Calculate pixel offsets (If necessary)
@@ -163,7 +167,7 @@
var/armor = L.run_armor_check(limb_to_hit, LASER)
L.apply_damage(damage, BURN, limb_to_hit, armor)
-/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=3)
- var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type,beam_sleep_time)
+/atom/proc/Beam(atom/BeamTarget, icon_state="b_beam", icon='icons/effects/beam.dmi', time = 5 SECONDS, maxdistance = 10, beam_type = /obj/effect/ebeam, beam_sleep_time = 3, beam_color)
+ var/datum/beam/newbeam = new(src, BeamTarget, icon, icon_state, time, maxdistance, beam_type, beam_sleep_time, beam_color)
INVOKE_ASYNC(newbeam, TYPE_PROC_REF(/datum/beam, Start))
return newbeam
diff --git a/code/datums/spells/alien_spells/basetype_alien_spell.dm b/code/datums/spells/alien_spells/basetype_alien_spell.dm
index 3cacc2e8e02..c4413e45d90 100644
--- a/code/datums/spells/alien_spells/basetype_alien_spell.dm
+++ b/code/datums/spells/alien_spells/basetype_alien_spell.dm
@@ -20,8 +20,7 @@ Updates the spell's actions on use as well, so they know when they can or can't
/obj/effect/proc_holder/spell/alien_spell
action_background_icon_state = "bg_alien"
clothes_req = FALSE
- /// Extremely fast cooldown, only present so the cooldown system doesn't explode
- base_cooldown = 1
+ base_cooldown = 0
create_attack_logs = FALSE
/// Every alien spell creates only logs, no attack messages on someone placing weeds, but you DO get attack messages on neurotoxin and corrosive acid
create_custom_logs = TRUE
diff --git a/code/datums/spells/alien_spells/build_resin_structure.dm b/code/datums/spells/alien_spells/build_resin_structure.dm
index aadbcabcdea..9da55a22ebf 100644
--- a/code/datums/spells/alien_spells/build_resin_structure.dm
+++ b/code/datums/spells/alien_spells/build_resin_structure.dm
@@ -8,14 +8,18 @@
return new /datum/spell_targeting/self
/obj/effect/proc_holder/spell/alien_spell/build_resin/cast(list/targets, mob/living/carbon/user)
- var/static/list/resin_buildings = list("Resin Wall (55)" = image(icon = 'icons/obj/smooth_structures/alien/resin_wall.dmi', icon_state = "resin_wall-0"),
- "Resin Nest (55)" = image(icon = 'icons/mob/alien.dmi', icon_state = "nest"),
- "Resin door (80)" = image(icon = 'icons/obj/smooth_structures/alien/resin_door.dmi', icon_state = "resin"))
+ var/static/list/resin_buildings = list("Resin Wall" = image(icon = 'icons/obj/smooth_structures/alien/resin_wall.dmi', icon_state = "resin_wall-0"),
+ "Resin Nest" = image(icon = 'icons/mob/alien.dmi', icon_state = "nest"),
+ "Resin Door" = image(icon = 'icons/obj/smooth_structures/alien/resin_door.dmi', icon_state = "resin"),
+ "Revival Nest" = image(icon = 'icons/mob/alien.dmi', icon_state = "placeholder_rejuv_nest"))
var/choice = show_radial_menu(user, user, resin_buildings, src, radius = 40)
var/turf/turf_to_spawn_at = user.loc
if(!choice)
revert_cast(user)
return
+ if(!do_mob(user, user, 3 SECONDS))
+ revert_cast()
+ return
if(isspaceturf(turf_to_spawn_at))
to_chat(user, "You cannot build the [choice] while in space!")
revert_cast(user)
@@ -27,15 +31,52 @@
return
visible_message("[user] vomits up a thick purple substance and shapes it!")
switch(choice)
- if("Resin Wall (55)")
+ if("Resin Wall")
new /obj/structure/alien/resin/wall(turf_to_spawn_at)
- if("Resin Nest (55)")
+ if("Resin Nest")
new /obj/structure/bed/nest(turf_to_spawn_at)
- if("Resin door (80)")
- var/plasma_current = user.get_plasma()
- if(plasma_current >= 25)
- new /obj/structure/alien/resin/door(turf_to_spawn_at)
- user.add_plasma(-25)
- return
- to_chat(user, "You don't have enough plasma to place a door down.")
- revert_cast(user)
+ if("Resin Door")
+ new /obj/structure/alien/resin/door(turf_to_spawn_at)
+ if("Revival Nest")
+ new /obj/structure/bed/revival_nest(turf_to_spawn_at)
+
+/obj/effect/proc_holder/spell/touch/alien_spell/consume_resin
+ name = "Consume resin structures"
+ desc = "Allows you to rip and tear straight through resin structures."
+ action_icon_state = "alien_resin"
+ hand_path = "/obj/item/melee/touch_attack/alien/consume_resin"
+ plasma_cost = 10
+ base_cooldown = 5 SECONDS
+
+/obj/item/melee/touch_attack/alien/consume_resin
+ name = "Resin consumption"
+ desc = "The hunger..."
+ icon_state = "alien_acid"
+
+/obj/item/melee/touch_attack/alien/consume_resin/afterattack(atom/target, mob/living/carbon/user, proximity)
+ if(target == user)
+ to_chat(user, "You stop trying to consume resin.")
+ ..()
+ return
+ if(!proximity || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ return
+ if(istype(target, /obj/structure/alien/weeds))
+ qdel(target)
+ if(istype(target, /obj/structure/alien/weeds/node))
+ user.add_plasma(50)
+ user.visible_message("[user] rips and tears into [target] with their teeth!", "You viciously rip apart and consume [target]!")
+ return
+ if(!plasma_check(10, user))
+ to_chat(user, "You don't have enough plasma to perform this action!")
+ return
+ var/static/list/resin_objects = list(/obj/structure/alien/resin, /obj/structure/alien/egg, /obj/structure/bed/nest, /obj/structure/bed/revival_nest)
+ for(var/resin_type in resin_objects)
+ if(!istype(target, resin_type))
+ continue
+ user.visible_message("[user] rips and tears into [target] with their teeth!")
+ if(!do_after(user, 3 SECONDS, target = target))
+ return
+ to_chat(user, "You viciously rip apart and consume [target]!")
+ user.add_plasma(-10)
+ qdel(target)
+ ..()
diff --git a/code/datums/spells/alien_spells/corrosive_acid_spit.dm b/code/datums/spells/alien_spells/corrosive_acid_spit.dm
index 18a58b9494b..17e7756f7c7 100644
--- a/code/datums/spells/alien_spells/corrosive_acid_spit.dm
+++ b/code/datums/spells/alien_spells/corrosive_acid_spit.dm
@@ -4,6 +4,7 @@
hand_path = "/obj/item/melee/touch_attack/alien/corrosive_acid"
action_icon_state = "alien_acid"
plasma_cost = 200
+ base_cooldown = 15 SECONDS
/obj/item/melee/touch_attack/alien/corrosive_acid
name = "Corrosive acid"
@@ -30,3 +31,45 @@
else
to_chat(user, "You cannot dissolve this object.")
..()
+
+/obj/effect/proc_holder/spell/touch/alien_spell/burning_touch
+ name = "Blazing touch"
+ desc = "Boil acid within your hand to burn through anything you touch with it, deals a lot of damage to aliens and destroys resin structures instantly."
+ hand_path = "/obj/item/melee/touch_attack/alien/burning_touch"
+ action_icon_state = "alien_acid"
+ plasma_cost = 100
+ base_cooldown = 10 SECONDS
+
+/obj/item/melee/touch_attack/alien/burning_touch
+ name = "Blazing touch"
+ desc = "The air warps around your hand, somehow the heat doesn't hurt."
+ icon_state = "alien_acid"
+
+/obj/item/melee/touch_attack/alien/burning_touch/afterattack(atom/target, mob/living/carbon/user, proximity)
+ if(target == user)
+ to_chat(user, "You cool down your boiled aid.")
+ ..()
+ return
+ if(!proximity || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
+ return
+ if(!plasma_check(100, user))
+ to_chat(user, "You don't have enough plasma to perform this action!")
+ return
+ if(isliving(target))
+ var/mob/living/guy_to_burn = target
+ add_attack_logs(user, target, "Applied blazing touch") // Want this logged
+ guy_to_burn.adjustFireLoss(60)
+ guy_to_burn.adjust_fire_stacks(3)
+ guy_to_burn.IgniteMob()
+ user.visible_message("[user] touches [target] and a fireball erupts on contact!")
+ user.add_plasma(-100)
+ ..()
+ else
+ var/static/list/resin_objects = list(/obj/structure/alien/resin, /obj/structure/alien/egg, /obj/structure/bed/nest, /obj/structure/bed/revival_nest)
+ for(var/resin_type in resin_objects)
+ if(!istype(target, resin_type))
+ continue
+ user.visible_message("[user] touches [target] and burns right through it!")
+ user.add_plasma(-100)
+ qdel(target)
+ ..()
diff --git a/code/datums/spells/alien_spells/lay_alien_eggs.dm b/code/datums/spells/alien_spells/lay_alien_eggs.dm
index 7789420e1c3..f2bfc89011f 100644
--- a/code/datums/spells/alien_spells/lay_alien_eggs.dm
+++ b/code/datums/spells/alien_spells/lay_alien_eggs.dm
@@ -5,3 +5,35 @@
weed_type = /obj/structure/alien/egg
weed_name = "alien egg"
action_icon_state = "alien_egg"
+ requires_do_after = FALSE
+
+/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers
+ name = "Combust facehuggers and eggs"
+ desc = "Take over the programming of facehuggers and eggs, sending out a shockwave which causes them to combust."
+ plasma_cost = 25
+ action_icon_state = "alien_egg"
+ base_cooldown = 3 SECONDS
+
+/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers/create_new_targeting()
+ return new /datum/spell_targeting/clicked_atom
+
+/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers/cast(list/targets, mob/living/carbon/user)
+ var/obj/target = targets[1]
+ var/turf/T = user.loc
+ if(!istype(T) || !istype(target))
+ revert_cast()
+ return FALSE
+
+ if(!istype(target, /obj/item/clothing/mask/facehugger) && !istype(target, /obj/structure/alien/egg))
+ revert_cast()
+ return FALSE
+
+ target.color = "#c72623"
+ addtimer(CALLBACK(src, PROC_REF(blow_it_up), target, user), 3 SECONDS)
+ to_chat(user, "[target] will explode in 3 seconds!")
+ return TRUE
+
+/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers/proc/blow_it_up(obj/target, mob/user)
+ add_attack_logs(user, target, "Caused it to explode")
+ explosion(get_turf(target), 0, 2, 3, 3, cause = user)
+ to_chat(user, "[target] has detonated!")
diff --git a/code/datums/spells/alien_spells/neurotoxin_spit.dm b/code/datums/spells/alien_spells/neurotoxin_spit.dm
index ca688886d13..ad4048f53a1 100644
--- a/code/datums/spells/alien_spells/neurotoxin_spit.dm
+++ b/code/datums/spells/alien_spells/neurotoxin_spit.dm
@@ -1,7 +1,7 @@
/obj/effect/proc_holder/spell/alien_spell/neurotoxin
name = "Neurotoxin spit"
desc = "This ability allows you to fire some neurotoxin. Knocks down anyone you hit, applies a small amount of stamina damage as well."
- base_cooldown = 5 SECONDS
+ base_cooldown = 3 SECONDS
plasma_cost = 50
selection_activated_message = "Your prepare some neurotoxin!"
selection_deactivated_message = "You swallow your prepared neurotoxin."
@@ -34,3 +34,9 @@
user.newtonian_move(get_dir(U, T))
return TRUE
+
+/obj/effect/proc_holder/spell/alien_spell/neurotoxin/death_to_xenos
+ name = "Neurotoxin spit"
+ desc = "This ability allows you to fire some neurotoxin. Knocks aliens down."
+ neurotoxin_type = /obj/item/projectile/bullet/anti_alien_toxin
+ base_cooldown = 2 SECONDS
diff --git a/code/datums/spells/alien_spells/plasma_weeds.dm b/code/datums/spells/alien_spells/plasma_weeds.dm
index c816475f7ea..b254403bc6e 100644
--- a/code/datums/spells/alien_spells/plasma_weeds.dm
+++ b/code/datums/spells/alien_spells/plasma_weeds.dm
@@ -2,9 +2,10 @@
name = "Plant weeds"
desc = "Allows you to plant some alien weeds on the floor below you. Does not work while in space."
plasma_cost = 50
- var/weed_type = /obj/structure/alien/weeds/node
+ var/atom/weed_type = /obj/structure/alien/weeds/node
var/weed_name = "alien weed node"
action_icon_state = "alien_plant"
+ var/requires_do_after = TRUE
/obj/effect/proc_holder/spell/alien_spell/plant_weeds/create_new_targeting()
return new /datum/spell_targeting/self
@@ -26,5 +27,10 @@
revert_cast()
return
+ user.visible_message("Vines burst from the back of [user], quickly scurring to the ground and swarm onto [user.loc].", "You begin infesting [user.loc] with [initial(weed_type.name)].")
+ if(requires_do_after && !do_mob(user, user, 2 SECONDS))
+ revert_cast()
+ return
+
user.visible_message("[user] has planted \a [weed_name]!")
new weed_type(T)
diff --git a/code/datums/spells/alien_spells/queen_evolve.dm b/code/datums/spells/alien_spells/queen_evolve.dm
index e8112f0506c..75502cfcd69 100644
--- a/code/datums/spells/alien_spells/queen_evolve.dm
+++ b/code/datums/spells/alien_spells/queen_evolve.dm
@@ -1,7 +1,7 @@
/obj/effect/proc_holder/spell/alien_spell/evolve_queen
name = "Evolve into an alien queen"
desc = "Evolve into an alien queen."
- plasma_cost = 500
+ plasma_cost = 300
action_icon_state = "alien_evolve_drone"
/obj/effect/proc_holder/spell/alien_spell/evolve_queen/create_new_targeting()
@@ -17,8 +17,7 @@
// If there is no queen, that means we can evolve
to_chat(user, "You begin to evolve!")
user.visible_message("[user] begins to twist and contort!")
- var/turf/userloc = user.loc
- var/mob/living/carbon/alien/humanoid/queen/new_xeno = new(userloc)
+ var/mob/living/carbon/alien/humanoid/queen/new_xeno = new(get_turf(user))
user.mind.transfer_to(new_xeno)
new_xeno.mind.name = new_xeno.name
SSblackbox.record_feedback("tally", "alien_growth", 1, "queen")
diff --git a/code/datums/spells/alien_spells/regurgitate.dm b/code/datums/spells/alien_spells/regurgitate.dm
index effd0a9629b..02960c88afb 100644
--- a/code/datums/spells/alien_spells/regurgitate.dm
+++ b/code/datums/spells/alien_spells/regurgitate.dm
@@ -9,6 +9,9 @@
/obj/effect/proc_holder/spell/alien_spell/regurgitate/cast(list/targets, mob/living/carbon/user)
for(var/mob/M in user.stomach_contents)
var/turf/output_loc = user.loc
+ if(!istype(output_loc))
+ return
+ user.stomach_contents -= M
M.forceMove(output_loc)
visible_message("[user] hurls out the contents of [p_their()] stomach!")
return
diff --git a/code/datums/spells/alien_spells/tail_lash.dm b/code/datums/spells/alien_spells/tail_lash.dm
new file mode 100644
index 00000000000..0daa1e8a6a0
--- /dev/null
+++ b/code/datums/spells/alien_spells/tail_lash.dm
@@ -0,0 +1,23 @@
+/obj/effect/proc_holder/spell/alien_spell/tail_lash
+ name = "Tail lash"
+ desc = "Knocks down anyone around you."
+ action_icon_state = "tailsweep"
+ base_cooldown = 10 SECONDS
+
+/obj/effect/proc_holder/spell/alien_spell/tail_lash/create_new_targeting()
+ return new /datum/spell_targeting/self
+
+/obj/effect/proc_holder/spell/alien_spell/tail_lash/cast(list/targets, mob/user)
+ var/turf/T = user.loc
+ var/cast_resolved = FALSE
+ if(!istype(T))
+ revert_cast()
+ return
+ for(var/mob/living/to_knock_down in orange(1, user))
+ if(to_knock_down.KnockDown(10 SECONDS))
+ cast_resolved = TRUE
+ to_knock_down.visible_message("[user] sweeps [to_knock_down] off their feet!")
+ if(!cast_resolved)
+ revert_cast()
+
+ return cast_resolved
diff --git a/code/datums/spells/alien_spells/transfer_plasma.dm b/code/datums/spells/alien_spells/transfer_plasma.dm
index 1edf34dfa67..3ab94da1daf 100644
--- a/code/datums/spells/alien_spells/transfer_plasma.dm
+++ b/code/datums/spells/alien_spells/transfer_plasma.dm
@@ -1,28 +1,55 @@
-/obj/effect/proc_holder/spell/touch/alien_spell/transfer_plasma
+/obj/effect/proc_holder/spell/alien_spell/transfer_plasma
name = "Transfer Plasma"
desc = "Transfers 50 plasma to a nearby alien"
- hand_path = "/obj/item/melee/touch_attack/alien/transfer_plasma"
action_icon_state = "alien_transfer"
plasma_cost = 50
-/obj/item/melee/touch_attack/alien/transfer_plasma
- name = "plasma transfer"
- desc = "Transfers 50 plasma to another alien."
- icon_state = "alien_transfer"
+/obj/effect/proc_holder/spell/alien_spell/transfer_plasma/create_new_targeting()
+ return new /datum/spell_targeting/clicked_atom
-/obj/item/melee/touch_attack/alien/transfer_plasma/afterattack(atom/target, mob/living/carbon/user, proximity)
- if(target == user)
- to_chat(user, "You withdraw your readied plasma.")
- ..()
+/obj/effect/proc_holder/spell/alien_spell/transfer_plasma/cast(list/targets, mob/living/carbon/user)
+ var/mob/living/carbon/alien/target = targets[1]
+ var/turf/T = user.loc
+ if(!istype(T) || !istype(target))
+ revert_cast()
+ return FALSE
+
+ user.Beam(target, icon_state = "sendbeam", time = 2 SECONDS, beam_color = "#f180bd")
+ target.add_plasma(50)
+ to_chat(user, "You have transfered 50 plasma to [target].")
+ to_chat(target, "[user] has transfered 50 plasma to you!")
+ return TRUE
+
+/obj/effect/proc_holder/spell/alien_spell/syphon_plasma
+ name = "Syphon plasma"
+ desc = "Syphons 150 plasma from a nearby alien."
+ action_icon_state = "alien_transfer"
+ plasma_cost = 0
+ base_cooldown = 10 SECONDS
+
+/obj/effect/proc_holder/spell/alien_spell/syphon_plasma/create_new_targeting()
+ return new /datum/spell_targeting/clicked_atom
+
+/obj/effect/proc_holder/spell/alien_spell/syphon_plasma/cast(list/targets, mob/living/carbon/user)
+ var/mob/living/carbon/alien/target = targets[1]
+ var/turf/T = user.loc
+ if(!istype(T) || !istype(target))
+ revert_cast()
+ return FALSE
+
+ user.Beam(target, icon_state = "drainbeam", time = 2 SECONDS, beam_color = "#f180bd")
+ var/obj/item/organ/internal/alien/plasmavessel/vessel = target.get_int_organ(/obj/item/organ/internal/alien/plasmavessel)
+ if(!vessel)
return
- if(!proximity || !isalien(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED))
- return
- if(!plasma_check(50, user))
- to_chat(user, "You don't have enough plasma to perform this action!")
- return
- user.add_plasma(-50)
- var/mob/living/carbon/transfering_to = target
- transfering_to.add_plasma(50)
- to_chat(user, "You have transfered 50 plasma to [transfering_to].")
- to_chat(transfering_to, "[user] has transfered 50 plasma to you!")
- ..()
+ var/plasma_syphoned
+ if(vessel.stored_plasma < 150)
+ user.add_plasma(vessel.stored_plasma)
+ plasma_syphoned = vessel.stored_plasma
+ vessel.stored_plasma = 0
+ else
+ user.add_plasma(150)
+ plasma_syphoned = 50
+ vessel.stored_plasma = vessel.stored_plasma - 150
+ to_chat(user, "You have syphoned [plasma_syphoned] plasma from [target].")
+ to_chat(target, "[user] has syphoned [plasma_syphoned] from you!")
+ return TRUE
diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm
index a15406306dc..17ea778639f 100644
--- a/code/game/mecha/combat/combat.dm
+++ b/code/game/mecha/combat/combat.dm
@@ -3,7 +3,7 @@
var/maxsize = 2
internal_damage_threshold = 50
maint_access = 0
- armor = list(melee = 30, bullet = 30, laser = 15, energy = 20, bomb = 20, rad = 0, fire = 100, acid = 100)
+ armor = list(melee = 30, bullet = 30, laser = 15, energy = 20, bomb = 20, rad = 0, fire = 100)
destruction_sleep_duration = 4 SECONDS
var/am = "d3c2fbcadca903a41161ccc9df9cf948"
diff --git a/code/game/mecha/combat/durand.dm b/code/game/mecha/combat/durand.dm
index 3694b525650..1ba971d347f 100644
--- a/code/game/mecha/combat/durand.dm
+++ b/code/game/mecha/combat/durand.dm
@@ -7,7 +7,7 @@
dir_in = 1 //Facing North.
max_integrity = 400
deflect_chance = 20
- armor = list(melee = 40, bullet = 35, laser = 15, energy = 10, bomb = 20, rad = 50, fire = 100, acid = 100)
+ armor = list(melee = 40, bullet = 35, laser = 15, energy = 10, bomb = 20, rad = 50, fire = 100, acid = 75)
max_temperature = 30000
infra_luminosity = 8
force = 40
diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm
index e32ec8e3236..f8f4c97d9d9 100644
--- a/code/game/mecha/combat/gygax.dm
+++ b/code/game/mecha/combat/gygax.dm
@@ -7,7 +7,7 @@
dir_in = 1 //Facing North.
max_integrity = 250
deflect_chance = 5
- armor = list(melee = 25, bullet = 20, laser = 30, energy = 15, bomb = 0, rad = 0, fire = 100, acid = 100)
+ armor = list(melee = 25, bullet = 20, laser = 30, energy = 15, bomb = 0, rad = 0, fire = 100, acid = 75)
max_temperature = 25000
infra_luminosity = 6
leg_overload_coeff = 2
diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm
index 6559f69ad4d..f57aa643db7 100644
--- a/code/game/mecha/combat/marauder.dm
+++ b/code/game/mecha/combat/marauder.dm
@@ -52,7 +52,8 @@
initial_icon = "ares"
operation_req_access = list(ACCESS_SECURITY)
max_integrity = 450
- armor = list(melee = 50, bullet = 40, laser = 20, energy = 20, bomb = 20, rad = 60, fire = 100, acid = 100)
+ resistance_flags = LAVA_PROOF | FIRE_PROOF
+ armor = list(melee = 50, bullet = 40, laser = 20, energy = 20, bomb = 20, rad = 60, fire = 100, acid = 75)
max_temperature = 40000
wreckage = /obj/structure/mecha_wreckage/ares
max_equip = 5
diff --git a/code/game/mecha/combat/phazon.dm b/code/game/mecha/combat/phazon.dm
index 1d7b748d344..4711eedb5fd 100644
--- a/code/game/mecha/combat/phazon.dm
+++ b/code/game/mecha/combat/phazon.dm
@@ -9,7 +9,7 @@
normal_step_energy_drain = 3
max_integrity = 200
deflect_chance = 30
- armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 30, RAD = 50, FIRE = 100, ACID = 100)
+ armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 30, RAD = 50, FIRE = 100, ACID = 75)
max_temperature = 25000
infra_luminosity = 3
wreckage = /obj/structure/mecha_wreckage/phazon
diff --git a/code/game/mecha/combat/reticence.dm b/code/game/mecha/combat/reticence.dm
index 1e9beb7016e..e6970740a80 100644
--- a/code/game/mecha/combat/reticence.dm
+++ b/code/game/mecha/combat/reticence.dm
@@ -7,7 +7,7 @@
dir_in = 1 //Facing North.
max_integrity = 150
deflect_chance = 30
- armor = list(MELEE = 25, BULLET = 20, LASER = 30, ENERGY = 15, BOMB = 0, RAD = 0, FIRE = 100, ACID = 100)
+ armor = list(MELEE = 25, BULLET = 20, LASER = 30, ENERGY = 15, BOMB = 0, RAD = 0, FIRE = 100, ACID = 75)
max_temperature = 15000
wreckage = /obj/structure/mecha_wreckage/reticence
operation_req_access = list(ACCESS_MIME)
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 8d41450c50b..3af23927e21 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -7,12 +7,12 @@
density = TRUE //Dense. To raise the heat.
opacity = TRUE ///opaque. Menacing.
anchored = TRUE //no pulling around.
- resistance_flags = FIRE_PROOF | ACID_PROOF
+ resistance_flags = FIRE_PROOF
layer = MOB_LAYER //icon draw layer
infra_luminosity = 15 //byond implementation is bugged.
force = 5
max_integrity = 300 //max_integrity is base health
- armor = list(melee = 20, bullet = 10, laser = 0, energy = 0, bomb = 0, rad = 0, fire = 100, acid = 100)
+ armor = list(melee = 20, bullet = 10, laser = 0, energy = 0, bomb = 0, rad = 0, fire = 100, acid = 75)
bubble_icon = "machine"
var/list/facing_modifiers = list(MECHA_FRONT_ARMOUR = 1.5, MECHA_SIDE_ARMOUR = 1, MECHA_BACK_ARMOUR = 0.5)
var/ruin_mecha = FALSE //if the mecha starts on a ruin, don't automatically give it a tracking beacon to prevent metagaming.
diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm
index 7c2b0ff3f7c..66ad6d2f864 100644
--- a/code/game/mecha/working/ripley.dm
+++ b/code/game/mecha/working/ripley.dm
@@ -78,9 +78,9 @@
initial_icon = "firefighter"
max_temperature = 65000
max_integrity = 250
- resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
+ resistance_flags = LAVA_PROOF | FIRE_PROOF
lights_power = 7
- armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 60, RAD = 70, FIRE = 100, ACID = 100)
+ armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 60, RAD = 70, FIRE = 100)
max_equip = 5 // More armor, less tools
wreckage = /obj/structure/mecha_wreckage/ripley/firefighter
diff --git a/code/game/objects/cleaning.dm b/code/game/objects/cleaning.dm
index f1ba88a0441..b65980d1daa 100644
--- a/code/game/objects/cleaning.dm
+++ b/code/game/objects/cleaning.dm
@@ -46,6 +46,7 @@
var/obj/effect/decal/cleanable/C = locate() in src
qdel(C)
clean_blood()
+ SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT)
return TRUE
/atom/proc/can_clean() //For determining if a cleaning object can actually remove decals
diff --git a/code/game/objects/effects/alien_acid.dm b/code/game/objects/effects/alien_acid.dm
index 8d1eb45036e..86c1c0c2c73 100644
--- a/code/game/objects/effects/alien_acid.dm
+++ b/code/game/objects/effects/alien_acid.dm
@@ -24,7 +24,6 @@
START_PROCESSING(SSobj, src)
-
/obj/effect/acid/Destroy()
STOP_PROCESSING(SSobj, src)
target = null
@@ -67,6 +66,14 @@
/obj/effect/acid/alien
var/target_strength = 30
+/obj/effect/acid/alien/Initialize(mapload, acid_pwr, acid_amt)
+ . = ..()
+ var/turf/cleanable_turf = get_turf(src)
+ RegisterSignal(cleanable_turf, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(remove_acid))
+
+/obj/effect/acid/alien/proc/remove_acid(datum/source)
+ SIGNAL_HANDLER
+ qdel(src)
/obj/effect/acid/alien/process()
. = ..()
diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm
index fd263b11f9d..a21489172e8 100644
--- a/code/game/objects/obj_defense.dm
+++ b/code/game/objects/obj_defense.dm
@@ -192,6 +192,11 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
SSacid.processing -= src
deconstruct(FALSE)
+/obj/cleaning_act(mob/user, atom/cleaner, cleanspeed, text_verb, text_description, text_targetname)
+ . = ..()
+ if(acid_level)
+ acid_level = 0
+
//// FIRE
/obj/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE)
diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm
index c11b47c82cd..9beb67b5e35 100644
--- a/code/game/objects/structures/aliens.dm
+++ b/code/game/objects/structures/aliens.dm
@@ -111,7 +111,7 @@
icon = 'icons/obj/smooth_structures/alien/resin_door.dmi'
icon_state = "resin"
base_icon_state = "resin"
- max_integrity = 100
+ max_integrity = 60
armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 50, ACID = 50)
damage_deflection = 0
flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2
@@ -156,7 +156,7 @@
/obj/structure/alien/resin/door/CanAtmosPass(turf/T)
return !density
-/obj/structure/alien/resin/door/proc/try_to_operate(mob/user)
+/obj/structure/alien/resin/door/proc/try_to_operate(mob/user, bumped_open = FALSE)
if(is_operating)
return
if(!iscarbon(user))
@@ -164,7 +164,7 @@
var/mob/living/carbon/C = user
if(C.get_int_organ(/obj/item/organ/internal/alien/hivenode))
if(!C.handcuffed)
- operate()
+ operate(bumped_open)
return
to_chat(user, "Your lack of connection to the hive prevents the resin door from opening")
/*
@@ -178,7 +178,7 @@
return
operate()
-/obj/structure/alien/resin/door/proc/operate()
+/obj/structure/alien/resin/door/proc/operate(bumped_open = FALSE)
is_operating = TRUE
if(!state_open)
playsound(loc, open_sound, 50, TRUE)
@@ -194,14 +194,14 @@
density = !density
opacity = !opacity
state_open = !state_open
- addtimer(CALLBACK(src, PROC_REF(operate_update)), 1 SECONDS)
+ addtimer(CALLBACK(src, PROC_REF(operate_update), bumped_open), 1 SECONDS)
-/obj/structure/alien/resin/door/proc/operate_update()
+/obj/structure/alien/resin/door/proc/operate_update(bumped_open)
air_update_turf(1)
update_icon(UPDATE_ICON_STATE)
is_operating = FALSE
- if(state_open)
+ if(state_open && bumped_open)
addtimer(CALLBACK(src, PROC_REF(mobless_try_to_operate)), close_delay)
/obj/structure/alien/resin/door/update_icon_state()
@@ -219,7 +219,7 @@
/obj/structure/alien/resin/door/Bumped(atom/user)
..()
if(!state_open)
- return try_to_operate(user)
+ return try_to_operate(user, TRUE)
/*
* Weeds
diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm
index 25b08b00413..3313812d833 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm
@@ -110,3 +110,118 @@
/obj/structure/bed/nest/prevents_buckled_mobs_attacking()
return TRUE
+
+/obj/structure/bed/revival_nest
+ name = "alien rejuvenation nest"
+ desc = "It's a gruesome pile of thick, sticky resin shaped like a flytrap. Heals damaged aliens and slowly revives the dead, breaks down non xenos and uses their genetic soup to make an alien egg."
+ icon = 'icons/mob/alien.dmi'
+ icon_state = "placeholder_rejuv_nest"
+ max_integrity = 30
+ var/image/nest_overlay
+ comfort = 0
+ flags = NODECONSTRUCT
+ var/processing_ticks = 0
+ var/revive_or_decay_timer
+
+/obj/structure/bed/revival_nest/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
+ for(var/mob/living/M in buckled_mobs) //breaking a nest releases all the buckled mobs, because the nest isn't holding them down anymore
+ if(HAS_TRAIT(user, TRAIT_XENO_IMMUNE))
+ unbuckle_mob(M)
+ add_fingerprint(user)
+ return
+
+ if(M != user)
+ M.visible_message("[user] tears [M] out of the rejuvination pod!",\
+ "[user] pulls you free from the rejuvination pod!",\
+ "You hear squelching...")
+ else
+ M.visible_message("[M] struggles to break free from the rejuvination pod!",\
+ "You struggle to break free from the rejuvination pod... (Stay still for 15 seconds.)",\
+ "You hear squelching...")
+ if(!do_after(M, 15 SECONDS, target = src))
+ if(M && M.buckled)
+ to_chat(M, "You fail to escape \the [src]!")
+ return
+ if(!M.buckled)
+ return
+ M.visible_message("[M] breaks free from the rejuvination pod!",\
+ "You break free from the rejuvination pod!",\
+ "You hear squelching...")
+ unbuckle_mob(M)
+ add_fingerprint(user)
+
+/obj/structure/bed/revival_nest/post_unbuckle_mob(mob/living/M)
+ STOP_PROCESSING(SSobj, src)
+ deltimer(revive_or_decay_timer)
+
+/obj/structure/bed/revival_nest/process()
+ for(var/mob/living/buckled_mob in buckled_mobs)
+ processing_ticks++
+ if(isalien(buckled_mob))
+ buckled_mob.adjustBruteLoss(-5)
+ buckled_mob.adjustFireLoss(-5)
+ buckled_mob.adjustToxLoss(-5)
+ buckled_mob.adjustOxyLoss(-5)
+ buckled_mob.adjustCloneLoss(-5)
+ for(var/datum/disease/virus in buckled_mob.viruses)
+ if(virus.stage < 1 && processing_ticks >= 4)
+ virus.cure()
+ processing_ticks = 0
+ if(virus.stage > 1 && processing_ticks >= 4)
+ virus.stage--
+ processing_ticks = 0
+ if(buckled_mob.stat == DEAD && !revive_or_decay_timer)
+ revive_or_decay_timer = addtimer(CALLBACK(src, PROC_REF(revive_dead_alien), buckled_mob), 40 SECONDS, TIMER_UNIQUE|TIMER_STOPPABLE)
+ else
+ buckled_mob.adjustBruteLoss(3)
+ buckled_mob.adjustFireLoss(3)
+
+/obj/structure/bed/revival_nest/proc/revive_dead_alien(mob/living/carbon/alien/dead_alien)
+ dead_alien.revive()
+ dead_alien.visible_message("Vines seep into the back of [dead_alien], and it awakes with a burning rage!")
+ if(dead_alien.ghost_can_reenter())
+ var/mob/dead/observer/dead_bro = dead_alien.grab_ghost()
+ SEND_SOUND(dead_alien, sound('sound/voice/hiss5.ogg'))
+ if(isalienqueen(dead_alien))
+ for(var/mob/living/carbon/alien/humanoid/queen/living_queen in GLOB.alive_mob_list)
+ if(living_queen.key || !living_queen.get_int_organ(/obj/item/organ/internal/brain))
+ to_chat(dead_bro, "We already have an alive queen. We've been reverted to our drone form!")
+ qdel(dead_alien)
+ var/mob/living/carbon/alien/humanoid/drone/new_drone = new(get_turf(src))
+ new_drone.key = dead_bro.key
+ else
+ var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as [dead_alien]?", ROLE_ALIEN, FALSE, source = dead_alien)
+ if(!length(candidates))
+ return
+ var/mob/C = pick(candidates)
+ dead_alien.key = C.key
+ dust_if_respawnable(C)
+ dead_alien.mind.name = dead_alien.name
+ dead_alien.mind.assigned_role = SPECIAL_ROLE_XENOMORPH
+ dead_alien.mind.special_role = SPECIAL_ROLE_XENOMORPH
+ SEND_SOUND(dead_alien, sound('sound/voice/hiss5.ogg'))
+
+/obj/structure/bed/revival_nest/user_buckle_mob(mob/living/M, mob/living/user)
+ if(!istype(M) || (get_dist(src, user) > 1) || (M.loc != loc) || user.incapacitated() || M.buckled)
+ return
+
+ if(!user.get_int_organ(/obj/item/organ/internal/alien/hivenode))
+ to_chat(user, "Your lack of linkage to the hive prevents you from buckling [M] into [src].")
+ return
+
+ if(has_buckled_mobs())
+ unbuckle_all_mobs()
+
+ if(buckle_mob(M))
+ M.visible_message("[user] secretes a thick vile goo, securing [M] into [src]!",\
+ "[user] drenches you in a foul-smelling resin, trapping you in [src]!",\
+ "You hear squelching...")
+ START_PROCESSING(SSobj, src)
+
+/obj/structure/bed/revival_nest/attack_alien(mob/living/carbon/alien/user)
+ if(user.a_intent != INTENT_HARM)
+ return attack_hand(user)
+ if(!do_after(user, 4 SECONDS, target = src) || QDELETED(src))
+ return
+ playsound(get_turf(user), pick('sound/effects/alien_resin_break2.ogg', 'sound/effects/alien_resin_break1.ogg'), 50, FALSE)
+ qdel(src)
diff --git a/code/modules/mob/living/carbon/alien/alien_base.dm b/code/modules/mob/living/carbon/alien/alien_base.dm
index 07722061279..8d2a727019e 100644
--- a/code/modules/mob/living/carbon/alien/alien_base.dm
+++ b/code/modules/mob/living/carbon/alien/alien_base.dm
@@ -5,18 +5,16 @@
bubble_icon = "alien"
icon = 'icons/mob/alien.dmi'
gender = NEUTER
- dna = null
var/nightvision = TRUE
see_in_dark = 4
var/obj/item/card/id/wear_id = null // Fix for station bounced radios -- Skie
var/has_fine_manipulation = FALSE
- var/move_delay_add = FALSE // movement delay to add
+ var/move_delay_add = 0 // movement delay to add
status_flags = CANPARALYSE|CANPUSH
var/heal_rate = 5
- var/large = FALSE
var/loudspeaker = FALSE
var/heat_protection = 0.5
var/leaping = FALSE
@@ -27,8 +25,6 @@
/mob/living/carbon/alien/Initialize(mapload)
. = ..()
create_reagents(1000)
- verbs += /mob/living/verb/mob_sleep
- verbs += /mob/living/verb/rest
for(var/organ_path in get_caste_organs())
var/obj/item/organ/internal/organ = new organ_path()
@@ -50,17 +46,17 @@
return GLOB.all_languages["Xenomorph"]
/mob/living/carbon/alien/say_quote(message, datum/language/speaking = null)
- var/verb = "hisses"
+ var/speech_verb = "hisses"
var/ending = copytext(message, length(message))
if(speaking && (speaking.name != "Galactic Common")) //this is so adminbooze xenos speaking common have their custom verbs,
- verb = speaking.get_spoken_verb(ending) //and use normal verbs for their own languages and non-common languages
+ speech_verb = speaking.get_spoken_verb(ending) //and use normal verbs for their own languages and non-common languages
else
- if(ending=="!")
- verb = "roars"
- else if(ending=="?")
- verb = "hisses curiously"
- return verb
+ if(ending == "!")
+ speech_verb = "roars"
+ else if(ending== "?")
+ speech_verb = "hisses curiously"
+ return speech_verb
/mob/living/carbon/alien/adjustToxLoss(amount)
@@ -68,7 +64,7 @@
/mob/living/carbon/alien/adjustFireLoss(amount) // Weak to Fire
if(amount > 0)
- return ..(amount * 2)
+ return ..(amount * 1.5)
else
return ..(amount)
@@ -77,17 +73,11 @@
return 2
/mob/living/carbon/alien/handle_environment(datum/gas_mixture/environment)
-
if(!environment)
return
var/loc_temp = get_temperature(environment)
-// to_chat(world, "Loc temp: [loc_temp] - Body temp: [bodytemperature] - Fireloss: [getFireLoss()] - Fire protection: [heat_protection] - Location: [loc] - src: [src]")
-
- // Aliens are now weak to fire.
-
- //After then, it reacts to the surrounding atmosphere based on your thermal protection
if(!on_fire) // If you're on fire, ignore local air temperature
if(loc_temp > bodytemperature)
//Place is hotter than we are
@@ -121,8 +111,8 @@
/mob/living/carbon/alien/Stat()
..()
if(statpanel("Status"))
- stat(null, "Intent: [a_intent]")
- stat(null, "Move Mode: [m_intent]")
+ stat("Intent: [a_intent]")
+ stat("Move Mode: [m_intent]")
show_stat_emergency_shuttle_eta()
/mob/living/carbon/alien/SetStunned(amount, updating = TRUE, force = 0)
@@ -141,24 +131,6 @@
/mob/living/carbon/alien/setDNA()
return
-/mob/living/carbon/alien/verb/nightvisiontoggle()
- set name = "Toggle Night Vision"
- set category = "Alien"
-
- if(!nightvision)
- see_in_dark = 8
- lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
- nightvision = TRUE
- usr.hud_used.nightvisionicon.icon_state = "nightvision1"
- else if(nightvision)
- see_in_dark = initial(see_in_dark)
- lighting_alpha = initial(lighting_alpha)
- nightvision = FALSE
- usr.hud_used.nightvisionicon.icon_state = "nightvision0"
-
- update_sight()
-
-
/mob/living/carbon/alien/assess_threat(mob/living/simple_animal/bot/secbot/judgebot, lasercolor)
if(judgebot.emagged)
return 10 //Everyone is a criminal!
@@ -209,34 +181,31 @@
/mob/living/carbon/alien/proc/deathrattle_message()
return "The hivemind echoes: [name] has been slain!"
-/mob/living/carbon/alien/CanContractDisease(datum/disease/D)
- return FALSE
-
/*----------------------------------------
Proc: AddInfectionImages()
Des: Gives the client of the alien an image on each infected mob.
----------------------------------------*/
/mob/living/carbon/alien/proc/AddInfectionImages()
- if(client)
- for(var/mob/living/C in GLOB.mob_list)
- if(HAS_TRAIT(C, TRAIT_XENO_HOST))
- var/obj/item/organ/internal/body_egg/alien_embryo/A = C.get_int_organ(/obj/item/organ/internal/body_egg/alien_embryo)
- if(A)
- var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[A.stage]")
- client.images += I
- return
-
+ if(!client)
+ return
+ for(var/mob/living/C in GLOB.mob_list)
+ if(HAS_TRAIT(C, TRAIT_XENO_HOST))
+ var/obj/item/organ/internal/body_egg/alien_embryo/A = C.get_int_organ(/obj/item/organ/internal/body_egg/alien_embryo)
+ if(!A)
+ continue
+ var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[A.stage]")
+ client.images += I
/*----------------------------------------
Proc: RemoveInfectionImages()
Des: Removes all infected images from the alien.
----------------------------------------*/
/mob/living/carbon/alien/proc/RemoveInfectionImages()
- if(client)
- for(var/image/I in client.images)
- if(dd_hasprefix_case(I.icon_state, "infected"))
- qdel(I)
- return
+ if(!client)
+ return
+ for(var/image/I in client.images)
+ if(dd_hasprefix_case(I.icon_state, "infected"))
+ qdel(I)
/mob/living/carbon/alien/canBeHandcuffed()
return TRUE
@@ -309,3 +278,8 @@ and carry the owner just to make sure*/
medicine.reagents.reaction(src, reagent_application, fraction)
medicine.reagents.trans_to(src, how_many_reagents)
return TRUE
+
+/mob/living/carbon/alien/update_stat(reason)
+ if(health <= HEALTH_THRESHOLD_CRIT && stat == CONSCIOUS)
+ KnockOut()
+ return ..()
diff --git a/code/modules/mob/living/carbon/alien/alien_death.dm b/code/modules/mob/living/carbon/alien/alien_death.dm
index 12757bd3a8b..fa5e5a1f12c 100644
--- a/code/modules/mob/living/carbon/alien/alien_death.dm
+++ b/code/modules/mob/living/carbon/alien/alien_death.dm
@@ -12,7 +12,7 @@
animation.icon = 'icons/mob/mob.dmi'
animation.master = src
- playsound(src.loc, 'sound/goonstation/effects/gib.ogg', 50, 1)
+ playsound(loc, 'sound/goonstation/effects/gib.ogg', 50, TRUE)
for(var/mob/M in stomach_contents) //Release eaten mobs when Beno is gibbed
LAZYREMOVE(stomach_contents, M)
@@ -21,6 +21,13 @@
var/mob/living/carbon/human/H = M
H.KnockDown(5 SECONDS)
+ for(var/obj/item/organ/internal/I in internal_organs)
+ if(isturf(loc))
+ var/atom/movable/thing = I.remove(src)
+ if(thing)
+ thing.forceMove(get_turf(src))
+ thing.throw_at(get_edge_target_turf(src, pick(GLOB.alldirs)), rand(1, 3), 5)
+
flick("gibbed-a", animation)
xgibs(loc)
GLOB.dead_mob_list -= src
diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm
index de23bdcd5bb..491d5612f72 100644
--- a/code/modules/mob/living/carbon/alien/alien_defense.dm
+++ b/code/modules/mob/living/carbon/alien/alien_defense.dm
@@ -10,9 +10,6 @@ In all, this is a lot like the monkey code.
This code could certainly use with a touch of TLC, but it functions alright. Bit odd aliens attacking other aliens are like, full logged though
*/
/mob/living/carbon/alien/attack_alien(mob/living/carbon/alien/M)
- if(isturf(loc) && istype(loc.loc, /area/start))
- to_chat(M, "No attacking people at spawn, you jackass.")
- return
switch(M.a_intent)
if(INTENT_HELP)
AdjustSleeping(-10 SECONDS)
@@ -82,9 +79,9 @@ This code could certainly use with a touch of TLC, but it functions alright. Bit
/mob/living/carbon/alien/attack_slime(mob/living/simple_animal/slime/M) // This is very RNG based, maybe come back to this later - GDN
if(..()) //successful slime attack
- var/damage = rand(5, 35)
+ var/damage = 10
if(M.is_adult)
- damage = rand(10, 40)
+ damage = 15
adjustBruteLoss(damage)
add_attack_logs(M, src, "Slime'd for [damage] damage")
updatehealth("slime attack")
diff --git a/code/modules/mob/living/carbon/alien/alien_login.dm b/code/modules/mob/living/carbon/alien/alien_login.dm
index 589a9741627..fa043b3e8c8 100644
--- a/code/modules/mob/living/carbon/alien/alien_login.dm
+++ b/code/modules/mob/living/carbon/alien/alien_login.dm
@@ -2,4 +2,3 @@
..()
AddInfectionImages()
update_plasma_display(src)
- return
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/alien_drone.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/alien_drone.dm
index 1195a46e735..35c75e4931a 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/alien_drone.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/alien_drone.dm
@@ -1,15 +1,14 @@
/mob/living/carbon/alien/humanoid/drone
name = "alien drone"
caste = "d"
- maxHealth = 100
- health = 100
+ maxHealth = 150
+ health = 150
icon_state = "aliend_s"
/mob/living/carbon/alien/humanoid/drone/Initialize(mapload)
. = ..()
- if(src.name == "alien drone")
- src.name = "alien drone ([rand(1, 1000)])"
- src.real_name = src.name
+ name = "alien drone ([rand(1, 1000)])"
+ real_name = name
AddSpell(new /obj/effect/proc_holder/spell/alien_spell/evolve_queen)
/mob/living/carbon/alien/humanoid/drone/get_caste_organs()
@@ -19,8 +18,3 @@
/obj/item/organ/internal/alien/acidgland,
/obj/item/organ/internal/alien/resinspinner,
)
-
-
-//Drones use the same base as generic humanoids.
-//Drone verbs
-
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
index a3084c4af42..0b8c0ab5441 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
@@ -1,38 +1,35 @@
/mob/living/carbon/alien/humanoid/hunter
name = "alien hunter"
caste = "h"
- maxHealth = 125
- health = 125
+ maxHealth = 150
+ health = 150
icon_state = "alienh_s"
- alien_movement_delay = -1 //hunters are faster than normal xenomorphs, and people
+ alien_movement_delay = -0.5 //hunters are faster than normal xenomorphs, and people
+ var/leap_on_click = FALSE
+ /// Are we on leap cooldown?
+ var/on_leap_cooldown = FALSE
/mob/living/carbon/alien/humanoid/hunter/Initialize(mapload)
. = ..()
- if(name == "alien hunter")
- name = "alien hunter ([rand(1, 1000)])"
+ name = "alien hunter ([rand(1, 1000)])"
real_name = name
/mob/living/carbon/alien/humanoid/hunter/get_caste_organs()
. = ..()
. += /obj/item/organ/internal/alien/plasmavessel/hunter
-
/mob/living/carbon/alien/humanoid/hunter/handle_environment()
if(m_intent == MOVE_INTENT_RUN || IS_HORIZONTAL(src))
..()
else
add_plasma(-heal_rate)
-
-//Hunter verbs
-
-/mob/living/carbon/alien/humanoid/hunter/proc/toggle_leap(message = 1)
+/mob/living/carbon/alien/humanoid/hunter/proc/toggle_leap(message = TRUE)
leap_on_click = !leap_on_click
leap_icon.icon_state = "leap_[leap_on_click ? "on":"off"]"
+ update_icons()
if(message)
- to_chat(src, "You will now [leap_on_click ? "leap at":"slash at"] enemies!")
- else
- return
+ to_chat(src, "You will now [leap_on_click ? "leap at" : "slash at"] enemies!")
/mob/living/carbon/alien/humanoid/hunter/ClickOn(atom/A, params)
face_atom(A)
@@ -44,64 +41,71 @@
#define MAX_ALIEN_LEAP_DIST 7
/mob/living/carbon/alien/humanoid/hunter/proc/leap_at(atom/A)
- if(pounce_cooldown > world.time)
- to_chat(src, "You are too fatigued to pounce right now!")
+ if(leaping || on_leap_cooldown)
return
- if(leaping) //Leap while you leap, so you can leap while you leap
- return
-
- if(!has_gravity(src) || !has_gravity(A))
- to_chat(src, "It is unsafe to leap without gravity!")
- //It's also extremely buggy visually, so it's balance+bugfix
- return
if(IS_HORIZONTAL(src))
return
- else //Maybe uses plasma in the future, although that wouldn't make any sense...
- leaping = 1
- update_icons()
- throw_at(A, MAX_ALIEN_LEAP_DIST, 1, spin = 0, diagonals_first = 1, callback = CALLBACK(src, PROC_REF(leap_end)))
+ leaping = TRUE
+ on_leap_cooldown = TRUE
+ update_icons()
+ Immobilize(15 SECONDS, TRUE)
+ addtimer(VARSET_CALLBACK(src, on_leap_cooldown, FALSE), 3 SECONDS)
+ throw_at(A, MAX_ALIEN_LEAP_DIST, 1.5, spin = 0, diagonals_first = 1, callback = CALLBACK(src, PROC_REF(leap_end)))
/mob/living/carbon/alien/humanoid/hunter/proc/leap_end()
- leaping = 0
+ leaping = FALSE
+ SetImmobilized(0, TRUE)
update_icons()
/mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/A)
if(!leaping)
return ..()
- if(A)
- if(isliving(A))
- var/mob/living/L = A
- var/blocked = 0
- if(ishuman(A))
- var/mob/living/carbon/human/H = A
- if(H.check_shields(src, 0, "the [name]", attack_type = LEAP_ATTACK))
- blocked = 1
- if(!blocked)
- L.visible_message("[src] pounces on [L]!", "[src] pounces on you!")
- if(ishuman(L))
- var/mob/living/carbon/human/H = L
- H.apply_effect(10 SECONDS, KNOCKDOWN, H.run_armor_check(null, MELEE))
- H.apply_damage(40, STAMINA)
- else
- L.Weaken(10 SECONDS)
- sleep(2)//Runtime prevention (infinite bump() calls on hulks)
- step_towards(src,L)
+ if(isliving(A))
+ var/mob/living/L = A
+ var/blocked = FALSE
+ if(ishuman(A))
+ var/mob/living/carbon/human/H = A
+ if(H.check_shields(src, 0, "the [name]", attack_type = LEAP_ATTACK))
+ blocked = TRUE
+ if(!blocked)
+ L.visible_message("[src] pounces on [L]!", "[src] pounces on you!")
+ if(ishuman(L))
+ var/mob/living/carbon/human/H = L
+ H.apply_effect(10 SECONDS, KNOCKDOWN, H.run_armor_check(null, MELEE))
+ H.apply_damage(40, STAMINA)
else
- Weaken(4 SECONDS, TRUE)
+ L.Weaken(5 SECONDS)
+ sleep(2)//Runtime prevention (infinite bump() calls on hulks)
+ step_towards(src, L)
+ else
+ Weaken(2 SECONDS, TRUE)
+ ..()
- toggle_leap(0)
- pounce_cooldown = world.time + pounce_cooldown_time
- else if(A.density && !A.CanPass(src))
- visible_message("[src] smashes into [A]!", "[src] smashes into [A]!")
- Weaken(4 SECONDS, TRUE)
-
- if(leaping)
- leaping = 0
- update_icons()
+ toggle_leap(FALSE)
+ else if(A.density && !A.CanPass(src))
+ visible_message("[src] smashes into [A]!", "[src] smashes into [A]!")
+ Weaken(2 SECONDS, TRUE)
+ playsound(get_turf(src), 'sound/effects/bang.ogg', 50, 0, 0) // owwie
+ ..()
+ if(leaping)
+ leaping = FALSE
+ update_icons()
+/mob/living/carbon/alien/humanoid/hunter/update_icons()
+ ..()
+ if(leap_on_click && !leaping)
+ icon_state = "alien[caste]_pounce"
+ if(leaping)
+ if(alt_icon == initial(alt_icon))
+ var/old_icon = icon
+ icon = alt_icon
+ alt_icon = old_icon
+ icon_state = "alien[caste]_leap"
+ pixel_x = -32
+ pixel_y = -32
/mob/living/carbon/alien/humanoid/float(on)
if(leaping)
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
index bd3075eadf6..9b9ae103770 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
@@ -1,8 +1,8 @@
/mob/living/carbon/alien/humanoid/sentinel
name = "alien sentinel"
caste = "s"
- maxHealth = 150
- health = 150
+ maxHealth = 175
+ health = 175
icon_state = "aliens_s"
/mob/living/carbon/alien/humanoid/sentinel/large
@@ -12,13 +12,6 @@
pixel_x = -16
maxHealth = 200
health = 200
- large = 1
-
-/mob/living/carbon/alien/humanoid/sentinel/praetorian
- name = "alien praetorian"
- maxHealth = 200
- health = 200
- large = 1
/mob/living/carbon/alien/humanoid/sentinel/large/update_icons()
overlays.Cut()
@@ -34,8 +27,7 @@
/mob/living/carbon/alien/humanoid/sentinel/Initialize(mapload)
. = ..()
- if(name == "alien sentinel")
- name = "alien sentinel ([rand(1, 1000)])"
+ name = "alien sentinel ([rand(1, 1000)])"
real_name = name
/mob/living/carbon/alien/humanoid/sentinel/get_caste_organs()
diff --git a/code/modules/mob/living/carbon/alien/humanoid/empress.dm b/code/modules/mob/living/carbon/alien/humanoid/empress.dm
index 2ab7d866323..9ea090b459e 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/empress.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/empress.dm
@@ -8,7 +8,6 @@
loudspeaker = TRUE
mob_size = MOB_SIZE_LARGE
bubble_icon = "alienroyal"
- large = 1
ventcrawler = VENTCRAWLER_NONE
move_resist = MOVE_FORCE_STRONG //Yes, big benos is huge and heavy
alien_disarm_damage = 60 //Empress do higher disarm stamina damage than normal aliens
@@ -37,16 +36,7 @@
/mob/living/carbon/alien/humanoid/empress/Initialize(mapload)
. = ..()
//there should only be one queen
- for(var/mob/living/carbon/alien/humanoid/empress/E in GLOB.alive_mob_list)
- if(E == src)
- continue
- if(E.stat == DEAD)
- continue
- if(E.client)
- name = "alien grand princess ([rand(1, 999)])" //if this is too cutesy feel free to change it/remove it.
- break
-
- real_name = name
+ ADD_TRAIT(src, TRAIT_FORCE_DOORS, UNIQUE_TRAIT_SOURCE(src))
/mob/living/carbon/alien/humanoid/empress/get_caste_organs()
. = ..()
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
index 004546a18f1..5b139d6652d 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm
@@ -7,10 +7,6 @@
var/obj/item/l_store = null
var/caste = ""
var/alt_icon = 'icons/mob/alienleap.dmi' //used to switch between the two alien icon files.
- var/next_attack = 0
- var/pounce_cooldown = 0
- var/pounce_cooldown_time = 30
- var/leap_on_click = 0
var/custom_pixel_x_offset = 0 //for admin fuckery.
var/custom_pixel_y_offset = 0
var/alien_disarm_damage = 30 //Aliens deal a good amount of stamina damage on disarm intent
@@ -32,13 +28,14 @@
/mob/living/carbon/alien/humanoid/Process_Spacemove(check_drift = 0)
if(..())
- return 1
-
- return 0
+ return TRUE
+ return FALSE
/mob/living/carbon/alien/humanoid/emp_act(severity)
- if(r_store) r_store.emp_act(severity)
- if(l_store) l_store.emp_act(severity)
+ if(r_store)
+ r_store.emp_act(severity)
+ if(l_store)
+ l_store.emp_act(severity)
..()
/mob/living/carbon/alien/humanoid/ex_act(severity)
@@ -70,9 +67,8 @@
/mob/living/carbon/alien/humanoid/restrained()
if(handcuffed)
- return 1
- return 0
-
+ return TRUE
+ return FALSE
/mob/living/carbon/alien/humanoid/movement_delay() //Aliens have a varied movespeed
. = ..()
@@ -101,9 +97,6 @@
popup.set_content(dat)
popup.open()
-/mob/living/carbon/alien/humanoid/canBeHandcuffed()
- return 1
-
/mob/living/carbon/alien/humanoid/cuff_resist(obj/item/I)
playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free
..(I, cuff_break = 1)
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm
index 5d0f1aff481..43c9bd95936 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm
@@ -4,14 +4,11 @@
to_chat(user, "You don't want to hurt [src]!")
return FALSE
..(user, TRUE)
- adjustBruteLoss(15)
+ adjustBruteLoss(10)
var/hitverb = "punched"
if(mob_size < MOB_SIZE_LARGE)
- Paralyse(2 SECONDS)
- spawn(0)
- step_away(src, user, 15)
- sleep(1)
- step_away(src, user, 15)
+ Stun(2 SECONDS)
+ throw_at(get_edge_target_turf(user, get_dir(user, src)), 3, 7)
hitverb = "slammed"
playsound(loc, "punch", 25, 1, -1)
visible_message("[user] has [hitverb] [src]!", "[user] has [hitverb] [src]!")
diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid_update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid_update_icons.dm
index 9c168e564c4..70f37d83d21 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/humanoid_update_icons.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid_update_icons.dm
@@ -28,8 +28,6 @@
else if(stat == UNCONSCIOUS || IsWeakened())
icon_state = "alien[caste]_unconscious"
pixel_y = 0
- else if(leap_on_click)
- icon_state = "alien[caste]_pounce"
else if(IS_HORIZONTAL(src))
icon_state = "alien[caste]_sleep"
@@ -38,21 +36,12 @@
else
icon_state = "alien[caste]_s"
- if(leaping)
- if(alt_icon == initial(alt_icon))
- var/old_icon = icon
- icon = alt_icon
- alt_icon = old_icon
- icon_state = "alien[caste]_leap"
- pixel_x = -32
- pixel_y = -32
- else
- if(alt_icon != initial(alt_icon))
- var/old_icon = icon
- icon = alt_icon
- alt_icon = old_icon
- pixel_x = get_standard_pixel_x_offset()
- pixel_y = get_standard_pixel_y_offset()
+ if(alt_icon != initial(alt_icon))
+ var/old_icon = icon
+ icon = alt_icon
+ alt_icon = old_icon
+ pixel_x = get_standard_pixel_x_offset()
+ pixel_y = get_standard_pixel_y_offset()
/mob/living/carbon/alien/humanoid/regenerate_icons()
..()
diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
index 2564f8ec7b8..1d0e6e931de 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
@@ -1,13 +1,11 @@
/mob/living/carbon/alien/humanoid/queen
name = "alien queen"
caste = "q"
- maxHealth = 250
- health = 250
+ maxHealth = 300
+ health = 300
icon_state = "alienq_s"
status_flags = CANPARALYSE
loudspeaker = TRUE
- heal_rate = 5
- large = 1
ventcrawler = VENTCRAWLER_NONE
pressure_resistance = 200 //Because big, stompy xenos should not be blown around like paper.
move_resist = MOVE_FORCE_STRONG //Yes, queenos is huge and heavy
@@ -17,19 +15,8 @@
/mob/living/carbon/alien/humanoid/queen/Initialize(mapload)
. = ..()
- //there should only be one queen
- for(var/mob/living/carbon/alien/humanoid/queen/Q in GLOB.alive_mob_list)
- if(Q == src)
- ADD_TRAIT(Q, TRAIT_FORCE_DOORS, VAMPIRE_TRAIT)
- continue
- if(Q.stat == DEAD)
- ADD_TRAIT(Q, TRAIT_FORCE_DOORS, VAMPIRE_TRAIT)
- continue
- if(Q.client)
- name = "alien princess ([rand(1, 999)])" //if this is too cutesy feel free to change it/remove it.
- break
-
- real_name = src.name
+ ADD_TRAIT(src, TRAIT_FORCE_DOORS, UNIQUE_TRAIT_SOURCE(src))
+ AddSpell(new /obj/effect/proc_holder/spell/alien_spell/tail_lash)
/mob/living/carbon/alien/humanoid/queen/get_caste_organs()
. = ..()
@@ -38,8 +25,7 @@
/obj/item/organ/internal/alien/acidgland,
/obj/item/organ/internal/alien/eggsac,
/obj/item/organ/internal/alien/resinspinner,
- /obj/item/organ/internal/alien/neurotoxin,
- )
+ /obj/item/organ/internal/alien/neurotoxin)
/mob/living/carbon/alien/humanoid/queen/deathrattle_message()
return "A shock reverberates through the hive; [name] has been slain!"
@@ -51,7 +37,6 @@
icon = 'icons/mob/alienlarge.dmi'
icon_state = "queen_s"
pixel_x = -16
- large = 1
/mob/living/carbon/alien/humanoid/queen/large/update_icons()
overlays.Cut()
diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm
index 20d6c23c669..c1e3b1d69cf 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva.dm
@@ -12,15 +12,14 @@
var/temperature_resistance = T0C+75
var/amount_grown = 0
var/max_grown = 200
- var/time_of_birth
death_message = "lets out a waning high-pitched cry."
death_sound = null
//This is fine right now, if we're adding organ specific damage this needs to be updated
/mob/living/carbon/alien/larva/Initialize(mapload)
. = ..()
- if(name == "alien larva")
- name = "alien larva ([rand(1, 1000)])"
+
+ name = "alien larva ([rand(1, 1000)])"
real_name = name
regenerate_icons()
add_language("Xenomorph")
@@ -42,7 +41,7 @@
/mob/living/carbon/alien/larva/Stat()
..()
- stat(null, "Progress: [amount_grown]/[max_grown]")
+ stat("Progress: [amount_grown]/[max_grown]")
/mob/living/carbon/alien/larva/add_plasma(amount)
if(stat != DEAD && amount > 0)
@@ -82,7 +81,6 @@
// new damage icon system
// now constructs damage icon for each organ from mask * damage field
-
/mob/living/carbon/alien/larva/show_inv(mob/user as mob)
return
diff --git a/code/modules/mob/living/carbon/alien/larva/larva_inventory.dm b/code/modules/mob/living/carbon/alien/larva/larva_inventory.dm
index fc5acb63fd0..0c5df6d99e9 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva_inventory.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva_inventory.dm
@@ -1,3 +1,3 @@
-//can't unequip since it can't equip anything
+//can't unequip since it can't equip anything // why the fuck is this it's own file
/mob/living/carbon/alien/larva/unEquip(obj/item/I, force, silent = FALSE)
return
diff --git a/code/modules/mob/living/carbon/alien/larva/larva_life.dm b/code/modules/mob/living/carbon/alien/larva/larva_life.dm
index ea964329fd4..141f5e8d950 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva_life.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva_life.dm
@@ -1,7 +1,5 @@
/mob/living/carbon/alien/larva/Life(seconds, times_fired)
set invisibility = 0
- if(notransform)
- return
if(..()) //not dead and not in stasis
// GROW!
if(amount_grown < max_grown)
@@ -19,10 +17,8 @@
if(IsParalyzed() || IsSleeping() || getOxyLoss() > 50 || (health <= HEALTH_THRESHOLD_CRIT && check_death_method()))
if(stat == CONSCIOUS)
KnockOut()
- create_debug_log("fell unconscious, trigger reason: [reason]")
else
if(stat == UNCONSCIOUS)
WakeUp()
- create_debug_log("woke up, trigger reason: [reason]")
update_damage_hud()
update_health_hud()
diff --git a/code/modules/mob/living/carbon/alien/larva/larva_update_icons.dm b/code/modules/mob/living/carbon/alien/larva/larva_update_icons.dm
index 60db90600d1..90e14393f5f 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva_update_icons.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva_update_icons.dm
@@ -1,4 +1,3 @@
-
/mob/living/carbon/alien/larva/regenerate_icons()
overlays = list()
update_icons()
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index ff85b6ec8e5..0bd858d98c5 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -1080,7 +1080,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven
if(statpanel("Status"))
var/obj/item/organ/internal/alien/plasmavessel/vessel = get_int_organ(/obj/item/organ/internal/alien/plasmavessel)
if(vessel)
- stat(null, "Plasma Stored: [vessel.stored_plasma]/[vessel.max_plasma]")
+ stat("Plasma Stored: [vessel.stored_plasma]/[vessel.max_plasma]")
/mob/living/carbon/get_all_slots()
return list(l_hand,
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 9af4de76228..f463a173a82 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -666,12 +666,10 @@ emp_act
visible_message("[src] is not affected by [M]'s disarm attempt!")
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
return FALSE
- var/obj/item/I = get_active_hand()
- if(I)
- unEquip(I)
var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_selected))
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
apply_effect(10 SECONDS, KNOCKDOWN, run_armor_check(affecting, MELEE))
+ M.changeNext_move(1.6 SECONDS)
apply_damage(M.alien_disarm_damage, STAMINA)
add_attack_logs(M, src, "Alien tackled")
visible_message("[M] has tackled down [src]!", "You hear aggressive shuffling!")
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 117d256420e..6de1b1b4d79 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -144,7 +144,8 @@
if(locate(/obj/item/grab, mob))
- delay += 7
+ if(!isalienhunter(mob)) // i hate grab code
+ delay += 7
if(istype(living_mob))
var/newdir = NONE
diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm
index 01c719abfff..56935aae546 100644
--- a/code/modules/projectiles/projectile/bullets.dm
+++ b/code/modules/projectiles/projectile/bullets.dm
@@ -275,8 +275,21 @@
if(isalien(target))
knockdown = 0
nodamage = TRUE
+ if(isrobot(target))
+ stun = 10 SECONDS
. = ..() // Execute the rest of the code.
+/obj/item/projectile/bullet/anti_alien_toxin
+ name = "neurotoxin spit"
+ icon_state = "neurotoxin"
+ damage = 15 // FRENDLY FIRE FRENDLY FIRE
+ damage_type = BURN
+
+/obj/item/projectile/bullet/anti_alien_toxin/on_hit(atom/target, blocked = 0)
+ if(isalien(target))
+ stun = 10 SECONDS
+ . = ..()
+
/obj/item/projectile/bullet/cap
name = "cap"
damage = 0
diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm
index 6e081554cae..a211c2e69f0 100644
--- a/code/modules/shuttle/supply.dm
+++ b/code/modules/shuttle/supply.dm
@@ -206,6 +206,10 @@
msg += "[S.rarity]: New species discovered: \"[capitalize(S.species)]\". Excellent work.
"
service_credits += S.rarity / 2 // That's right, no bonus for potency. Send a crappy sample first to "show improvement" later
credits_to_deposit += S.rarity / 2
+
+ if(istype(thing, /obj/item/organ/internal/alien))
+ var/obj/item/organ/internal/alien/organ = thing
+ credits_to_deposit += organ.cargo_profit
qdel(MA)
SSeconomy.sold_atoms += "."
diff --git a/code/modules/surgery/organs/brain.dm b/code/modules/surgery/organs/brain.dm
index f756a29f392..762fc793df6 100644
--- a/code/modules/surgery/organs/brain.dm
+++ b/code/modules/surgery/organs/brain.dm
@@ -38,16 +38,20 @@
if(isnull(dna)) // someone didn't set this right...
stack_trace("[src] at [loc] did not contain a dna datum at time of removal.")
dna = H.dna.Clone()
- name = "\the [dna.real_name]'s [initial(src.name)]"
+ if(dna.real_name)
+ name = "\the [dna.real_name]'s [initial(name)]"
+ brainmob.name = dna.real_name
+ brainmob.real_name = dna.real_name
+ else
+ name = "\the [H.real_name]'s [initial(name)]"
+ brainmob.name = H.real_name
+ brainmob.real_name = H.real_name
brainmob.dna = dna.Clone() // Silly baycode, what you do
-// brainmob.dna = H.dna.Clone() Putting in and taking out a brain doesn't make it a carbon copy of the original brain of the body you put it in
- brainmob.name = dna.real_name
- brainmob.real_name = dna.real_name
brainmob.timeofhostdeath = H.timeofdeath
if(H.mind)
H.mind.transfer_to(brainmob)
- to_chat(brainmob, "You feel slightly disoriented. That's normal when you're just a [initial(src.name)].")
+ to_chat(brainmob, "You feel slightly disoriented. That's normal when you're just a [initial(name)].")
/obj/item/organ/internal/brain/examine(mob/user) // -- TLE
. = ..()
diff --git a/code/modules/surgery/organs/subtypes/xenos.dm b/code/modules/surgery/organs/subtypes/xenos.dm
index d69ef938b7e..98960fdd4b5 100644
--- a/code/modules/surgery/organs/subtypes/xenos.dm
+++ b/code/modules/surgery/organs/subtypes/xenos.dm
@@ -2,20 +2,51 @@
origin_tech = "biotech=5"
icon_state = "xgibmid2"
var/list/alien_powers = list()
+ var/list/human_powers = list()
tough = TRUE
sterile = TRUE
+ /// Amount of credits that will be received by selling this in the cargo shuttle
+ var/cargo_profit = 250
+ /// Has this organ been hijacked? Can hijack via a hemostat
+ var/hijacked = FALSE
/// This adds and removes alien spells upon addition, if a noncarbon tries to do this well... I blame adminbus
/obj/item/organ/internal/alien/insert(mob/living/carbon/M, special = 0)
..()
- for(var/powers_to_add in alien_powers)
- M.AddSpell(new powers_to_add)
+ if(!hijacked)
+ for(var/powers_to_add in alien_powers)
+ M.AddSpell(new powers_to_add)
+ else
+ for(var/powers_to_add in human_powers)
+ M.AddSpell(new powers_to_add)
/obj/item/organ/internal/alien/remove(mob/living/carbon/M, special = 0)
- for(var/powers_to_remove in alien_powers)
- M.RemoveSpell(new powers_to_remove)
+ if(!hijacked)
+ for(var/powers_to_remove in alien_powers)
+ M.RemoveSpell(new powers_to_remove)
+ else
+ for(var/powers_to_add in human_powers)
+ M.AddSpell(new powers_to_add)
. = ..()
+/obj/item/organ/internal/alien/examine(mob/user)
+ . = ..()
+ . += "Can be sold on the cargo shuttle for [cargo_profit] credits."
+ if(hijacked)
+ . += "This organ is hijacked, use a Hemostat on it to revert it to it's original function."
+ else
+ . += "You can hijack the latent functions of this organ by using a Hemostat on it."
+
+/obj/item/organ/internal/alien/attackby(obj/item/hemostat/item, mob/user, params)
+ if(istype(item))
+ if(!hijacked)
+ to_chat(user, "You slice off the control node of this organ. This organ will now be effective against aliens.")
+ else
+ to_chat(user, "You reattach the control node of this organ. This organ will now be effective against those who attack the hive.")
+ hijacked = !hijacked
+ return
+ return ..()
+
/obj/item/organ/internal/alien/prepare_eat()
var/obj/S = ..()
S.reagents.add_reagent("sacid", 10)
@@ -28,18 +59,18 @@
icon_state = "plasma"
w_class = WEIGHT_CLASS_NORMAL
origin_tech = "biotech=5;plasmatech=4"
- parent_organ = "chest"
slot = "plasmavessel"
- alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/plant_weeds, /obj/effect/proc_holder/spell/touch/alien_spell/transfer_plasma)
+ alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/plant_weeds, /obj/effect/proc_holder/spell/alien_spell/transfer_plasma)
+ human_powers = list(/obj/effect/proc_holder/spell/alien_spell/syphon_plasma)
- var/stored_plasma = 0
- var/max_plasma = 500
+ var/stored_plasma = 100
+ var/max_plasma = 300
var/heal_rate = 5
var/plasma_rate = 10
/obj/item/organ/internal/alien/plasmavessel/prepare_eat()
var/obj/S = ..()
- S.reagents.add_reagent("plasma", stored_plasma/10)
+ S.reagents.add_reagent("plasma", stored_plasma / 10)
return S
/obj/item/organ/internal/alien/plasmavessel/queen
@@ -47,14 +78,12 @@
icon_state = "plasma_large"
origin_tech = "biotech=6;plasmatech=4"
stored_plasma = 200
- max_plasma = 500
plasma_rate = 25
/obj/item/organ/internal/alien/plasmavessel/drone
name = "large xeno plasma vessel"
icon_state = "plasma_large"
stored_plasma = 200
- max_plasma = 500
/obj/item/organ/internal/alien/plasmavessel/sentinel
stored_plasma = 100
@@ -63,16 +92,15 @@
/obj/item/organ/internal/alien/plasmavessel/hunter
name = "small xeno plasma vessel"
icon_state = "plasma_tiny"
- stored_plasma = 100
- max_plasma = 150
- alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/plant_weeds)
+ stored_plasma = 50
+ max_plasma = 100
/obj/item/organ/internal/alien/plasmavessel/larva
name = "tiny xeno plasma vessel"
icon_state = "plasma_tiny"
- max_plasma = 100
- alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/plant_weeds)
-
+ stored_plasma = 25
+ max_plasma = 50
+ cargo_profit = 150
/obj/item/organ/internal/alien/plasmavessel/on_life()
//If there are alien weeds on the ground then heal if needed or give some plasma
@@ -83,7 +111,7 @@
var/heal_amt = heal_rate
if(!isalien(owner))
heal_amt *= 0.2
- owner.add_plasma((plasma_rate*0.5))
+ owner.add_plasma((plasma_rate / 2))
owner.adjustBruteLoss(-heal_amt)
owner.adjustFireLoss(-heal_amt)
owner.adjustOxyLoss(-heal_amt)
@@ -97,20 +125,17 @@
. =..()
M.update_plasma_display(M)
-
/obj/item/organ/internal/alien/acidgland
name = "xeno acid gland"
icon_state = "acid"
- parent_organ = "head"
slot = "acid"
origin_tech = "biotech=5;materials=2;combat=2"
alien_powers = list(/obj/effect/proc_holder/spell/touch/alien_spell/corrosive_acid)
-
+ human_powers = list(/obj/effect/proc_holder/spell/touch/alien_spell/burning_touch)
/obj/item/organ/internal/alien/hivenode
name = "xeno hive node"
icon_state = "hivenode"
- parent_organ = "head"
slot = "hivenode"
origin_tech = "biotech=5;magnets=4;bluespace=3"
w_class = WEIGHT_CLASS_TINY
@@ -133,24 +158,25 @@
/obj/item/organ/internal/alien/neurotoxin
name = "xeno neurotoxin gland"
icon_state = "neurotox"
- parent_organ = "head"
slot = "neurotox"
origin_tech = "biotech=5;combat=5"
alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/neurotoxin)
+ human_powers = list(/obj/effect/proc_holder/spell/alien_spell/neurotoxin/death_to_xenos)
/obj/item/organ/internal/alien/resinspinner
- name = "xeno resin organ"//...there tiger....
- parent_organ = "mouth"
+ name = "xeno resin organ"
icon_state = "liver-x"
slot = "spinner"
origin_tech = "biotech=5;materials=4"
alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/build_resin)
+ human_powers = list(/obj/effect/proc_holder/spell/touch/alien_spell/consume_resin)
/obj/item/organ/internal/alien/eggsac
name = "xeno egg sac"
icon_state = "eggsac"
- parent_organ = "groin"
slot = "eggsac"
w_class = WEIGHT_CLASS_BULKY
origin_tech = "biotech=6"
alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/plant_weeds/eggs)
+ human_powers = list(/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers)
+ cargo_profit = 1000
diff --git a/icons/mob/alien.dmi b/icons/mob/alien.dmi
index 15631f719db..aa921ea1343 100644
Binary files a/icons/mob/alien.dmi and b/icons/mob/alien.dmi differ
diff --git a/paradise.dme b/paradise.dme
index ef10a3ef4d1..742bfa526f9 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -568,6 +568,7 @@
#include "code\datums\spells\alien_spells\plasma_weeds.dm"
#include "code\datums\spells\alien_spells\queen_evolve.dm"
#include "code\datums\spells\alien_spells\regurgitate.dm"
+#include "code\datums\spells\alien_spells\tail_lash.dm"
#include "code\datums\spells\alien_spells\transfer_plasma.dm"
#include "code\datums\spells\alien_spells\whisper.dm"
#include "code\datums\station_traits\_station_trait.dm"