diff --git a/_maps/map_files/RandomRuins/SpaceRuins/freegolems.dmm b/_maps/map_files/RandomRuins/SpaceRuins/freegolems.dmm new file mode 100644 index 00000000000..e40a050fdca --- /dev/null +++ b/_maps/map_files/RandomRuins/SpaceRuins/freegolems.dmm @@ -0,0 +1,55 @@ +"a" = (/turf/template_noop,/area/template_noop) +"b" = (/turf/simulated/shuttle/wall,/area/shuttle/freegolem) +"c" = (/turf/simulated/shuttle/plating,/area/shuttle/freegolem) +"d" = (/obj/structure/shuttle/engine/heater{icon_state = "heater"; dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating/airless,/area/shuttle/freegolem) +"e" = (/obj/structure/shuttle/engine/propulsion{dir = 8; icon_state = "burst_l"},/turf/space,/area/shuttle/freegolem) +"f" = (/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"g" = (/obj/machinery/door/airlock/shuttle,/obj/structure/fans/tiny,/turf/simulated/shuttle/plating,/area/shuttle/freegolem) +"h" = (/obj/item/storage/toolbox/mechanical,/turf/simulated/shuttle/plating,/area/shuttle/freegolem) +"i" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/shuttle/plating,/area/shuttle/freegolem) +"j" = (/obj/machinery/light/small,/turf/simulated/shuttle/plating,/area/shuttle/freegolem) +"k" = (/obj/machinery/door/airlock/shuttle,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"l" = (/obj/machinery/computer/arcade/battle,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"m" = (/obj/machinery/light/small{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"n" = (/obj/machinery/light{dir = 1; on = 1},/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"o" = (/obj/structure/fans/tiny,/obj/machinery/door/airlock/shuttle,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"p" = (/obj/item/resonator,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"q" = (/obj/machinery/light{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"r" = (/obj/machinery/mineral/ore_redemption,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"s" = (/obj/structure/statue/gold/rd{name = "statue of the Liberator"},/obj/structure/window/reinforced{dir = 4; pixel_x = 0},/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"t" = (/obj/structure/computerframe,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"u" = (/obj/structure/extinguisher_cabinet{pixel_y = 30},/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"v" = (/obj/machinery/door/airlock/shuttle,/obj/structure/fans/tiny,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"w" = (/obj/item/book/manual/research_and_development{name = "Sacred Text of the Liberator"; pixel_x = -4; pixel_y = 3},/obj/structure/window/reinforced{dir = 4; pixel_x = 0},/obj/structure/table/wood,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"x" = (/obj/machinery/light/small,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"y" = (/obj/item/resonator/upgraded,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"z" = (/obj/machinery/autolathe,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"A" = (/obj/structure/table/wood,/obj/machinery/reagentgrinder,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"B" = (/obj/machinery/computer/arcade/orion_trail,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"C" = (/obj/structure/extinguisher_cabinet{pixel_y = -30},/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"D" = (/obj/structure/table/wood,/obj/item/storage/firstaid/brute,/obj/item/storage/firstaid/brute,/obj/item/storage/firstaid/brute,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"E" = (/obj/structure/table/wood,/obj/structure/table/wood,/obj/item/storage/firstaid/fire,/obj/item/storage/firstaid/fire,/obj/item/storage/firstaid/fire,/obj/machinery/light,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"F" = (/obj/structure/table/wood,/obj/item/storage/firstaid/adv,/obj/item/storage/firstaid/adv,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"G" = (/obj/structure/table/wood,/turf/simulated/shuttle/floor{icon_state = "floor5"},/area/shuttle/freegolem) +"H" = (/obj/machinery/light/small{dir = 1},/turf/simulated/shuttle/plating,/area/shuttle/freegolem) +"I" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/shuttle/plating,/area/shuttle/freegolem) +"J" = (/obj/structure/ore_box,/turf/simulated/shuttle/plating,/area/shuttle/freegolem) + +(1,1,1) = {" +aaaaabbbbbbbbbbggbbb +aaaaabcccccccchccide +aaaaabccjccjcccjcide +aabbbbkkbbbbkkbbbbbb +aablfmffmfbffffnffde +aaofffffppkfffffffde +bbbkkbbbbbbqffffrbbb +bstffffmffkffffffkuv +bwfffxffffkffffffkxv +bbbkkbbbbbbqfffyzbbb +aaofffffppkffffffAde +aabBfxffxfbCffDEFGde +aabbbbkkbbbbkkbbbbbb +aaaaabccHccHcccHcIde +aaaaabJJJJJJJJhccIde +aaaaabbbbbbbbbbggbbb +"} diff --git a/code/__DEFINES/gamemode.dm b/code/__DEFINES/gamemode.dm index 42835d43813..328904d3884 100644 --- a/code/__DEFINES/gamemode.dm +++ b/code/__DEFINES/gamemode.dm @@ -24,6 +24,7 @@ #define SPECIAL_ROLE_CULTIST "Cultist" #define SPECIAL_ROLE_DEATHSQUAD "Death Commando" #define SPECIAL_ROLE_ERT "Response Team" +#define SPECIAL_ROLE_FREE_GOLEM "Free Golem" #define SPECIAL_ROLE_GOLEM "Golem" #define SPECIAL_ROLE_HEAD_REV "Head Revolutionary" #define SPECIAL_ROLE_HONKSQUAD "Honksquad" diff --git a/code/_globalvars/lists/names.dm b/code/_globalvars/lists/names.dm index e88c2dfbb28..be5f4867c56 100644 --- a/code/_globalvars/lists/names.dm +++ b/code/_globalvars/lists/names.dm @@ -9,6 +9,7 @@ GLOBAL_LIST_INIT(first_names_female, file2list("config/names/first_female.txt")) GLOBAL_LIST_INIT(last_names, file2list("config/names/last.txt")) GLOBAL_LIST_INIT(clown_names, file2list("config/names/clown.txt")) GLOBAL_LIST_INIT(mime_names, file2list("config/names/mime.txt")) +GLOBAL_LIST_INIT(golem_names, file2list("config/names/golem.txt")) GLOBAL_LIST_INIT(verbs, file2list("config/names/verbs.txt")) GLOBAL_LIST_INIT(adjectives, file2list("config/names/adjectives.txt")) diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index 114835b21c3..796d57f2a72 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -953,6 +953,10 @@ to destroy them and players will be able to make replacements. /obj/item/stock_parts/console_screen = 1, /obj/item/stock_parts/matter_bin = 3) +/obj/item/circuitboard/machine/mining_equipment_vendor/golem + name = "Golem Ship Equipment Vendor (Machine Board)" + build_path = /obj/machinery/mineral/equipment_vendor/golem + /obj/item/circuitboard/clawgame name = "circuit board (Claw Game)" build_path = /obj/machinery/arcade/claw diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm new file mode 100644 index 00000000000..7bb0e94e2a4 --- /dev/null +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -0,0 +1,251 @@ +//Ancient cryogenic sleepers. Players become NT crewmen from a hundred year old space station, now on the verge of collapse. + +/obj/effect/mob_spawn/human/oldsec + name = "old cryogenics pod" + desc = "A humming cryo pod. You can barely recognise a security uniform underneath the built up ice. The machine is attempting to wake up its occupant." + mob_name = "a security officer" + icon = 'icons/obj/cryogenic2.dmi' + icon_state = "sleeper" + roundstart = FALSE + death = FALSE + random = TRUE + mob_species = /datum/species/human + flavour_text = "You are a security officer working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ + cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \ + your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \ + Work as a team with your fellow survivors and do not abandon them." + uniform = /obj/item/clothing/under/retro/security + shoes = /obj/item/clothing/shoes/jackboots + id = /obj/item/card/id/away/old/sec + r_pocket = /obj/item/restraints/handcuffs + l_pocket = /obj/item/flash + assignedrole = "Ancient Crew" + +/obj/effect/mob_spawn/human/oldsec/Destroy() + new /obj/structure/showcase/machinery/oldpod/used(drop_location()) + return ..() + +/obj/effect/mob_spawn/human/oldmed + name = "old cryogenics pod" + desc = "A humming cryo pod. You can barely recognise a medical uniform underneath the built up ice. The machine is attempting to wake up its occupant." + mob_name = "a medical doctor" + icon = 'icons/obj/cryogenic2.dmi' + icon_state = "sleeper" + roundstart = FALSE + death = FALSE + random = TRUE + mob_species = /datum/species/human + flavour_text = "You are a medical working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ + cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \ + your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \ + Work as a team with your fellow survivors and do not abandon them." + uniform = /obj/item/clothing/under/retro/medical + shoes = /obj/item/clothing/shoes/black + id = /obj/item/card/id/away/old/med + l_pocket = /obj/item/stack/medical/ointment + r_pocket = /obj/item/stack/medical/ointment + assignedrole = "Ancient Crew" + +/obj/effect/mob_spawn/human/oldmed/Destroy() + new /obj/structure/showcase/machinery/oldpod/used(drop_location()) + return ..() + +/obj/effect/mob_spawn/human/oldeng + name = "old cryogenics pod" + desc = "A humming cryo pod. You can barely recognise an engineering uniform underneath the built up ice. The machine is attempting to wake up its occupant." + mob_name = "an engineer" + icon = 'icons/obj/cryogenic2.dmi' + icon_state = "sleeper" + roundstart = FALSE + death = FALSE + random = TRUE + mob_species = /datum/species/human + flavour_text = "You are an engineer working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ + cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \ + your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \ + Work as a team with your fellow survivors and do not abandon them." + uniform = /obj/item/clothing/under/retro/engineering + shoes = /obj/item/clothing/shoes/workboots + id = /obj/item/card/id/away/old/eng + gloves = /obj/item/clothing/gloves/color/fyellow/old + l_pocket = /obj/item/tank/emergency_oxygen + assignedrole = "Ancient Crew" + +/obj/effect/mob_spawn/human/oldeng/Destroy() + new /obj/structure/showcase/machinery/oldpod/used(drop_location()) + return ..() + +/obj/effect/mob_spawn/human/oldsci + name = "old cryogenics pod" + desc = "A humming cryo pod. You can barely recognise a science uniform underneath the built up ice. The machine is attempting to wake up its occupant." + mob_name = "a scientist" + icon = 'icons/obj/cryogenic2.dmi' + icon_state = "sleeper" + roundstart = FALSE + death = FALSE + random = TRUE + mob_species = /datum/species/human + flavour_text = "You are a scientist working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ + cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \ + your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \ + Work as a team with your fellow survivors and do not abandon them." + uniform = /obj/item/clothing/under/retro/science + shoes = /obj/item/clothing/shoes/laceup + id = /obj/item/card/id/away/old/sci + l_pocket = /obj/item/stack/medical/bruise_pack + assignedrole = "Ancient Crew" + +/obj/effect/mob_spawn/human/oldsci/Destroy() + new /obj/structure/showcase/machinery/oldpod/used(drop_location()) + return ..() + +/obj/structure/showcase/machinery/oldpod + name = "damaged cryogenic pod" + desc = "A damaged cryogenic pod long since lost to time, including its former occupant..." + icon = 'icons/obj/cryogenic2.dmi' + icon_state = "sleeper-open" + +/obj/structure/showcase/machinery/oldpod/used + name = "opened cryogenic pod" + desc = "A cryogenic pod that has recently discharged its occupant. The pod appears non-functional." + +//Golem shells: Spawns in Free Golem ships in lavaland. Ghosts become mineral golems and are advised to spread personal freedom. + +/obj/item/golem_shell + name = "incomplete free golem shell" + icon = 'icons/obj/wizard.dmi' + icon_state = "construct" + desc = "The incomplete body of a golem. Add ten sheets of any mineral to finish." + var/shell_type = /obj/effect/mob_spawn/human/golem + var/has_owner = FALSE //if the resulting golem obeys someone + w_class = WEIGHT_CLASS_BULKY + +/obj/item/golem_shell/attackby(obj/item/I, mob/user, params) + ..() + var/static/list/golem_shell_species_types = list( + /obj/item/stack/sheet/metal = /datum/species/golem, + /obj/item/stack/sheet/glass = /datum/species/golem/glass, + /obj/item/stack/sheet/plasteel = /datum/species/golem/plasteel, + /obj/item/stack/sheet/mineral/sandstone = /datum/species/golem/sand, + /obj/item/stack/sheet/mineral/plasma = /datum/species/golem/plasma, + /obj/item/stack/sheet/mineral/diamond = /datum/species/golem/diamond, + /obj/item/stack/sheet/mineral/gold = /datum/species/golem/gold, + /obj/item/stack/sheet/mineral/silver = /datum/species/golem/silver, + /obj/item/stack/sheet/mineral/uranium = /datum/species/golem/uranium, + /obj/item/stack/sheet/mineral/bananium = /datum/species/golem/bananium, + /obj/item/stack/sheet/mineral/tranquillite = /datum/species/golem/tranquillite, + /obj/item/stack/sheet/mineral/titanium = /datum/species/golem/titanium, + /obj/item/stack/sheet/mineral/plastitanium = /datum/species/golem/plastitanium, + /obj/item/stack/sheet/mineral/abductor = /datum/species/golem/alloy, + /obj/item/stack/sheet/mineral/wood = /datum/species/golem/wood, + /obj/item/stack/sheet/bluespace_crystal = /datum/species/golem/bluespace, + /obj/item/stack/sheet/runed_metal = /datum/species/golem/runic, + /obj/item/stack/medical/gauze = /datum/species/golem/cloth, + /obj/item/stack/sheet/cloth = /datum/species/golem/cloth, + /obj/item/stack/sheet/plastic = /datum/species/golem/plastic, + /obj/item/stack/tile/brass = /datum/species/golem/clockwork, + /obj/item/stack/sheet/cardboard = /datum/species/golem/cardboard, + /obj/item/stack/sheet/leather = /datum/species/golem/leather, + /obj/item/stack/sheet/bone = /datum/species/golem/bone) + + if(istype(I, /obj/item/stack)) + var/obj/item/stack/O = I + var/species = golem_shell_species_types[O.merge_type] + if(species) + if(O.use(10)) + to_chat(user, "You finish up the golem shell with ten sheets of [O].") + new shell_type(get_turf(src), species, user) + qdel(src) + else + to_chat(user, "You need at least ten sheets to finish a golem.") + else + to_chat(user, "You can't build a golem out of this kind of material.") + +/obj/effect/mob_spawn/human/golem + name = "inert free golem shell" + desc = "A humanoid shape, empty, lifeless, and full of potential." + mob_name = "a free golem" + icon = 'icons/obj/wizard.dmi' + icon_state = "construct" + mob_species = /datum/species/golem + roundstart = FALSE + death = FALSE + anchored = FALSE + move_resist = MOVE_FORCE_NORMAL + density = FALSE + var/has_owner = FALSE + var/can_transfer = TRUE //if golems can switch bodies to this new shell + var/mob/living/owner = null //golem's owner if it has one + flavour_text = "You are a Free Golem. Your family worships The Liberator. In his infinite and divine wisdom, he set your clan free to \ + travel the stars with a single declaration: \"Yeah go do whatever.\" Though you are bound to the one who created you, it is customary in your society to repeat those same words to newborn \ + golems, so that no golem may ever be forced to serve again." + +/obj/effect/mob_spawn/human/golem/Initialize(mapload, datum/species/golem/species = null, mob/creator = null) + if(species) //spawners list uses object name to register so this goes before ..() + name += " ([initial(species.prefix)])" + mob_species = species + . = ..() + var/area/A = get_area(src) + if(!mapload && A) + notify_ghosts("\A [initial(species.prefix)] golem shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_GOLEM) + if(has_owner && creator) + flavour_text = "You are a Golem. You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. \ + Serve [creator], and assist [creator.p_them()] in completing [creator.p_their()] goals at any cost." + owner = creator + +/obj/effect/mob_spawn/human/golem/special(mob/living/new_spawn, name) + var/datum/species/golem/X = mob_species + to_chat(new_spawn, "[initial(X.info_text)]") + if(!owner) + to_chat(new_spawn, "Build golem shells in the autolathe, and feed refined mineral sheets to the shells to bring them to life! You are generally a peaceful group unless provoked.") + else + new_spawn.mind.store_memory("Serve [owner.real_name], your creator.") + new_spawn.mind.enslave_mind_to_creator(owner) + log_game("[key_name(new_spawn)] possessed a golem shell enslaved to [key_name(owner)].") + log_admin("[key_name(new_spawn)] possessed a golem shell enslaved to [key_name(owner)].") + if(ishuman(new_spawn)) + var/mob/living/carbon/human/H = new_spawn + if(has_owner) + var/datum/species/golem/G = H.dna.species + G.owner = owner + H.set_cloned_appearance() + if(!name) + if(has_owner) + H.fully_replace_character_name(null, "[initial(X.prefix)] Golem ([rand(1,999)])") + else + H.fully_replace_character_name(null, H.dna.species.random_name()) + else + H.fully_replace_character_name(null, name) + if(has_owner) + new_spawn.mind.assigned_role = "Servant Golem" + else + new_spawn.mind.assigned_role = "Free Golem" + +/obj/effect/mob_spawn/human/golem/attack_hand(mob/user) + . = ..() + if(.) + return + if(isgolem(user) && can_transfer) + var/transfer_choice = alert("Transfer your soul to [src]? (Warning, your old body will die!)",,"Yes","No") + if(transfer_choice != "Yes") + return + if(QDELETED(src) || uses <= 0) + return + log_game("[key_name(user)] golem-swapped into [src]") + user.visible_message("A faint light leaves [user], moving to [src] and animating it!","You leave your old body behind, and transfer into [src]!") + show_flavour = FALSE + create(ckey = user.ckey,name = user.real_name) + user.death() + return + +/obj/effect/mob_spawn/human/golem/servant + has_owner = TRUE + name = "inert servant golem shell" + mob_name = "a servant golem" + +/obj/effect/mob_spawn/human/golem/adamantine + name = "dust-caked free golem shell" + desc = "A humanoid shape, empty, lifeless, and full of potential." + mob_name = "a free golem" + can_transfer = FALSE + mob_species = /datum/species/golem/adamantine diff --git a/code/modules/awaymissions/mission_code/ruins/freegolems.dm b/code/modules/awaymissions/mission_code/ruins/freegolems.dm new file mode 100644 index 00000000000..f67ccd91f03 --- /dev/null +++ b/code/modules/awaymissions/mission_code/ruins/freegolems.dm @@ -0,0 +1,66 @@ +//Items + +/obj/item/bedsheet/rd/royal_cape + name = "Royal Cape of the Liberator" + desc = "Majestic." + dream_messages = list("mining", "stone", "a golem", "freedom", "doing whatever") + +/obj/item/storage/box/rndboards + name = "the Liberator's legacy" + desc = "A box containing a gift for worthy golems." + +/obj/item/storage/box/rndboards/New() + ..() + contents = list() + new /obj/item/circuitboard/machine/protolathe(src) + new /obj/item/circuitboard/machine/destructive_analyzer(src) + new /obj/item/circuitboard/machine/circuit_imprinter(src) + new /obj/item/circuitboard/computer/rdconsole(src) + +/obj/item/areaeditor/golem + name = "golem land claim" + desc = "Used to define new areas in space or on an asteroid." + fluffnotice = "Praise the Liberator!" + +/obj/item/areaeditor/golem/attack_self(mob/user) + . = ..() + var/area/A = get_area() + if(get_area_type() == AREA_STATION) + . += "
According to the [src], you are now in \"[sanitize(A.name)]\".
" + var/datum/browser/popup = new(user, "blueprints", "[src]", 700, 500) + popup.set_content(.) + popup.open() + onclose(usr, "blueprints") + +/obj/item/disk/design_disk/golem_shell + name = "golem creation disk" + desc = "A gift from the Liberator." + icon_state = "datadisk1" + max_blueprints = 1 + +/obj/item/disk/design_disk/golem_shell/Initialize() + . = ..() + var/datum/design/golem_shell/G = new + blueprints[1] = G + +/datum/design/golem_shell + name = "Golem Shell Construction" + desc = "Allows for the construction of a Golem Shell." + id = "golem" + build_type = AUTOLATHE + materials = list(MAT_METAL = 40000) + build_path = /obj/item/golem_shell + category = list("Imported") + + +//Structures + +//Areas + +/area/shuttle/freegolem + name = "Free Golem Ship" + icon_state = "purple" + +/area/mine/dangerous/explored/golem + name = "Small Asteroid" + diff --git a/code/modules/awaymissions/mission_code/ruins/oldstation.dm b/code/modules/awaymissions/mission_code/ruins/oldstation.dm index 1a68a990705..1886aba02ab 100644 --- a/code/modules/awaymissions/mission_code/ruins/oldstation.dm +++ b/code/modules/awaymissions/mission_code/ruins/oldstation.dm @@ -360,116 +360,4 @@ /area/ruin/space/ancientstation/hivebot name = "Hivebot Mothership" - icon_state = "teleporter" - -// Mob Spawners -//Ancient cryogenic sleepers. Players become NT crewmen from a hundred year old space station, now on the verge of collapse. - -/obj/effect/mob_spawn/human/oldsec - name = "old cryogenics pod" - desc = "A humming cryo pod. You can barely recognise a security uniform underneath the built up ice. The machine is attempting to wake up its occupant." - mob_name = "a security officer" - icon = 'icons/obj/cryogenic2.dmi' - icon_state = "sleeper" - roundstart = FALSE - death = FALSE - random = TRUE - mob_species = /datum/species/human - flavour_text = "You are a security officer working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ - cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \ - your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \ - Work as a team with your fellow survivors and do not abandon them." - uniform = /obj/item/clothing/under/retro/security - shoes = /obj/item/clothing/shoes/jackboots - id = /obj/item/card/id/away/old/sec - r_pocket = /obj/item/restraints/handcuffs - l_pocket = /obj/item/flash - assignedrole = "Ancient Crew" - -/obj/effect/mob_spawn/human/oldsec/Destroy() - new /obj/structure/showcase/machinery/oldpod/used(drop_location()) - return ..() - -/obj/effect/mob_spawn/human/oldmed - name = "old cryogenics pod" - desc = "A humming cryo pod. You can barely recognise a medical uniform underneath the built up ice. The machine is attempting to wake up its occupant." - mob_name = "a medical doctor" - icon = 'icons/obj/cryogenic2.dmi' - icon_state = "sleeper" - roundstart = FALSE - death = FALSE - random = TRUE - mob_species = /datum/species/human - flavour_text = "You are a medical working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ - cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \ - your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \ - Work as a team with your fellow survivors and do not abandon them." - uniform = /obj/item/clothing/under/retro/medical - shoes = /obj/item/clothing/shoes/black - id = /obj/item/card/id/away/old/med - l_pocket = /obj/item/stack/medical/ointment - r_pocket = /obj/item/stack/medical/ointment - assignedrole = "Ancient Crew" - -/obj/effect/mob_spawn/human/oldmed/Destroy() - new /obj/structure/showcase/machinery/oldpod/used(drop_location()) - return ..() - -/obj/effect/mob_spawn/human/oldeng - name = "old cryogenics pod" - desc = "A humming cryo pod. You can barely recognise an engineering uniform underneath the built up ice. The machine is attempting to wake up its occupant." - mob_name = "an engineer" - icon = 'icons/obj/cryogenic2.dmi' - icon_state = "sleeper" - roundstart = FALSE - death = FALSE - random = TRUE - mob_species = /datum/species/human - flavour_text = "You are an engineer working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ - cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \ - your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \ - Work as a team with your fellow survivors and do not abandon them." - uniform = /obj/item/clothing/under/retro/engineering - shoes = /obj/item/clothing/shoes/workboots - id = /obj/item/card/id/away/old/eng - gloves = /obj/item/clothing/gloves/color/fyellow/old - l_pocket = /obj/item/tank/emergency_oxygen - assignedrole = "Ancient Crew" - -/obj/effect/mob_spawn/human/oldeng/Destroy() - new /obj/structure/showcase/machinery/oldpod/used(drop_location()) - return ..() - -/obj/effect/mob_spawn/human/oldsci - name = "old cryogenics pod" - desc = "A humming cryo pod. You can barely recognise a science uniform underneath the built up ice. The machine is attempting to wake up its occupant." - mob_name = "a scientist" - icon = 'icons/obj/cryogenic2.dmi' - icon_state = "sleeper" - roundstart = FALSE - death = FALSE - random = TRUE - mob_species = /datum/species/human - flavour_text = "You are a scientist working for Nanotrasen, stationed onboard a state of the art research station. You vaguely recall rushing into a \ - cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \ - your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \ - Work as a team with your fellow survivors and do not abandon them." - uniform = /obj/item/clothing/under/retro/science - shoes = /obj/item/clothing/shoes/laceup - id = /obj/item/card/id/away/old/sci - l_pocket = /obj/item/stack/medical/bruise_pack - assignedrole = "Ancient Crew" - -/obj/effect/mob_spawn/human/oldsci/Destroy() - new /obj/structure/showcase/machinery/oldpod/used(drop_location()) - return ..() - -/obj/structure/showcase/machinery/oldpod - name = "damaged cryogenic pod" - desc = "A damaged cryogenic pod long since lost to time, including its former occupant..." - icon = 'icons/obj/cryogenic2.dmi' - icon_state = "sleeper-open" - -/obj/structure/showcase/machinery/oldpod/used - name = "opened cryogenic pod" - desc = "A cryogenic pod that has recently discharged its occupant. The pod appears non-functional." + icon_state = "teleporter" \ No newline at end of file diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm index 42b616990c6..8fe17f24053 100644 --- a/code/modules/mining/equipment_locker.dm +++ b/code/modules/mining/equipment_locker.dm @@ -426,6 +426,23 @@ new /datum/data/mining_equipment("Point Transfer Card", /obj/item/card/mining_point_card, 500), ) +/obj/machinery/mineral/equipment_vendor/golem + name = "golem ship equipment vendor" + circuit = /obj/item/circuitboard/machine/mining_equipment_vendor/golem + +/obj/machinery/mineral/equipment_vendor/golem/Initialize() + . = ..() + desc += "\nIt seems a few selections have been added." + prize_list += list( + new /datum/data/mining_equipment("Extra Id", /obj/item/card/id/mining, 250), + new /datum/data/mining_equipment("Science Goggles", /obj/item/clothing/glasses/science, 250), + new /datum/data/mining_equipment("Monkey Cube", /obj/item/reagent_containers/food/snacks/monkeycube, 300), + new /datum/data/mining_equipment("Toolbelt", /obj/item/storage/belt/utility, 350), + new /datum/data/mining_equipment("Royal Cape of the Liberator", /obj/item/bedsheet/rd/royal_cape, 500), + new /datum/data/mining_equipment("Grey Slime Extract", /obj/item/slime_extract/grey, 1000), + new /datum/data/mining_equipment("KA Trigger Modification Kit", /obj/item/borg/upgrade/modkit/trigger_guard, 1700), + new /datum/data/mining_equipment("The Liberator's Legacy", /obj/item/storage/box/rndboards, 2000) + ) /datum/data/mining_equipment/ var/equipment_name = "generic" diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm index 2d4b555448b..cadff45a439 100644 --- a/code/modules/mob/language.dm +++ b/code/modules/mob/language.dm @@ -529,6 +529,13 @@ return TRUE return FALSE +/datum/language/abductor/golem + name = "Golem Mindlink" + desc = "Communicate with other alien alloy golems through a psychic link." + +/datum/language/abductor/golem/check_special_condition(mob/living/carbon/human/other, mob/living/carbon/human/speaker) + return TRUE + /datum/language/corticalborer name = "Cortical Link" desc = "Cortical borers possess a strange link between their tiny minds." diff --git a/code/modules/mob/living/carbon/human/species/golem.dm b/code/modules/mob/living/carbon/human/species/golem.dm index c3fa38611b5..28d8ff7d477 100644 --- a/code/modules/mob/living/carbon/human/species/golem.dm +++ b/code/modules/mob/living/carbon/human/species/golem.dm @@ -2,11 +2,14 @@ name = "Golem" name_plural = "Golems" - icobase = 'icons/mob/human_races/r_golem.dmi' - deform = 'icons/mob/human_races/r_golem.dmi' + icobase = 'icons/mob/human_races/golems/golem.dmi' + deform = 'icons/mob/human_races/golems/golem.dmi' species_traits = list(NO_BREATHE, NO_BLOOD, RADIMMUNE, VIRUSIMMUNE, NOGUNS) - + bodyflags = HAS_SKIN_COLOR + brute_mod = 0.45 //55% damage reduction + burn_mod = 0.45 + tox_mod = 0.45 oxy_mod = 0 dietflags = DIET_OMNI //golems can eat anything because they are magic or something @@ -34,6 +37,9 @@ slowdown = 3 siemens_coeff = 0 + blacklisted = TRUE // To prevent golem subtypes from overwhelming the odds when random species changes, only the Random Golem type can be chosen + dangerous_existence = TRUE + has_organ = list( "brain" = /obj/item/organ/internal/brain/golem ) //Has standard darksight of 2. @@ -42,12 +48,35 @@ "is crumbling into dust!", "is smashing their body apart!") + var/golem_color = "#434B4D" + var/info_text = "As an Iron Golem, you don't have any special traits." + var/random_eligible = TRUE //If false, the golem subtype can't be made through golem mutation toxin + var/prefix = "Iron" + var/list/special_names = list("Tarkus") + var/human_surname_chance = 3 + var/special_name_chance = 5 + var/owner //dobby is a free golem + +/datum/species/golem/random_name() + var/golem_surname = pick(GLOB.golem_names) + // 3% chance that our golem has a human surname, because cultural contamination + if(prob(human_surname_chance)) + golem_surname = pick(GLOB.last_names) + else if(special_names && special_names.len && prob(special_name_chance)) + golem_surname = pick(special_names) + + var/golem_name = "[prefix] [golem_surname]" + return golem_name + /datum/species/golem/on_species_gain(mob/living/carbon/human/H) ..() if(H.mind) H.mind.assigned_role = "Golem" - H.mind.special_role = SPECIAL_ROLE_GOLEM - H.real_name = "adamantine golem ([rand(1, 1000)])" + if(owner) + H.mind.special_role = SPECIAL_ROLE_GOLEM + else + H.mind.special_role = SPECIAL_ROLE_FREE_GOLEM + H.real_name = "[prefix] golem ([rand(1, 1000)])" H.name = H.real_name H.equip_to_slot_or_del(new /obj/item/clothing/under/golem(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/suit/golem(H), slot_wear_suit) @@ -56,10 +85,948 @@ H.equip_to_slot_or_del(new /obj/item/clothing/gloves/golem(H), slot_gloves) -////////Adamantine Golem stuff I dunno where else to put it +//Random Golem + +/datum/species/golem/random + name = "Random Golem" + blacklisted = FALSE + dangerous_existence = FALSE + var/static/list/random_golem_types + +/datum/species/golem/random/on_species_gain(mob/living/carbon/C, datum/species/old_species) + ..() + if(!random_golem_types) + random_golem_types = subtypesof(/datum/species/golem) - type + for(var/V in random_golem_types) + var/datum/species/golem/G = V + if(!initial(G.random_eligible)) + random_golem_types -= G + var/datum/species/golem/golem_type = pick(random_golem_types) + var/mob/living/carbon/human/H = C + H.set_species(golem_type) + to_chat(H, "[initial(golem_type.info_text)]") + + +//Golem subtypes + +//The suicide bombers of golemkind +/datum/species/golem/plasma + name = "Plasma Golem" + skinned_type = /obj/item/stack/ore/plasma + //Can burn and takes damage from heat + heat_level_1 = 360 + heat_level_2 = 400 + heat_level_3 = 460 + info_text = "As a Plasma Golem, you burn easily. Be careful, if you get hot enough while burning, you'll blow up!" + heatmod = 0 //fine until they blow up + prefix = "Plasma" + special_names = list("Flood","Fire","Bar","Man") + var/boom_warning = FALSE + var/datum/action/innate/ignite/ignite + +/datum/species/golem/plasma/handle_life(mob/living/carbon/human/H) + if(H.bodytemperature > 750) + if(!boom_warning && H.on_fire) + to_chat(H, "You feel like you could blow up at any moment!") + boom_warning = TRUE + else + if(boom_warning) + to_chat(H, "You feel more stable.") + boom_warning = FALSE + + if(H.bodytemperature > 850 && H.on_fire && prob(25)) + explosion(get_turf(H), 1, 2, 4, flame_range = 5) + if(H) + H.gib() + if(H.fire_stacks < 2) //flammable + H.adjust_fire_stacks(1) + ..() + +/datum/species/golem/plasma/on_species_gain(mob/living/carbon/C, datum/species/old_species) + ..() + if(ishuman(C)) + ignite = new + ignite.Grant(C) + +/datum/species/golem/plasma/on_species_loss(mob/living/carbon/C) + if(ignite) + ignite.Remove(C) + ..() + +/datum/action/innate/ignite + name = "Ignite" + desc = "Set yourself aflame, bringing yourself closer to exploding!" + check_flags = AB_CHECK_CONSCIOUS + button_icon_state = "sacredflame" + +/datum/action/innate/ignite/Activate() + if(ishuman(owner)) + var/mob/living/carbon/human/H = owner + if(H.fire_stacks) + to_chat(owner, "You ignite yourself!") + else + to_chat(owner, "You try to ignite yourself, but fail!") + H.IgniteMob() //firestacks are already there passively + +//Harder to hurt +/datum/species/golem/diamond + name = "Diamond Golem" + brute_mod = 0.3 //70% damage reduction up from 55% + burn_mod = 0.3 + tox_mod = 0.3 + skinned_type = /obj/item/stack/ore/diamond + info_text = "As a Diamond Golem, you are more resistant than the average golem." + prefix = "Diamond" + special_names = list("Back") + +//Faster but softer and less armoured +/datum/species/golem/gold + name = "Gold Golem" + slowdown = 2 + brute_mod = 0.75 //25% damage reduction down from 55% + burn_mod = 0.75 + tox_mod = 0.75 + skinned_type = /obj/item/stack/ore/gold + info_text = "As a Gold Golem, you are faster but less resistant than the average golem." + prefix = "Golden" + special_names = list("Boy") + +//Heavier, thus higher chance of stunning when punching +/datum/species/golem/silver + name = "Silver Golem" + punchstunthreshold = 9 //60% chance, from 40% + skinned_type = /obj/item/stack/ore/silver + info_text = "As a Silver Golem, your attacks have a higher chance of stunning. Being made of silver, your body is immune to most types of magic." + prefix = "Silver" + special_names = list("Surfer", "Chariot", "Lining") + +//Harder to stun, deals more damage, but it's even slower +/datum/species/golem/plasteel + name = "Plasteel Golem" + stunmod = 0.4 + punchdamagelow = 12 + punchdamagehigh = 21 + punchstunthreshold = 18 //still 40% stun chance + slowdown = 5 //pretty fucking slow + skinned_type = /obj/item/stack/ore/iron + info_text = "As a Plasteel Golem, you are slower, but harder to stun, and hit very hard when punching." + attack_verb = "smash" + attack_sound = 'sound/effects/meteorimpact.ogg' //hits pretty hard + prefix = "Plasteel" + special_names = null + +//More resistant to burn damage +//Add ashstorm resistance if we ever port lavaland +/datum/species/golem/titanium + name = "Titanium Golem" + skinned_type = /obj/item/stack/ore/titanium + info_text = "As a Titanium Golem, you are resistant to burn damage." + burnmod = 0.3 + prefix = "Titanium" + special_names = list("Dioxide") + +//Even more resistant to burn damage +//Add ashstorm and lava resistance if we ever port lavaland +/datum/species/golem/plastitanium + name = "Plastitanium Golem" + skinned_type = /obj/item/stack/ore/titanium + info_text = "As a Plastitanium Golem, you are very resistant to burn damage." + burnmod = 0.15 + prefix = "Plastitanium" + special_names = null + +//Fast and regenerates... but can only speak like an abductor +/datum/species/golem/alloy + name = "Alien Alloy Golem" + skinned_type = /obj/item/stack/sheet/mineral/abductor + language = "Golem Mindlink" + default_language = "Golem Mindlink" + slowdown = 2 //faster + info_text = "As an Alloy Golem, you are made of advanced alien materials: you are faster and regenerate over time. You are, however, only able to speak telepathically to other alloy golems." + prefix = "Alien" + special_names = list("Outsider", "Technology", "Watcher", "Stranger") //ominous and unknown + +//Regenerates because self-repairing super-advanced alien tech +/datum/species/golem/alloy/handle_life(mob/living/carbon/human/H) + if(H.stat == DEAD) + return + H.heal_overall_damage(2, 2, 0, BODYPART_ORGANIC) + H.adjustToxLoss(-2) + H.adjustOxyLoss(-2) + +/datum/species/golem/alloy/can_understand(mob/other) //Can understand everyone, but they can only speak over their mindlink + return TRUE + +/datum/species/golem/alloy/on_species_gain(mob/living/carbon/human/H) + ..() + H.languages.Cut() + H.add_language("Golem Mindlink") + +//Regenerates like dionas, less resistant +/datum/species/golem/wood + name = "Wood Golem" + skinned_type = /obj/item/stack/sheet/mineral/wood + //Can burn and take damage from heat + brute_mod = 0.7 //30% damage reduction down from 55% + burn_mod = 1 + heatmod = 1.5 + + heat_level_1 = 300 + heat_level_2 = 340 + heat_level_3 = 400 + + dietflags = 0 //Regenerate nutrition in light, no diet necessary + taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE + + info_text = "As a Wooden Golem, you have plant-like traits: you take damage from extreme temperatures, can be set on fire, and have lower armor than a normal golem. You regenerate when in the light and wither in the darkness." + prefix = "Wooden" + special_names = list("Bark", "Willow", "Catalpa", "Woody", "Oak", "Sap", "Twig", "Branch", "Maple", "Birch", "Elm", "Basswood", "Cottonwood", "Larch", "Aspen", "Ash", "Beech", "Buckeye", "Cedar", "Chestnut", "Cypress", "Fir", "Hawthorn", "Hazel", "Hickory", "Ironwood", "Juniper", "Leaf", "Mangrove", "Palm", "Pawpaw", "Pine", "Poplar", "Redwood", "Redbud", "Sassafras", "Spruce", "Sumac", "Trunk", "Walnut", "Yew") + human_surname_chance = 0 + special_name_chance = 100 + +/datum/species/golem/wood/handle_life(mob/living/carbon/human/H) + var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing + if(isturf(H.loc)) //else, there's considered to be no light + var/turf/T = H.loc + light_amount = min(T.get_lumcount() * 10, 5) //hardcapped so it's not abused by having a ton of flashlights + H.nutrition = min(H.nutrition+light_amount, NUTRITION_LEVEL_WELL_FED+10) + + if(light_amount > 0) + H.clear_alert("nolight") + else + H.throw_alert("nolight", /obj/screen/alert/nolight) + + if((light_amount >= 5) && !H.suiciding) //if there's enough light, heal + + H.adjustBruteLoss(-(light_amount/2)) + H.adjustFireLoss(-(light_amount/4)) + if(H.nutrition < NUTRITION_LEVEL_STARVING+50) + H.take_overall_damage(10,0) + ..() + +//Radioactive +/datum/species/golem/uranium + name = "Uranium Golem" + skinned_type = /obj/item/stack/ore/uranium + info_text = "As an Uranium Golem, you emit radiation pulses every once in a while. It won't harm fellow golems, but organic lifeforms will be affected." + + var/last_event = 0 + var/active = null + prefix = "Uranium" + special_names = list("Oxide", "Rod", "Meltdown") + +/datum/species/golem/uranium/handle_life(mob/living/carbon/human/H) + if(!active) + if(world.time > last_event+30) + active = 1 + radiation_pulse(H, 50) + last_event = world.time + active = null + ..() + +//Immune to physical bullets and resistant to brute, but very vulnerable to burn damage. Dusts on death. +/datum/species/golem/sand + name = "Sand Golem" + skinned_type = /obj/item/stack/ore/glass //this is sand + brute_mod = 0.25 + burn_mod = 3 + info_text = "As a Sand Golem, you are immune to physical bullets and take very little brute damage, but are extremely vulnerable to burn damage and energy weapons. You will also turn to sand when dying, preventing any form of recovery." + attack_sound = 'sound/effects/shovel_dig.ogg' + prefix = "Sand" + special_names = list("Castle", "Bag", "Dune", "Worm", "Storm") + +/datum/species/golem/sand/handle_death(gibbed, mob/living/carbon/human/H) + H.visible_message("[H] turns into a pile of sand!") + for(var/obj/item/W in H) + H.dropItemToGround(W) + for(var/i=1, i <= rand(3, 5), i++) + new /obj/item/stack/ore/glass(get_turf(H)) + qdel(H) + +/datum/species/golem/sand/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H) + if(!(P.original == H && P.firer == H)) + if(P.flag == "bullet" || P.flag == "bomb") + playsound(H, 'sound/effects/shovel_dig.ogg', 70, 1) + H.visible_message("The [P.name] sinks harmlessly in [H]'s sandy body!", \ + "The [P.name] sinks harmlessly in [H]'s sandy body!") + return BULLET_ACT_BLOCK + return BULLET_ACT_HIT + +//Reflects lasers and resistant to burn damage, but very vulnerable to brute damage. Shatters on death. +/datum/species/golem/glass + name = "Glass Golem" + skinned_type = /obj/item/shard + brutemod = 3 //very fragile + burnmod = 0.25 + info_text = "As a Glass Golem, you reflect lasers and energy weapons, and are very resistant to burn damage. However, you are extremely vulnerable to brute damage. On death, you'll shatter beyond any hope of recovery." + attack_sound = 'sound/effects/glassbr2.ogg' + prefix = "Glass" + special_names = list("Lens", "Prism", "Fiber", "Bead") + +/datum/species/golem/glass/spec_death(gibbed, mob/living/carbon/human/H) + playsound(H, "shatter", 70, 1) + H.visible_message("[H] shatters!") + for(var/obj/item/W in H) + H.dropItemToGround(W) + for(var/i=1, i <= rand(3, 5), i++) + new /obj/item/shard(get_turf(H)) + qdel(H) + +/datum/species/golem/glass/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H) + if(!(P.original == H && P.firer == H)) //self-shots don't reflect + if(P.flag == "laser" || P.flag == "energy") + H.visible_message("The [P.name] gets reflected by [H]'s glass skin!", \ + "The [P.name] gets reflected by [H]'s glass skin!") + if(P.starting) + var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) + var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) + var/turf/target = get_turf(P.starting) + // redirect the projectile + P.preparePixelProjectile(locate(CLAMP(target.x + new_x, 1, world.maxx), CLAMP(target.y + new_y, 1, world.maxy), H.z), H) + return BULLET_ACT_FORCE_PIERCE + return BULLET_ACT_HIT + +//Teleports when hit or when it wants to +/datum/species/golem/bluespace + name = "Bluespace Golem" + skinned_type = /obj/item/stack/ore/bluespace_crystal + info_text = "As a Bluespace Golem, you are spatially unstable: You will teleport when hit, and you can teleport manually at a long distance." + attack_verb = "bluespace punch" + attack_sound = 'sound/effects/phasein.ogg' + prefix = "Bluespace" + special_names = list("Crystal", "Polycrystal") + + var/datum/action/innate/unstable_teleport/unstable_teleport + var/teleport_cooldown = 100 + var/last_teleport = 0 + var/tele_range = 6 + +/datum/species/golem/bluespace/proc/reactive_teleport(mob/living/carbon/human/H) + H.visible_message("[H] teleports!", "You destabilize and teleport!") + var/list/turfs = new/list() + for(var/turf/T in orange(tele_range, H)) + if(istype(T, /turf/space)) + continue + if(T.density) + continue + if(T.x>world.maxx-tele_range || T.x