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