diff --git a/.travis.yml b/.travis.yml
index f47db96174..6b0a88de28 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,7 +5,7 @@ sudo: false
env:
BYOND_MAJOR="508"
BYOND_MINOR="1293"
- MACRO_COUNT=1151
+ MACRO_COUNT=1133
cache:
directories:
diff --git a/baystation12.dme b/baystation12.dme
index 14b6b5dae8..d66394cc49 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -757,7 +757,6 @@
#include "code\game\objects\structures\inflatable.dm"
#include "code\game\objects\structures\janicart.dm"
#include "code\game\objects\structures\kitchen_spike.dm"
-#include "code\game\objects\structures\lamarr_cage.dm"
#include "code\game\objects\structures\lattice.dm"
#include "code\game\objects\structures\mirror.dm"
#include "code\game\objects\structures\mop_bucket.dm"
@@ -775,6 +774,10 @@
#include "code\game\objects\structures\windoor_assembly.dm"
#include "code\game\objects\structures\window.dm"
#include "code\game\objects\structures\window_spawner.dm"
+#include "code\game\objects\structures\alien\alien.dm"
+#include "code\game\objects\structures\alien\egg.dm"
+#include "code\game\objects\structures\alien\node.dm"
+#include "code\game\objects\structures\alien\resin.dm"
#include "code\game\objects\structures\crates_lockers\closets.dm"
#include "code\game\objects\structures\crates_lockers\crates.dm"
#include "code\game\objects\structures\crates_lockers\largecrate.dm"
@@ -1259,6 +1262,7 @@
#include "code\modules\mob\living\carbon\alien\diona\update_icons.dm"
#include "code\modules\mob\living\carbon\alien\larva\larva.dm"
#include "code\modules\mob\living\carbon\alien\larva\life.dm"
+#include "code\modules\mob\living\carbon\alien\larva\powers.dm"
#include "code\modules\mob\living\carbon\alien\larva\progression.dm"
#include "code\modules\mob\living\carbon\brain\brain.dm"
#include "code\modules\mob\living\carbon\brain\brain_item.dm"
@@ -1305,8 +1309,6 @@
#include "code\modules\mob\living\carbon\human\species\station\resomi.dm"
#include "code\modules\mob\living\carbon\human\species\station\slime.dm"
#include "code\modules\mob\living\carbon\human\species\station\station.dm"
-#include "code\modules\mob\living\carbon\human\species\xenomorphs\alien_embryo.dm"
-#include "code\modules\mob\living\carbon\human\species\xenomorphs\alien_facehugger.dm"
#include "code\modules\mob\living\carbon\human\species\xenomorphs\alien_powers.dm"
#include "code\modules\mob\living\carbon\human\species\xenomorphs\alien_species.dm"
#include "code\modules\mob\living\carbon\human\species\xenomorphs\xenomorphs.dm"
diff --git a/code/datums/diseases/xeno_transformation.dm b/code/datums/diseases/xeno_transformation.dm
index d6fa155cfc..172a62c08e 100644
--- a/code/datums/diseases/xeno_transformation.dm
+++ b/code/datums/diseases/xeno_transformation.dm
@@ -53,9 +53,12 @@
affected_mob.updatehealth()
if(prob(40))
if(gibbed != 0) return 0
- var/turf/T = find_loc(affected_mob)
- gibs(T)
src.cure(0)
gibbed = 1
- affected_mob:Alienize()
-
+ var/mob/living/carbon/human/H = affected_mob
+ if(istype(H))
+ var/turf/origin = find_loc(affected_mob)
+ gibs(origin)
+ H.set_species("Xenomorph [pick(list("Hunter","Sentinel","Drone"))]")
+ return
+ affected_mob.gib()
\ No newline at end of file
diff --git a/code/game/antagonist/alien/xenomorph.dm b/code/game/antagonist/alien/xenomorph.dm
index 08cbeebca9..36f5216045 100644
--- a/code/game/antagonist/alien/xenomorph.dm
+++ b/code/game/antagonist/alien/xenomorph.dm
@@ -11,6 +11,11 @@ var/datum/antagonist/xenos/xenomorphs
welcome_text = "Hiss! You are a larval alien. Hide and bide your time until you are ready to evolve."
antaghud_indicator = "hudalien"
+ faction_role_text = "Xenomorph Thrall"
+ faction_descriptor = "Hive"
+ faction_welcome = "Your will is ripped away as your humanity merges with the xenomorph overmind. You are now \
+ a thrall to the queen and her brood. Obey their instructions without question. Serve the hive."
+
hard_cap = 5
hard_cap_round = 8
initial_spawn_req = 4
diff --git a/code/game/asteroid.dm b/code/game/asteroid.dm
index 795970068c..350401df13 100644
--- a/code/game/asteroid.dm
+++ b/code/game/asteroid.dm
@@ -1,6 +1,5 @@
-var/global/list/space_surprises = list( /obj/item/clothing/mask/facehugger =4,
- /obj/item/weapon/pickaxe/silver =4,
+var/global/list/space_surprises = list( /obj/item/weapon/pickaxe/silver =4,
/obj/item/weapon/pickaxe/drill =4,
/obj/item/weapon/pickaxe/jackhammer =4,
//mob/living/simple_animal/hostile/carp =3,
@@ -22,7 +21,7 @@ proc/spawn_room(var/atom/start_loc,var/x_size,var/y_size,var/wall,var/floor , va
//world << "Room spawned at [start_loc.x],[start_loc.y],[start_loc.z]"
if(!wall)
- wall = pick(/turf/simulated/wall/r_wall,/turf/simulated/wall,/obj/effect/alien/resin)
+ wall = pick(/turf/simulated/wall/r_wall,/turf/simulated/wall,/obj/structure/alien/resin)
if(!floor)
floor = pick(/turf/simulated/floor,/turf/simulated/floor/tiled,/turf/simulated/floor/reinforced)
@@ -43,9 +42,9 @@ proc/spawn_room(var/atom/start_loc,var/x_size,var/y_size,var/wall,var/floor , va
if(x == 0 || x==x_size-1 || y==0 || y==y_size-1)
- if(wall == /obj/effect/alien/resin)
+ if(wall == /obj/structure/alien/resin)
T = new floor(cur_loc)
- new /obj/effect/alien/resin(T)
+ new /obj/structure/alien/resin(T)
else
T = new wall(cur_loc)
room_turfs["walls"] += T
@@ -73,7 +72,7 @@ proc/admin_spawn_room_at_pos()
if("Regular wall")
wall=/turf/simulated/wall
if("Resin wall")
- wall=/obj/effect/alien/resin
+ wall=/obj/structure/alien/resin
switch(alert("Floor type",null,"Regular floor","Reinforced floor"))
if("Regular floor")
floor=/turf/simulated/floor/tiled
diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm
index aa9f939493..24754c2270 100644
--- a/code/game/objects/effects/aliens.dm
+++ b/code/game/objects/effects/aliens.dm
@@ -1,271 +1,11 @@
-/* Alien Effects!
- * Contains:
- * effect/alien
- * Resin
- * Weeds
- * Acid
- * Egg
- */
-
-/*
- * effect/alien
- */
-/obj/effect/alien
- name = "alien thing"
- desc = "theres something alien about this"
- icon = 'icons/mob/alien.dmi'
-
-/*
- * Resin
- */
-/obj/effect/alien/resin
- name = "resin"
- desc = "Looks like some kind of slimy growth."
- icon_state = "resin"
-
- density = 1
- opacity = 1
- anchored = 1
- var/health = 200
- //var/mob/living/affecting = null
-
-/obj/effect/alien/resin/wall
- name = "resin wall"
- desc = "Purple slime solidified into a wall."
- icon_state = "resinwall" //same as resin, but consistency ho!
-
-/obj/effect/alien/resin/membrane
- name = "resin membrane"
- desc = "Purple slime just thin enough to let light pass through."
- icon_state = "resinmembrane"
- opacity = 0
- health = 120
-
-/obj/effect/alien/resin/New()
- ..()
- var/turf/T = get_turf(src)
- T.thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT
-
-/obj/effect/alien/resin/Destroy()
- var/turf/T = get_turf(src)
- T.thermal_conductivity = initial(T.thermal_conductivity)
- ..()
-
-/obj/effect/alien/resin/proc/healthcheck()
- if(health <=0)
- density = 0
- qdel(src)
- return
-
-/obj/effect/alien/resin/bullet_act(var/obj/item/projectile/Proj)
- health -= Proj.damage
- ..()
- healthcheck()
- return
-
-/obj/effect/alien/resin/ex_act(severity)
- switch(severity)
- if(1.0)
- health-=50
- if(2.0)
- health-=50
- if(3.0)
- if (prob(50))
- health-=50
- else
- health-=25
- healthcheck()
- return
-
-/obj/effect/alien/resin/hitby(AM as mob|obj)
- ..()
- for(var/mob/O in viewers(src, null))
- O.show_message("[src] was hit by [AM].", 1)
- var/tforce = 0
- if(ismob(AM))
- tforce = 10
- else
- tforce = AM:throwforce
- playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
- health = max(0, health - tforce)
- healthcheck()
- ..()
- return
-
-/obj/effect/alien/resin/attack_hand()
- usr.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
- if (HULK in usr.mutations)
- usr << "You easily destroy the [name]."
- for(var/mob/O in oviewers(src))
- O.show_message("[usr] destroys the [name]!", 1)
- health = 0
- else
-
- // Aliens can get straight through these.
- if(istype(usr,/mob/living/carbon))
- var/mob/living/carbon/M = usr
- if(locate(/obj/item/organ/xenos/hivenode) in M.internal_organs)
- for(var/mob/O in oviewers(src))
- O.show_message("[usr] strokes the [name] and it melts away!", 1)
- health = 0
- healthcheck()
- return
-
- usr << "You claw at the [name]."
- for(var/mob/O in oviewers(src))
- O.show_message("[usr] claws at the [name]!", 1)
- health -= rand(5,10)
- healthcheck()
- return
-
-/obj/effect/alien/resin/attackby(obj/item/weapon/W as obj, mob/user as mob)
-
- user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
- var/aforce = W.force
- health = max(0, health - aforce)
- playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
- healthcheck()
- ..()
- return
-
-/obj/effect/alien/resin/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
- if(air_group) return 0
- if(istype(mover) && mover.checkpass(PASSGLASS))
- return !opacity
- return !density
-
-
-/*
- * Weeds
- */
-#define NODERANGE 3
-
-/obj/effect/alien/weeds
- name = "weeds"
- desc = "Weird purple weeds."
- icon_state = "weeds"
-
- anchored = 1
- density = 0
- layer = 2
- var/health = 15
- var/obj/effect/alien/weeds/node/linked_node = null
-
-/obj/effect/alien/weeds/node
- icon_state = "weednode"
- name = "purple sac"
- desc = "Weird purple octopus-like thing."
- layer = 3
- light_range = NODERANGE
- var/node_range = NODERANGE
-
-/obj/effect/alien/weeds/node/New()
- ..(src.loc, src)
-
-
-/obj/effect/alien/weeds/New(pos, node)
- ..()
- if(istype(loc, /turf/space))
- qdel(src)
- return
- linked_node = node
- if(icon_state == "weeds")icon_state = pick("weeds", "weeds1", "weeds2")
- spawn(rand(150, 200))
- if(src)
- Life()
- return
-
-/obj/effect/alien/weeds/proc/Life()
- set background = 1
- var/turf/U = get_turf(src)
-/*
- if (locate(/obj/movable, U))
- U = locate(/obj/movable, U)
- if(U.density == 1)
- qdel(src)
- return
-
-Alien plants should do something if theres a lot of poison
- if(U.poison> 200000)
- health -= round(U.poison/200000)
- update()
- return
-*/
- if (istype(U, /turf/space))
- qdel(src)
- return
-
- if(!linked_node || (get_dist(linked_node, src) > linked_node.node_range) )
- return
-
- direction_loop:
- for(var/dirn in cardinal)
- var/turf/T = get_step(src, dirn)
-
- if (!istype(T) || T.density || locate(/obj/effect/alien/weeds) in T || istype(T.loc, /area/arrival) || istype(T, /turf/space))
- continue
-
- // if (locate(/obj/movable, T)) // don't propogate into movables
- // continue
-
- for(var/obj/O in T)
- if(O.density)
- continue direction_loop
-
- PoolOrNew(/obj/effect/alien/weeds, T, linked_node)
-
-
-/obj/effect/alien/weeds/ex_act(severity)
- switch(severity)
- if(1.0)
- qdel(src)
- if(2.0)
- if (prob(50))
- qdel(src)
- if(3.0)
- if (prob(5))
- qdel(src)
- return
-
-/obj/effect/alien/weeds/attackby(var/obj/item/weapon/W, var/mob/user)
- user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
- if(W.attack_verb.len)
- visible_message("\The [src] have been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]")
- else
- visible_message("\The [src] have been attacked with \the [W][(user ? " by [user]." : ".")]")
-
- var/damage = W.force / 4.0
-
- if(istype(W, /obj/item/weapon/weldingtool))
- var/obj/item/weapon/weldingtool/WT = W
-
- if(WT.remove_fuel(0, user))
- damage = 15
- playsound(loc, 'sound/items/Welder.ogg', 100, 1)
-
- health -= damage
- healthcheck()
-
-/obj/effect/alien/weeds/proc/healthcheck()
- if(health <= 0)
- qdel(src)
-
-
-/obj/effect/alien/weeds/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
- if(exposed_temperature > 300 + T0C)
- health -= 5
- healthcheck()
-
-#undef NODERANGE
-
-
/*
* Acid
*/
-/obj/effect/alien/acid
+/obj/effect/acid
name = "acid"
- desc = "Burbling corrossive stuff. I wouldn't want to touch it."
+ desc = "Burbling corrosive stuff. Probably a bad idea to roll around in it."
icon_state = "acid"
+ icon = 'icons/mob/alien.dmi'
density = 0
opacity = 0
@@ -275,9 +15,9 @@ Alien plants should do something if theres a lot of poison
var/ticks = 0
var/target_strength = 0
-/obj/effect/alien/acid/New(loc, target)
+/obj/effect/acid/New(loc, supplied_target)
..(loc)
- src.target = target
+ target = supplied_target
if(isturf(target)) // Turf take twice as long to take down.
target_strength = 8
@@ -285,17 +25,13 @@ Alien plants should do something if theres a lot of poison
target_strength = 4
tick()
-/obj/effect/alien/acid/proc/tick()
+/obj/effect/acid/proc/tick()
if(!target)
qdel(src)
- ticks += 1
-
+ ticks++
if(ticks >= target_strength)
-
- for(var/mob/O in hearers(src, null))
- O.show_message("[src.target] collapses under its own weight into a puddle of goop and undigested debris!", 1)
-
+ target.visible_message("\The [target] collapses under its own weight into a puddle of goop and undigested debris!")
if(istype(target, /turf/simulated/wall)) // I hate turf code.
var/turf/simulated/wall/W = target
W.dismantle_wall(1)
@@ -306,135 +42,11 @@ Alien plants should do something if theres a lot of poison
switch(target_strength - ticks)
if(6)
- visible_message("[src.target] is holding up against the acid!")
+ visible_message("\The [src.target] is holding up against the acid!")
if(4)
- visible_message("[src.target]\s structure is being melted by the acid!")
+ visible_message("\The [src.target]\s structure is being melted by the acid!")
if(2)
- visible_message("[src.target] is struggling to withstand the acid!")
+ visible_message("\The [src.target] is struggling to withstand the acid!")
if(0 to 1)
- visible_message("[src.target] begins to crumble under the acid!")
- spawn(rand(150, 200)) tick()
-
-/*
- * Egg
- */
-/var/const //for the status var
- BURST = 0
- BURSTING = 1
- GROWING = 2
- GROWN = 3
-
- MIN_GROWTH_TIME = 1800 //time it takes to grow a hugger
- MAX_GROWTH_TIME = 3000
-
-/obj/effect/alien/egg
- desc = "It looks like a weird egg"
- name = "egg"
- icon_state = "egg_growing"
- density = 0
- anchored = 1
-
- var/health = 100
- var/status = GROWING //can be GROWING, GROWN or BURST; all mutually exclusive
- flags = PROXMOVE
-
-/obj/effect/alien/egg/New()
- if(config.aliens_allowed)
- ..()
- spawn(rand(MIN_GROWTH_TIME,MAX_GROWTH_TIME))
- Grow()
- else
- qdel(src)
-
-/obj/effect/alien/egg/attack_hand(user as mob)
-
- var/mob/living/carbon/M = user
- if(!istype(M) || !(locate(/obj/item/organ/xenos/hivenode) in M.internal_organs))
- return attack_hand(user)
-
- switch(status)
- if(BURST)
- user << "You clear the hatched egg."
- qdel(src)
- return
- if(GROWING)
- user << "The child is not developed yet."
- return
- if(GROWN)
- user << "You retrieve the child."
- Burst(0)
- return
-
-/obj/effect/alien/egg/proc/GetFacehugger()
- return locate(/obj/item/clothing/mask/facehugger) in contents
-
-/obj/effect/alien/egg/proc/Grow()
- icon_state = "egg"
- status = GROWN
- new /obj/item/clothing/mask/facehugger(src)
- return
-
-/obj/effect/alien/egg/proc/Burst(var/kill = 1) //drops and kills the hugger if any is remaining
- if(status == GROWN || status == GROWING)
- var/obj/item/clothing/mask/facehugger/child = GetFacehugger()
- icon_state = "egg_hatched"
- flick("egg_opening", src)
- status = BURSTING
- spawn(15)
- status = BURST
- child.loc = get_turf(src)
-
- if(kill && istype(child))
- child.Die()
- else
- for(var/mob/M in range(1,src))
- if(CanHug(M))
- child.Attach(M)
- break
-
-/obj/effect/alien/egg/bullet_act(var/obj/item/projectile/Proj)
- health -= Proj.damage
- ..()
- healthcheck()
- return
-
-
-/obj/effect/alien/egg/attackby(var/obj/item/weapon/W, var/mob/user)
- if(health <= 0)
- return
- if(W.attack_verb.len)
- src.visible_message("\The [src] has been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]")
- else
- src.visible_message("\The [src] has been attacked with \the [W][(user ? " by [user]." : ".")]")
- var/damage = W.force / 4.0
-
- if(istype(W, /obj/item/weapon/weldingtool))
- var/obj/item/weapon/weldingtool/WT = W
-
- if(WT.remove_fuel(0, user))
- damage = 15
- playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
-
- src.health -= damage
- src.healthcheck()
-
-
-/obj/effect/alien/egg/proc/healthcheck()
- if(health <= 0)
- Burst()
-
-/obj/effect/alien/egg/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
- if(exposed_temperature > 500 + T0C)
- health -= 5
- healthcheck()
-
-/obj/effect/alien/egg/HasProximity(atom/movable/AM as mob|obj)
- if(status == GROWN)
- if(!CanHug(AM))
- return
-
- var/mob/living/carbon/C = AM
- if(C.stat == CONSCIOUS && C.status_flags & XENO_HOST)
- return
-
- Burst(0)
+ visible_message("\The [src.target] begins to crumble under the acid!")
+ spawn(rand(150, 200)) tick()
\ No newline at end of file
diff --git a/code/game/objects/structures/alien/alien.dm b/code/game/objects/structures/alien/alien.dm
new file mode 100644
index 0000000000..df94cf95ac
--- /dev/null
+++ b/code/game/objects/structures/alien/alien.dm
@@ -0,0 +1,61 @@
+/obj/structure/alien
+ name = "alien thing"
+ desc = "There's something alien about this."
+ icon = 'icons/mob/alien.dmi'
+ var/health = 50
+
+/obj/structure/alien/proc/healthcheck()
+ if(health <=0)
+ density = 0
+ qdel(src)
+ return
+
+/obj/structure/alien/bullet_act(var/obj/item/projectile/Proj)
+ health -= Proj.damage
+ ..()
+ healthcheck()
+ return
+
+/obj/structure/alien/ex_act(severity)
+ switch(severity)
+ if(1.0)
+ health-=50
+ if(2.0)
+ health-=50
+ if(3.0)
+ if (prob(50))
+ health-=50
+ else
+ health-=25
+ healthcheck()
+ return
+
+/obj/structure/alien/hitby(AM as mob|obj)
+ ..()
+ visible_message("\The [src] was hit by \the [AM].")
+ var/tforce = 0
+ if(ismob(AM))
+ tforce = 10
+ else
+ tforce = AM:throwforce
+ playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
+ health = max(0, health - tforce)
+ healthcheck()
+ ..()
+ return
+
+/obj/structure/alien/attack_generic()
+ attack_hand(usr)
+
+/obj/structure/alien/attackby(var/obj/item/weapon/W, var/mob/user)
+ health = max(0, health - W.force)
+ playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
+ healthcheck()
+ ..()
+ return
+
+/obj/structure/alien/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
+ if(air_group) return 0
+ if(istype(mover) && mover.checkpass(PASSGLASS))
+ return !opacity
+ return !density
\ No newline at end of file
diff --git a/code/game/objects/structures/alien/egg.dm b/code/game/objects/structures/alien/egg.dm
new file mode 100644
index 0000000000..c16c1a182e
--- /dev/null
+++ b/code/game/objects/structures/alien/egg.dm
@@ -0,0 +1,96 @@
+#define MAX_PROGRESS 100
+
+/obj/structure/alien/egg
+ desc = "It looks like a weird egg."
+ name = "egg"
+ icon_state = "egg_growing"
+ density = 0
+ anchored = 1
+ var/progress = 0
+
+/obj/structure/alien/egg/New()
+ ..()
+ processing_objects += src
+
+/obj/structure/alien/egg/Destroy()
+ processing_objects -= src
+ ..()
+
+/obj/structure/alien/egg/CanUseTopic(var/mob/user)
+ return isobserver(user) ? STATUS_INTERACTIVE : STATUS_CLOSE
+
+/obj/structure/alien/egg/Topic(href, href_list)
+ if(..())
+ return 1
+
+ if(href_list["spawn"])
+ attack_ghost(usr)
+
+/obj/structure/alien/egg/process()
+ progress++
+ if(progress >= MAX_PROGRESS)
+ for(var/mob/M in dead_mob_list)
+ if(istype(M,/mob/dead) && M.client && M.client.prefs && (M.client.prefs.be_special & BE_ALIEN))
+ M << "An alien is ready to hatch! ([ghost_follow_link(src, M)]) (spawn)"
+ processing_objects -= src
+ update_icon()
+
+/obj/structure/alien/egg/update_icon()
+ if(progress == -1)
+ icon_state = "egg_hatched"
+ else if(progress < MAX_PROGRESS)
+ icon_state = "egg_growing"
+ else
+ icon_state = "egg"
+
+/obj/structure/alien/egg/attack_ghost(var/mob/dead/observer/user)
+ if(progress == -1) //Egg has been hatched.
+ return
+
+ if(progress < MAX_PROGRESS)
+ user << "\The [src] has not yet matured."
+ return
+
+ if(!user.MayRespawn(1))
+ return
+
+ // Check for bans properly.
+ if(jobban_isbanned(user, "Xenomorph"))
+ user << "You are banned from playing a Xenomorph."
+ return
+
+ var/confirm = alert(user, "Are you sure you want to join as a Xenomorph larva?", "Become Larva", "No", "Yes")
+
+ if(!src || confirm != "Yes")
+ return
+
+ if(!user || !user.ckey)
+ return
+
+ if(progress == -1) //Egg has been hatched.
+ user << "Too slow..."
+ return
+
+ flick("egg_opening",src)
+ progress = -1 // No harvesting pls.
+ sleep(5)
+
+ if(!src || !user)
+ visible_message("\The [src] writhes with internal motion, but nothing comes out.")
+ progress = MAX_PROGRESS // Someone else can have a go.
+ return // What a pain.
+
+ // Create the mob, transfer over key.
+ var/mob/living/carbon/alien/larva/larva = new(get_turf(src))
+ larva.ckey = user.ckey
+ spawn(-1)
+ if(user) qdel(user) // Remove the keyless ghost if it exists.
+
+ visible_message("\The [src] splits open with a wet slithering noise, and \the [larva] writhes free!")
+
+ // Turn us into a hatched egg.
+ name = "hatched alien egg"
+ desc += " This one has hatched."
+ update_icon()
+
+#undef MAX_PROGRESS
diff --git a/code/game/objects/structures/alien/node.dm b/code/game/objects/structures/alien/node.dm
new file mode 100644
index 0000000000..15a9062862
--- /dev/null
+++ b/code/game/objects/structures/alien/node.dm
@@ -0,0 +1,19 @@
+/obj/structure/alien/node
+ name = "alien weed node"
+ desc = "Some kind of strange, pulsating structure."
+ icon_state = "weednode"
+ health = 100
+ layer = 3.1
+
+/obj/structure/alien/node/New()
+ ..()
+ processing_objects += src
+
+/obj/structure/alien/node/Destroy()
+ processing_objects -= src
+ ..()
+
+/obj/structure/alien/node/process()
+ if(locate(/obj/effect/plant) in loc)
+ return
+ new /obj/effect/plant(get_turf(src), plant_controller.seeds["xenomorph"])
diff --git a/code/game/objects/structures/alien/resin.dm b/code/game/objects/structures/alien/resin.dm
new file mode 100644
index 0000000000..05f6bca0e7
--- /dev/null
+++ b/code/game/objects/structures/alien/resin.dm
@@ -0,0 +1,50 @@
+/obj/structure/alien/resin
+ name = "resin"
+ desc = "Looks like some kind of slimy growth."
+ icon_state = "resin"
+
+ density = 1
+ opacity = 1
+ anchored = 1
+ health = 200
+
+/obj/structure/alien/resin/wall
+ name = "resin wall"
+ desc = "Purple slime solidified into a wall."
+ icon_state = "resinwall"
+
+/obj/structure/alien/resin/membrane
+ name = "resin membrane"
+ desc = "Purple slime just thin enough to let light pass through."
+ icon_state = "resinmembrane"
+ opacity = 0
+ health = 120
+
+/obj/structure/alien/resin/New()
+ ..()
+ var/turf/T = get_turf(src)
+ T.thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT
+
+/obj/structure/alien/resin/Destroy()
+ var/turf/T = get_turf(src)
+ T.thermal_conductivity = initial(T.thermal_conductivity)
+ ..()
+
+/obj/structure/alien/resin/attack_hand(var/mob/user)
+ if (HULK in user.mutations)
+ visible_message("\The [user] destroys \the [name]!")
+ health = 0
+ else
+ // Aliens can get straight through these.
+ if(istype(user,/mob/living/carbon))
+ var/mob/living/carbon/M = user
+ if(locate(/obj/item/organ/xenos/hivenode) in M.internal_organs)
+ visible_message("\The [user] strokes \the [name] and it melts away!")
+ health = 0
+ healthcheck()
+ return
+ visible_message("\The [user] claws at \the [src]!")
+ // Todo check attack datums.
+ health -= rand(5,10)
+ healthcheck()
+ return
\ No newline at end of file
diff --git a/code/game/objects/structures/lamarr_cage.dm b/code/game/objects/structures/lamarr_cage.dm
deleted file mode 100644
index 7d0bc76b18..0000000000
--- a/code/game/objects/structures/lamarr_cage.dm
+++ /dev/null
@@ -1,87 +0,0 @@
-/obj/structure/lamarr
- name = "lab cage"
- icon = 'icons/obj/stationobjs.dmi'
- icon_state = "labcage1"
- desc = "A glass lab container for storing interesting creatures."
- density = 1
- anchored = 1
- unacidable = 1//Dissolving the case would also delete Lamarr
- var/health = 30
- var/occupied = 1
- var/destroyed = 0
-
-/obj/structure/lamarr/ex_act(severity)
- switch(severity)
- if (1)
- new /obj/item/weapon/material/shard( src.loc )
- Break()
- qdel(src)
- if (2)
- if (prob(50))
- src.health -= 15
- src.healthcheck()
- if (3)
- if (prob(50))
- src.health -= 5
- src.healthcheck()
-
-
-/obj/structure/lamarr/bullet_act(var/obj/item/projectile/Proj)
- health -= Proj.damage
- ..()
- src.healthcheck()
- return
-
-/obj/structure/lamarr/proc/healthcheck()
- if (src.health <= 0)
- if (!( src.destroyed ))
- src.density = 0
- src.destroyed = 1
- new /obj/item/weapon/material/shard( src.loc )
- playsound(src, "shatter", 70, 1)
- Break()
- else
- playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
- return
-
-/obj/structure/lamarr/update_icon()
- if(src.destroyed)
- src.icon_state = "labcageb[src.occupied]"
- else
- src.icon_state = "labcage[src.occupied]"
- return
-
-
-/obj/structure/lamarr/attackby(obj/item/weapon/W as obj, mob/user as mob)
- src.health -= W.force
- src.healthcheck()
- ..()
- return
-
-/obj/structure/lamarr/attack_hand(mob/user as mob)
- if (src.destroyed)
- return
- else
- usr << "You kick the lab cage."
- for(var/mob/O in oviewers())
- if ((O.client && !( O.blinded )))
- O << "[usr] kicks the lab cage."
- src.health -= 2
- healthcheck()
- return
-
-/obj/structure/lamarr/proc/Break()
- if(occupied)
- new /obj/item/clothing/mask/facehugger/lamarr(src.loc)
- occupied = 0
- update_icon()
- return
-
-/obj/item/clothing/mask/facehugger/lamarr
- name = "Lamarr"
- desc = "The worst she might do is attempt to... couple with your head."//hope we don't get sued over a harmless reference, rite?
- sterile = 1
- gender = FEMALE
-
-/obj/item/clothing/mask/facehugger/lamarr/New()//to prevent deleting it if aliums are disabled
- return
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index a76565bf75..53ff4c3a75 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -1119,16 +1119,6 @@
log_admin("[key_name(usr)] AIized [key_name(H)]")
H.AIize()
- else if(href_list["makealien"])
- if(!check_rights(R_SPAWN)) return
-
- var/mob/living/carbon/human/H = locate(href_list["makealien"])
- if(!istype(H))
- usr << "This can only be used on instances of type /mob/living/carbon/human"
- return
-
- usr.client.cmd_admin_alienize(H)
-
else if(href_list["makeslime"])
if(!check_rights(R_SPAWN)) return
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index 11591be4b1..9154badcc6 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -16,6 +16,7 @@
// callproc moved to code/modules/admin/callproc
+
/client/proc/Cell()
set category = "Debug"
set name = "Cell"
@@ -100,23 +101,6 @@
paiController.pai_candidates.Remove(candidate)
feedback_add_details("admin_verb","MPAI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-/client/proc/cmd_admin_alienize(var/mob/M in mob_list)
- set category = "Fun"
- set name = "Make Alien"
-
- if(!ticker)
- alert("Wait until the game starts")
- return
- if(ishuman(M))
- log_admin("[key_name(src)] has alienized [M.key].")
- spawn(10)
- M:Alienize()
- feedback_add_details("admin_verb","MKAL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
- log_admin("[key_name(usr)] made [key_name(M)] into an alien.")
- message_admins("\blue [key_name_admin(usr)] made [key_name(M)] into an alien.", 1)
- else
- alert("Invalid mob")
-
/client/proc/cmd_admin_slimeize(var/mob/M in mob_list)
set category = "Fun"
set name = "Make slime"
diff --git a/code/modules/admin/view_variables/topic.dm b/code/modules/admin/view_variables/topic.dm
index c842170b6b..6f05d00de6 100644
--- a/code/modules/admin/view_variables/topic.dm
+++ b/code/modules/admin/view_variables/topic.dm
@@ -278,20 +278,6 @@
return
holder.Topic(href, list("makerobot"=href_list["makerobot"]))
- else if(href_list["makealien"])
- if(!check_rights(R_SPAWN)) return
-
- var/mob/living/carbon/human/H = locate(href_list["makealien"])
- if(!istype(H))
- usr << "This can only be done to instances of type /mob/living/carbon/human"
- return
-
- if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return
- if(!H)
- usr << "Mob doesn't exist anymore"
- return
- holder.Topic(href, list("makealien"=href_list["makealien"]))
-
else if(href_list["makeslime"])
if(!check_rights(R_SPAWN)) return
diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm
index efe3bf1da6..cce046e127 100644
--- a/code/modules/hydroponics/seed.dm
+++ b/code/modules/hydroponics/seed.dm
@@ -22,6 +22,7 @@
var/trash_type // Garbage item produced when eaten.
var/splat_type = /obj/effect/decal/cleanable/fruit_smudge // Graffiti decal.
var/has_mob_product
+ var/force_layer
/datum/seed/New()
diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm
index b8b0530788..97a4ba64e3 100644
--- a/code/modules/hydroponics/seed_datums.dm
+++ b/code/modules/hydroponics/seed_datums.dm
@@ -1106,3 +1106,23 @@
set_trait(TRAIT_PRODUCTION,7)
set_trait(TRAIT_YIELD,3)
set_trait(TRAIT_POTENCY,3)
+
+// Alien weeds.
+/datum/seed/xenomorph
+ name = "xenomorph"
+ seed_name = "alien weed"
+ display_name = "alien weeds"
+ force_layer = 3
+ chems = list("phoron" = list(1,3))
+
+/datum/seed/xenomorph/New()
+ ..()
+ set_trait(TRAIT_PLANT_ICON,"vine2")
+ set_trait(TRAIT_IMMUTABLE,1)
+ set_trait(TRAIT_PRODUCT_COLOUR,"#3D1934")
+ set_trait(TRAIT_FLESH_COLOUR,"#3D1934")
+ set_trait(TRAIT_PLANT_COLOUR,"#3D1934")
+ set_trait(TRAIT_PRODUCTION,1)
+ set_trait(TRAIT_YIELD,-1)
+ set_trait(TRAIT_SPREAD,2)
+ set_trait(TRAIT_POTENCY,50)
\ No newline at end of file
diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm
index e8f2cfa918..6ac6782231 100644
--- a/code/modules/hydroponics/spreading/spreading.dm
+++ b/code/modules/hydroponics/spreading/spreading.dm
@@ -132,7 +132,7 @@
update_icon()
plant_controller.add_plant(src)
// Some plants eat through plating.
- if(!isnull(seed.chems["pacid"]))
+ if(islist(seed.chems) && !isnull(seed.chems["pacid"]))
var/turf/T = get_turf(src)
T.ex_act(prob(80) ? 3 : 2)
@@ -188,12 +188,12 @@
icon_state = "[seed.get_trait(TRAIT_PLANT_ICON)]-[growth]"
if(growth>2 && growth == max_growth)
- layer = 5
+ layer = (seed && seed.force_layer) ? seed.force_layer : 5
opacity = 1
- if(!isnull(seed.chems["woodpulp"]))
+ if(islist(seed.chems) && !isnull(seed.chems["woodpulp"]))
density = 1
else
- layer = 3
+ layer = (seed && seed.force_layer) ? seed.force_layer : 5
density = 0
/obj/effect/plant/proc/calc_dir()
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 5d3915c7fd..8804ce7781 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -91,11 +91,14 @@ var/global/list/image/ghost_sightless_images = list() //this is a list of images
/mob/dead/observer/Topic(href, href_list)
if (href_list["track"])
- var/mob/target = locate(href_list["track"]) in mob_list
- if(target)
- ManualFollow(target)
-
-
+ if(istype(href_list["track"],/mob))
+ var/mob/target = locate(href_list["track"]) in mob_list
+ if(target)
+ ManualFollow(target)
+ else
+ var/atom/target = locate(href_list["track"])
+ if(istype(target))
+ ManualFollow(target)
/mob/dead/attackby(obj/item/W, mob/user)
if(istype(W,/obj/item/weapon/book/tome))
@@ -320,7 +323,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(following && following == target)
return
following = target
- src << "Now following [target]"
+ src << "Now following \the [target]"
if(ismob(target))
forceMove(get_turf(target))
var/mob/M = target
diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm
index 548eee230b..c67249dfe5 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva.dm
@@ -11,4 +11,5 @@
/mob/living/carbon/alien/larva/New()
..()
add_language("Xenomorph") //Bonus language.
- internal_organs |= new /obj/item/organ/xenos/hivenode(src)
\ No newline at end of file
+ internal_organs |= new /obj/item/organ/xenos/hivenode(src)
+ create_reagents(100)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm
index 8d40ef9d5a..5ca32e24d0 100644
--- a/code/modules/mob/living/carbon/alien/larva/life.dm
+++ b/code/modules/mob/living/carbon/alien/larva/life.dm
@@ -1,12 +1,34 @@
+#define MIN_LARVA_BLOOD_DRINK 0.5
+
//Larvae regenerate health and nutrition from plasma and alien weeds.
/mob/living/carbon/alien/larva/handle_environment(var/datum/gas_mixture/environment)
if(!environment) return
var/turf/T = get_turf(src)
- if(environment.gas["phoron"] > 0 || (T && locate(/obj/effect/alien/weeds) in T.contents))
+ var/obj/effect/plant/plant = locate() in T
+ if(environment.gas["phoron"] > 0 || (plant && plant.seed.type == /datum/seed/xenomorph))
update_progression()
adjustBruteLoss(-1)
adjustFireLoss(-1)
adjustToxLoss(-1)
- adjustOxyLoss(-1)
\ No newline at end of file
+ adjustOxyLoss(-1)
+
+// Maybe not the -best- place but it's semiappropriate and fitting.
+// Drink the blood of your host!
+/mob/living/carbon/alien/larva/handle_chemicals_in_body()
+ if(!loc)
+ return
+ if(!istype(loc, /obj/item/weapon/holder))
+ return
+ var/mob/living/carbon/human/M = loc.loc //ergh, replace with a flag sometime
+ if(!istype(M))
+ return
+ if(M.vessel.total_volume > 0)
+ M.vessel.trans_to(src,min(M.vessel.total_volume,MIN_LARVA_BLOOD_DRINK))
+ update_progression()
+ else
+ src << "This host is depleted of blood..."
+ leave_host()
+
+#undef MIN_LARVA_BLOOD_DRINK
diff --git a/code/modules/mob/living/carbon/alien/larva/powers.dm b/code/modules/mob/living/carbon/alien/larva/powers.dm
new file mode 100644
index 0000000000..57e3427163
--- /dev/null
+++ b/code/modules/mob/living/carbon/alien/larva/powers.dm
@@ -0,0 +1,111 @@
+/mob/living/carbon/alien/larva/proc/check_can_infest(var/mob/living/M)
+ if(!src)
+ return 0
+ if(!istype(loc, /turf))
+ src << "You cannot infest a target in your current position."
+ return 0
+ if(incapacitated())
+ src << "You cannot infest a target in your current state."
+ return 0
+ if(!M)
+ return 1
+ if(!M.lying)
+ src << "\The [M] is not prone."
+ return 0
+ if(!(src.Adjacent(M)))
+ src << "\The [M] is not in range."
+ return 0
+ return 1
+
+/mob/living/carbon/alien/larva/verb/attach_host()
+
+ set name = "Attach to host"
+ set desc = "Burrow into a prone victim and begin drinking their blood."
+ set category = "Abilities"
+
+ if(!check_can_infest())
+ return
+
+ var/list/choices = list()
+ for(var/mob/living/carbon/human/H in view(1,src))
+ if(isxenomorph(H))
+ continue
+ if(src.Adjacent(H) && H.lying)
+ choices += H
+
+ if(!choices.len)
+ src << "There are no viable hosts within range."
+ return
+
+ var/mob/living/carbon/human/H = input(src,"Who do you wish to infest?") as null|anything in choices
+
+ if(!H || !src || !H.lying) return
+
+ visible_message("\The [src] begins questing blindly towards \the [H]'s warm flesh...")
+
+ if(!do_after(src,30))
+ return
+
+ if(!check_can_infest(H))
+ return
+
+ var/obj/item/organ/external/E = pick(H.organs)
+ src << "You burrow deeply into \the [H]'s [E.name]!"
+ var/obj/item/weapon/holder/holder = new (loc)
+ src.loc = holder
+ holder.name = src.name
+ E.embed(holder,0,"\The [src] burrows deeply into \the [H]'s [E.name]!")
+
+/mob/living/carbon/alien/larva/verb/release_host()
+ set category = "Abilities"
+ set name = "Release Host"
+ set desc = "Release your host."
+
+ if(incapacitated())
+ src << "You cannot leave your host in your current state."
+ return
+
+ if(!loc || !loc.loc)
+ src << "You are not inside a host."
+ return
+
+ var/mob/living/carbon/human/H = loc.loc
+
+ if(!istype(H))
+ src << "You are not inside a host."
+ return
+
+ src << "You begin writhing your way free of \the [H]'s flesh..."
+
+ if(!do_after(src, 30))
+ return
+
+ if(!H || !src)
+ return
+
+ leave_host()
+
+/mob/living/carbon/alien/larva/proc/leave_host()
+ if(!loc || !loc.loc)
+ src << "You are not inside a host."
+ return
+ var/mob/living/carbon/human/H = loc.loc
+ if(!istype(H))
+ src << "You are not inside a host."
+ return
+ var/obj/item/weapon/holder/holder = loc
+ var/obj/item/organ/external/affected
+ if(istype(holder))
+ for(var/obj/item/organ/external/organ in H.organs) //Grab the organ holding the implant.
+ for(var/obj/item/O in organ.implants)
+ if(O == holder)
+ affected = organ
+ break
+ affected.implants -= holder
+ holder.loc = get_turf(holder)
+ else
+ src.loc = get_turf(src)
+ if(affected)
+ src << "You crawl out of \the [H]'s [affected.name] and plop to the ground."
+ else
+ src << "You plop to the ground."
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm
index 429e82b3d0..4c40057812 100644
--- a/code/modules/mob/living/carbon/alien/life.dm
+++ b/code/modules/mob/living/carbon/alien/life.dm
@@ -9,8 +9,7 @@
..()
- if (stat != DEAD) //still breathing
- // GROW!
+ if (stat != DEAD && can_progress())
update_progression()
blinded = null
@@ -18,6 +17,10 @@
//Status updates, death etc.
update_icons()
+/mob/living/carbon/alien/proc/can_progress()
+ return 1
+
+
/mob/living/carbon/alien/handle_mutations_and_radiation()
// Currently both Dionaea and larvae like to eat radiation, so I'm defining the
@@ -158,7 +161,7 @@
adjustFireLoss((environment.temperature - (T0C+66))/5) // Might be too high, check in testing.
if (fire) fire.icon_state = "fire2"
if(prob(20))
- src << "\red You feel a searing heat!"
+ src << "You feel a searing heat!"
else
if (fire) fire.icon_state = "fire0"
diff --git a/code/modules/mob/living/carbon/alien/progression.dm b/code/modules/mob/living/carbon/alien/progression.dm
index 54c7f9a969..e9d099ea2a 100644
--- a/code/modules/mob/living/carbon/alien/progression.dm
+++ b/code/modules/mob/living/carbon/alien/progression.dm
@@ -1,7 +1,7 @@
/mob/living/carbon/alien/verb/evolve()
- set name = "Evolve"
- set desc = "Evolve into your adult form."
+ set name = "Moult"
+ set desc = "Moult your skin and become an adult."
set category = "Abilities"
if(stat != CONSCIOUS)
@@ -12,11 +12,11 @@
return
if(handcuffed || legcuffed)
- src << "\red You cannot evolve when you are cuffed."
+ src << "You cannot evolve when you are cuffed."
return
if(amount_grown < max_grown)
- src << "\red You are not fully grown."
+ src << "You are not fully grown."
return
// confirm_evolution() handles choices and other specific requirements.
@@ -27,6 +27,7 @@
var/mob/living/carbon/human/adult = new adult_form(get_turf(src))
adult.set_species(new_species)
show_evolution_blurb()
+ // TODO: drop a moulted skin. Ew.
if(mind)
mind.transfer_to(adult)
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index d77493b0b3..662d06479b 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -20,6 +20,7 @@
var/prone_icon // If set, draws this from icobase when mob is prone.
var/eyes = "eyes_s" // Icon for eyes.
+ var/has_floating_eyes // Eyes will overlay over darkness (glow)
var/blood_color = "#A10808" // Red.
var/flesh_color = "#FFC896" // Pink.
var/base_color // Used by changelings. Should also be used for icon previes..
@@ -152,6 +153,9 @@
var/pass_flags = 0
+/datum/species/proc/get_eyes(var/mob/living/carbon/human/H)
+ return
+
/datum/species/New()
if(hud_type)
hud = new hud_type()
diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm
deleted file mode 100644
index c60d8bca1d..0000000000
--- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_embryo.dm
+++ /dev/null
@@ -1,159 +0,0 @@
-// This is to replace the previous datum/disease/alien_embryo for slightly improved handling and maintainability
-// It functions almost identically (see code/datums/diseases/alien_embryo.dm)
-
-/obj/item/alien_embryo
- name = "alien embryo"
- desc = "All slimy and yuck."
- icon = 'icons/mob/alien.dmi'
- icon_state = "larva0_dead"
- var/mob/living/affected_mob
- var/stage = 0
-
-/obj/item/alien_embryo/New()
- if(istype(loc, /mob/living))
- affected_mob = loc
- processing_objects.Add(src)
- spawn(0)
- AddInfectionImages(affected_mob)
- else
- qdel(src)
-
-/obj/item/alien_embryo/Destroy()
- if(affected_mob)
- affected_mob.status_flags &= ~(XENO_HOST)
- spawn(0)
- RemoveInfectionImages(affected_mob)
- ..()
-
-/obj/item/alien_embryo/process()
- if(!affected_mob) return
- if(loc != affected_mob)
- affected_mob.status_flags &= ~(XENO_HOST)
- processing_objects.Remove(src)
- spawn(0)
- RemoveInfectionImages(affected_mob)
- affected_mob = null
- return
-
- if(stage < 5 && prob(3))
- stage++
- spawn(0)
- RefreshInfectionImage(affected_mob)
-
- switch(stage)
- if(2, 3)
- if(prob(1))
- affected_mob.emote("sneeze")
- if(prob(1))
- affected_mob.emote("cough")
- if(prob(1))
- affected_mob << "\red Your throat feels sore."
- if(prob(1))
- affected_mob << "\red Mucous runs down the back of your throat."
- if(4)
- if(prob(1))
- affected_mob.emote("sneeze")
- if(prob(1))
- affected_mob.emote("cough")
- if(prob(2))
- affected_mob << "\red Your muscles ache."
- if(prob(20))
- affected_mob.take_organ_damage(1)
- if(prob(2))
- affected_mob << "\red Your stomach hurts."
- if(prob(20))
- affected_mob.adjustToxLoss(1)
- affected_mob.updatehealth()
- if(5)
- affected_mob << "\red You feel something tearing its way out of your stomach..."
- affected_mob.adjustToxLoss(10)
- affected_mob.updatehealth()
- if(prob(50))
- AttemptGrow()
-
-/obj/item/alien_embryo/proc/AttemptGrow(var/gib_on_success = 1)
- var/list/candidates = get_alien_candidates()
- var/picked = null
-
- // To stop clientless larva, we will check that our host has a client
- // if we find no ghosts to become the alien. If the host has a client
- // he will become the alien but if he doesn't then we will set the stage
- // to 2, so we don't do a process heavy check everytime.
-
- if(candidates.len)
- picked = pick(candidates)
- else if(affected_mob.client)
- picked = affected_mob.key
- else
- stage = 4 // Let's try again later.
- return
-
- if(affected_mob.lying)
- affected_mob.overlays += image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "burst_lie")
- else
- affected_mob.overlays += image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "burst_stand")
- spawn(6)
- var/mob/living/carbon/alien/larva/new_xeno = new(affected_mob.loc)
- new_xeno.key = picked
- new_xeno << sound('sound/voice/hiss5.ogg',0,0,0,100) //To get the player's attention
- if(gib_on_success)
- affected_mob.gib()
- qdel(src)
-
-/*----------------------------------------
-Proc: RefreshInfectionImage()
-Des: Removes all infection images from aliens and places an infection image on all infected mobs for aliens.
-----------------------------------------*/
-/obj/item/alien_embryo/proc/RefreshInfectionImage()
-
- for(var/mob/living/carbon/alien in player_list)
-
- if(!locate(/obj/item/organ/xenos/hivenode) in alien.internal_organs)
- continue
-
- if(alien.client)
- for(var/image/I in alien.client.images)
- if(dd_hasprefix_case(I.icon_state, "infected"))
- qdel(I)
- for(var/mob/living/L in mob_list)
- if(iscorgi(L) || iscarbon(L))
- if(L.status_flags & XENO_HOST)
- var/I = image('icons/mob/alien.dmi', loc = L, icon_state = "infected[stage]")
- alien.client.images += I
-
-/*----------------------------------------
-Proc: AddInfectionImages(C)
-Des: Checks if the passed mob (C) is infected with the alien egg, then gives each alien client an infected image at C.
-----------------------------------------*/
-/obj/item/alien_embryo/proc/AddInfectionImages(var/mob/living/C)
- if(C)
-
- for(var/mob/living/carbon/alien in player_list)
-
- if(!locate(/obj/item/organ/xenos/hivenode) in alien.internal_organs)
- continue
-
- if(alien.client)
- if(C.status_flags & XENO_HOST)
- var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[stage]")
- alien.client.images += I
-
-/*----------------------------------------
-Proc: RemoveInfectionImage(C)
-Des: Removes the alien infection image from all aliens in the world located in passed mob (C).
-----------------------------------------*/
-
-/obj/item/alien_embryo/proc/RemoveInfectionImages(var/mob/living/C)
-
- if(C)
-
- for(var/mob/living/carbon/alien in player_list)
-
- if(!locate(/obj/item/organ/xenos/hivenode) in alien.internal_organs)
- continue
-
- if(alien.client)
- for(var/image/I in alien.client.images)
- if(I.loc == C)
- if(dd_hasprefix_case(I.icon_state, "infected"))
- qdel(I)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm
deleted file mode 100644
index 335b566092..0000000000
--- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm
+++ /dev/null
@@ -1,231 +0,0 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
-
-//TODO: Make these simple_animals
-
-var/const/MIN_IMPREGNATION_TIME = 100 //time it takes to impregnate someone
-var/const/MAX_IMPREGNATION_TIME = 150
-
-var/const/MIN_ACTIVE_TIME = 200 //time between being dropped and going idle
-var/const/MAX_ACTIVE_TIME = 400
-
-/obj/item/clothing/mask/facehugger
- name = "alien"
- desc = "It has some sort of a tube at the end of its tail."
- icon = 'icons/mob/alien.dmi'
- icon_state = "facehugger"
- item_state = "facehugger"
- w_class = 3 //note: can be picked up by aliens unlike most other items of w_class below 4
- flags = PROXMOVE
- body_parts_covered = FACE|EYES
- throw_range = 5
-
- var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case
- var/sterile = 0
- var/strength = 5
- var/attached = 0
-
-/obj/item/clothing/mask/facehugger/attack_hand(user as mob)
-
- if((stat == CONSCIOUS && !sterile))
- if(Attach(user))
- return
-
- ..()
-
-/obj/item/clothing/mask/facehugger/attack(mob/living/M as mob, mob/user as mob)
- ..()
- user.drop_from_inventory(src)
- Attach(M)
-
-/obj/item/clothing/mask/facehugger/New()
- if(config.aliens_allowed)
- ..()
- else
- qdel(src)
-
-/obj/item/clothing/mask/facehugger/examine(mob/user)
- ..(user)
- switch(stat)
- if(DEAD,UNCONSCIOUS)
- user << "\red \b [src] is not moving."
- if(CONSCIOUS)
- user << "\red \b [src] seems to be active."
- if (sterile)
- user << "\red \b It looks like the proboscis has been removed."
- return
-
-/obj/item/clothing/mask/facehugger/attackby(obj/item/I, mob/user)
- if(I.force)
- user.do_attack_animation(src)
- Die()
- return
-
-/obj/item/clothing/mask/facehugger/bullet_act()
- Die()
- return
-
-/obj/item/clothing/mask/facehugger/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
- if(exposed_temperature > T0C+80)
- Die()
- return
-
-/obj/item/clothing/mask/facehugger/equipped(mob/M)
- Attach(M)
-
-/obj/item/clothing/mask/facehugger/Crossed(atom/target)
- HasProximity(target)
- return
-
-/obj/item/clothing/mask/facehugger/on_found(mob/finder as mob)
- if(stat == CONSCIOUS)
- HasProximity(finder)
- return 1
- return
-
-/obj/item/clothing/mask/facehugger/HasProximity(atom/movable/AM as mob|obj)
- if(CanHug(AM))
- Attach(AM)
-
-/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed)
- ..()
- if(stat == CONSCIOUS)
- icon_state = "[initial(icon_state)]_thrown"
- spawn(15)
- if(icon_state == "[initial(icon_state)]_thrown")
- icon_state = "[initial(icon_state)]"
-
-/obj/item/clothing/mask/facehugger/throw_impact(atom/hit_atom)
- ..()
- if(stat == CONSCIOUS)
- icon_state = "[initial(icon_state)]"
- throwing = 0
- GoIdle(30,100) //stunned for a few seconds - allows throwing them to be useful for positioning but not as an offensive action (unless you're setting up a trap)
-
-/obj/item/clothing/mask/facehugger/proc/Attach(M as mob)
-
- if((!iscorgi(M) && !iscarbon(M)))
- return
-
- if(attached)
- return
-
- var/mob/living/carbon/C = M
- if(istype(C) && locate(/obj/item/organ/xenos/hivenode) in C.internal_organs)
- return
-
-
- attached++
- spawn(MAX_IMPREGNATION_TIME)
- attached = 0
-
- var/mob/living/L = M //just so I don't need to use :
-
- if(loc == L) return
- if(stat != CONSCIOUS) return
- if(!sterile) L.take_organ_damage(strength,0) //done here so that even borgs and humans in helmets take damage
-
- L.visible_message("\red \b [src] leaps at [L]'s face!")
-
- if(iscarbon(M))
- var/mob/living/carbon/target = L
-
- if(target.wear_mask)
- if(prob(20)) return
- var/obj/item/clothing/W = target.wear_mask
- if(!W.canremove) return
- target.drop_from_inventory(W)
-
- target.visible_message("\red \b [src] tears [W] off of [target]'s face!")
-
- target.equip_to_slot(src, slot_wear_mask)
- target.contents += src // Monkey sanity check - Snapshot
-
- if(!sterile) L.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
- else if (iscorgi(M))
- var/mob/living/simple_animal/corgi/corgi = M
- src.loc = corgi
- corgi.facehugger = src
- corgi.wear_mask = src
- //C.regenerate_icons()
-
- GoIdle() //so it doesn't jump the people that tear it off
-
- spawn(rand(MIN_IMPREGNATION_TIME,MAX_IMPREGNATION_TIME))
- Impregnate(L)
-
- return
-
-/obj/item/clothing/mask/facehugger/proc/Impregnate(mob/living/target as mob)
- if(!target || target.wear_mask != src || target.stat == DEAD) //was taken off or something
- return
-
- if(!sterile)
- //target.contract_disease(new /datum/disease/alien_embryo(0)) //so infection chance is same as virus infection chance
- new /obj/item/alien_embryo(target)
- target.status_flags |= XENO_HOST
-
- target.visible_message("\red \b [src] falls limp after violating [target]'s face!")
-
- Die()
- icon_state = "[initial(icon_state)]_impregnated"
-
- if(iscorgi(target))
- var/mob/living/simple_animal/corgi/C = target
- src.loc = get_turf(C)
- C.facehugger = null
- else
- target.visible_message("\red \b [src] violates [target]'s face!")
- return
-
-/obj/item/clothing/mask/facehugger/proc/GoActive()
- if(stat == DEAD || stat == CONSCIOUS)
- return
-
- stat = CONSCIOUS
- icon_state = "[initial(icon_state)]"
-
- return
-
-/obj/item/clothing/mask/facehugger/proc/GoIdle(var/min_time=MIN_ACTIVE_TIME, var/max_time=MAX_ACTIVE_TIME)
- if(stat == DEAD || stat == UNCONSCIOUS)
- return
-
-/* RemoveActiveIndicators() */
-
- stat = UNCONSCIOUS
- icon_state = "[initial(icon_state)]_inactive"
-
- spawn(rand(min_time,max_time))
- GoActive()
- return
-
-/obj/item/clothing/mask/facehugger/proc/Die()
- if(stat == DEAD)
- return
-
-/* RemoveActiveIndicators() */
-
- icon_state = "[initial(icon_state)]_dead"
- stat = DEAD
-
- src.visible_message("\red \b[src] curls up into a ball!")
-
- return
-
-/proc/CanHug(var/mob/M)
-
- if(iscorgi(M))
- return 1
-
- if(!iscarbon(M))
- return 0
-
- var/mob/living/carbon/C = M
- if(istype(C) && locate(/obj/item/organ/xenos/hivenode) in C.internal_organs)
- return 0
-
- if(ishuman(C))
- var/mob/living/carbon/human/H = C
- if(H.head && (H.head.body_parts_covered & FACE) && !(H.head.item_flags & FLEXIBLEMATERIAL))
- return 0
- return 1
diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm
index a73e363904..b24fdd50c3 100644
--- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm
+++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_powers.dm
@@ -88,13 +88,13 @@
verbs -= /mob/living/carbon/human/proc/lay_egg
return
- if(locate(/obj/effect/alien/egg) in get_turf(src))
+ if(locate(/obj/structure/alien/egg) in get_turf(src))
src << "There's already an egg here."
return
if(check_alien_ability(75,1,"egg sac"))
visible_message("[src] has laid an egg!")
- new /obj/effect/alien/egg(loc)
+ new /obj/structure/alien/egg(loc)
return
@@ -121,7 +121,7 @@
if(check_alien_ability(50,1,"resin spinner"))
visible_message("[src] has planted some alien weeds!")
- new /obj/effect/alien/weeds/node(loc)
+ new /obj/structure/alien/node(loc)
return
/mob/living/carbon/human/proc/corrosive_acid(O as obj|turf in oview(1)) //If they right click to corrode, an error will flash if its an invalid target./N
@@ -154,7 +154,7 @@
return
if(check_alien_ability(200,0,"acid gland"))
- new /obj/effect/alien/acid(get_turf(O), O)
+ new /obj/effect/acid(get_turf(O), O)
visible_message("[src] vomits globs of vile stuff all over [O]. It begins to sizzle and melt under the bubbling mess of acid!")
return
@@ -199,7 +199,7 @@
/mob/living/carbon/human/proc/resin() // -- TLE
set name = "Secrete Resin (75)"
- set desc = "Secrete tough malleable resin."
+ set desc = "Secrete tough, malleable resin."
set category = "Abilities"
var/choice = input("Choose what you wish to shape.","Resin building") as null|anything in list("resin door","resin wall","resin membrane","resin nest") //would do it through typesof but then the player choice would have the type path and we don't want the internal workings to be exposed ICly - Urist
@@ -214,9 +214,51 @@
if("resin door")
new /obj/structure/simple_door/resin(loc)
if("resin wall")
- new /obj/effect/alien/resin/wall(loc)
+ new /obj/structure/alien/resin/wall(loc)
if("resin membrane")
- new /obj/effect/alien/resin/membrane(loc)
+ new /obj/structure/alien/resin/membrane(loc)
if("resin nest")
new /obj/structure/bed/nest(loc)
- return
\ No newline at end of file
+ return
+
+mob/living/carbon/human/proc/xeno_infest(mob/living/carbon/human/M as mob in oview())
+ set name = "Infest (500)"
+ set desc = "Link a victim to the hivemind."
+ set category = "Abilities"
+
+ if(!M.Adjacent(src))
+ src << "They are too far away."
+ return
+
+ if(!M.mind)
+ src << "This mindless flesh adds nothing to the hive."
+ return
+
+ if(M.species.get_bodytype() == "Xenomorph" || !isnull(M.internal_organs_by_name["hive node"]))
+ src << "They are already part of the hive."
+ return
+
+ var/obj/item/organ/affecting = M.get_organ("chest")
+ if(!affecting || (affecting.status & ORGAN_ROBOT))
+ src << "This form is not compatible with our physiology."
+ return
+
+ src.visible_message("\The [src] crouches over \the [M], extending a hideous protuberance from its head!")
+
+ if(!do_after(src, 150))
+ return
+
+ if(!M || !M.Adjacent(src))
+ src << "They are too far away."
+ return
+
+ if(M.species.get_bodytype() == "Xenomorph" || !isnull(M.internal_organs_by_name["hive node"]) || !affecting || (affecting.status & ORGAN_ROBOT))
+ return
+
+ if(!check_alien_ability(500,1,"egg sac"))
+ return
+
+ src.visible_message("\The [src] regurgitates something into \the [M]'s torso!")
+ M << "A hideous lump of alien mass strains your ribcage as it settles within!"
+ var/obj/item/organ/xenos/hivenode/node = new(affecting)
+ node.replaced(M,affecting)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm
index 1c5e88ce59..3c89ed183b 100644
--- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm
+++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_species.dm
@@ -15,8 +15,8 @@
eyes = "blank_eyes"
- brute_mod = 0.5 // Hardened carapace.
- burn_mod = 2 // Weak to fire.
+ brute_mod = 0.25 // Hardened carapace.
+ burn_mod = 1.1 // Weak to fire.
warning_low_pressure = 50
hazard_low_pressure = -1
@@ -98,11 +98,11 @@
var/datum/gas_mixture/environment = T.return_air()
if(!environment) return
- if(environment.gas["phoron"] > 0 || locate(/obj/effect/alien/weeds) in T)
- if(!regenerate(H))
- var/obj/item/organ/xenos/plasmavessel/P = H.internal_organs_by_name["plasma vessel"]
- P.stored_plasma += weeds_plasma_rate
- P.stored_plasma = min(max(P.stored_plasma,0),P.max_plasma)
+ var/obj/effect/plant/plant = locate() in T
+ if((environment.gas["phoron"] > 0 || (plant && plant.seed && plant.seed.name == "xenomorph")) && !regenerate(H))
+ var/obj/item/organ/xenos/plasmavessel/P = H.internal_organs_by_name["plasma vessel"]
+ P.stored_plasma += weeds_plasma_rate
+ P.stored_plasma = min(max(P.stored_plasma,0),P.max_plasma)
..()
/datum/species/xenos/proc/regenerate(var/mob/living/carbon/human/H)
@@ -140,14 +140,6 @@
return 0
-/datum/species/xenos/handle_login_special(var/mob/living/carbon/human/H)
- H.AddInfectionImages()
- ..()
-
-/datum/species/xenos/handle_logout_special(var/mob/living/carbon/human/H)
- H.RemoveInfectionImages()
- ..()
-
/datum/species/xenos/drone
name = "Xenomorph Drone"
caste_name = "drone"
@@ -278,7 +270,8 @@
/mob/living/carbon/human/proc/transfer_plasma,
/mob/living/carbon/human/proc/corrosive_acid,
/mob/living/carbon/human/proc/neurotoxin,
- /mob/living/carbon/human/proc/resin
+ /mob/living/carbon/human/proc/resin,
+ /mob/living/carbon/human/proc/xeno_infest
)
/datum/species/xenos/queen/handle_login_special(var/mob/living/carbon/human/H)
diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/xenomorphs.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/xenomorphs.dm
index 6cb8a46475..504577c7d3 100644
--- a/code/modules/mob/living/carbon/human/species/xenomorphs/xenomorphs.dm
+++ b/code/modules/mob/living/carbon/human/species/xenomorphs/xenomorphs.dm
@@ -22,28 +22,3 @@ proc/create_new_xenomorph(var/alien_caste,var/target)
/mob/living/carbon/human/xqueen/New(var/new_loc)
h_style = "Bald"
..(new_loc, "Xenomorph Queen")
-
-// I feel like we should generalize/condense down all the various icon-rendering antag procs.
-/*----------------------------------------
-Proc: AddInfectionImages()
-Des: Gives the client of the alien an image on each infected mob.
-----------------------------------------*/
-/mob/living/carbon/human/proc/AddInfectionImages()
- if (client)
- for (var/mob/living/C in mob_list)
- if(C.status_flags & XENO_HOST)
- var/obj/item/alien_embryo/A = locate() in C
- var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[A.stage]")
- client.images += I
- return
-
-/*----------------------------------------
-Proc: RemoveInfectionImages()
-Des: Removes all infected images from the alien.
-----------------------------------------*/
-/mob/living/carbon/human/proc/RemoveInfectionImages()
- if (client)
- for(var/image/I in client.images)
- if(dd_hasprefix_case(I.icon_state, "infected"))
- qdel(I)
- return
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 6fb02ee4d5..9140428d79 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -163,6 +163,8 @@ Please contact me on #coderbus IRC. ~Carn x
icon = stand_icon
for(var/image/I in overlays_standing)
overlays += I
+ if(species.has_floating_eyes)
+ overlays |= species.get_eyes(src)
if(lying && !species.prone_icon) //Only rotate them if we're not drawing a specific icon for being prone.
var/matrix/M = matrix()
diff --git a/code/modules/mob/living/carbon/metroid/items.dm b/code/modules/mob/living/carbon/metroid/items.dm
index d068e33e6c..6832f096f2 100644
--- a/code/modules/mob/living/carbon/metroid/items.dm
+++ b/code/modules/mob/living/carbon/metroid/items.dm
@@ -281,87 +281,3 @@
/mob/living/carbon/slime/has_eyes()
return 0
-//////////////////////////////Old shit from metroids/RoRos, and the old cores, would not take much work to re-add them////////////////////////
-
-/*
-// Basically this slime Core catalyzes reactions that normally wouldn't happen anywhere
-/obj/item/slime_core
- name = "slime extract"
- desc = "Goo extracted from a slime. Legends claim these to have \"magical powers\"."
- icon = 'icons/mob/slimes.dmi'
- icon_state = "slime extract"
- force = 1.0
- w_class = 1.0
- throwforce = 1.0
- throw_speed = 2
- throw_range = 6
- origin_tech = list(TECH_BIO = 4)
- var/POWERFLAG = 0 // sshhhhhhh
- var/Flush = 30
- var/Uses = 5 // uses before it goes inert
-
-/obj/item/slime_core/New()
- ..()
- create_reagents(100)
- POWERFLAG = rand(1,10)
- Uses = rand(7, 25)
- //flags |= NOREACT
-/*
- spawn()
- Life()
-
- proc/Life()
- while(src)
- sleep(25)
- Flush--
- if(Flush <= 0)
- reagents.clear_reagents()
- Flush = 30
-*/
-
-
-
-/obj/item/weapon/reagent_containers/food/snacks/egg/slime
- name = "slime egg"
- desc = "A small, gelatinous egg."
- icon = 'icons/mob/mob.dmi'
- icon_state = "slime egg-growing"
- bitesize = 12
- origin_tech = list(TECH_BIO = 4)
- var/grown = 0
-
-/obj/item/weapon/reagent_containers/food/snacks/egg/slime/New()
- ..()
- reagents.add_reagent("nutriment", 4)
- reagents.add_reagent("slimejelly", 1)
- spawn(rand(1200,1500))//the egg takes a while to "ripen"
- Grow()
-
-/obj/item/weapon/reagent_containers/food/snacks/egg/slime/proc/Grow()
- grown = 1
- icon_state = "slime egg-grown"
- processing_objects.Add(src)
- return
-
-/obj/item/weapon/reagent_containers/food/snacks/egg/slime/proc/Hatch()
- processing_objects.Remove(src)
- var/turf/T = get_turf(src)
- src.visible_message(" The [name] pulsates and quivers!")
- spawn(rand(50,100))
- src.visible_message(" The [name] bursts open!")
- new/mob/living/carbon/slime(T)
- qdel(src)
-
-
-/obj/item/weapon/reagent_containers/food/snacks/egg/slime/process()
- var/turf/location = get_turf(src)
- var/datum/gas_mixture/environment = location.return_air()
- if (environment.phoron > MOLES_PHORON_VISIBLE)//phoron exposure causes the egg to hatch
- src.Hatch()
-
-/obj/item/weapon/reagent_containers/food/snacks/egg/slime/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if(istype( W, /obj/item/weapon/pen/crayon ))
- return
- else
- ..()
-*/
diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm
index 322d08dc9f..39406eb6c8 100644
--- a/code/modules/mob/living/simple_animal/friendly/corgi.dm
+++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm
@@ -22,7 +22,6 @@
var/obj/item/inventory_head
var/obj/item/inventory_back
- var/facehugger
//IAN! SQUEEEEEEEEE~
/mob/living/simple_animal/corgi/Ian
@@ -123,13 +122,6 @@
var/icon/back_icon = image('icons/mob/corgi_back.dmi',back_icon_state)
if(back_icon)
overlays += back_icon
-
- if(facehugger)
- if(istype(src, /mob/living/simple_animal/corgi/puppy))
- overlays += image('icons/mob/mask.dmi',"facehugger_corgipuppy")
- else
- overlays += image('icons/mob/mask.dmi',"facehugger_corgi")
-
return
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index 10b9d0ebbf..ee1d62529a 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -161,30 +161,6 @@
qdel(src)
return O
-//human -> alien
-/mob/living/carbon/human/proc/Alienize()
- if (transforming)
- return
- for(var/obj/item/W in src)
- drop_from_inventory(W)
- regenerate_icons()
- transforming = 1
- canmove = 0
- icon = null
- invisibility = 101
- for(var/t in organs)
- qdel(t)
-
- var/alien_caste = pick("Hunter","Sentinel","Drone")
- var/mob/living/carbon/human/new_xeno = create_new_xenomorph(alien_caste,loc)
-
- new_xeno.a_intent = I_HURT
- new_xeno.key = key
-
- new_xeno << "You are now an alien."
- qdel(src)
- return
-
/mob/living/carbon/human/proc/slimeize(adult as num, reproduce as num)
if (transforming)
return
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index 1e2f7d1e52..ed81beb42b 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -939,11 +939,14 @@ Note that amputating the affected organ does in fact remove the infection from t
/obj/item/organ/external/proc/is_malfunctioning()
return ((status & ORGAN_ROBOT) && (brute_dam + burn_dam) >= 10 && prob(brute_dam + burn_dam))
-/obj/item/organ/external/proc/embed(var/obj/item/weapon/W, var/silent = 0)
+/obj/item/organ/external/proc/embed(var/obj/item/weapon/W, var/silent = 0, var/supplied_message)
if(!owner || loc != owner)
return
if(!silent)
- owner.visible_message("\The [W] sticks in the wound!")
+ if(supplied_message)
+ owner.visible_message("[supplied_message]")
+ else
+ owner.visible_message("\The [W] sticks in the wound!")
implants += W
owner.embedded_flag = 1
owner.verbs += /mob/proc/yank_out_object
diff --git a/code/modules/organs/subtypes/xenos.dm b/code/modules/organs/subtypes/xenos.dm
index 0b1233085f..f1049da61e 100644
--- a/code/modules/organs/subtypes/xenos.dm
+++ b/code/modules/organs/subtypes/xenos.dm
@@ -38,15 +38,32 @@
icon_state = "xgibtorso"
organ_tag = "acid gland"
-/obj/item/organ/xenos/hivenode
- name = "hive node"
- parent_organ = "chest"
- icon_state = "xgibmid2"
- organ_tag = "hive node"
-
/obj/item/organ/xenos/resinspinner
name = "resin spinner"
parent_organ = "head"
icon_state = "xgibmid2"
organ_tag = "resin spinner"
+/obj/item/organ/xenos/hivenode
+ name = "hive node"
+ parent_organ = "chest"
+ icon_state = "xgibmid2"
+ organ_tag = "hive node"
+
+/obj/item/organ/xenos/hivenode/removed(var/mob/living/user)
+ if(owner && ishuman(owner))
+ var/mob/living/carbon/human/H = owner
+ H << "You feel your connection to the hivemind fray and fade away..."
+ H.remove_language("Hivemind")
+ if(H.mind && H.species.get_bodytype() != "Xenomorph")
+ xenomorphs.remove_antagonist(H.mind)
+ ..(user)
+
+/obj/item/organ/xenos/hivenode/replaced(var/mob/living/carbon/human/target,var/obj/item/organ/external/affected)
+ ..(target, affected)
+ if(owner && ishuman(owner))
+ var/mob/living/carbon/human/H = owner
+ H.add_language("Hivemind")
+ if(H.mind && H.species.get_bodytype() != "Xenomorph")
+ H << "You feel a sense of pressure as a vast intelligence meshes with your thoughts..."
+ xenomorphs.add_antagonist_mind(H.mind,1, xenomorphs.faction_role_text, xenomorphs.faction_welcome)
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm
index e0781a9e6b..e6ddb91e89 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm
@@ -175,11 +175,7 @@
W.visible_message("The fungi are completely dissolved by the solution!")
/datum/reagent/toxin/plantbgone/touch_obj(var/obj/O, var/volume)
- if(istype(O, /obj/effect/alien/weeds/))
- var/obj/effect/alien/weeds/alien_weeds = O
- alien_weeds.health -= rand(15, 35)
- alien_weeds.healthcheck()
- else if(istype(O, /obj/effect/plant))
+ if(istype(O, /obj/effect/plant))
qdel(O)
/datum/reagent/toxin/plantbgone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
diff --git a/code/modules/surgery/organs_internal.dm b/code/modules/surgery/organs_internal.dm
index d352c4aed4..be738c01f8 100644
--- a/code/modules/surgery/organs_internal.dm
+++ b/code/modules/surgery/organs_internal.dm
@@ -12,46 +12,6 @@
var/obj/item/organ/external/affected = target.get_organ(target_zone)
return affected && affected.open == (affected.encased ? 3 : 2)
-//////////////////////////////////////////////////////////////////
-// ALIEN EMBRYO SURGERY //
-//////////////////////////////////////////////////////////////////
-/datum/surgery_step/internal/remove_embryo
- allowed_tools = list(
- /obj/item/weapon/hemostat = 100, \
- /obj/item/weapon/wirecutters = 75, \
- /obj/item/weapon/material/kitchen/utensil/fork = 20
- )
- blood_level = 2
-
- min_duration = 80
- max_duration = 100
-
- can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/embryo = 0
- for(var/obj/item/alien_embryo/A in target)
- embryo = 1
- break
-
- if (!hasorgans(target))
- return
- var/obj/item/organ/external/affected = target.get_organ(target_zone)
- return ..() && affected && embryo && affected.open == 3 && target_zone == "chest"
-
- begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/msg = "[user] starts to pull something out from [target]'s ribcage with \the [tool]."
- var/self_msg = "You start to pull something out from [target]'s ribcage with \the [tool]."
- user.visible_message(msg, self_msg)
- target.custom_pain("Something hurts horribly in your chest!",1)
- ..()
-
- end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- user.visible_message("\red [user] rips the larva out of [target]'s ribcage!",
- "You rip the larva out of [target]'s ribcage!")
-
- for(var/obj/item/alien_embryo/A in target)
- A.loc = A.loc.loc
-
-
//////////////////////////////////////////////////////////////////
// CHEST INTERNAL ORGAN SURGERY //
//////////////////////////////////////////////////////////////////
diff --git a/html/changelogs/zuhayr-xenomorphs.yml b/html/changelogs/zuhayr-xenomorphs.yml
new file mode 100644
index 0000000000..7e6d528ff0
--- /dev/null
+++ b/html/changelogs/zuhayr-xenomorphs.yml
@@ -0,0 +1,21 @@
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+author: Zuhayr
+delete-after: True
+changes:
+ - rscdel: "Removed facehuggers, alien embryos, and embryo removal surgery."
+ - rscadd: "Xenomorph Queens (or infested surgeons...) can now add a hive node to a victim in order to slave them to the hive."
+ - tweak: "Xenomorph brute/burn mods were tweaked to buff them significantly."
+ - tweak: "Alien larvae now hatch from eggs when ghosts click on them."
+ - tweak: "Alien larvae now gain progression towards adulthood from being inside a human with blood, which they drink."
+ - tweak: "Alien weeds now use the vine system."
\ No newline at end of file
diff --git a/maps/exodus-1.dmm b/maps/exodus-1.dmm
index 01d8701485..d796056290 100644
--- a/maps/exodus-1.dmm
+++ b/maps/exodus-1.dmm
@@ -4305,7 +4305,7 @@
"bEO" = (/obj/structure/table/standard,/obj/item/weapon/folder/white,/obj/item/weapon/stamp/rd{pixel_x = 3; pixel_y = -2},/obj/item/weapon/paper/monitorkey,/obj/item/device/megaphone,/obj/item/weapon/paper_bin{pixel_x = 1; pixel_y = 9},/obj/item/weapon/pen,/obj/effect/floor_decal/corner/grey/diagonal,/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/hor)
"bEP" = (/obj/machinery/computer/aifixer,/obj/machinery/requests_console{announcementConsole = 1; department = "Research Director's Desk"; departmentType = 5; name = "Research Director RC"; pixel_x = -2; pixel_y = 30},/obj/structure/window/reinforced{dir = 4},/obj/effect/floor_decal/corner/grey/diagonal,/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/hor)
"bEQ" = (/obj/structure/table/standard,/obj/effect/floor_decal/corner/grey/diagonal,/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/hor)
-"bER" = (/obj/structure/lamarr,/obj/machinery/light{dir = 1},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/hor)
+"bER" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/hor)
"bES" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/effect/floor_decal/industrial/warning{dir = 8},/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/hor)
"bET" = (/obj/machinery/ai_status_display{pixel_y = 32},/obj/effect/floor_decal/industrial/warning{dir = 4},/obj/machinery/papershredder,/turf/simulated/floor/tiled/white,/area/crew_quarters/heads/hor)
"bEU" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/obj/effect/floor_decal/corner/blue{dir = 4},/turf/simulated/floor/tiled/white,/area/rnd/docking)
diff --git a/maps/exodus-5.dmm b/maps/exodus-5.dmm
index 164f842fc1..b1786473de 100644
--- a/maps/exodus-5.dmm
+++ b/maps/exodus-5.dmm
@@ -125,7 +125,7 @@
"cu" = (/obj/structure/cable/blue,/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/effect/floor_decal/corner/grey/diagonal,/turf/simulated/floor/tiled/white,/area/outpost/research/kitchen)
"cv" = (/obj/structure/bed/chair{dir = 8},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/effect/floor_decal/corner/grey/diagonal,/turf/simulated/floor/tiled/white,/area/outpost/research/kitchen)
"cw" = (/turf/simulated/floor/airless,/turf/simulated/shuttle/wall{icon_state = "pwall"; dir = 10},/area/shuttle/alien/mine)
-"cx" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/tiled/airless,/area/outpost/abandoned)
+"cx" = (/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/alien/mine)
"cy" = (/obj/item/stack/rods,/turf/simulated/floor/tiled/airless,/area/outpost/abandoned)
"cz" = (/obj/structure/lattice,/turf/simulated/floor/asteroid,/area/mine/explored)
"cA" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/corner/lime/full{dir = 4},/turf/simulated/floor/tiled/white,/area/outpost/research/analysis)
@@ -152,7 +152,7 @@
"cV" = (/obj/structure/disposalpipe/trunk,/obj/structure/disposaloutlet{dir = 1},/turf/simulated/floor/asteroid,/area/mine/explored)
"cW" = (/obj/structure/window/reinforced/tinted{dir = 4; icon_state = "twindow"},/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 8},/turf/simulated/floor/airless,/area/shuttle/alien/mine)
"cX" = (/turf/simulated/floor/tiled/airless,/area/outpost/abandoned)
-"cY" = (/obj/item/weapon/material/shard{icon_state = "medium"},/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/floor/tiled/airless,/area/outpost/abandoned)
+"cY" = (/turf/simulated/floor/plating,/area/outpost/abandoned)
"cZ" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 0},/turf/simulated/wall/r_wall,/area/outpost/research/hallway)
"da" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/research{name = "Spectrometry Lab"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled/white,/area/outpost/research/hallway)
"db" = (/turf/simulated/floor/wood,/area/outpost/research/kitchen)
@@ -197,12 +197,11 @@
"dO" = (/obj/machinery/conveyor{dir = 1; id = "anolaser"},/obj/machinery/door/window/westleft{dir = 2; layer = 3.1; name = "laser testing"; req_access = list(65)},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/tiled/white,/area/outpost/research/lab)
"dP" = (/turf/simulated/floor/tiled/white,/area/outpost/research/hallway)
"dQ" = (/obj/structure/extinguisher_cabinet{pixel_x = -25; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/corner/grey{dir = 1},/obj/effect/floor_decal/corner/purple{dir = 8},/turf/simulated/floor/tiled/white,/area/outpost/research/hallway)
-"dR" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/alien/mine)
-"dS" = (/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/alien/mine)
+"dR" = (/obj/effect/decal/remains/xeno,/turf/simulated/floor/plating,/area/outpost/abandoned)
+"dS" = (/obj/structure/lattice,/obj/item/weapon/material/shard{icon_state = "small"},/turf/unsimulated/mask,/area/outpost/abandoned)
"dT" = (/obj/machinery/door/airlock/hatch,/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/alien/mine)
"dU" = (/obj/item/stack/rods,/obj/structure/window/reinforced{dir = 4},/obj/item/weapon/material/shard,/turf/simulated/floor/airless,/area/outpost/abandoned)
"dV" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/outpost/research/hallway)
-"dW" = (/obj/item/stack/rods,/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor/tiled/airless,/area/outpost/abandoned)
"dX" = (/obj/structure/cable/blue{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/tiled/white,/area/outpost/research/hallway)
"dY" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/white,/area/outpost/research/hallway)
"dZ" = (/obj/structure/cable/blue{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled/white,/area/outpost/research/hallway)
@@ -235,8 +234,6 @@
"eA" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/floor/wood,/area/outpost/research/hallway)
"eB" = (/obj/machinery/vending/cola,/turf/simulated/floor/wood,/area/outpost/research/hallway)
"eC" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/airless,/area/outpost/abandoned)
-"eD" = (/obj/effect/alien/weeds,/turf/simulated/floor/tiled/airless,/area/outpost/abandoned)
-"eE" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor/tiled/airless,/area/outpost/abandoned)
"eF" = (/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled/white,/area/outpost/research/hallway)
"eG" = (/obj/structure/sign/science{desc = "A warning sign which reads 'ANOMALOUS MATERIALS'"; name = "\improper ANOMALOUS MATERIALS"; pixel_x = 32},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/effect/floor_decal/corner/blue/diagonal{dir = 4},/turf/simulated/floor/tiled/white,/area/outpost/research/hallway)
"eH" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/corner/blue{dir = 4},/turf/simulated/floor/tiled/white,/area/outpost/research/hallway)
@@ -260,7 +257,6 @@
"eZ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/airless,/area/outpost/abandoned)
"fa" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/airless,/area/outpost/abandoned)
"fb" = (/obj/effect/decal/remains/xeno,/turf/simulated/floor/tiled/airless,/area/outpost/abandoned)
-"fc" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/tiled/airless,/area/outpost/abandoned)
"fd" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/door/firedoor/border_only,/obj/effect/floor_decal/corner/blue{dir = 4},/turf/simulated/floor/tiled/white,/area/outpost/research/hallway)
"fe" = (/obj/structure/table/rack,/obj/item/weapon/storage/toolbox/emergency{pixel_x = 5; pixel_y = 5},/turf/simulated/floor/plating,/area/outpost/research/disposal)
"ff" = (/obj/machinery/alarm{frequency = 1439; pixel_y = 22},/turf/simulated/floor/plating,/area/outpost/research/disposal)
@@ -274,9 +270,6 @@
"fn" = (/obj/item/weapon/material/shard,/obj/item/stack/rods,/turf/simulated/floor/airless,/area/outpost/abandoned)
"fo" = (/obj/structure/table/standard,/turf/simulated/floor/tiled/airless,/area/outpost/abandoned)
"fp" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/airless,/area/outpost/abandoned)
-"fq" = (/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/floor,/area/outpost/abandoned)
-"fr" = (/obj/effect/alien/weeds,/turf/simulated/floor/plating,/area/outpost/abandoned)
-"fs" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/plating,/area/outpost/abandoned)
"ft" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled/white,/area/outpost/research/hallway)
"fu" = (/obj/structure/extinguisher_cabinet{pixel_x = -25; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/white,/area/outpost/research/hallway)
"fv" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/reagent_dispensers/water_cooler,/turf/simulated/floor/wood,/area/outpost/research/hallway)
@@ -308,7 +301,6 @@
"fV" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/outpost/abandoned)
"fW" = (/obj/item/stack/rods,/turf/simulated/floor/airless,/area/outpost/abandoned)
"fX" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_research{name = "Outpost Primary Access"; req_access = list(65)},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled/white,/area/outpost/research/dock)
-"fY" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor/plating,/area/outpost/abandoned)
"fZ" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 0},/turf/simulated/wall,/area/outpost/research/dock)
"ga" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_research{name = "Outpost Primary Access"; req_access = list(65)},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/white,/area/outpost/research/dock)
"gb" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/outpost/research/dock)
@@ -342,7 +334,6 @@
"gD" = (/obj/machinery/computer/shuttle_control/research,/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor/tiled/white,/area/outpost/research/dock)
"gE" = (/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/turf/simulated/floor/tiled/white,/area/outpost/research/dock)
"gF" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "research_outpost_dock"; pixel_x = 0; pixel_y = 30; req_one_access = list(13,65); tag_door = "research_outpost_hatch"},/obj/effect/floor_decal/industrial/warning/corner{dir = 4},/turf/simulated/floor/tiled/white,/area/outpost/research/dock)
-"gG" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/obj/effect/decal/remains/xeno,/turf/simulated/floor/plating,/area/outpost/abandoned)
"gH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/outpost/research/dock)
"gI" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'VACUUM'"; icon_state = "space"; layer = 4; name = "VACUUM"; pixel_x = 0; pixel_y = 32},/obj/effect/floor_decal/industrial/warning/corner{dir = 1},/turf/simulated/floor/tiled/white,/area/outpost/research/dock)
"gJ" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/obj/effect/floor_decal/corner/purple{dir = 4},/turf/simulated/floor/tiled/white,/area/outpost/research/dock)
@@ -371,7 +362,6 @@
"hg" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/structure/grille,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/outpost/research/anomaly_analysis)
"hh" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled/white,/area/outpost/research/dock)
"hi" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/effect/floor_decal/corner/red/diagonal,/turf/simulated/floor/tiled/white,/area/outpost/research/dock)
-"hj" = (/obj/structure/lattice,/obj/item/weapon/material/shard{icon_state = "small"},/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/unsimulated/mask,/area/outpost/abandoned)
"hk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled/white,/area/outpost/research/dock)
"hl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled/white,/area/outpost/research/dock)
"hm" = (/obj/structure/lattice,/turf/unsimulated/mask,/area/outpost/abandoned)
@@ -404,8 +394,6 @@
"hN" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/airless,/area/outpost/abandoned)
"hO" = (/obj/machinery/door/firedoor/border_only{dir = 4; name = "Firelock"},/obj/machinery/door/airlock/maintenance{name = "Maintenance Storage"; req_one_access = list(12,65)},/obj/structure/cable/blue{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/outpost/research/hallway)
"hP" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/airless,/area/outpost/abandoned)
-"hQ" = (/obj/effect/alien/weeds{icon_state = "weeds1"},/turf/simulated/floor/airless,/area/outpost/abandoned)
-"hR" = (/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/floor/tiled/airless,/area/outpost/abandoned)
"hS" = (/obj/effect/floor_decal/corner/red/diagonal,/turf/simulated/floor/tiled/white,/area/outpost/research/dock)
"hT" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/tiled/white,/area/outpost/research/dock)
"hU" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/camera/network/research_outpost{c_tag = "Research Outpost Shuttle Dock"; dir = 8},/turf/simulated/floor/tiled/white,/area/outpost/research/dock)
@@ -419,7 +407,6 @@
"ic" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/window/westleft{base_state = "right"; icon_state = "right"},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 9},/obj/effect/floor_decal/industrial/loading{dir = 4},/turf/simulated/floor/tiled/white,/area/outpost/research/eva)
"id" = (/turf/simulated/floor/airless,/area/outpost/abandoned)
"ie" = (/obj/structure/disposalpipe/trunk{dir = 4},/obj/machinery/disposal/deliveryChute{dir = 8; name = "disposal inlet"},/obj/structure/window/reinforced{dir = 1},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 1},/turf/simulated/floor/tiled/white,/area/outpost/research/eva)
-"if" = (/obj/effect/alien/weeds,/turf/simulated/floor,/area/outpost/abandoned)
"ig" = (/obj/structure/table/standard,/turf/simulated/floor/airless,/area/outpost/abandoned)
"ih" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/blue{d2 = 8; icon_state = "0-8"},/obj/structure/cable/blue{d2 = 4; icon_state = "0-4"},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/effect/floor_decal/corner/grey{dir = 8},/turf/simulated/floor/tiled/white,/area/outpost/research/hallway)
"ii" = (/obj/structure/table/rack,/turf/simulated/floor/airless,/area/outpost/abandoned)
@@ -451,7 +438,6 @@
"iI" = (/obj/item/weapon/anodevice{pixel_x = 3; pixel_y = 3},/obj/item/weapon/anodevice,/obj/structure/table/steel,/turf/simulated/floor/tiled/white,/area/outpost/research/anomaly_analysis)
"iJ" = (/obj/effect/decal/remains/human,/turf/simulated/floor/tiled/airless,/area/outpost/abandoned)
"iK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/outpost/research/dock)
-"iL" = (/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor/tiled/airless,/area/outpost/abandoned)
"iM" = (/obj/structure/table/rack,/turf/simulated/floor/tiled/airless,/area/outpost/abandoned)
"iN" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'INTERNALS REQUIRED'."; name = "INTERNALS REQUIRED"; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/asteroid,/area/mine/explored)
"iO" = (/obj/structure/closet/emcloset,/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/tiled/white,/area/outpost/research/dock)
@@ -530,8 +516,6 @@
"kj" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/effect/floor_decal/industrial/warning/corner{dir = 4},/turf/simulated/floor/tiled/white,/area/outpost/research/eva)
"kk" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/alarm{pixel_y = 22},/turf/simulated/floor/tiled/white,/area/outpost/research/eva)
"kl" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{req_one_access = list(12,65)},/turf/simulated/floor/plating,/area/outpost/research/eva)
-"km" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/floor,/area/outpost/abandoned)
-"kn" = (/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/floor/airless,/area/outpost/abandoned)
"ko" = (/turf/simulated/wall,/area/outpost/research/eva)
"kp" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 5},/turf/simulated/floor/tiled/white,/area/outpost/research/eva)
"kq" = (/obj/machinery/conveyor{dir = 2; id = "anotempload"},/turf/simulated/floor/plating,/area/outpost/research/eva)
@@ -603,8 +587,6 @@
"lE" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/camera/network/research_outpost{c_tag = "Research Outpost Isolation Starboard"; dir = 8},/turf/simulated/floor/tiled,/area/outpost/research/isolation_monitoring)
"lF" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/turf/simulated/floor/tiled,/area/outpost/research/isolation_monitoring)
"lG" = (/obj/effect/floor_decal/industrial/outline/grey,/turf/simulated/floor/tiled/dark,/area/outpost/research/anomaly_storage)
-"lH" = (/obj/effect/alien/resin,/turf/simulated/floor/tiled/airless,/area/outpost/abandoned)
-"lI" = (/obj/effect/alien/weeds,/turf/simulated/floor/airless,/area/outpost/abandoned)
"lJ" = (/obj/structure/ore_box,/obj/machinery/light_construct/small{dir = 1},/turf/simulated/floor/airless{icon_state = "asteroidplating"},/area/mine/explored)
"lK" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22; pixel_y = 0},/obj/structure/dispenser/oxygen,/turf/simulated/floor/tiled/white,/area/outpost/research/eva)
"lL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/floodlight,/turf/simulated/floor/tiled/white,/area/outpost/research/eva)
@@ -633,7 +615,6 @@
"mi" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/item/weapon/material/shard,/turf/simulated/floor/airless,/area/outpost/abandoned)
"mj" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/outpost/abandoned)
"mk" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/outpost/abandoned)
-"ml" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor/airless,/area/outpost/abandoned)
"mm" = (/obj/structure/ore_box,/turf/simulated/floor/airless{icon_state = "asteroidplating"},/area/mine/explored)
"mn" = (/obj/machinery/suspension_gen,/turf/simulated/floor/tiled/white,/area/outpost/research/eva)
"mo" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/floor/tiled/white,/area/outpost/research/eva)
@@ -655,7 +636,6 @@
"mE" = (/obj/structure/closet/hydrant{pixel_x = -32},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor/plating,/area/outpost/research/emergency_storage)
"mF" = (/obj/structure/table/rack,/obj/item/weapon/storage/box/gloves{pixel_x = 4; pixel_y = 5},/obj/item/weapon/storage/box/samplebags{pixel_x = 3; pixel_y = -3},/obj/item/weapon/storage/toolbox/emergency{pixel_x = 5; pixel_y = 5},/turf/simulated/floor/plating,/area/outpost/research/emergency_storage)
"mG" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor/tiled,/area/outpost/research/isolation_monitoring)
-"mH" = (/obj/effect/decal/remains/human,/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor/tiled/airless,/area/outpost/abandoned)
"mI" = (/obj/structure/closet,/turf/simulated/floor/airless{icon_state = "asteroidplating"},/area/mine/explored)
"mJ" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "research_inner"; locked = 1; name = "Research Outpost External Access"},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/tiled/white,/area/outpost/research/eva)
"mK" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/outpost/abandoned)
@@ -1617,28 +1597,28 @@ aaababababababababababababababababababababababababababababababababababababababab
aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbnbibhababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaIbobqbpbtbrbwbubybxbzbsbvbAaEbBbCaEbEbDaEbHbJbIbKbHbfacacacbdababababababababababbdbdacacadadafafafafafafafafafafafafafafafafafadadacbdababababababababababababababababababababababababababababababababaaaa
aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbLbGbFbXabababababababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacababababababaIbMbPbNaIbQbSbRbTbSbSbObvbUaEbVbYbWcabZcccbchcgcjcibfacacacbdabababababababababababbdacacadadafafafafafafafafafafafafafafafafafadadbdbdababababababababababababababababababababababababababababababababaaaa
aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababckcecdcfbXabababababababababababababababababababababababababababababababababababababababababababababababababababababacacacacacacacacacababababaIbMcmclaIcnbRcocqcpakarakcrasasasasctcsaEcuchcjcjcvbfacacacbdabababababababababababbdacacadadafafafafafafafafafafafafafafafafafadadbdabababababababababababababababababababababababababababababababababaaaa
-aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcIdldlcwcycxbFbXabababababababababababababababababababababababababababababababababababababababababababababababababababagagacaeczczczczczczczczamagabaIbMcBcAaIcCcEcDcGcFcKcHcMcLcOcNcQascScRdcbHbHcTbHcUbfcVacbdbdabababababababababababbdbdbdadadafafafafafafafafafafafafafafafafafadadbdabababababababababababababababababababababababababababababababababaaaa
-aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcWdRdSdTcYcXcPbXbXababababababababababababababababababababababababababababababababababababababababababababababababababacacacczacacacacacacacaccJasasasasasdaasasasasddasasdhdkdjdodndpasdrdqdVdbdedsdgdfdidtbdbdabababbdbdbdababababababababbdadadafafafafafafafafafafafafafafafafafadadbdabababababababababababababababababababababababababababababababababaaaa
-aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcIdldldudvcxdmabababababababababababababababababababababababababababababababababababababababababababababababababababbdacacacczacdwdwdwdwdwdwdwaEdydxdAdzdCdBdEdDdGdFdIdHasdJdLdKdNdMdOasdQdPdVdbdbdbdbdbbfbdbdabababbdbdacbdbdbdbdabababababbdadadafafafafafafafafafafafafafafafafafadadbdabababababababababababababababababababababababababababababababababaaaa
-aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXbXdUdWcXdmabababababababababababababababababababababababababababababababababababababababababababababababababababagagacacczacdwdwdwdwdwdwdweidYdXeadZdZebecdZeaedefeeemegeoenepepereqeuetexehekejelbfbfbdbdbdbdbdbdacacbdacacbdababababbdbdadadafafafafafafafafafafafafafafafafafadadbdabababababababababababababababababababababababababababababababababaaaa
-aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXbXeLeCeEeDdmabababababababababababababababababababababababababababababababababababababababababababababababababababagacacacczacdwdwdwdwdwdwdwePdYeFeveseyeweAezeBcZeHeGaseIeKeJeOeMeQaseSeRaEeNeNeNeNeTacaceUacacacacacacacacacbdbdbdbdabbdacadadafafafafafafafafafafafafafafafafafadadbdabababababababababababababababababababababababababababababababababaaaa
-aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXbXeZeVfadmfcfbdmdmdmdmabababababababababababababababababababababababababababababababababababababababababababababababbdacacacacczacdwdwdwdwdwdwdwaNdYeFeveseXeWeAezeYasfgfdasfhasasasasemasflfjaEfefmfffifkaceUghghacacacacacacacacacacacbdbdbdacadadafafafafafacafafafafafacafafafafafadadbdabababababababababababababababababababababababababababababababababaaaa
-aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXfOfnidfpfofobhcXfqdmfrfsdmabababababababababababababababababababababababababababababababababababababababababababababababbdacacacacczacdwdwdwdwdwdwdwaEfuftfvesfwezeAfxfzasfAfyfCfBfEfDfFasfHfGfIdPaEfLfKfJfNfMfQfPfPfSfSfSfSfSfSfSfSfSfSfSfSfSfSfTadadadafafafafafacafafafafafacafafafafafadadbdabababababababababababababababababababababababababababababababababaaaa
-aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXfWfUfncXcXcXcxfVfqfcfsfYfrdmabababababababababababababababababababababababababababababababababababababababababababababababacacacacacczfZgcgbgfgdgcgbgggegafXgNgNgNgjgjgjgjgjgidPglgkaugmgnasgpgogrgqaEgvgtgsgugwgAasasgBacacacacacacacacadadadadadadadadadafafafafafacacacacacacacafafafafafadadbdabababababababababababababababababababababababababababababababababaaaa
-aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababgCfWjFfWididfcgxcXdmeDgydmfsgGdmabababababababababababababababababababababababababababababababababababababababababababababababbdacacacacacgHgDgzgFgEgIgzgOgJgLgKiagMgPgjgRgQgQgjgSdPgUgTgWgVgXasgZgYfghaaEaEhOaEaEaEdPhbhcgBgBgBgBhggBgBgBgBadadadadadadadadadadadadadadadadadadadadadadadadadadadadbdabababababababababababababababababababababababababababababababababaaaa
-aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXbXhehdidhjhmidcXeDcXhffccxdmdmdmdmdmdmababababababababababababababababababababababababababababababababababababababababababababababacacacacachnhihhhhhhhhhkhohlhrhqhthshugjhwhvhyhxhzgqhahAdPdPhBfydPdPgrgqhDhChGhEhahHdPdPhIgBhKhJgBhLhMhVhXgBadadadbdbdbdacadadadadadadadadadadadadadadadadadadadadadbdabababababababababababababababababababababababababababababababababaaaa
-aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXbXhNhPcXidhmhQcXfbcXiddmiffbdmighRcXiidmabababababababababababababababababababababababababababababababababababababababababababababababacacacachnhShSgzhTgzhUhFgzhYhWiVhZibgjhvicieirijihilikinimipioisiqitimimimiviuixiwiziyiBiAiDiCiFiEiHiGiIgBadadadbdabbdbdbdacacacacacacacacacacacacacacbdacacacacbdbdabababababababababababababababababababababababababababababababababaaaa
-aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXbXbXababdmfoeDiJeDcXeDiLcXigbhcXhRdmigeDhRiMdmababababababababababababababababababababababababababababababababababbdbdbdbdbdbdababababababkDiNacacaciKhShSiPiOiRiQgOiSiUiTkfiWiXgjjaiYjbgjgjjnjnjojqiZjijqjpjqjsjrjrjrjrjijqjvjwjwjcgBjejdgBjfjhjgjjgBadadadbdabababbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdababababababababababababababababababababababababababababababababababaaaa
-aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXdmdmdmdmdmdmfocXdveDcXeDjFigigfVfqifdmigcXeDiMdmababababababababababababababababababababababababababababababababbdbdbdacacacacbdbdbdababjkacacacacacacjHgcgbgfjHjHjHjHjHjljHjJjJjJgjjmgjjtjLjNjnjujOjqjxjzjyjBjAjDjCjGjEjEjIjqjZkajwjKkbkbkbkbjMjQkehXgBadadadbdababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
-aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXdmjRcXcXjSdmhNjThPdmhpdmjVjUjWdmcXkmidkncXeEcXdmabababababababababababababababababababababababababababababababbdbdacacacacacacacacbdbdabacacacacacacacadadjXjXkokcjYkdjPkikgkLkhkkkjkpklkqkBkskrktkHjqkukwkvkxjGjDkykzjGjEkAjqkQkRjwkFkCkIkGkbgBgBgBgBgBadadadbdababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
-aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdmjRcXcXcXhfcxeDiLeDcxcXcXfbhRcXcXcXdmcXkncXcXdmababababababababababababababababababababababababababababababbdbdacacacacacacacacacacbdmRacacacacacacacacadadjXkokJhvkKkEkMkNlNkokokOkPgjljlijnjnkSlkjqkTkVlPkXkWkZkYlblaldlcjqlxlyjwlflelelgkbababbdbdadadadadbdababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
-aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdmlhcXcXcXhfcXeDfccXgycxeDhRiLcXhReDdmlIcXcxcXdmabababababababababababababababababababababababababababababbdbdadadadadadacacacacacacacllacacacacacacacacacadjXkokJhvlnlmlplomqlqkolrgjgjltlsjnlQlSlRjqlulwlvlAlzlClBkTlDlFlEjqmdmejwlGlGlGlGkbabbdbdadadadadadbdababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
-aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdmlhiJcXfodmlHdmmkmjdmcXdmmkmjdmcXkmdmfbmlidlIdmabababababababababababababababababababababababababababababbdlJadadmRadadadacacacacacacacacacacacacacacacacacadkolKhvlLjPnFlMnGlOkolTgjlUltlsjnlVlWmujqlXlZlYkxmamcmbjGmfjGjGjqmEmFjwkbkbkbkbkbbdbdadadadadadbdbdababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
-aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdmdmdmdmdmdmlHdmcxhRcXeDeDcXeDcXcxcXdmmgmimhmKdmabababababababababababababababababababababababababababababbdmmadadadadadadadacacacacacacacacacacacacacacacacadkomomnmpkEnOlMmsmrkomtgjmvltlsjnmwjnmVjqmxkUmymAmzmCmBlZlZmGmDjqndnejwababababbdbdadadadadadbdbdabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
-aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdmlHdmhReDmHeDcxcXhRdmcXeDdmnhcXcXiMdmagababababababababababababababababababababababababababababbdadadadadmIadadadadacacacacacacacacacacacacacacacadkokonmnnkokonLmJnLkomLgjlUmNmMjnmOmQmPjqmSmUmTmXmWmZmYnbnancjGjqjwjwjwabababbdbdadadadadadbdbdababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
-aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdmlHdmeDcXcxhRcXeDcxdmlHdmdmigcXcXiMnfagababababababababababababababababababababababababababababbdningadnjninkadadadadacacacacacacacacacacacacacacadadadnlnonokonHnJnIkonpgjadnrnqjnnsntntnSnunwnvnSnxnznynZnAnCnBnZabababababbdbdadadadadadbdbdabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
-aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdmlHdmdmdmdmdmdmdmdmdmlHdmfocXcXcXiMnDagababababababababababababababababababababababababababababbdniadadadninkadadadadadadadacacacacacacacacacacacacadadadadadkonKnNnMkoofadadadadjnnPnRnQnSnTnVnUnSnWnYnXnZoaocobnZababababbdbdadadadadadbdbdababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
-aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdmlHlHlHlHlHlHlHlHlHlHlHdmigcXidcXiidmagababababababababababababababababababababababababababababbdadadadadoeodadadadadadadadacacacacacacacacacacacacadadadadadkopEpFnLkoofadadadadoGogntntnSohojoinSokomolnZonopoonZabababbdbdadadadadadbdbdabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
+aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcIdldlcwcycXbFbXabababababababababababababababababababababababababababababababababababababababababababababababababababagagacaeczczczczczczczczamagabaIbMcBcAaIcCcEcDcGcFcKcHcMcLcOcNcQascScRdcbHbHcTbHcUbfcVacbdbdabababababababababababbdbdbdadadafafafafafafafafafafafafafafafafafadadbdabababababababababababababababababababababababababababababababababaaaa
+aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcWcxcxdToPcXcPbXbXababababababababababababababababababababababababababababababababababababababababababababababababababacacacczacacacacacacacaccJasasasasasdaasasasasddasasdhdkdjdodndpasdrdqdVdbdedsdgdfdidtbdbdabababbdbdbdababababababababbdadadafafafafafafafafafafafafafafafafafadadbdabababababababababababababababababababababababababababababababababaaaa
+aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababcIdldldudvcXdmabababababababababababababababababababababababababababababababababababababababababababababababababababbdacacacczacdwdwdwdwdwdwdwaEdydxdAdzdCdBdEdDdGdFdIdHasdJdLdKdNdMdOasdQdPdVdbdbdbdbdbbfbdbdabababbdbdacbdbdbdbdabababababbdadadafafafafafafafafafafafafafafafafafadadbdabababababababababababababababababababababababababababababababababaaaa
+aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXbXdUcycXdmabababababababababababababababababababababababababababababababababababababababababababababababababababagagacacczacdwdwdwdwdwdwdweidYdXeadZdZebecdZeaedefeeemegeoenepepereqeuetexehekejelbfbfbdbdbdbdbdbdacacbdacacbdababababbdbdadadafafafafafafafafafafafafafafafafafadadbdabababababababababababababababababababababababababababababababababaaaa
+aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXbXeLeCcXcXdmabababababababababababababababababababababababababababababababababababababababababababababababababababagacacacczacdwdwdwdwdwdwdwePdYeFeveseyeweAezeBcZeHeGaseIeKeJeOeMeQaseSeRaEeNeNeNeNeTacaceUacacacacacacacacacbdbdbdbdabbdacadadafafafafafafafafafafafafafafafafafadadbdabababababababababababababababababababababababababababababababababaaaa
+aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXbXeZeVfadmcXfbdmdmdmdmabababababababababababababababababababababababababababababababababababababababababababababababbdacacacacczacdwdwdwdwdwdwdwaNdYeFeveseXeWeAezeYasfgfdasfhasasasasemasflfjaEfefmfffifkaceUghghacacacacacacacacacacacbdbdbdacadadafafafafafacafafafafafacafafafafafadadbdabababababababababababababababababababababababababababababababababaaaa
+aaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXfOfnidfpfofobhcXbGdmcYcYdmabababababababababababababababababababababababababababababababababababababababababababababababbdacacacacczacdwdwdwdwdwdwdwaEfuftfvesfwezeAfxfzasfAfyfCfBfEfDfFasfHfGfIdPaEfLfKfJfNfMfQfPfPfSfSfSfSfSfSfSfSfSfSfSfSfSfSfTadadadafafafafafacafafafafafacafafafafafadadbdabababababababababababababababababababababababababababababababababaaaa
+aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXfWfUfncXcXcXcXfVbGcXcYcYcYdmabababababababababababababababababababababababababababababababababababababababababababababababacacacacacczfZgcgbgfgdgcgbgggegafXgNgNgNgjgjgjgjgjgidPglgkaugmgnasgpgogrgqaEgvgtgsgugwgAasasgBacacacacacacacacadadadadadadadadadafafafafafacacacacacacacafafafafafadadbdabababababababababababababababababababababababababababababababababaaaa
+aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababgCfWjFfWididcXgxcXdmcXgydmcYdRdmabababababababababababababababababababababababababababababababababababababababababababababababbdacacacacacgHgDgzgFgEgIgzgOgJgLgKiagMgPgjgRgQgQgjgSdPgUgTgWgVgXasgZgYfghaaEaEhOaEaEaEdPhbhcgBgBgBgBhggBgBgBgBadadadadadadadadadadadadadadadadadadadadadadadadadadadadbdabababababababababababababababababababababababababababababababababaaaa
+aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXbXhehdiddShmidcXcXcXhfcXcXdmdmdmdmdmdmababababababababababababababababababababababababababababababababababababababababababababababacacacacachnhihhhhhhhhhkhohlhrhqhthshugjhwhvhyhxhzgqhahAdPdPhBfydPdPgrgqhDhChGhEhahHdPdPhIgBhKhJgBhLhMhVhXgBadadadbdbdbdacadadadadadadadadadadadadadadadadadadadadadbdabababababababababababababababababababababababababababababababababaaaa
+aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXbXhNhPcXidhmidcXfbcXiddmbGfbdmigcXcXiidmabababababababababababababababababababababababababababababababababababababababababababababababacacacachnhShSgzhTgzhUhFgzhYhWiVhZibgjhvicieirijihilikinimipioisiqitimimimiviuixiwiziyiBiAiDiCiFiEiHiGiIgBadadadbdabbdbdbdacacacacacacacacacacacacacacbdacacacacbdbdabababababababababababababababababababababababababababababababababaaaa
+aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXbXbXababdmfocXiJcXcXcXcXcXigbhcXcXdmigcXcXiMdmababababababababababababababababababababababababababababababababababbdbdbdbdbdbdababababababkDiNacacaciKhShSiPiOiRiQgOiSiUiTkfiWiXgjjaiYjbgjgjjnjnjojqiZjijqjpjqjsjrjrjrjrjijqjvjwjwjcgBjejdgBjfjhjgjjgBadadadbdabababbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdababababababababababababababababababababababababababababababababababaaaa
+aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXdmdmdmdmdmdmfocXdvcXcXcXjFigigfVbGbGdmigcXcXiMdmababababababababababababababababababababababababababababababababbdbdbdacacacacbdbdbdababjkacacacacacacjHgcgbgfjHjHjHjHjHjljHjJjJjJgjjmgjjtjLjNjnjujOjqjxjzjyjBjAjDjCjGjEjEjIjqjZkajwjKkbkbkbkbjMjQkehXgBadadadbdababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
+aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababbXdmjRcXcXjSdmhNjThPdmhpdmjVjUjWdmcXbGididcXcXcXdmabababababababababababababababababababababababababababababababbdbdacacacacacacacacbdbdabacacacacacacacadadjXjXkokcjYkdjPkikgkLkhkkkjkpklkqkBkskrktkHjqkukwkvkxjGjDkykzjGjEkAjqkQkRjwkFkCkIkGkbgBgBgBgBgBadadadbdababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
+aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdmjRcXcXcXhfcXcXcXcXcXcXcXfbcXcXcXcXdmcXidcXcXdmababababababababababababababababababababababababababababababbdbdacacacacacacacacacacbdmRacacacacacacacacadadjXkokJhvkKkEkMkNlNkokokOkPgjljlijnjnkSlkjqkTkVlPkXkWkZkYlblaldlcjqlxlyjwlflelelgkbababbdbdadadadadbdababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
+aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdmlhcXcXcXhfcXcXcXcXgycXcXcXcXcXcXcXdmidcXcXcXdmabababababababababababababababababababababababababababababbdbdadadadadadacacacacacacacllacacacacacacacacacadjXkokJhvlnlmlplomqlqkolrgjgjltlsjnlQlSlRjqlulwlvlAlzlClBkTlDlFlEjqmdmejwlGlGlGlGkbabbdbdadadadadadbdababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
+aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdmlhiJcXfodmcXdmmkmjdmcXdmmkmjdmcXbGdmfbidididdmabababababababababababababababababababababababababababababbdlJadadmRadadadacacacacacacacacacacacacacacacacacadkolKhvlLjPnFlMnGlOkolTgjlUltlsjnlVlWmujqlXlZlYkxmamcmbjGmfjGjGjqmEmFjwkbkbkbkbkbbdbdadadadadadbdbdababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
+aaaaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdmdmdmdmdmdmcXdmcXcXcXcXcXcXcXcXcXcXdmmgmimhmKdmabababababababababababababababababababababababababababababbdmmadadadadadadadacacacacacacacacacacacacacacacacadkomomnmpkEnOlMmsmrkomtgjmvltlsjnmwjnmVjqmxkUmymAmzmCmBlZlZmGmDjqndnejwababababbdbdadadadadadbdbdabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
+aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdmcXdmcXcXiJcXcXcXcXdmcXcXdmnhcXcXiMdmagababababababababababababababababababababababababababababbdadadadadmIadadadadacacacacacacacacacacacacacacacadkokonmnnkokonLmJnLkomLgjlUmNmMjnmOmQmPjqmSmUmTmXmWmZmYnbnancjGjqjwjwjwabababbdbdadadadadadbdbdababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
+aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdmcXdmcXcXcXcXcXcXcXdmcXdmdmigcXcXiMnfagababababababababababababababababababababababababababababbdningadnjninkadadadadacacacacacacacacacacacacacacadadadnlnonokonHnJnIkonpgjadnrnqjnnsntntnSnunwnvnSnxnznynZnAnCnBnZabababababbdbdadadadadadbdbdabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
+aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdmcXdmdmdmdmdmdmdmdmdmcXdmfocXcXcXiMnDagababababababababababababababababababababababababababababbdniadadadninkadadadadadadadacacacacacacacacacacacacadadadadadkonKnNnMkoofadadadadjnnPnRnQnSnTnVnUnSnWnYnXnZoaocobnZababababbdbdadadadadadbdbdababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
+aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdmcXcXcXcXcXcXcXcXcXcXcXdmigcXidcXiidmagababababababababababababababababababababababababababababbdadadadadoeodadadadadadadadacacacacacacacacacacacacadadadadadkopEpFnLkoofadadadadoGogntntnSohojoinSokomolnZonopoonZabababbdbdadadadadadbdbdabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
aaaaababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababdmdmdmdmdmdmdmdmdmdmdmdmdmdmmKoroqdmdmagababababababababababababababababababababababababababababbdadadadadadadadadadadadadadacacacacacacacacacacacacadadadadadovouoxowozoyoAoAoAoApaoBoDoCnSoEoHoFnSoIoKoJnZoLoNoMnZababbdbdadadadadadbdbdababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababagagagdmcXcXcXdmagagababababababababababababababababababababababababababababbdningadadadadadadadadacacacacacacacacacacbdbdbdbdbdadadadadadadadadadadoOadadadadjnjnjnjnnSnSnSnSnSpnpnpnnZnZnZnZnZabbdbdadadadadadbdbdabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaaaa
aaabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababagagagdmcXoPcXdmagabababababababababababababababababababababababababababababbdniadadadadadadadadacacacacacacacacacacacbdbdbdababababbdbdbdbdbdbdbdadoOadacbdbdbdababababababababababababababababbdbdadadadadadbdbdabababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababaa