line endings

This commit is contained in:
silicons
2021-02-21 22:18:05 -07:00
parent c3de692726
commit 8d8ccd3bb7
53 changed files with 12576 additions and 260 deletions

View File

@@ -0,0 +1,290 @@
var/global/list/changeling_fabricated_clothing = list(
"w_uniform" = /obj/item/clothing/under/chameleon/changeling,
"head" = /obj/item/clothing/head/chameleon/changeling,
"wear_suit" = /obj/item/clothing/suit/chameleon/changeling,
"shoes" = /obj/item/clothing/shoes/chameleon/changeling,
"gloves" = /obj/item/clothing/gloves/chameleon/changeling,
"wear_mask" = /obj/item/clothing/mask/chameleon/changeling,
"glasses" = /obj/item/clothing/glasses/chameleon/changeling,
"back" = /obj/item/storage/backpack/chameleon/changeling,
"belt" = /obj/item/storage/belt/chameleon/changeling,
"wear_id" = /obj/item/card/id/syndicate/changeling
)
/datum/power/changeling/fabricate_clothing
name = "Fabricate Clothing"
desc = "We reform our flesh to resemble various cloths, leathers, and other materials, allowing us to quickly create a disguise. \
We cannot be relieved of this clothing by others."
helptext = "The disguise we create offers no defensive ability. Each equipment slot that is empty will be filled with fabricated equipment. \
To remove our new fabricated clothing, use this ability again."
ability_icon_state = "ling_fabricate_clothing"
genomecost = 1
verbpath = /mob/proc/changeling_fabricate_clothing
//Grows biological versions of chameleon clothes.
/mob/proc/changeling_fabricate_clothing()
set category = "Changeling"
set name = "Fabricate Clothing (10)"
if(changeling_generic_equip_all_slots(changeling_fabricated_clothing, cost = 10))
return 1
return 0
/obj/item/clothing/under/chameleon/changeling
name = "malformed flesh"
icon_state = "lingchameleon"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_uniforms.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_uniforms.dmi',
)
item_state = "lingchameleon"
worn_state = "lingchameleon"
desc = "The flesh all around us has grown a new layer of cells that can shift appearance and create a biological fabric that cannot be distinguished from \
ordinary cloth, allowing us to make ourselves appear to wear almost anything."
origin_tech = list() //The base chameleon items have origin technology, which we will inherit if we don't null out this variable.
canremove = 0 //Since this is essentially flesh impersonating clothes, tearing someone's skin off as if it were clothing isn't possible.
/obj/item/clothing/under/chameleon/changeling/emp_act(severity) //As these are purely organic, EMP does nothing to them.
return
/obj/item/clothing/under/chameleon/changeling/verb/shred() //Remove individual pieces if needed.
set name = "Shred Jumpsuit"
set category = "Chameleon Items"
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
playsound(src, 'sound/effects/splat.ogg', 30, 1)
visible_message("<span class='warning'>[H] tears off [src]!</span>",
"<span class='notice'>We remove [src].</span>")
qdel(src)
/obj/item/clothing/head/chameleon/changeling
name = "malformed head"
icon_state = "lingchameleon"
desc = "Our head is swelled with a large quanity of rapidly shifting skin cells. We can reform our head to resemble various hats and \
helmets that biologicals are so fond of wearing."
origin_tech = list()
canremove = 0
/obj/item/clothing/head/chameleon/changeling/emp_act(severity)
return
/obj/item/clothing/head/chameleon/changeling/verb/shred() //The copypasta is real.
set name = "Shred Helmet"
set category = "Chameleon Items"
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
playsound(src, 'sound/effects/splat.ogg', 30, 1)
visible_message("<span class='warning'>[H] tears off [src]!</span>",
"<span class='notice'>We remove [src].</span>")
qdel(src)
/obj/item/clothing/suit/chameleon/changeling
name = "chitinous chest"
icon_state = "lingchameleon"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_suits.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_suits.dmi',
)
item_state = "armor"
desc = "The cells in our chest are rapidly shifting, ready to reform into material that can resemble most pieces of clothing."
origin_tech = list()
canremove = 0
/obj/item/clothing/suit/chameleon/changeling/emp_act(severity)
return
/obj/item/clothing/suit/chameleon/changeling/verb/shred()
set name = "Shred Suit"
set category = "Chameleon Items"
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
playsound(src, 'sound/effects/splat.ogg', 30, 1)
visible_message("<span class='warning'>[H] tears off [src]!</span>",
"<span class='notice'>We remove [src].</span>")
qdel(src)
/obj/item/clothing/shoes/chameleon/changeling
name = "malformed feet"
icon_state = "lingchameleon"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_shoes.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_shoes.dmi',
)
item_state = "black"
desc = "Our feet are overlayed with another layer of flesh and bone on top. We can reform our feet to resemble various boots and shoes."
origin_tech = list()
canremove = 0
/obj/item/clothing/shoes/chameleon/changeling/emp_act()
return
/obj/item/clothing/shoes/chameleon/changeling/verb/shred()
set name = "Shred Shoes"
set category = "Chameleon Items"
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
playsound(src, 'sound/effects/splat.ogg', 30, 1)
visible_message("<span class='warning'>[H] tears off [src]!</span>",
"<span class='notice'>We remove [src].</span>")
qdel(src)
/obj/item/storage/backpack/chameleon/changeling
name = "backpack"
icon_state = "backpack"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_storage.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_storage.dmi',
)
item_state = "backpack"
desc = "A large pouch imbedded in our back, it can shift form to resemble many common backpacks that other biologicals are fond of using."
origin_tech = list()
canremove = 0
/obj/item/storage/backpack/chameleon/changeling/emp_act()
return
/obj/item/storage/backpack/chameleon/changeling/verb/shred()
set name = "Shred Backpack"
set category = "Chameleon Items"
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
playsound(src, 'sound/effects/splat.ogg', 30, 1)
visible_message("<span class='warning'>[H] tears off [src]!</span>",
"<span class='notice'>We remove [src].</span>")
for(var/atom/movable/AM in src.contents) //Dump whatever's in the bag before deleting.
AM.forceMove(get_turf(loc))
qdel(src)
/obj/item/clothing/gloves/chameleon/changeling
name = "malformed hands"
icon_state = "lingchameleon"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_gloves.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_gloves.dmi',
)
item_state = "lingchameleon"
desc = "Our hands have a second layer of flesh on top. We can reform our hands to resemble a large variety of fabrics and materials that biologicals \
tend to wear on their hands. Remember that these won't protect your hands from harm."
origin_tech = list()
canremove = 0
/obj/item/clothing/gloves/chameleon/changeling/emp_act()
return
/obj/item/clothing/gloves/chameleon/changeling/verb/shred()
set name = "Shred Gloves"
set category = "Chameleon Items"
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
playsound(src, 'sound/effects/splat.ogg', 30, 1)
visible_message("<span class='warning'>[H] tears off [src]!</span>",
"<span class='notice'>We remove [src].</span>")
qdel(src)
/obj/item/clothing/mask/chameleon/changeling
name = "chitin visor"
icon_state = "lingchameleon"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_masks.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_masks.dmi',
)
item_state = "gas_alt"
desc = "A transparent visor of brittle chitin covers our face. We can reform it to resemble various masks that biologicals use. It can also utilize internal \
tanks.."
origin_tech = list()
canremove = 0
/obj/item/clothing/mask/chameleon/changeling/emp_act()
return
/obj/item/clothing/mask/chameleon/changeling/verb/shred()
set name = "Shred Mask"
set category = "Chameleon Items"
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
playsound(src, 'sound/effects/splat.ogg', 30, 1)
visible_message("<span class='warning'>[H] tears off [src]!</span>",
"<span class='notice'>We remove [src].</span>")
qdel(src)
/obj/item/clothing/glasses/chameleon/changeling
name = "chitin goggles"
icon_state = "lingchameleon"
item_state = "glasses"
desc = "A transparent piece of eyewear made out of brittle chitin. We can reform it to resemble various glasses and goggles."
origin_tech = list()
canremove = 0
/obj/item/clothing/glasses/chameleon/changeling/emp_act()
return
/obj/item/clothing/glasses/chameleon/changeling/verb/shred()
set name = "Shred Glasses"
set category = "Chameleon Items"
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
playsound(src, 'sound/effects/splat.ogg', 30, 1)
visible_message("<span class='warning'>[H] tears off [src]!</span>",
"<span class='notice'>We remove [src].</span>")
qdel(src)
/obj/item/storage/belt/chameleon/changeling
name = "waist pouch"
desc = "We can store objects in this, as well as shift it's appearance, so that it resembles various common belts."
icon_state = "lingchameleon"
item_icons = list(
slot_l_hand_str = 'icons/mob/items/lefthand_storage.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_storage.dmi',
)
item_state = "utility"
origin_tech = list()
canremove = 0
/obj/item/storage/belt/chameleon/changeling/emp_act()
return
/obj/item/storage/belt/chameleon/changeling/verb/shred()
set name = "Shred Belt"
set category = "Chameleon Items"
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
playsound(src, 'sound/effects/splat.ogg', 30, 1)
visible_message("<span class='warning'>[H] tears off [src]!</span>",
"<span class='notice'>We remove [src].</span>")
qdel(src)
/obj/item/card/id/syndicate/changeling
name = "chitinous card"
desc = "A card that we can reform to resemble identification cards. Due to the nature of the material this is made of, it cannot store any access codes."
icon_state = "changeling"
assignment = "Harvester"
origin_tech = list()
electronic_warfare = 1 //The lack of RFID stuff makes it hard for AIs to track, I guess. *handwaves*
registered_user = null
access = null
canremove = 0
/obj/item/card/id/syndicate/changeling/New(mob/user as mob)
..()
registered_user = user
/obj/item/card/id/syndicate/changeling/Initialize(mapload)
. = ..()
access = null
/obj/item/card/id/syndicate/changeling/verb/shred()
set name = "Shred ID Card"
set category = "Chameleon Items"
if(ishuman(loc))
var/mob/living/carbon/human/H = loc
playsound(src, 'sound/effects/splat.ogg', 30, 1)
visible_message("<span class='warning'>[H] tears off [src]!</span>",
"<span class='notice'>We remove [src].</span>")
qdel(src)
/obj/item/card/id/syndicate/changeling/Click() //Since we can't hold it in our hands, and attack_hand() doesn't work if it in inventory...
if(!registered_user)
registered_user = usr
usr.set_id_info(src)
ui_interact(registered_user)
..()

View File

@@ -0,0 +1,133 @@
/obj/mecha/medical/odysseus/
desc = "These exosuits are developed and produced by Vey-Med. (&copy; All rights reserved)."
name = "Odysseus"
catalogue_data = list(
/datum/category_item/catalogue/technology/odysseus,
/datum/category_item/catalogue/information/organization/vey_med
)
icon_state = "odysseus"
initial_icon = "odysseus"
step_in = 2
max_temperature = 15000
health = 120
maxhealth = 120
wreckage = /obj/effect/decal/mecha_wreckage/odysseus
internal_damage_threshold = 35
deflect_chance = 15
step_energy_drain = 6
var/obj/item/clothing/glasses/hud/health/mech/hud
/obj/mecha/medical/odysseus/New()
..()
hud = new /obj/item/clothing/glasses/hud/health/mech(src)
return
/obj/mecha/medical/odysseus/moved_inside(var/mob/living/carbon/human/H as mob)
if(..())
if(H.glasses)
occupant_message("<font color='red'>[H.glasses] prevent you from using [src] [hud]</font>")
else
H.glasses = hud
H.recalculate_vis()
return 1
else
return 0
/obj/mecha/medical/odysseus/go_out()
if(ishuman(occupant))
var/mob/living/carbon/human/H = occupant
if(H.glasses == hud)
H.glasses = null
H.recalculate_vis()
..()
return
/*
verb/set_perspective()
set name = "Set client perspective."
set category = "Exosuit Interface"
set src = usr.loc
var/perspective = input("Select a perspective type.",
"Client perspective",
occupant.client.perspective) in list(MOB_PERSPECTIVE,EYE_PERSPECTIVE)
to_chat(world, "[perspective]")
occupant.client.perspective = perspective
return
verb/toggle_eye()
set name = "Toggle eye."
set category = "Exosuit Interface"
set src = usr.loc
if(occupant.client.eye == occupant)
occupant.client.eye = src
else
occupant.client.eye = occupant
to_chat(world, "[occupant.client.eye]")
return
*/
//TODO - Check documentation for client.eye and client.perspective...
/obj/item/clothing/glasses/hud/health/mech
name = "Integrated Medical Hud"
// process_hud(var/mob/M) //TODO VIS
/*
to_chat(world, "view(M)")
for(var/mob/mob in view(M))
to_chat(world, "[mob]")
to_chat(world, "view(M.client)")
for(var/mob/mob in view(M.client))
to_chat(world, "[mob]")
to_chat(world, "view(M.loc)")
for(var/mob/mob in view(M.loc))
to_chat(world, "[mob]")
if(!M || M.stat || !(M in view(M))) return
if(!M.client) return
var/client/C = M.client
var/image/holder
for(var/mob/living/carbon/human/patient in view(M.loc))
if(M.see_invisible < patient.invisibility)
continue
var/foundVirus = 0
for (var/ID in patient.virus2)
if (ID in virusDB)
foundVirus = 1
break
holder = patient.hud_list[HEALTH_HUD]
if(patient.stat == DEAD)
holder.icon_state = "hudhealth-100"
C.images += holder
else
holder.icon_state = RoundHealth((patient.health-config_legacy.health_threshold_crit)/(patient.getMaxHealth()-config_legacy.health_threshold_crit)*100)
C.images += holder
holder = patient.hud_list[STATUS_HUD]
if(patient.isSynthetic())
holder.icon_state = "hudrobo"
else if(patient.stat == DEAD)
holder.icon_state = "huddead"
else if(foundVirus)
holder.icon_state = "hudill"
else if(patient.has_brain_worms())
var/mob/living/simple_mob/animal/borer/B = patient.has_brain_worms()
if(B.controlling)
holder.icon_state = "hudbrainworm"
else
holder.icon_state = "hudhealthy"
else
holder.icon_state = "hudhealthy"
C.images += holder
*/
/obj/mecha/medical/odysseus/loaded/Initialize(mapload)
..()
var/obj/item/mecha_parts/mecha_equipment/ME = new /obj/item/mecha_parts/mecha_equipment/tool/sleeper
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/tool/sleeper
ME.attach(src)
ME = new /obj/item/mecha_parts/mecha_equipment/tool/syringe_gun
ME.attach(src)

View File

@@ -0,0 +1,72 @@
// These are objects you can use inside special maps (like PoIs), or for adminbuse.
// Players cannot see or interact with these.
/obj/effect/map_effect
anchored = TRUE
invisibility = 99 // So a badmin can go view these by changing their see_invisible.
icon = 'icons/effects/map_effects.dmi'
// Below vars concern check_for_player_proximity() and is used to not waste effort if nobody is around to appreciate the effects.
var/always_run = FALSE // If true, the game will not try to suppress this from firing if nobody is around to see it.
var/proximity_needed = 12 // How many tiles a mob with a client must be for this to run.
var/ignore_ghosts = FALSE // If true, ghosts won't satisfy the above requirement.
var/ignore_afk = TRUE // If true, AFK people (5 minutes) won't satisfy it as well.
var/retry_delay = 3 SECONDS // How long until we check for players again.
/obj/effect/map_effect/ex_act()
return
/obj/effect/map_effect/singularity_pull()
return
/obj/effect/map_effect/singularity_act()
return
// Base type for effects that run on variable intervals.
/obj/effect/map_effect/interval
var/interval_lower_bound = 5 SECONDS // Lower number for how often the map_effect will trigger.
var/interval_upper_bound = 5 SECONDS // Higher number for above.
var/halt = FALSE // Set to true to stop the loop when it reaches the next iteration.
/obj/effect/map_effect/interval/Initialize(mapload)
handle_interval_delay()
return ..()
/obj/effect/map_effect/interval/Destroy()
halt = TRUE // Shouldn't need it to GC but just in case.
return ..()
// Override this for the specific thing to do. Be sure to call parent to keep looping.
/obj/effect/map_effect/interval/proc/trigger()
handle_interval_delay()
// Handles the delay and making sure it doesn't run when it would be bad.
/obj/effect/map_effect/interval/proc/handle_interval_delay()
// Check to see if we're useful first.
if(halt)
return // Do not pass .(), do not recursively collect 200 thaler.
if(!always_run && !check_for_player_proximity(src, proximity_needed, ignore_ghosts, ignore_afk))
spawn(retry_delay) // Maybe someday we'll have fancy TG timers/schedulers.
if(!QDELETED(src))
.()
return
var/next_interval = rand(interval_lower_bound, interval_upper_bound)
spawn(next_interval)
if(!QDELETED(src))
trigger()
// Helper proc to optimize the use of effects by making sure they do not run if nobody is around to perceive it.
/proc/check_for_player_proximity(var/atom/proximity_to, var/radius = 12, var/ignore_ghosts = FALSE, var/ignore_afk = TRUE)
if(!proximity_to)
return FALSE
for(var/thing in player_list)
var/mob/M = thing // Avoiding typechecks for more speed, player_list will only contain mobs anyways.
if(ignore_ghosts && isobserver(M))
continue
if(ignore_afk && M.client && M.client.is_afk(5 MINUTES))
continue
if(M.z == proximity_to.z && get_dist(M, proximity_to) <= radius)
return TRUE
return FALSE

View File

@@ -0,0 +1,66 @@
//The effect when you wrap a dead body in gift wrap
/obj/effect/spresent
name = "strange present"
desc = "It's a ... present?"
icon = 'icons/obj/items.dmi'
icon_state = "strangepresent"
density = 1
anchored = 0
// this is banned, use temporary-visual - kevinz000
/obj/effect/temporary_effect
name = "self deleting effect"
desc = "How are you examining what which cannot be seen?"
icon = 'icons/effects/effects.dmi'
invisibility = 0
var/time_to_die = 10 SECONDS // Afer which, it will delete itself.
/obj/effect/temporary_effect/Initialize(mapload)
. = ..()
if(time_to_die)
QDEL_IN(src, time_to_die)
// Shown really briefly when attacking with axes.
/obj/effect/temporary_effect/cleave_attack
name = "cleaving attack"
desc = "Something swinging really wide."
icon = 'icons/effects/96x96.dmi'
icon_state = "cleave"
plane = MOB_PLANE
layer = ABOVE_MOB_LAYER
time_to_die = 6
alpha = 140
mouse_opacity = 0
pixel_x = -32
pixel_y = -32
/obj/effect/temporary_effect/cleave_attack/Initialize(mapload) // Makes the slash fade smoothly. When completely transparent it should qdel itself.
. = ..()
animate(src, alpha = 0, time = time_to_die - 1)
/obj/effect/temporary_effect/shuttle_landing
name = "shuttle landing"
desc = "You better move if you don't want to go splat!"
icon_state = "shuttle_warning_still"
time_to_die = 4.9 SECONDS
/obj/effect/temporary_effect/shuttle_landing/Initialize(mapload)
flick("shuttle_warning", src) // flick() forces the animation to always begin at the start.
. = ..()
// The manifestation of Zeus's might. Or just a really unlucky day.
// This is purely a visual effect, this isn't the part of the code that hurts things.
/obj/effect/temporary_effect/lightning_strike
name = "lightning"
desc = "How <i>shocked</i> you must be, to see this text. You must have <i>lightning</i> reflexes. \
The humor in this description is just so <i>electrifying</i>."
icon = 'icons/effects/96x256.dmi'
icon_state = "lightning_strike"
plane = PLANE_LIGHTING_ABOVE
time_to_die = 1 SECOND
pixel_x = -32
/obj/effect/temporary_effect/lightning_strike/Initialize(mapload)
icon_state += "[rand(1,2)]" // To have two variants of lightning sprites.
animate(src, alpha = 0, time = time_to_die - 1)
. = ..()

View File

@@ -0,0 +1,225 @@
/obj/item/card/id/syndicate
name = "agent card"
icon_state = "generic-s"
assignment = "Agent"
origin_tech = list(TECH_ILLEGAL = 3)
var/electronic_warfare = 1
var/mob/registered_user = null
/obj/item/card/id/syndicate/Initialize(mapload)
. = ..()
access = syndicate_access.Copy()
/obj/item/card/id/syndicate/station_access/Initialize(mapload)
. = ..() // Same as the normal Syndicate id, only already has all station access
access |= get_all_station_access()
/obj/item/card/id/syndicate/Destroy()
unset_registered_user(registered_user)
return ..()
/obj/item/card/id/syndicate/prevent_tracking()
return electronic_warfare
/obj/item/card/id/syndicate/afterattack(var/obj/item/O as obj, mob/user as mob, proximity)
if(!proximity) return
if(istype(O, /obj/item/card/id))
var/obj/item/card/id/I = O
src.access |= I.access
if(player_is_antag(user.mind))
to_chat(user, "<span class='notice'>The microscanner activates as you pass it over the ID, copying its access.</span>")
/obj/item/card/id/syndicate/attack_self(mob/user as mob)
// We use the fact that registered_name is not unset should the owner be vaporized, to ensure the id doesn't magically become unlocked.
if(!registered_user && register_user(user))
to_chat(user, "<span class='notice'>The microscanner marks you as its owner, preventing others from accessing its internals.</span>")
if(registered_user == user)
switch(alert("Would you like edit the ID, or show it?","Show or Edit?", "Edit","Show"))
if("Edit")
ui_interact(user)
if("Show")
..()
else
..()
/obj/item/card/id/syndicate/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
var/data[0]
var/entries[0]
entries[++entries.len] = list("name" = "Age", "value" = age)
entries[++entries.len] = list("name" = "Appearance", "value" = "Set")
entries[++entries.len] = list("name" = "Assignment", "value" = assignment)
entries[++entries.len] = list("name" = "Blood Type", "value" = blood_type)
entries[++entries.len] = list("name" = "DNA Hash", "value" = dna_hash)
entries[++entries.len] = list("name" = "Fingerprint Hash", "value" = fingerprint_hash)
entries[++entries.len] = list("name" = "Name", "value" = registered_name)
entries[++entries.len] = list("name" = "Photo", "value" = "Update")
entries[++entries.len] = list("name" = "Sex", "value" = sex)
entries[++entries.len] = list("name" = "Factory Reset", "value" = "Use With Care")
data["electronic_warfare"] = electronic_warfare
data["entries"] = entries
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "agent_id_card.tmpl", "Fake ID", 600, 400)
ui.set_initial_data(data)
ui.open()
/obj/item/card/id/syndicate/proc/register_user(var/mob/user)
if(!istype(user) || user == registered_user)
return FALSE
unset_registered_user()
registered_user = user
user.set_id_info(src)
user.register(OBSERVER_EVENT_DESTROY, src, /obj/item/card/id/syndicate/proc/unset_registered_user)
return TRUE
/obj/item/card/id/syndicate/proc/unset_registered_user(var/mob/user)
if(!registered_user || (user && user != registered_user))
return
registered_user.unregister(OBSERVER_EVENT_DESTROY, src)
registered_user = null
/obj/item/card/id/syndicate/CanUseTopic(mob/user)
if(user != registered_user)
return STATUS_CLOSE
return ..()
/obj/item/card/id/syndicate/Topic(href, href_list, var/datum/topic_state/state)
if(..())
return 1
var/user = usr
if(href_list["electronic_warfare"])
electronic_warfare = text2num(href_list["electronic_warfare"])
to_chat(user, "<span class='notice'>Electronic warfare [electronic_warfare ? "enabled" : "disabled"].</span>")
else if(href_list["set"])
switch(href_list["set"])
if("Age")
var/new_age = input(user,"What age would you like to put on this card?","Agent Card Age", age) as null|num
if(!isnull(new_age) && CanUseTopic(user, state))
if(new_age < 0)
age = initial(age)
else
age = new_age
to_chat(user, "<span class='notice'>Age has been set to '[age]'.</span>")
. = 1
if("Appearance")
var/datum/card_state/choice = input(user, "Select the appearance for this card.", "Agent Card Appearance") as null|anything in id_card_states()
if(choice && CanUseTopic(user, state))
src.icon_state = choice.icon_state
src.item_state = choice.item_state
src.sprite_stack = choice.sprite_stack
update_icon()
to_chat(usr, "<span class='notice'>Appearance changed to [choice].</span>")
. = 1
if("Assignment")
var/new_job = sanitize(input(user,"What assignment would you like to put on this card?\nChanging assignment will not grant or remove any access levels.","Agent Card Assignment", assignment) as null|text)
if(!isnull(new_job) && CanUseTopic(user, state))
src.assignment = new_job
to_chat(user, "<span class='notice'>Occupation changed to '[new_job]'.</span>")
update_name()
. = 1
if("Blood Type")
var/default = blood_type
if(default == initial(blood_type) && ishuman(user))
var/mob/living/carbon/human/H = user
if(H.dna)
default = H.dna.b_type
var/new_blood_type = sanitize(input(user,"What blood type would you like to be written on this card?","Agent Card Blood Type",default) as null|text)
if(!isnull(new_blood_type) && CanUseTopic(user, state))
src.blood_type = new_blood_type
to_chat(user, "<span class='notice'>Blood type changed to '[new_blood_type]'.</span>")
. = 1
if("DNA Hash")
var/default = dna_hash
if(default == initial(dna_hash) && ishuman(user))
var/mob/living/carbon/human/H = user
if(H.dna)
default = H.dna.unique_enzymes
var/new_dna_hash = sanitize(input(user,"What DNA hash would you like to be written on this card?","Agent Card DNA Hash",default) as null|text)
if(!isnull(new_dna_hash) && CanUseTopic(user, state))
src.dna_hash = new_dna_hash
to_chat(user, "<span class='notice'>DNA hash changed to '[new_dna_hash]'.</span>")
. = 1
if("Fingerprint Hash")
var/default = fingerprint_hash
if(default == initial(fingerprint_hash) && ishuman(user))
var/mob/living/carbon/human/H = user
if(H.dna)
default = md5(H.dna.uni_identity)
var/new_fingerprint_hash = sanitize(input(user,"What fingerprint hash would you like to be written on this card?","Agent Card Fingerprint Hash",default) as null|text)
if(!isnull(new_fingerprint_hash) && CanUseTopic(user, state))
src.fingerprint_hash = new_fingerprint_hash
to_chat(user, "<span class='notice'>Fingerprint hash changed to '[new_fingerprint_hash]'.</span>")
. = 1
if("Name")
var/new_name = sanitizeName(input(user,"What name would you like to put on this card?","Agent Card Name", registered_name) as null|text)
if(!isnull(new_name) && CanUseTopic(user, state))
src.registered_name = new_name
update_name()
to_chat(user, "<span class='notice'>Name changed to '[new_name]'.</span>")
. = 1
if("Photo")
set_id_photo(user)
to_chat(user, "<span class='notice'>Photo changed.</span>")
. = 1
if("Sex")
var/new_sex = sanitize(input(user,"What sex would you like to put on this card?","Agent Card Sex", sex) as null|text)
if(!isnull(new_sex) && CanUseTopic(user, state))
src.sex = new_sex
to_chat(user, "<span class='notice'>Sex changed to '[new_sex]'.</span>")
. = 1
if("Factory Reset")
if(alert("This will factory reset the card, including access and owner. Continue?", "Factory Reset", "No", "Yes") == "Yes" && CanUseTopic(user, state))
age = initial(age)
access = syndicate_access.Copy()
assignment = initial(assignment)
blood_type = initial(blood_type)
dna_hash = initial(dna_hash)
electronic_warfare = initial(electronic_warfare)
fingerprint_hash = initial(fingerprint_hash)
icon_state = initial(icon_state)
sprite_stack = list("")
update_icon()
name = initial(name)
registered_name = initial(registered_name)
unset_registered_user()
sex = initial(sex)
to_chat(user, "<span class='notice'>All information has been deleted from \the [src].</span>")
. = 1
// Always update the UI, or buttons will spin indefinitely
SSnanoui.update_uis(src)
/var/global/list/id_card_states
/proc/id_card_states()
if(!id_card_states)
id_card_states = list()
for(var/path in typesof(/obj/item/card/id))
var/obj/item/card/id/ID = new path()
var/datum/card_state/CS = new()
CS.icon_state = initial(ID.icon_state)
CS.item_state = initial(ID.item_state)
CS.sprite_stack = ID.initial_sprite_stack
CS.name = initial(ID.name)
id_card_states += CS
id_card_states = dd_sortedObjectList(id_card_states)
return id_card_states
/datum/card_state
var/name
var/icon_state
var/item_state
var/sprite_stack
/datum/card_state/dd_SortValue()
return name
/obj/item/card/id/syndicate_command
name = "syndicate ID card"
desc = "An ID straight from the Syndicate."
registered_name = "Syndicate"
assignment = "Syndicate Overlord"
icon_state = "syndicate-id"
access = list(access_syndicate, access_external_airlocks)

View File

@@ -0,0 +1,77 @@
//This is in the material folder because it's used by them...
//Actual name may need to change
//All of the important code is in material_weapons.dm
/obj/item/whetstone
name = "whetstone"
desc = "A simple, fine grit stone, useful for sharpening dull edges and polishing out dents."
icon = 'icons/obj/weapons.dmi'
icon_state = "whetstone"
force = 3
w_class = ITEMSIZE_SMALL
var/repair_amount = 5
var/repair_time = 40
/obj/item/whetstone/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/stack/material))
var/obj/item/stack/material/M = I
if(M.amount >= 5)
to_chat(user, "You begin to refine the [src] with [M]...")
if(do_after(user, 70))
M.use(5)
var/obj/item/SK
SK = new /obj/item/material/sharpeningkit(get_turf(user), M.material.name)
to_chat(user, "You sharpen and refine the [src] into \a [SK].")
qdel(src)
if(SK)
user.put_in_hands(SK)
else
to_chat(user, "You need 5 [src] to refine it into a sharpening kit.")
/obj/item/material/sharpeningkit
name = "sharpening kit"
desc = "A refined, fine grit whetstone, useful for sharpening dull edges, polishing out dents, and, with extra material, replacing an edge."
icon = 'icons/obj/kitchen.dmi'
icon_state = "sharpener"
hitsound = 'sound/weapons/genhit3.ogg'
force_divisor = 0.7
thrown_force_divisor = 1
var/repair_amount = 5
var/repair_time = 40
var/sharpen_time = 100
var/uses = 0
/obj/item/material/sharpeningkit/examine(mob/user, distance)
. = ..()
to_chat(user, "There [uses == 1 ? "is" : "are"] [uses] [material] [uses == 1 ? src.material.sheet_singular_name : src.material.sheet_plural_name] left for use.")
/obj/item/material/sharpeningkit/Initialize(mapload)
. = ..()
setrepair()
/obj/item/material/sharpeningkit/proc/setrepair()
repair_amount = material.hardness * 0.1
repair_time = material.weight * 0.5
sharpen_time = material.weight * 3
/obj/item/material/sharpeningkit/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/stack/material))
var/obj/item/stack/material/S = W
if(S.material == material)
S.use(1)
uses += 1
to_chat(user, "You add a [S.material.name] [S.material.sheet_singular_name] to [src].")
return
if(istype(W, /obj/item/material))
if(istype(W, /obj/item/material/sharpeningkit))
to_chat(user, "Really? Sharpening a [W] with [src]? You goofball.")
return
var/obj/item/material/M = W
if(uses >= M.w_class*2)
if(M.sharpen(src.material.name, sharpen_time, src, user))
uses -= M.w_class*2
return
else
to_chat(user, "Not enough material to sharpen [M]. You need [M.w_class*2] [M.material.sheet_plural_name].")
return
else
to_chat(user, "You can't sharpen [W] with [src]!")

View File

@@ -0,0 +1,383 @@
////////////////////////////////////
//Mob spawner structure. This one is an on map structure that players can see, sometimes break.
////////////////////////////////////
/obj/structure/mob_spawner
name = "mob spawner"
desc = "This shouldn't be seen, yell at a dev."
icon = 'icons/effects/effects.dmi'
icon_state = "rift"
anchored = 1
var/last_spawn = 0
var/spawn_delay = 10 MINUTES
var/list/spawn_types = list(
/mob/living/simple_mob/animal/passive/dog/corgi = 100,
/mob/living/simple_mob/animal/passive/cat = 25
)
var/total_spawns = -1 //Total mob spawns, over all time, -1 for no limit
var/simultaneous_spawns = 3 //Max spawned mobs active at one time
var/mob_faction
var/destructible = 0
var/health = 50
var/list/spawned_mobs = list()
/obj/structure/mob_spawner/New()
..()
START_PROCESSING(SSobj, src)
last_spawn = world.time + rand(0,spawn_delay)
/obj/structure/mob_spawner/Destroy()
STOP_PROCESSING(SSobj, src)
for(var/mob/living/L in spawned_mobs)
L.source_spawner = null
spawned_mobs.Cut()
return ..()
/obj/structure/mob_spawner/process()
if(!can_spawn())
return
var/chosen_mob = choose_spawn()
if(chosen_mob)
do_spawn(chosen_mob)
/obj/structure/mob_spawner/proc/can_spawn()
if(!total_spawns)
return 0
if(spawned_mobs.len >= simultaneous_spawns)
return 0
if(world.time < last_spawn + spawn_delay)
return 0
return 1
/obj/structure/mob_spawner/proc/choose_spawn()
return pickweight(spawn_types)
/obj/structure/mob_spawner/proc/do_spawn(var/mob_path)
if(!ispath(mob_path))
return 0
var/mob/living/L = new mob_path(get_turf(src))
L.source_spawner = src
spawned_mobs.Add(L)
last_spawn = world.time
if(total_spawns > 0)
total_spawns--
if(mob_faction)
L.faction = mob_faction
return L
/obj/structure/mob_spawner/proc/get_death_report(var/mob/living/L)
if(L in spawned_mobs)
spawned_mobs.Remove(L)
/obj/structure/mob_spawner/attackby(var/obj/item/I, var/mob/living/user)
if(!I.force || I.flags & NOBLUDGEON || !destructible)
return
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
user.do_attack_animation(src)
visible_message("<span class='warning'>\The [src] has been [I.attack_verb.len ? "[pick(I.attack_verb)]":"attacked"] with \the [I] by [user].</span>")
take_damage(I.force)
/obj/structure/mob_spawner/bullet_act(var/obj/item/projectile/Proj)
..()
if(destructible)
take_damage(Proj.get_structure_damage())
/obj/structure/mob_spawner/take_damage(var/damage)
health -= damage
if(health <= 0)
visible_message("<span class='warning'>\The [src] breaks apart!</span>")
qdel(src)
/obj/structure/mob_spawner/clear_zlevel/can_spawn()
if(!..())
return 0
var/turf/T = get_turf(src)
if(!T)
return 0
for(var/mob/living/L in player_list)
var/turf/L_T
if(L.stat == DEAD)
continue
L_T = get_turf(L)
if(T.z == L_T.z)
return 0
return 1
/*
This code is based on the mob spawner and the proximity sensor, the idea is to lazy load mobs to avoid having the server use mobs when they arent needed.
It also makes it so a ghost wont know where all the goodies/mobs are.
*/
/obj/structure/mob_spawner/scanner
name ="Lazy Mob Spawner"
var/range = 10 //range in tiles from the spawner to detect moving stuff
/obj/structure/mob_spawner/scanner/process()
if(!can_spawn())
return
if(world.time > last_spawn + spawn_delay)
var/turf/mainloc = get_turf(src)
for(var/mob/living/A in range(range,mainloc))
if ((A.faction != mob_faction) && (A.move_speed < 12))
var/chosen_mob = choose_spawn()
if(chosen_mob)
do_spawn(chosen_mob)
//////////////
// Spawners //
/////////////
/obj/structure/mob_spawner/scanner/corgi
name = "Corgi Lazy Spawner"
desc = "This is a proof of concept, not sure why you would use this one"
spawn_delay = 3 MINUTES
mob_faction = "Corgi"
spawn_types = list(
/mob/living/simple_mob/animal/passive/dog/corgi = 75,
/mob/living/simple_mob/animal/passive/dog/corgi/puppy = 50
)
simultaneous_spawns = 5
range = 7
destructible = 1
health = 200
total_spawns = 100
/obj/structure/mob_spawner/scanner/wild_animals
name = "Wilderness Lazy Spawner"
spawn_delay = 10 MINUTES
range = 10
simultaneous_spawns = 1
mob_faction = "wild animal"
total_spawns = -1
destructible = 0
anchored = 1
invisibility = 101
spawn_types = list(
/mob/living/simple_mob/animal/passive/gaslamp = 20,
// /mob/living/simple_mob/otie/feral = 10,
/mob/living/simple_mob/vore/aggressive/dino/virgo3b = 5,
/mob/living/simple_mob/vore/aggressive/dragon/virgo3b = 1
)
/obj/structure/mob_spawner/scanner/xenos
name = "Xenomorph Egg"
spawn_delay = 10 MINUTES
range = 10
simultaneous_spawns = 1
mob_faction = "xeno"
total_spawns = -1
destructible = 1
health = 50
anchored = 1
icon = 'icons/mob/actions.dmi'
icon_state = "alien_egg"
spawn_types = list(
/mob/living/simple_mob/animal/space/alien/drone = 20,
/mob/living/simple_mob/animal/space/alien = 10,
/mob/living/simple_mob/animal/space/alien/sentinel = 5,
/mob/living/simple_mob/animal/space/alien/queen = 1
)
/obj/structure/mob_spawner/scanner/xenos/royal
name = "Royal Xenomorph Egg"
spawn_delay = 10 MINUTES
range = 10
simultaneous_spawns = 1
mob_faction = "xeno"
total_spawns = 1
destructible = 1
health = 50
anchored = 1
icon = 'icons/mob/actions.dmi'
icon_state = "alien_egg"
spawn_types = list(
/mob/living/simple_mob/animal/space/alien/queen = 5
)
////////////////////////////////////
//Invisible mob spawner. This one spawns mobs until depleted. Often used in caves.
////////////////////////////////////
/obj/mob_spawner
name = "RENAME ME, JERK"
desc = "Spawns the mobs!"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
invisibility = 101
mouse_opacity = 0
density = 0
anchored = 1
//Weighted with values (not %chance, but relative weight)
//Can be left value-less for all equally likely
var/list/mobs_to_pick_from
//When the below chance fails, the spawner is marked as depleted and stops spawning
var/prob_spawn = 100 //Chance of spawning a mob whenever they don't have one
var/prob_fall = 5 //Above decreases by this much each time one spawns
//Settings to help mappers/coders have their mobs do what they want in this case
var/faction //To prevent infighting if it spawns various mobs, set a faction
var/atmos_comp //TRUE will set all their survivability to be within 20% of the current air
//var/guard //# will set the mobs to remain nearby their spawn point within this dist
//Internal use only
var/mob/living/simple_mob/my_mob
var/depleted = FALSE
/obj/mob_spawner/Initialize(mapload)
. = ..()
if(!LAZYLEN(mobs_to_pick_from))
log_world("Mob spawner at [x],[y],[z] ([get_area(src)]) had no mobs_to_pick_from set on it!")
return INITIALIZE_HINT_QDEL
START_PROCESSING(SSobj, src)
/obj/mob_spawner/process()
if(my_mob && my_mob.stat != DEAD)
return //No need
if(LAZYLEN(loc.human_mobs(world.view)))
return //I'll wait.
if(prob(prob_spawn))
prob_spawn -= prob_fall
var/picked_type = pickweight(mobs_to_pick_from)
my_mob = new picked_type(get_turf(src))
my_mob.low_priority = TRUE
if(faction)
my_mob.faction = faction
if(atmos_comp)
var/turf/T = get_turf(src)
var/datum/gas_mixture/env = T.return_air()
if(env)
my_mob.minbodytemp = env.temperature * 0.8
my_mob.maxbodytemp = env.temperature * 1.2
var/list/gaslist = env.gas
my_mob.min_oxy = gaslist[/datum/gas/oxygen] * 0.8
my_mob.min_tox = gaslist[/datum/gas/phoron] * 0.8
my_mob.min_n2 = gaslist[/datum/gas/nitrogen] * 0.8
my_mob.min_co2 = gaslist[/datum/gas/carbon_dioxide] * 0.8
my_mob.max_oxy = gaslist[/datum/gas/oxygen] * 1.2
my_mob.max_tox = gaslist[/datum/gas/phoron] * 1.2
my_mob.max_n2 = gaslist[/datum/gas/nitrogen] * 1.2
my_mob.max_co2 = gaslist[/datum/gas/carbon_dioxide] * 1.2
return
else
STOP_PROCESSING(SSobj, src)
depleted = TRUE
return
/obj/mob_spawner/carp
name = "Carp Spawner"
prob_fall = 15
mobs_to_pick_from = list(
/mob/living/simple_mob/animal/space/carp = 3,
/mob/living/simple_mob/animal/space/carp/large = 1
)
/obj/mob_spawner/carp/small
prob_fall = 30
mobs_to_pick_from = list(
/mob/living/simple_mob/animal/space/carp = 3,
/mob/living/simple_mob/animal/space/carp/large = 1,
)
/obj/mob_spawner/carp/hard
mobs_to_pick_from = list(
/mob/living/simple_mob/animal/space/carp/large = 2,
/mob/living/simple_mob/animal/space/carp/large/huge = 1
)
/obj/mob_spawner/carp/medium
prob_fall = 10
mobs_to_pick_from = list(
/mob/living/simple_mob/animal/space/carp = 5,
/mob/living/simple_mob/animal/space/carp/large = 2
)
/obj/mob_spawner/carp/large
name = "Carp Horde Spawner"
prob_fall = 10
mobs_to_pick_from = list(
/mob/living/simple_mob/animal/space/carp = 8,
/mob/living/simple_mob/animal/space/carp/large = 3,
/mob/living/simple_mob/animal/space/carp/large/huge = 1
)
/obj/mob_spawner/derelict
name = "Derelict random mob spawner"
faction = "derelict"
mobs_to_pick_from = list(
/mob/living/simple_mob/mechanical/corrupt_maint_drone = 2,
/mob/living/simple_mob/mechanical/infectionbot = 3,
/mob/living/simple_mob/mechanical/combat_drone = 1
)
/obj/mob_spawner/derelict/corrupt_maint_swarm
name = "Derelict maint swarm"
faction = "derelict"
mobs_to_pick_from = list(
/mob/living/simple_mob/mechanical/corrupt_maint_drone = 4
)
/obj/mob_spawner/derelict/mech_wizard
name = "Derelict wizard"
faction = "derelict"
mobs_to_pick_from = list(
/mob/living/simple_mob/mechanical/technomancer_golem = 2
)
/obj/mob_spawner/hound_spawner
name = "Corrupt Hound Spawner"
prob_fall = 50
mobs_to_pick_from = list(
/mob/living/simple_mob/vore/aggressive/corrupthound = 1
)
/obj/mob_spawner/drone_spawner
name = "Drone Swarm Spawner"
prob_fall = 10
mobs_to_pick_from = list(
/mob/living/simple_mob/mechanical/corrupt_maint_drone = 3
)
/obj/mob_spawner/alien
name = "Alien Spawner"
prob_fall = 10
mobs_to_pick_from = list(
/mob/living/simple_mob/animal/space/alien = 1
)
/obj/mob_spawner/alien/easy
name = "Easy Alien Spawner"
mobs_to_pick_from = list(
/mob/living/simple_mob/animal/space/alien = 1,
/mob/living/simple_mob/animal/space/alien/drone = 2,
/mob/living/simple_mob/animal/space/alien/sentinel = 1,
)
/obj/mob_spawner/alien/medium
name = "Medium Alien Spawner"
mobs_to_pick_from = list(
/mob/living/simple_mob/animal/space/alien = 2,
/mob/living/simple_mob/animal/space/alien/drone = 3,
/mob/living/simple_mob/animal/space/alien/sentinel = 2,
/mob/living/simple_mob/animal/space/alien/sentinel/praetorian = 1
)
/obj/mob_spawner/alien/hard
name = "Hard Alien Spawner"
mobs_to_pick_from = list(
/mob/living/simple_mob/animal/space/alien = 4,
/mob/living/simple_mob/animal/space/alien/sentinel = 4,
/mob/living/simple_mob/animal/space/alien/sentinel/praetorian = 2
)

View File

@@ -0,0 +1,107 @@
// Based on catwalk.dm from https://github.com/Endless-Horizon/CEV-Eris
/obj/structure/catwalk
name = "catwalk"
desc = "Cats really don't like these things."
plane = DECAL_PLANE
layer = ABOVE_UTILITY
icon = 'icons/turf/catwalks.dmi'
icon_state = "catwalk"
density = 0
var/health = 100
var/maxhealth = 100
anchored = 1.0
/obj/structure/catwalk/Initialize(mapload)
. = ..()
for(var/obj/structure/catwalk/O in range(1))
O.update_icon()
for(var/obj/structure/catwalk/C in get_turf(src))
if(C != src)
warning("Duplicate [type] in [loc] ([x], [y], [z])")
return INITIALIZE_HINT_QDEL
update_icon()
/obj/structure/catwalk/Destroy()
var/turf/location = loc
. = ..()
location.alpha = initial(location.alpha)
for(var/obj/structure/catwalk/L in orange(location, 1))
L.update_icon()
/obj/structure/catwalk/update_icon()
var/connectdir = 0
for(var/direction in cardinal)
if(locate(/obj/structure/catwalk, get_step(src, direction)))
connectdir |= direction
//Check the diagonal connections for corners, where you have, for example, connections both north and east. In this case it checks for a north-east connection to determine whether to add a corner marker or not.
var/diagonalconnect = 0 //1 = NE; 2 = SE; 4 = NW; 8 = SW
//NORTHEAST
if(connectdir & NORTH && connectdir & EAST)
if(locate(/obj/structure/catwalk, get_step(src, NORTHEAST)))
diagonalconnect |= 1
//SOUTHEAST
if(connectdir & SOUTH && connectdir & EAST)
if(locate(/obj/structure/catwalk, get_step(src, SOUTHEAST)))
diagonalconnect |= 2
//NORTHWEST
if(connectdir & NORTH && connectdir & WEST)
if(locate(/obj/structure/catwalk, get_step(src, NORTHWEST)))
diagonalconnect |= 4
//SOUTHWEST
if(connectdir & SOUTH && connectdir & WEST)
if(locate(/obj/structure/catwalk, get_step(src, SOUTHWEST)))
diagonalconnect |= 8
icon_state = "catwalk[connectdir]-[diagonalconnect]"
/obj/structure/catwalk/ex_act(severity)
switch(severity)
if(1.0)
qdel(src)
if(2.0)
qdel(src)
if(3.0)
qdel(src)
return
/obj/structure/catwalk/attackby(obj/item/C as obj, mob/user as mob)
if(istype(C, /obj/item/weldingtool))
var/obj/item/weldingtool/WT = C
if(WT.isOn())
if(WT.remove_fuel(0, user))
to_chat(user, "<span class='notice'>Slicing lattice joints ...</span>")
new /obj/item/stack/rods(src.loc)
new /obj/item/stack/rods(src.loc)
new /obj/structure/lattice(src.loc)
qdel(src)
if(C.is_screwdriver())
if(health < maxhealth)
to_chat(user, "<span class='notice'>You begin repairing \the [src.name] with \the [C.name].</span>")
if(do_after(user, 20, src))
health = maxhealth
else
take_damage(C.force)
user.setClickCooldown(user.get_attack_speed(C))
return ..()
/obj/structure/catwalk/Crossed()
. = ..()
if(isliving(usr))
playsound(src, pick('sound/effects/footstep/catwalk1.ogg', 'sound/effects/footstep/catwalk2.ogg', 'sound/effects/footstep/catwalk3.ogg', 'sound/effects/footstep/catwalk4.ogg', 'sound/effects/footstep/catwalk5.ogg'), 25, 1)
/obj/structure/catwalk/CheckExit(atom/movable/O, turf/target)
if(O.checkpass(PASSGRILLE))
return 1
if(target && target.z < src.z)
return 0
return 1
/obj/structure/catwalk/take_damage(amount)
health -= amount
if(health <= 0)
visible_message("<span class='warning'>\The [src] breaks down!</span>")
playsound(loc, 'sound/effects/grillehit.ogg', 50, 1)
new /obj/item/stack/rods(get_turf(src))
Destroy()

View File

@@ -0,0 +1,487 @@
/obj/structure/closet
name = "closet"
desc = "It's a basic storage unit."
icon = 'icons/obj/closet.dmi'
icon_state = "closed"
density = 1
w_class = ITEMSIZE_HUGE
layer = UNDER_JUNK_LAYER
var/icon_closed = "closed"
var/icon_opened = "open"
var/opened = 0
var/sealed = 0
var/seal_tool = /obj/item/weldingtool //Tool used to seal the closet, defaults to welder
var/wall_mounted = 0 //never solid (You can always pass over it)
var/health = 100
var/breakout = 0 //if someone is currently breaking out. mutex
var/breakout_time = 2 //2 minutes by default
var/breakout_sound = 'sound/effects/grillehit.ogg' //Sound that plays while breaking out
var/storage_capacity = 2 * MOB_MEDIUM //This is so that someone can't pack hundreds of items in a locker/crate
//then open it in a populated area to crash clients.
var/storage_cost = 40 //How much space this closet takes up if it's stuffed in another closet
var/open_sound = 'sound/machines/click.ogg'
var/close_sound = 'sound/machines/click.ogg'
var/store_misc = 1 //Chameleon item check
var/store_items = 1 //Will the closet store items?
var/store_mobs = 1 //Will the closet store mobs?
var/max_closets = 0 //Number of other closets allowed on tile before it won't close.
var/list/starts_with
/obj/structure/closet/Initialize(mapload)
..()
PopulateContents()
// Closets need to come later because of spawners potentially creating objects during init.
return INITIALIZE_HINT_LATELOAD
/obj/structure/closet/LateInitialize()
. = ..()
if(starts_with)
create_objects_in_loc(src, starts_with)
starts_with = null
if(!opened) // if closed, any item at the crate's loc is put in the contents
if(istype(loc, /mob/living)) return //VOREStation Edit - No collecting mob organs if spawned inside mob
var/obj/item/I
for(I in src.loc)
if(I.density || I.anchored || I == src) continue
I.forceMove(src)
// adjust locker size to hold all items with 5 units of free store room
var/content_size = 0
for(I in src.contents)
content_size += CEILING(I.w_class/2, 1)
if(content_size > storage_capacity-5)
storage_capacity = content_size + 5
update_icon()
/**
* The proc that fills the closet with its initial contents.
*/
/obj/structure/closet/proc/PopulateContents()
return
/obj/structure/closet/examine(mob/user)
if(..(user, 1) && !opened)
var/content_size = 0
for(var/obj/item/I in src.contents)
if(!I.anchored)
content_size += CEILING(I.w_class/2, 1)
if(!content_size)
to_chat(user, "It is empty.")
else if(storage_capacity > content_size*4)
to_chat(user, "It is barely filled.")
else if(storage_capacity > content_size*2)
to_chat(user, "It is less than half full.")
else if(storage_capacity > content_size)
to_chat(user, "There is still some free space.")
else
to_chat(user, "It is full.")
/obj/structure/closet/CanAllowThrough(atom/movable/mover, turf/target)
if(wall_mounted)
return TRUE
return ..()
/obj/structure/closet/proc/can_open()
if(src.sealed)
return 0
return 1
/obj/structure/closet/proc/can_close()
var/closet_count = 0
for(var/obj/structure/closet/closet in get_turf(src))
if(closet != src)
if(!closet.anchored)
closet_count ++
if(closet_count > max_closets)
return 0
return 1
/obj/structure/closet/proc/dump_contents()
//Cham Projector Exception
for(var/obj/effect/dummy/chameleon/AD in src)
AD.forceMove(src.loc)
for(var/obj/I in src)
I.forceMove(src.loc)
for(var/mob/M in src)
M.forceMove(src.loc)
if(M.client)
M.client.eye = M.client.mob
M.client.perspective = MOB_PERSPECTIVE
/obj/structure/closet/proc/open()
if(src.opened)
return 0
if(!src.can_open())
return 0
src.dump_contents()
src.icon_state = src.icon_opened
src.opened = 1
playsound(src.loc, open_sound, 15, 1, -3)
if(initial(density))
density = !density
return 1
/obj/structure/closet/proc/close()
if(!src.opened)
return 0
if(!src.can_close())
return 0
var/stored_units = 0
if(store_misc)
stored_units += store_misc(stored_units)
if(store_items)
stored_units += store_items(stored_units)
if(store_mobs)
stored_units += store_mobs(stored_units)
if(max_closets)
stored_units += store_closets(stored_units)
src.icon_state = src.icon_closed
src.opened = 0
playsound(src.loc, close_sound, 15, 1, -3)
if(initial(density))
density = !density
return 1
//Cham Projector Exception
/obj/structure/closet/proc/store_misc(var/stored_units)
var/added_units = 0
for(var/obj/effect/dummy/chameleon/AD in src.loc)
if((stored_units + added_units) > storage_capacity)
break
AD.forceMove(src)
added_units++
return added_units
/obj/structure/closet/proc/store_items(var/stored_units)
var/added_units = 0
for(var/obj/item/I in src.loc)
var/item_size = CEILING(I.w_class / 2, 1)
if(stored_units + added_units + item_size > storage_capacity)
continue
if(!I.anchored)
I.forceMove(src)
added_units += item_size
return added_units
/obj/structure/closet/proc/store_mobs(var/stored_units)
var/added_units = 0
for(var/mob/living/M in src.loc)
if(M.buckled || M.pinned.len)
continue
if(stored_units + added_units + M.mob_size > storage_capacity)
break
if(M.client)
M.client.perspective = EYE_PERSPECTIVE
M.client.eye = src
M.forceMove(src)
added_units += M.mob_size
return added_units
/obj/structure/closet/proc/store_closets(var/stored_units)
var/added_units = 0
for(var/obj/structure/closet/C in src.loc)
if(C == src) //Don't store ourself
continue
if(C.anchored) //Don't worry about anchored things on the same tile
continue
if(C.max_closets) //Prevents recursive storage
continue
if(stored_units + added_units + storage_cost > storage_capacity)
break
C.forceMove(src)
added_units += storage_cost
return added_units
/obj/structure/closet/proc/toggle(mob/user as mob)
if(!(src.opened ? src.close() : src.open()))
to_chat(user, "<span class='notice'>It won't budge!</span>")
return
update_icon()
// this should probably use dump_contents()
/obj/structure/closet/ex_act(severity)
switch(severity)
if(1)
for(var/atom/movable/A as mob|obj in src)//pulls everything out of the locker and hits it with an explosion
A.forceMove(src.loc)
A.ex_act(severity + 1)
qdel(src)
if(2)
if(prob(50))
for (var/atom/movable/A as mob|obj in src)
A.forceMove(src.loc)
A.ex_act(severity + 1)
qdel(src)
if(3)
if(prob(5))
for(var/atom/movable/A as mob|obj in src)
A.forceMove(src.loc)
qdel(src)
/obj/structure/closet/blob_act()
damage(100)
/obj/structure/closet/proc/damage(var/damage)
health -= damage
if(health <= 0)
for(var/atom/movable/A in src)
A.forceMove(src.loc)
qdel(src)
/obj/structure/closet/bullet_act(var/obj/item/projectile/Proj)
var/proj_damage = Proj.get_structure_damage()
if(!proj_damage)
return
..()
damage(proj_damage)
return
/obj/structure/closet/attackby(obj/item/W as obj, mob/user as mob)
if(src.opened)
if(istype(W, /obj/item/grab))
var/obj/item/grab/G = W
src.MouseDrop_T(G.affecting, user) //act like they were dragged onto the closet
return 0
if(istype(W,/obj/item/tk_grab))
return 0
if(istype(W, /obj/item/weldingtool))
var/obj/item/weldingtool/WT = W
if(!WT.remove_fuel(0,user))
if(!WT.isOn())
return
else
to_chat(user, "<span class='notice'>You need more welding fuel to complete this task.</span>")
return
playsound(src, WT.usesound, 50)
new /obj/item/stack/material/steel(src.loc)
for(var/mob/M in viewers(src))
M.show_message("<span class='notice'>\The [src] has been cut apart by [user] with \the [WT].</span>", 3, "You hear welding.", 2)
qdel(src)
return
if(istype(W, /obj/item/storage/laundry_basket) && W.contents.len)
var/obj/item/storage/laundry_basket/LB = W
var/turf/T = get_turf(src)
for(var/obj/item/I in LB.contents)
LB.remove_from_storage(I, T)
user.visible_message("<span class='notice'>[user] empties \the [LB] into \the [src].</span>", \
"<span class='notice'>You empty \the [LB] into \the [src].</span>", \
"<span class='notice'>You hear rustling of clothes.</span>")
return
if(isrobot(user))
return
if(W.loc != user) // This should stop mounted modules ending up outside the module.
return
usr.drop_item()
if(W)
W.forceMove(src.loc)
else if(istype(W, /obj/item/packageWrap))
return
else if(istype(W, /obj/item/extraction_pack)) //so fulton extracts dont open closets
src.close()
return
else if(seal_tool)
if(istype(W, seal_tool))
var/obj/item/S = W
if(istype(S, /obj/item/weldingtool))
var/obj/item/weldingtool/WT = S
if(!WT.remove_fuel(0,user))
if(!WT.isOn())
return
else
to_chat(user, "<span class='notice'>You need more welding fuel to complete this task.</span>")
return
if(do_after(user, 20 * S.toolspeed))
playsound(src, S.usesound, 50)
src.sealed = !src.sealed
src.update_icon()
for(var/mob/M in viewers(src))
M.show_message("<span class='warning'>[src] has been [sealed?"sealed":"unsealed"] by [user.name].</span>", 3)
else if(W.is_wrench())
if(sealed)
if(anchored)
user.visible_message("\The [user] begins unsecuring \the [src] from the floor.", "You start unsecuring \the [src] from the floor.")
else
user.visible_message("\The [user] begins securing \the [src] to the floor.", "You start securing \the [src] to the floor.")
playsound(src, W.usesound, 50)
if(do_after(user, 20 * W.toolspeed))
if(!src) return
to_chat(user, "<span class='notice'>You [anchored? "un" : ""]secured \the [src]!</span>")
anchored = !anchored
else
src.attack_hand(user)
return
/obj/structure/closet/MouseDrop_T(atom/movable/O as mob|obj, mob/user as mob)
if(istype(O, /obj/screen)) //fix for HUD elements making their way into the world -Pete
return
if(O.loc == user)
return
if(user.restrained() || user.stat || user.weakened || user.stunned || user.paralysis)
return
if((!( istype(O, /atom/movable) ) || O.anchored || !Adjacent(user) || !Adjacent(O) || !user.Adjacent(O) || user.contents.Find(src)))
return
if(!isturf(user.loc)) // are you in a container/closet/pod/etc?
return
if(!src.opened)
return
if(istype(O, /obj/structure/closet))
return
step_towards(O, src.loc)
if(user != O)
user.show_viewers("<span class='danger'>[user] stuffs [O] into [src]!</span>")
src.add_fingerprint(user)
return
/obj/structure/closet/attack_robot(mob/user)
if(Adjacent(user))
attack_hand(user)
/obj/structure/closet/relaymove(mob/user as mob)
if(user.stat || !isturf(src.loc))
return
if(!src.open())
to_chat(user, "<span class='notice'>It won't budge!</span>")
/obj/structure/closet/attack_hand(mob/user as mob)
src.add_fingerprint(user)
src.toggle(user)
// tk grab then use on self
/obj/structure/closet/attack_self_tk(mob/user as mob)
src.add_fingerprint(user)
if(!src.toggle())
to_chat(usr, "<span class='notice'>It won't budge!</span>")
/obj/structure/closet/attack_ghost(mob/ghost)
if(ghost.client && ghost.client.inquisitive_ghost)
ghost.examinate(src)
if (!src.opened)
to_chat(ghost, "It contains: [english_list(contents)].")
/obj/structure/closet/verb/verb_toggleopen()
set src in oview(1)
set category = "Object"
set name = "Toggle Open"
if(!usr.canmove || usr.stat || usr.restrained())
return
if(ishuman(usr) || isrobot(usr))
src.add_fingerprint(usr)
src.toggle(usr)
else
to_chat(usr, "<span class='warning'>This mob type can't use this verb.</span>")
/obj/structure/closet/update_icon()//Putting the sealed stuff in updateicon() so it's easy to overwrite for special cases (Fridges, cabinets, and whatnot)
overlays.Cut()
if(!opened)
icon_state = icon_closed
if(sealed)
overlays += "welded"
else
icon_state = icon_opened
/obj/structure/closet/attack_generic(var/mob/user, var/damage, var/attack_message = "destroys")
if(damage < STRUCTURE_MIN_DAMAGE_THRESHOLD)
return
user.do_attack_animation(src)
visible_message("<span class='danger'>[user] [attack_message] the [src]!</span>")
dump_contents()
spawn(1) qdel(src)
return 1
/obj/structure/closet/proc/req_breakout()
if(opened)
return 0 //Door's open... wait, why are you in it's contents then?
if(!sealed)
return 0 //closed but not sealed...
return 1
/obj/structure/closet/proc/mob_breakout(var/mob/living/escapee)
if(breakout || !req_breakout())
return
escapee.setClickCooldown(100)
//okay, so the closet is either sealed or locked... resist!!!
to_chat(escapee, "<span class='warning'>You lean on the back of \the [src] and start pushing the door open. (this will take about [breakout_time] minutes)</span>")
visible_message("<span class='danger'>\The [src] begins to shake violently!</span>")
breakout = 1 //can't think of a better way to do this right now.
for(var/i in 1 to (6*breakout_time * 2)) //minutes * 6 * 5seconds * 2
if(!do_after(escapee, 50)) //5 seconds
breakout = 0
return
if(!escapee || escapee.incapacitated() || escapee.loc != src)
breakout = 0
return //closet/user destroyed OR user dead/unconcious OR user no longer in closet OR closet opened
//Perform the same set of checks as above for weld and lock status to determine if there is even still a point in 'resisting'...
if(!req_breakout())
breakout = 0
return
playsound(src.loc, breakout_sound, 100, 1)
animate_shake()
add_fingerprint(escapee)
//Well then break it!
breakout = 0
to_chat(escapee, "<span class='warning'>You successfully break out!</span>")
visible_message("<span class='danger'>\The [escapee] successfully broke out of \the [src]!</span>")
playsound(src.loc, breakout_sound, 100, 1)
break_open()
animate_shake()
/obj/structure/closet/proc/break_open()
sealed = 0
update_icon()
//Do this to prevent contents from being opened into nullspace (read: bluespace)
if(istype(loc, /obj/structure/bigDelivery))
var/obj/structure/bigDelivery/BD = loc
BD.unwrap()
open()
/obj/structure/closet/proc/animate_shake()
var/init_px = pixel_x
var/shake_dir = pick(-1, 1)
animate(src, transform=turn(matrix(), 8*shake_dir), pixel_x=init_px + 2*shake_dir, time=1)
animate(transform=null, pixel_x=init_px, time=6, easing=ELASTIC_EASING)
/obj/structure/closet/onDropInto(var/atom/movable/AM)
return
/obj/structure/closet/AllowDrop()
return TRUE
/obj/structure/closet/return_air_for_internal_lifeform(var/mob/living/L)
if(src.loc)
if(istype(src.loc, /obj/structure/closet))
return (loc.return_air_for_internal_lifeform(L))
return return_air()
/obj/structure/closet/take_damage(var/damage)
if(damage < STRUCTURE_MIN_DAMAGE_THRESHOLD)
return
dump_contents()
spawn(1) qdel(src)
return 1

View File

@@ -0,0 +1,321 @@
/obj/structure/closet/secure_closet/medical1
name = "medicine closet"
desc = "Filled with medical junk."
icon_state = "medical1"
icon_closed = "medical"
icon_locked = "medical1"
icon_opened = "medicalopen"
icon_broken = "medicalbroken"
icon_off = "medicaloff"
req_access = list(access_medical)
starts_with = list(
/obj/item/storage/box/autoinjectors,
/obj/item/storage/box/syringes,
/obj/item/reagent_containers/dropper = 2,
/obj/item/reagent_containers/glass/beaker = 2,
/obj/item/reagent_containers/glass/bottle/inaprovaline = 2,
/obj/item/reagent_containers/glass/bottle/antitoxin = 2)
/obj/structure/closet/secure_closet/medical2
name = "anesthetics closet"
desc = "Used to knock people out."
icon_state = "medical1"
icon_closed = "medical"
icon_locked = "medical1"
icon_opened = "medicalopen"
icon_broken = "medicalbroken"
icon_off = "medicaloff"
req_access = list(access_surgery)
starts_with = list(
/obj/item/tank/anesthetic = 3,
/obj/item/clothing/mask/breath/medical = 3)
/obj/structure/closet/secure_closet/medical3
name = "medical doctor's locker"
req_access = list(access_medical_equip)
icon_state = "securemed1"
icon_closed = "securemed"
icon_locked = "securemed1"
icon_opened = "securemedopen"
icon_broken = "securemedbroken"
icon_off = "securemedoff"
starts_with = list(
/obj/item/clothing/under/rank/medical,
/obj/item/clothing/under/rank/nurse,
/obj/item/clothing/under/rank/orderly,
/obj/item/clothing/suit/storage/toggle/labcoat,
/obj/item/clothing/suit/storage/toggle/fr_jacket,
/obj/item/clothing/shoes/white,
/obj/item/cartridge/medical,
/obj/item/radio/headset/headset_med,
/obj/item/radio/headset/headset_med/alt,
/obj/item/clothing/suit/storage/hooded/wintercoat/medical,
/obj/item/clothing/shoes/boots/winter/medical,
/obj/item/clothing/under/rank/nursesuit,
/obj/item/clothing/head/nursehat,
/obj/item/gps/medical,
/obj/item/storage/box/freezer = 3)
/obj/structure/closet/secure_closet/medical3/Initialize(mapload)
if(prob(50))
starts_with += /obj/item/storage/backpack/medic
else
starts_with += /obj/item/storage/backpack/satchel/med
if(prob(50))
starts_with += /obj/item/storage/backpack/dufflebag/med
switch(pick("blue", "green", "purple", "black", "navyblue"))
if ("blue")
starts_with += /obj/item/clothing/under/rank/medical/scrubs
starts_with += /obj/item/clothing/head/surgery/blue
if ("green")
starts_with += /obj/item/clothing/under/rank/medical/scrubs/green
starts_with += /obj/item/clothing/head/surgery/green
if ("purple")
starts_with += /obj/item/clothing/under/rank/medical/scrubs/purple
starts_with += /obj/item/clothing/head/surgery/purple
if ("black")
starts_with += /obj/item/clothing/under/rank/medical/scrubs/black
starts_with += /obj/item/clothing/head/surgery/black
if ("navyblue")
starts_with += /obj/item/clothing/under/rank/medical/scrubs/navyblue
starts_with += /obj/item/clothing/head/surgery/navyblue
switch(pick("blue", "green", "purple", "black", "navyblue"))
if ("blue")
starts_with += /obj/item/clothing/under/rank/medical/scrubs
starts_with += /obj/item/clothing/head/surgery/blue
if ("green")
starts_with += /obj/item/clothing/under/rank/medical/scrubs/green
starts_with += /obj/item/clothing/head/surgery/green
if ("purple")
starts_with += /obj/item/clothing/under/rank/medical/scrubs/purple
starts_with += /obj/item/clothing/head/surgery/purple
if ("black")
starts_with += /obj/item/clothing/under/rank/medical/scrubs/black
starts_with += /obj/item/clothing/head/surgery/black
if ("navyblue")
starts_with += /obj/item/clothing/under/rank/medical/scrubs/navyblue
starts_with += /obj/item/clothing/head/surgery/navyblue
return ..()
/obj/structure/closet/secure_closet/paramedic
name = "paramedic locker"
desc = "Supplies for a first responder."
icon_state = "medical1"
icon_closed = "medical"
icon_locked = "medical1"
icon_opened = "medicalopen"
icon_broken = "medicalbroken"
icon_off = "medicaloff"
req_access = list(access_medical_equip)
starts_with = list(
/obj/item/storage/backpack/dufflebag/emt,
/obj/item/clothing/under/bodysuit/bodysuitemt,
/obj/item/storage/box/autoinjectors,
/obj/item/storage/box/syringes,
/obj/item/reagent_containers/glass/bottle/inaprovaline,
/obj/item/reagent_containers/glass/bottle/antitoxin,
/obj/item/storage/belt/medical/emt,
/obj/item/clothing/mask/gas,
/obj/item/clothing/suit/storage/toggle/fr_jacket,
/obj/item/clothing/suit/storage/toggle/labcoat/emt,
/obj/item/radio/headset/headset_med/alt,
/obj/item/cartridge/medical,
/obj/item/storage/briefcase/inflatable,
/obj/item/flashlight,
/obj/item/tank/emergency/oxygen/engi,
/obj/item/clothing/glasses/hud/health,
/obj/item/healthanalyzer,
/obj/item/radio/off,
/obj/random/medical,
/obj/item/tool/crowbar,
/obj/item/gps/medical,
/obj/item/extinguisher/mini,
/obj/item/storage/box/freezer,
/obj/item/clothing/accessory/storage/white_vest,
/obj/item/barrier_tape_roll/medical)
/obj/structure/closet/secure_closet/paramedic/Initialize(mapload)
starts_with += /obj/item/gps/medical
return ..()
/obj/structure/closet/secure_closet/CMO
name = "chief medical officer's locker"
req_access = list(access_cmo)
icon_state = "cmosecure1"
icon_closed = "cmosecure"
icon_locked = "cmosecure1"
icon_opened = "cmosecureopen"
icon_broken = "cmosecurebroken"
icon_off = "cmosecureoff"
starts_with = list(
/obj/item/clothing/under/rank/chief_medical_officer,
/obj/item/clothing/under/rank/chief_medical_officer/skirt,
/obj/item/clothing/under/rank/chief_medical_officer/skirt_pleated,
/obj/item/clothing/suit/storage/toggle/labcoat/cmo,
/obj/item/clothing/suit/storage/toggle/labcoat/cmoalt,
/obj/item/cartridge/cmo,
/obj/item/clothing/gloves/sterile/latex,
/obj/item/clothing/shoes/brown ,
/obj/item/radio/headset/heads/cmo,
/obj/item/radio/headset/heads/cmo/alt,
/obj/item/flash,
/obj/item/reagent_containers/hypospray/vial,
/obj/item/clothing/suit/storage/hooded/wintercoat/medical,
/obj/item/clothing/shoes/boots/winter/medical,
/obj/item/storage/box/freezer,
/obj/item/clothing/mask/gas,
/obj/item/barrier_tape_roll/medical,
/obj/item/clothing/suit/bio_suit/cmo,
/obj/item/clothing/head/bio_hood/cmo,
/obj/item/gps/medical/cmo,
/obj/item/clothing/shoes/white,
/obj/item/reagent_containers/glass/beaker/vial, //VOREStation Add
/obj/item/clothing/under/rank/chief_medical_officer/turtleneck)
/obj/structure/closet/secure_closet/CMO/Initialize(mapload)
if(prob(50))
starts_with += /obj/item/storage/backpack/medic
else
starts_with += /obj/item/storage/backpack/satchel/med
if(prob(50))
starts_with += /obj/item/storage/backpack/dufflebag/med
switch(pick("blue", "green", "purple", "black", "navyblue"))
if ("blue")
starts_with += /obj/item/clothing/under/rank/medical/scrubs
starts_with += /obj/item/clothing/head/surgery/blue
if ("green")
starts_with += /obj/item/clothing/under/rank/medical/scrubs/green
starts_with += /obj/item/clothing/head/surgery/green
if ("purple")
starts_with += /obj/item/clothing/under/rank/medical/scrubs/purple
starts_with += /obj/item/clothing/head/surgery/purple
if ("black")
starts_with += /obj/item/clothing/under/rank/medical/scrubs/black
starts_with += /obj/item/clothing/head/surgery/black
if ("navyblue")
starts_with += /obj/item/clothing/under/rank/medical/scrubs/navyblue
starts_with += /obj/item/clothing/head/surgery/navyblue
return ..()
/obj/structure/closet/secure_closet/animal
name = "animal control closet"
req_access = list(access_surgery)
starts_with = list(
/obj/item/assembly/signaler,
/obj/item/radio/electropack = 3)
/obj/structure/closet/secure_closet/chemical
name = "chemical closet"
desc = "Store dangerous chemicals in here."
icon_state = "medical1"
icon_closed = "medical"
icon_locked = "medical1"
icon_opened = "medicalopen"
icon_broken = "medicalbroken"
icon_off = "medicaloff"
req_access = list(access_chemistry)
starts_with = list(
/obj/item/storage/box/pillbottles = 2,
/obj/item/storage/box/beakers,
/obj/item/storage/box/autoinjectors,
/obj/item/storage/box/syringes,
/obj/item/reagent_containers/dropper = 2,
/obj/item/reagent_containers/glass/bottle/inaprovaline = 2,
/obj/item/reagent_containers/glass/bottle/antitoxin = 2,
/obj/item/storage/fancy/vials) //VOREStation Add
/obj/structure/closet/secure_closet/psych
name = "psychiatric closet"
desc = "Store psychology tools and medicines in here."
icon_state = "medical1"
icon_closed = "medical"
icon_locked = "medical1"
icon_opened = "medicalopen"
icon_broken = "medicalbroken"
icon_off = "medicaloff"
req_access = list(access_psychiatrist)
starts_with = list(
/obj/item/clothing/under/rank/psych,
/obj/item/clothing/under/rank/psych/turtleneck,
/obj/item/clothing/suit/straight_jacket,
/obj/item/reagent_containers/glass/bottle/stoxin,
/obj/item/reagent_containers/syringe,
/obj/item/storage/pill_bottle/citalopram,
/obj/item/reagent_containers/pill/methylphenidate,
/obj/item/clipboard,
/obj/item/folder/white,
/obj/item/tape_recorder,
/obj/item/cassette_tape/random = 3,
/obj/item/camera,
/obj/item/toy/plushie/therapy/blue)
/obj/structure/closet/secure_closet/medical_wall
name = "first aid closet"
desc = "It's a secure wall-mounted storage unit for first aid supplies."
icon_state = "medical_wall_locked"
icon_closed = "medical_wall_unlocked"
icon_locked = "medical_wall_locked"
icon_opened = "medical_wall_open"
icon_broken = "medical_wall_spark"
icon_off = "medical_wall_off"
plane = TURF_PLANE
layer = ABOVE_TURF_LAYER
anchored = 1
density = 0
wall_mounted = 1
req_access = list(access_medical_equip)
/obj/structure/closet/secure_closet/medical_wall/update_icon()
if(broken)
icon_state = icon_broken
else
if(!opened)
if(locked)
icon_state = icon_locked
else
icon_state = icon_closed
else
icon_state = icon_opened
/obj/structure/closet/secure_closet/medical_wall/pills
name = "pill cabinet"
starts_with = list(
/obj/item/storage/pill_bottle/tramadol,
/obj/item/storage/pill_bottle/antitox,
/obj/item/storage/pill_bottle/carbon,
/obj/random/medical/pillbottle)
/obj/structure/closet/secure_closet/medical_wall/anesthetics
name = "anesthetics wall closet"
desc = "Used to knock people out."
req_access = list(access_surgery)
starts_with = list(
/obj/item/tank/anesthetic = 3,
/obj/item/clothing/mask/breath/medical = 3)
/obj/structure/closet/secure_closet/medical_wall/synth_anesthetics
name = "robotics anesthetics wall closet"
desc = "Used to knock people out."
req_access = list(access_robotics)
starts_with = list(
/obj/item/tank/anesthetic = 3,
/obj/item/clothing/mask/breath/medical = 3)

View File

@@ -0,0 +1,179 @@
//Chain link fences
//Sprites ported from /VG/
#define CUT_TIME 10 SECONDS
#define CLIMB_TIME 5 SECONDS
#define NO_HOLE 0 //section is intact
#define MEDIUM_HOLE 1 //medium hole in the section - can climb through
#define LARGE_HOLE 2 //large hole in the section - can walk through
#define MAX_HOLE_SIZE LARGE_HOLE
/obj/structure/fence
name = "fence"
desc = "A chain link fence. Not as effective as a wall, but generally it keeps people out."
description_info = "Projectiles can freely pass fences."
density = TRUE
anchored = TRUE
icon = 'icons/obj/fence.dmi'
icon_state = "straight"
var/cuttable = TRUE
var/hole_size= NO_HOLE
var/invulnerable = FALSE
/obj/structure/fence/Initialize(mapload)
update_cut_status()
return ..()
/obj/structure/fence/examine(mob/user)
. = ..()
switch(hole_size)
if(MEDIUM_HOLE)
user.show_message("There is a large hole in \the [src].")
if(LARGE_HOLE)
user.show_message("\The [src] has been completely cut through.")
/obj/structure/fence/get_description_interaction()
var/list/results = list()
if(cuttable && !invulnerable && hole_size < MAX_HOLE_SIZE)
results += "[desc_panel_image("wirecutters")]to [hole_size > NO_HOLE ? "expand the":"cut a"] hole into the fence, allowing passage."
return results
/obj/structure/fence/end
icon_state = "end"
cuttable = FALSE
/obj/structure/fence/corner
icon_state = "corner"
cuttable = FALSE
/obj/structure/fence/post
icon_state = "post"
cuttable = FALSE
/obj/structure/fence/cut/medium
icon_state = "straight_cut2"
hole_size = MEDIUM_HOLE
/obj/structure/fence/cut/large
icon_state = "straight_cut3"
hole_size = LARGE_HOLE
// Projectiles can pass through fences.
/obj/structure/fence/CanAllowThrough(atom/movable/mover, turf/target)
if(istype(mover, /obj/item/projectile))
return TRUE
return ..()
/obj/structure/fence/attackby(obj/item/W, mob/user)
if(W.is_wirecutter())
if(!cuttable)
to_chat(user, span("warning", "This section of the fence can't be cut."))
return
if(invulnerable)
to_chat(user, span("warning", "This fence is too strong to cut through."))
return
var/current_stage = hole_size
if(current_stage >= MAX_HOLE_SIZE)
to_chat(user, span("notice", "This fence has too much cut out of it already."))
return
user.visible_message(span("danger", "\The [user] starts cutting through \the [src] with \the [W]."),\
span("danger", "You start cutting through \the [src] with \the [W]."))
playsound(src, W.usesound, 50, 1)
if(do_after(user, CUT_TIME * W.toolspeed, target = src))
if(current_stage == hole_size)
switch(++hole_size)
if(MEDIUM_HOLE)
visible_message(span("notice", "\The [user] cuts into \the [src] some more."))
to_chat(user, span("notice", "You could probably fit yourself through that hole now. Although climbing through would be much faster if you made it even bigger."))
climbable = TRUE
if(LARGE_HOLE)
visible_message(span("notice", "\The [user] completely cuts through \the [src]."))
to_chat(user, span("notice", "The hole in \the [src] is now big enough to walk through."))
climbable = FALSE
update_cut_status()
return TRUE
/obj/structure/fence/proc/update_cut_status()
if(!cuttable)
return
density = TRUE
switch(hole_size)
if(NO_HOLE)
icon_state = initial(icon_state)
if(MEDIUM_HOLE)
icon_state = "straight_cut2"
if(LARGE_HOLE)
icon_state = "straight_cut3"
density = FALSE
//FENCE DOORS
/obj/structure/fence/door
name = "fence door"
desc = "Not very useful without a real lock."
icon_state = "door_closed"
cuttable = FALSE
var/open = FALSE
var/locked = FALSE
/obj/structure/fence/door/Initialize(mapload)
update_door_status()
return ..()
/obj/structure/fence/door/opened
icon_state = "door_opened"
open = TRUE
density = TRUE
/obj/structure/fence/door/locked
desc = "It looks like it has a strong padlock attached."
locked = TRUE
/obj/structure/fence/door/attack_hand(mob/user)
if(can_open(user))
toggle(user)
else
to_chat(user, span("warning", "\The [src] is [!open ? "locked" : "stuck open"]."))
return TRUE
/obj/structure/fence/door/proc/toggle(mob/user)
switch(open)
if(FALSE)
visible_message(span("notice", "\The [user] opens \the [src]."))
open = TRUE
if(TRUE)
visible_message(span("notice", "\The [user] closes \the [src]."))
open = FALSE
update_door_status()
playsound(src, 'sound/machines/click.ogg', 100, 1)
/obj/structure/fence/door/proc/update_door_status()
switch(open)
if(FALSE)
density = TRUE
icon_state = "door_closed"
if(TRUE)
density = FALSE
icon_state = "door_opened"
/obj/structure/fence/door/proc/can_open(mob/user)
if(locked)
return FALSE
return TRUE
#undef CUT_TIME
#undef CLIMB_TIME
#undef NO_HOLE
#undef MEDIUM_HOLE
#undef LARGE_HOLE
#undef MAX_HOLE_SIZE

View File

@@ -0,0 +1,42 @@
/obj/structure/foodcart
name = "Foodcart"
icon = 'icons/obj/kitchen.dmi'
icon_state = "foodcart-0"
desc = "The ultimate in food transport! When opened you notice two compartments with odd blue glows to them. One feels very warm, while the other is very cold."
anchored = 0
opacity = 0
density = 1
/obj/structure/foodcart/Initialize(mapload)
. = ..()
for(var/obj/item/I in loc)
if(istype(I, /obj/item/reagent_containers/food))
I.loc = src
update_icon()
/obj/structure/foodcart/attackby(obj/item/O as obj, mob/user as mob)
if(istype(O, /obj/item/reagent_containers/food))
user.drop_item()
O.loc = src
update_icon()
else
return
/obj/structure/foodcart/attack_hand(var/mob/user as mob)
if(contents.len)
var/obj/item/reagent_containers/food/choice = input("What would you like to grab from the cart?") as null|obj in contents
if(choice)
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
return
if(ishuman(user))
if(!user.get_active_hand())
user.put_in_hands(choice)
else
choice.loc = get_turf(src)
update_icon()
/obj/structure/foodcart/update_icon()
if(contents.len < 5)
icon_state = "foodcart-[contents.len]"
else
icon_state = "foodcart-5"

View File

@@ -0,0 +1,42 @@
/obj/structure/lightpost
name = "lightpost"
desc = "A homely lightpost."
icon = 'icons/obj/32x64.dmi'
icon_state = "lightpost"
plane = MOB_PLANE
layer = ABOVE_MOB_LAYER
anchored = TRUE
density = TRUE
opacity = FALSE
var/lit = TRUE // If true, will have a glowing overlay and lighting.
var/festive = FALSE // If true, adds a festive bow overlay to it.
/obj/structure/lightpost/Initialize(mapload)
update_icon()
return ..()
/obj/structure/lightpost/update_icon()
cut_overlays()
if(lit)
set_light(5, 1, "#E9E4AF")
var/image/glow = image(icon_state = "[icon_state]-glow")
glow.plane = PLANE_LIGHTING_ABOVE
add_overlay(glow)
else
set_light(0)
if(festive)
var/image/bow = image(icon_state = "[icon_state]-festive")
add_overlay(bow)
/obj/structure/lightpost/unlit
lit = FALSE
/obj/structure/lightpost/festive
desc = "A homely lightpost adorned with festive decor."
festive = TRUE
/obj/structure/lightpost/festive/unlit
lit = FALSE

View File

@@ -0,0 +1,189 @@
/*
CONTAINS:
SAFES
FLOOR SAFES
*/
//SAFES
/obj/structure/safe
name = "safe"
desc = "A huge chunk of metal with a dial embedded in it. Fine print on the dial reads \"Scarborough Arms - 2 tumbler safe, guaranteed thermite resistant, explosion resistant, and assistant resistant.\""
icon = 'icons/obj/structures.dmi'
icon_state = "safe"
anchored = 1
density = 1
var/open = 0 //is the safe open?
var/tumbler_1_pos //the tumbler position- from 0 to 72
var/tumbler_1_open //the tumbler position to open at- 0 to 72
var/tumbler_2_pos
var/tumbler_2_open
var/dial = 0 //where is the dial pointing?
var/space = 0 //the combined w_class of everything in the safe
var/maxspace = 24 //the maximum combined w_class of stuff in the safe
/obj/structure/safe/New()
tumbler_1_pos = rand(0, 72)
tumbler_1_open = rand(0, 72)
tumbler_2_pos = rand(0, 72)
tumbler_2_open = rand(0, 72)
/obj/structure/safe/Initialize(mapload)
. = ..()
for(var/obj/item/I in loc)
if(space >= maxspace)
return
if(I.w_class + space <= maxspace)
space += I.w_class
I.forceMove(src)
/obj/structure/safe/proc/check_unlocked(mob/user as mob, canhear)
if(user && canhear)
if(tumbler_1_pos == tumbler_1_open)
to_chat(user, "<span class='notice'>You hear a [pick("tonk", "krunk", "plunk")] from \the [src].</span>")
if(tumbler_2_pos == tumbler_2_open)
to_chat(user, "<span class='notice'>You hear a [pick("tink", "krink", "plink")] from \the [src].</span>")
if(tumbler_1_pos == tumbler_1_open && tumbler_2_pos == tumbler_2_open)
if(user) visible_message("<b>[pick("Spring", "Sprang", "Sproing", "Clunk", "Krunk")]!</b>")
return 1
return 0
/obj/structure/safe/proc/decrement(num)
num -= 1
if(num < 0)
num = 71
return num
/obj/structure/safe/proc/increment(num)
num += 1
if(num > 71)
num = 0
return num
/obj/structure/safe/update_icon()
if(open)
icon_state = "[initial(icon_state)]-open"
else
icon_state = initial(icon_state)
/obj/structure/safe/attack_hand(mob/user as mob)
user.set_machine(src)
var/dat = "<center>"
dat += "<a href='?src=\ref[src];open=1'>[open ? "Close" : "Open"] [src]</a> | <a href='?src=\ref[src];decrement=1'>-</a> [dial * 5] <a href='?src=\ref[src];increment=1'>+</a>"
if(open)
dat += "<table>"
for(var/i = contents.len, i>=1, i--)
var/obj/item/P = contents[i]
dat += "<tr><td><a href='?src=\ref[src];retrieve=\ref[P]'>[P.name]</a></td></tr>"
dat += "</table></center>"
user << browse("<html><head><title>[name]</title></head><body>[dat]</body></html>", "window=safe;size=350x300")
/obj/structure/safe/Topic(href, href_list)
if(!ishuman(usr)) return
var/mob/living/carbon/human/user = usr
var/canhear = 0
if(user.get_type_in_hands(/obj/item/clothing/accessory/stethoscope))
canhear = 1
if(href_list["open"])
if(check_unlocked())
to_chat(user, "<span class='notice'>You [open ? "close" : "open"] [src].</span>")
open = !open
update_icon()
updateUsrDialog()
return
else
to_chat(user, "<span class='notice'>You can't [open ? "close" : "open"] [src], the lock is engaged!</span>")
return
if(href_list["decrement"])
dial = decrement(dial)
if(dial == tumbler_1_pos + 1 || dial == tumbler_1_pos - 71)
tumbler_1_pos = decrement(tumbler_1_pos)
if(canhear)
to_chat(user, "<span class='notice'>You hear a [pick("clack", "scrape", "clank")] from \the [src].</span>")
if(tumbler_1_pos == tumbler_2_pos + 37 || tumbler_1_pos == tumbler_2_pos - 35)
tumbler_2_pos = decrement(tumbler_2_pos)
if(canhear)
to_chat(user, "<span class='notice'>You hear a [pick("click", "chink", "clink")] from \the [src].</span>")
playsound(user, 'sound/machines/click.ogg', 20, 1)
check_unlocked(user, canhear)
updateUsrDialog()
return
if(href_list["increment"])
dial = increment(dial)
if(dial == tumbler_1_pos - 1 || dial == tumbler_1_pos + 71)
tumbler_1_pos = increment(tumbler_1_pos)
if(canhear)
to_chat(user, "<span class='notice'>You hear a [pick("clack", "scrape", "clank")] from \the [src].</span>")
if(tumbler_1_pos == tumbler_2_pos - 37 || tumbler_1_pos == tumbler_2_pos + 35)
tumbler_2_pos = increment(tumbler_2_pos)
if(canhear)
to_chat(user, "<span class='notice'>You hear a [pick("click", "chink", "clink")] from \the [src].</span>")
playsound(user, 'sound/machines/click.ogg', 20, 1)
check_unlocked(user, canhear)
updateUsrDialog()
return
if(href_list["retrieve"])
user << browse("", "window=safe") // Close the menu
var/obj/item/P = locate(href_list["retrieve"]) in src
if(open)
if(P && in_range(src, user))
user.put_in_hands(P)
updateUsrDialog()
/obj/structure/safe/attackby(obj/item/I as obj, mob/user as mob)
if(open)
if(I.w_class + space <= maxspace)
space += I.w_class
user.drop_item()
I.loc = src
to_chat(user, "<span class='notice'>You put [I] in \the [src].</span>")
updateUsrDialog()
return
else
to_chat(user, "<span class='notice'>[I] won't fit in \the [src].</span>")
return
else
if(istype(I, /obj/item/clothing/accessory/stethoscope))
to_chat(user, "Hold [I] in one of your hands while you manipulate the dial.")
return
obj/structure/safe/ex_act(severity)
return
//FLOOR SAFES
/obj/structure/safe/floor
name = "floor safe"
icon_state = "floorsafe"
density = 0
level = 1 //underfloor
plane = TURF_PLANE
layer = ABOVE_UTILITY
/obj/structure/safe/floor/Initialize(mapload)
. = ..()
var/turf/T = loc
if(istype(T) && !T.is_plating())
hide(1)
update_icon()
/obj/structure/safe/floor/hide(var/intact)
invisibility = intact ? 101 : 0
/obj/structure/safe/floor/hides_under_flooring()
return 1

View File

@@ -0,0 +1,94 @@
/turf/unsimulated/beach
name = "Beach"
icon = 'icons/misc/beach.dmi'
/turf/unsimulated/beach/sand
name = "Sand"
icon_state = "sand"
/turf/unsimulated/beach/coastline
name = "Coastline"
icon = 'icons/misc/beach2.dmi'
icon_state = "sandwater"
/turf/unsimulated/beach/water
name = "Water"
icon_state = "water"
/turf/unsimulated/beach/water/Initialize(mapload)
. = ..()
add_overlay(/obj/effect/turf_overlay/beach_water, TRUE)
/obj/effect/turf_overlay/beach_water
icon = 'icons/misc/beach.dmi'
icon_state = "water2"
layer = ABOVE_MOB_LAYER
/turf/simulated/floor/outdoors/beach
name = "Beach"
icon = 'icons/misc/beach.dmi'
footstep_sounds = list("human" = list(
'sound/effects/footstep/carpet1.ogg',
'sound/effects/footstep/carpet2.ogg',
'sound/effects/footstep/carpet3.ogg',
'sound/effects/footstep/carpet4.ogg',
'sound/effects/footstep/carpet5.ogg'))
/turf/simulated/floor/outdoors/beach/sand
name = "Sand"
icon_state = "sand"
/turf/simulated/floor/outdoors/beach/sand/desert
name = "Dunes"
desc = "It seems to go on and on.."
icon = 'icons/turf/desert.dmi'
icon_state = "desert"
/turf/simulated/floor/outdoors/beach/sand/desert/Initialize(mapload)
. = ..()
if(prob(5))
icon_state = "desert[rand(0,4)]"
/turf/simulated/floor/outdoors/beach/sand/lowdesert
name = "\improper low desert"
icon = 'icons/turf/desert.dmi'
icon_state = "lowdesert"
/turf/simulated/floor/outdoors/beach/outdoors/sand/lowdesert/Initialize(mapload)
. = ..()
if(prob(5))
icon_state = "lowdesert[rand(0,4)]"
/turf/simulated/floor/beach/sand/dirt
name = "worn out path"
desc = "A compacted bit of sand with footprints all over it..."
icon_state = "dirt-dark"
icon = 'icons/turf/outdoors.dmi'
/turf/simulated/floor/outdoors/beach/sand/dirtlight
name = "sun bleached path"
desc = "A cracked path of compacted sand, worn by heavy traffic and bleached by constant sunlight."
icon_state = "dirt-light"
icon = 'icons/turf/outdoors.dmi'
/turf/simulated/floor/outdoors/beach/coastline
name = "Coastline"
icon = 'icons/misc/beach2.dmi'
icon_state = "sandwater"
/turf/simulated/floor/outdoors/beach/water
name = "Water"
icon_state = "water"
initial_flooring = /decl/flooring/outdoors/water
/turf/simulated/floor/outdoors/beach/water/ocean
icon_state = "seadeep"
/turf/simulated/floor/outdoors/beach/water/Initialize(mapload)
. = ..()
add_overlay(/obj/effect/turf_overlay/beach_ocean, TRUE)
/obj/effect/turf_overlay/beach_ocean
icon = 'icons/misc/beach.dmi'
icon_state = "water5"
layer = ABOVE_MOB_LAYER

View File

@@ -0,0 +1,82 @@
///////////////////
// Generic skyfall turf
// Really only works well if the map doesn't have 'indoor' areas otherwise they can fall into one.
// TODO: Fix that.
/turf/unsimulated/floor/sky
name = "the sky"
desc = "It's the sky! Be careful!"
icon = 'icons/turf/floors.dmi'
icon_state = "sky_slow"
dir = SOUTH
var/does_skyfall = TRUE
var/list/skyfall_levels
/turf/unsimulated/floor/sky/Initialize(mapload)
. = ..()
if(does_skyfall && !LAZYLEN(skyfall_levels))
log_world("[x],[y],[z], [get_area(src)] doesn't have skyfall_levels defined! Can't skyfall!")
if(locate(/turf/simulated) in orange(src,1))
set_light(2, 2, color)
/turf/unsimulated/floor/sky/Entered(atom/movable/AM,atom/oldloc)
..()
if(!does_skyfall)
return //We don't do that
if(isobserver(AM))
return //Don't ghostport, very annoying
if(AM.throwing)
return //Being thrown over, not fallen yet
if(!(AM.can_fall()))
return // Phased shifted kin should not fall
if(istype(AM, /obj/item/projectile))
return // pewpew should not fall out of the sky. pew.
if(istype(AM, /obj/effect/projectile))
return // ...neither should the effects be falling
var/mob/living/L
if(isliving(AM))
L = AM
if(L.is_floating)
return //Flyers/nograv can ignore it
do_fall(AM)
/turf/unsimulated/floor/sky/hitby(var/atom/movable/AM, var/speed)
. = ..()
if(!does_skyfall)
return //We don't do that
do_fall(AM)
/turf/unsimulated/floor/sky/proc/do_fall(atom/movable/AM)
//Bye
var/attempts = 100
var/turf/simulated/T
while(attempts && !T)
var/turf/simulated/candidate = locate(rand(5,world.maxx-5),rand(5,world.maxy-5),pick(skyfall_levels))
if(candidate.density)
attempts--
continue
T = candidate
break
if(!T)
return
AM.forceMove(T)
if(isliving(AM))
var/mob/living/L = AM
message_admins("\The [AM] fell out of the sky.")
L.fall_impact(T, 42, 90, FALSE, TRUE) //You will not be defibbed from this.
/turf/unsimulated/floor/sky/virgo2_sky
name = "virgo 2 atmosphere"
desc = "Be careful where you step!"
color = "#eacd7c"
VIRGO2_SET_ATMOS
/turf/unsimulated/floor/sky/virgo2_sky/Initialize(mapload)
skyfall_levels = list(z+1)
. = ..()

View File

@@ -0,0 +1,291 @@
// This is a datum-based artificial intelligence for simple mobs (and possibly others) to use.
// The neat thing with having this here instead of on the mob is that it is independant of Life(), and that different mobs
// can use a more or less complex AI by giving it a different datum.
/mob/living
var/datum/ai_holder/ai_holder = null
var/ai_holder_type = null // Which ai_holder datum to give to the mob when initialized. If null, nothing happens.
/mob/living/Initialize(mapload)
if(ai_holder_type)
ai_holder = new ai_holder_type(src)
return ..()
/mob/living/Destroy()
QDEL_NULL(ai_holder)
return ..()
/datum/ai_holder
var/mob/living/holder = null // The mob this datum is going to control.
var/stance = STANCE_IDLE // Determines if the mob should be doing a specific thing, e.g. attacking, following, standing around, etc.
var/intelligence_level = AI_NORMAL // Adjust to make the AI be intentionally dumber, or make it more robust (e.g. dodging grenades).
var/autopilot = FALSE // If true, the AI won't be deactivated if a client gets attached to the AI's mob.
var/busy = FALSE // If true, the SSticker will skip processing this mob until this is false. Good for if you need the
// mob to stay still (e.g. delayed attacking). If you need the mob to be inactive for an extended period of time,
// consider sleeping the AI instead.
/datum/ai_holder/hostile
hostile = TRUE
/datum/ai_holder/retaliate
hostile = TRUE
retaliate = TRUE
/datum/ai_holder/New(var/new_holder)
ASSERT(new_holder)
holder = new_holder
SSai.processing += src
home_turf = get_turf(holder)
..()
/datum/ai_holder/Destroy()
holder = null
SSai.processing -= src // We might've already been asleep and removed, but byond won't care if we do this again and it saves a conditional.
home_turf = null
return ..()
// Now for the actual AI stuff.
// Makes this ai holder not get processed.
// Called automatically when the host mob is killed.
// Potential future optimization would be to sleep AIs which mobs that are far away from in-round players.
/datum/ai_holder/proc/go_sleep()
if(stance == STANCE_SLEEP)
return
forget_everything() // If we ever wake up, its really unlikely that our current memory will be of use.
set_stance(STANCE_SLEEP)
SSai.processing -= src
// Reverses the above proc.
// Revived mobs will wake their AI if they have one.
/datum/ai_holder/proc/go_wake()
/* if(stance != STANCE_SLEEP)
return
if(!should_wake())
return
*/
set_stance(STANCE_IDLE)
SSai.processing += src
/datum/ai_holder/proc/should_wake()
if(holder.client && !autopilot)
return FALSE
if(holder.stat >= DEAD)
return FALSE
return TRUE
// Resets a lot of 'memory' vars.
/datum/ai_holder/proc/forget_everything()
// Some of these might be redundant, but hopefully this prevents future bugs if that changes.
lose_follow()
lose_target()
lose_target_position()
give_up_movement()
// 'Tactical' processes such as moving a step, meleeing an enemy, firing a projectile, and other fairly cheap actions that need to happen quickly.
/datum/ai_holder/proc/handle_tactics()
if(busy)
return
handle_special_tactic()
handle_stance_tactical()
// 'Strategical' processes that are more expensive on the CPU and so don't get run as often as the above proc, such as A* pathfinding or robust targeting.
/datum/ai_holder/proc/handle_strategicals()
if(busy)
return
handle_special_strategical()
handle_stance_strategical()
// Override these for special things without polluting the main loop.
/datum/ai_holder/proc/handle_special_tactic()
/datum/ai_holder/proc/handle_special_strategical()
/*
//AI Actions
if(!ai_inactive)
//Stanceyness
handle_stance()
//Movement
if(!stop_automated_movement && wander && !anchored) //Allowed to move?
handle_wander_movement()
//Speaking
if(speak_chance && stance == STANCE_IDLE) // Allowed to chatter?
handle_idle_speaking()
//Resisting out buckles
if(stance != STANCE_IDLE && incapacitated(INCAPACITATION_BUCKLED_PARTIALLY))
handle_resist()
//Resisting out of closets
if(istype(loc,/obj/structure/closet))
var/obj/structure/closet/C = loc
if(C.welded)
resist()
else
C.open()
*/
// For setting the stance WITHOUT processing it
/datum/ai_holder/proc/set_stance(var/new_stance)
ai_log("set_stance() : Setting stance from [stance] to [new_stance].", AI_LOG_INFO)
stance = new_stance
if(stance_coloring) // For debugging or really weird mobs.
stance_color()
// This is called every half a second.
/datum/ai_holder/proc/handle_stance_tactical()
ai_log("========= Fast Process Beginning ==========", AI_LOG_TRACE) // This is to make it easier visually to disinguish between 'blocks' of what a tick did.
ai_log("handle_stance_tactical() : Called.", AI_LOG_TRACE)
if(stance == STANCE_SLEEP)
ai_log("handle_stance_tactical() : Going to sleep.", AI_LOG_TRACE)
go_sleep()
return
if(target && can_see_target(target))
track_target_position()
if(stance != STANCE_DISABLED && is_disabled()) // Stunned/confused/etc
ai_log("handle_stance_tactical() : Disabled.", AI_LOG_TRACE)
set_stance(STANCE_DISABLED)
return
if(stance in STANCES_COMBAT)
// Should resist? We check this before fleeing so that we can actually flee and not be trapped in a chair.
if(holder.incapacitated(INCAPACITATION_BUCKLED_PARTIALLY))
ai_log("handle_stance_tactical() : Going to handle_resist().", AI_LOG_TRACE)
handle_resist()
else if(istype(holder.loc, /obj/structure/closet))
var/obj/structure/closet/C = holder.loc
ai_log("handle_stance_tactical() : Inside a closet. Going to attempt escape.", AI_LOG_TRACE)
if(C.sealed)
holder.resist()
else
C.open()
// Should we flee?
if(should_flee())
ai_log("handle_stance_tactical() : Going to flee.", AI_LOG_TRACE)
set_stance(STANCE_FLEE)
return
switch(stance)
if(STANCE_IDLE)
if(should_go_home())
ai_log("handle_stance_tactical() : STANCE_IDLE, going to go home.", AI_LOG_TRACE)
go_home()
else if(should_follow_leader())
ai_log("handle_stance_tactical() : STANCE_IDLE, going to follow leader.", AI_LOG_TRACE)
set_stance(STANCE_FOLLOW)
else if(should_wander())
ai_log("handle_stance_tactical() : STANCE_IDLE, going to wander randomly.", AI_LOG_TRACE)
handle_wander_movement()
if(STANCE_ALERT)
ai_log("handle_stance_tactical() : STANCE_ALERT, going to threaten_target().", AI_LOG_TRACE)
threaten_target()
if(STANCE_APPROACH)
ai_log("handle_stance_tactical() : STANCE_APPROACH, going to walk_to_target().", AI_LOG_TRACE)
walk_to_target()
if(STANCE_FIGHT)
ai_log("handle_stance_tactical() : STANCE_FIGHT, going to engage_target().", AI_LOG_TRACE)
engage_target()
if(STANCE_MOVE)
ai_log("handle_stance_tactical() : STANCE_MOVE, going to walk_to_destination().", AI_LOG_TRACE)
walk_to_destination()
if(STANCE_REPOSITION) // This is the same as above but doesn't stop if an enemy is visible since its an 'in-combat' move order.
ai_log("handle_stance_tactical() : STANCE_REPOSITION, going to walk_to_destination().", AI_LOG_TRACE)
walk_to_destination()
if(STANCE_FOLLOW)
ai_log("handle_stance_tactical() : STANCE_FOLLOW, going to walk_to_leader().", AI_LOG_TRACE)
walk_to_leader()
if(STANCE_FLEE)
ai_log("handle_stance_tactical() : STANCE_FLEE, going to flee_from_target().", AI_LOG_TRACE)
flee_from_target()
if(STANCE_DISABLED)
ai_log("handle_stance_tactical() : STANCE_DISABLED.", AI_LOG_TRACE)
if(!is_disabled())
ai_log("handle_stance_tactical() : No longer disabled.", AI_LOG_TRACE)
set_stance(STANCE_IDLE)
else
handle_disabled()
ai_log("handle_stance_tactical() : Exiting.", AI_LOG_TRACE)
ai_log("========= Fast Process Ending ==========", AI_LOG_TRACE)
// This is called every two seconds.
/datum/ai_holder/proc/handle_stance_strategical()
ai_log("++++++++++ Slow Process Beginning ++++++++++", AI_LOG_TRACE)
ai_log("handle_stance_strategical() : Called.", AI_LOG_TRACE)
switch(stance)
if(STANCE_IDLE)
if(speak_chance) // In the long loop since otherwise it wont shut up.
handle_idle_speaking()
if(hostile)
ai_log("handle_stance_strategical() : STANCE_IDLE, going to find_target().", AI_LOG_TRACE)
find_target()
if(STANCE_APPROACH)
if(target)
ai_log("handle_stance_strategical() : STANCE_APPROACH, going to calculate_path([target]).", AI_LOG_TRACE)
calculate_path(target)
if(STANCE_MOVE)
if(hostile && find_target()) // This will switch its stance.
ai_log("handle_stance_strategical() : STANCE_MOVE, found target and was inturrupted.", AI_LOG_TRACE)
if(STANCE_FOLLOW)
if(hostile && find_target()) // This will switch its stance.
ai_log("handle_stance_strategical() : STANCE_FOLLOW, found target and was inturrupted.", AI_LOG_TRACE)
else if(leader)
ai_log("handle_stance_strategical() : STANCE_FOLLOW, going to calculate_path([leader]).", AI_LOG_TRACE)
calculate_path(leader)
ai_log("handle_stance_strategical() : Exiting.", AI_LOG_TRACE)
ai_log("++++++++++ Slow Process Ending ++++++++++", AI_LOG_TRACE)
// Helper proc to turn AI 'busy' mode on or off without having to check if there is an AI, to simplify writing code.
/mob/living/proc/set_AI_busy(value)
if(ai_holder)
ai_holder.busy = value
/mob/living/proc/is_AI_busy()
if(!ai_holder)
return FALSE
return ai_holder.busy
// Helper proc to check for the AI's stance.
// Returns null if there's no AI holder, or the mob has a player and autopilot is not on.
// Otherwise returns the stance.
/mob/living/proc/get_AI_stance()
if(!ai_holder)
return null
if(client && !ai_holder.autopilot)
return null
return ai_holder.stance
// Similar to above but only returns 1 or 0.
/mob/living/proc/has_AI()
return get_AI_stance() ? TRUE : FALSE
// 'Taunts' the AI into attacking the taunter.
/mob/living/proc/taunt(atom/movable/taunter, force_target_switch = FALSE)
if(ai_holder)
ai_holder.receive_taunt(taunter, force_target_switch)

View File

@@ -0,0 +1,172 @@
// A simple datum that just holds many lists of lines for mobs to pick from.
// This is its own datum in order to be able to have different types of mobs be able to use the same lines if desired,
// even when inheritence wouldn't be able to do so.
// Also note this also contains emotes, despite its name.
// and now sounds because its probably better that way.
/mob/living
var/datum/say_list/say_list = null
var/say_list_type = /datum/say_list // Type to give us on initialization. Default has empty lists, so the mob will be silent.
/mob/living/Initialize(mapload)
if(say_list_type)
say_list = new say_list_type(src)
return ..()
/mob/living/Destroy()
QDEL_NULL(say_list)
return ..()
/datum/say_list
var/list/speak = list() // Things the mob might say if it talks while idle.
var/list/emote_hear = list() // Hearable emotes it might perform
var/list/emote_see = list() // Unlike speak_emote, the list of things in this variable only show by themselves with no spoken text. IE: Ian barks, Ian yaps
var/list/say_understood = list() // When accepting an order.
var/list/say_cannot = list() // When they cannot comply.
var/list/say_maybe_target = list() // When they briefly see something.
var/list/say_got_target = list() // When a target is first assigned.
var/list/say_threaten = list() // When threatening someone.
var/list/say_stand_down = list() // When the threatened thing goes away.
var/list/say_escalate = list() // When the threatened thing doesn't go away.
var/threaten_sound = null // Sound file played when the mob's AI calls threaten_target() for the first time.
var/stand_down_sound = null // Sound file played when the mob's AI loses sight of the threatened target.
// Subtypes.
// This one's pretty dumb, but pirates are dumb anyways and it makes for a good test.
/datum/say_list/pirate
speak = list("Yarr!",
"Yohoho and a bottle of rum...",
"Getting tired of hardtack.",
"What do you do with a drunken sailor...",
"One day, we'll get that big score.",
"They ain't catching this pirate, no siree.")
say_understood = list("Alright, matey.")
say_cannot = list("No, matey.")
say_maybe_target = list("Eh?", "Who goes there?")
say_got_target = list("Yarrrr!", "Just drop your loot and run.")
say_threaten = list("You best leave, this booty is mine.", "No plank to walk on, just walk away.")
say_stand_down = list("Good.", "That's right, run, you lilly livers.")
say_escalate = list("Yarr! That booty is mine!", "Going to gut you, landlubber.")
threaten_sound = 'sound/weapons/TargetOn.ogg'
stand_down_sound = 'sound/weapons/TargetOff.ogg'
// Mercs!
/datum/say_list/merc
speak = list("When are we gonna get out of this chicken-shit outfit?",
"Wish I had better equipment...",
"I knew I should have been a line chef...",
"Fuckin' helmet keeps fogging up.",
"Anyone else smell that?")
emote_see = list("sniffs", "coughs", "taps his foot", "looks around", "checks his equipment")
say_understood = list("Understood!", "Affirmative!")
say_cannot = list("Negative!")
say_maybe_target = list("Who's there?")
say_got_target = list("Engaging!")
say_threaten = list("Get out of here!", "Hey! Private Property!")
say_stand_down = list("Good.")
say_escalate = list("Your funeral!", "Bring it!")
threaten_sound = 'sound/weapons/TargetOn.ogg'
stand_down_sound = 'sound/weapons/TargetOff.ogg'
/datum/say_list/merc/elite // colder. also, actually just assholes.
speak = list("I got better pay on my last job.",
"So, y'think we'll get to shoot anyone today?",
"Fuck, I hate those guys.",
"Would be nice for something to happen, for once.",
"Think those NT shits'll rear their heads?",
"Any of you see anything recently?")
emote_see = list("taps his foot", "looks around coldly", "checks his equipment", "rummages in his webbing")
say_understood = list("Aff.", "Affirmative.", "Copy.", "Understood.")
say_cannot = list("Neg.", "Negative.")
say_maybe_target = list("I heard something.")
say_got_target = list("Oh, good, I needed more range fodder.", "I'm going to enjoy this.", "I see you.", "Not quiet enough.")
say_threaten = list("Hoy, private property, fuck off.", "You're acting mighty bold for a bullet sponge.", "First and last warning; find somewhere else to be.", "I wouldn't do that if I were you.", "Back off or your field medic's getting a bonus.")
say_stand_down = list("Damn it, I was hoping you'd push your luck.", "What, that's it? Pussy.", "And don't come back.", "Good call. Don't do it again.", "Harrumph.", "That'll teach 'ya.")
say_escalate = list("Oh, I'm gonna enjoy this.", "I'm going to enjoy making you regret that.", "Last mistake you'll make.")
/datum/say_list/malf_drone
speak = list("ALERT.","Hostile-ile-ile entities dee-twhoooo-wected.","Threat parameterszzzz- szzet.","Bring sub-sub-sub-systems uuuup to combat alert alpha-a-a.")
emote_see = list("beeps menacingly","whirrs threateningly","scans its immediate vicinity")
say_understood = list("Affirmative.", "Positive.")
say_cannot = list("Denied.", "Negative.")
say_maybe_target = list("Possible threat detected. Investigating.", "Motion detected.", "Investigating.")
say_got_target = list("Threat detected.", "New task: Remove threat.", "Threat removal engaged.", "Engaging target.")
say_threaten = list("Motion detected, judging target...")
say_stand_down = list("Visual lost.", "Error: Target not found.")
say_escalate = list("Viable target found. Removing.", "Engaging target.", "Target judgement complete. Removal required.")
threaten_sound = 'sound/effects/turret/move1.wav'
stand_down_sound = 'sound/effects/turret/move2.wav'
/datum/say_list/crab
emote_hear = list("clicks")
emote_see = list("clacks")
/datum/say_list/spider
emote_hear = list("chitters")
/datum/say_list/hivebot
speak = list(
"Resuming task: Protect area.",
"No threats found.",
"Error: No targets found."
)
emote_hear = list("hums ominously", "whirrs softly", "grinds a gear")
emote_see = list("looks around the area", "turns from side to side")
say_understood = list("Affirmative.", "Positive.")
say_cannot = list("Denied.", "Negative.")
say_maybe_target = list("Possible threat detected. Investigating.", "Motion detected.", "Investigating.")
say_got_target = list("Threat detected.", "New task: Remove threat.", "Threat removal engaged.", "Engaging target.")
/datum/say_list/lizard
emote_hear = list("hisses")
/datum/say_list/crab
emote_hear = list("hisses")
//Vox Pirate Saylist
/datum/say_list/merc/voxpirate
speak = list("Lookings for scrap, yaya.",
"Tank is lookings low.",
"Knowings should haves stayed on the Ark.",
"Quills itchings...",
"Cravings Teshari on stick.",
"Plates locking up. Not good.")
emote_see = list("sniffs", "coughs", "taps his foot", "looks around", "checks his equipment")
say_understood = list("Yayaya!")
say_cannot = list("Skreking negatives!", "Can't do that.")
say_maybe_target = list("Who's theres?", "Is hearing things?")
say_got_target = list("Dust!", "Easy loot!")
say_threaten = list("Gets out of heres!")
say_stand_down = list("Yaya, runs!", "Kikikiki!")
say_escalate = list("Skrek!", "Bringings it!", "Takings shot", "Lock claws!")
//Synth Horror Saylist
/datum/say_list/cyber_horror
speak = list("H@!#$$P M@!$#",
"GHAA!@@#",
"KR@!!N",
"K!@@##L!@@ %!@#E",
"G@#!$ H@!#%",
"H!@%%@ @!E")
emote_hear = list("emits", "groans", "wails", "pleads")
emote_see = list ("stares unblinkingly.", "jitters and twitches.", "emits a synthetic scream.", "rapidly twitches.", "convulses.", "twitches uncontrollably.", "goes stock still.")
say_threaten = list ("FR@#DOM","EN@ T#I$-$","N0$ M^> B@!#")
say_got_target = list("I *#@ Y@%","!E@#$P","F#RR @I","D0@#$ ##OK %","IT $##TS")

View File

@@ -0,0 +1,201 @@
//Pilot
/obj/item/clothing/head/pilot
name = "pilot helmet"
desc = "Standard pilot gear. Protects the head from impacts."
icon_state = "pilot_helmet1"
item_icons = list(slot_head_str = 'icons/mob/pilot_helmet.dmi')
sprite_sheets = list(
SPECIES_TESHARI = 'icons/mob/species/teshari/pilot_helmet.dmi'
)
flags = THICKMATERIAL
armor = list(melee = 20, bullet = 10, laser = 10, energy = 5, bomb = 10, bio = 0, rad = 0)
flags_inv = HIDEEARS
cold_protection = HEAD
min_cold_protection_temperature = HELMET_MIN_COLD_PROTECTION_TEMPERATURE
heat_protection = HEAD
max_heat_protection_temperature = HELMET_MAX_HEAT_PROTECTION_TEMPERATURE
w_class = ITEMSIZE_NORMAL
var/obj/machinery/computer/shuttle_control/shuttle_comp
var/obj/screen/pilot_hud
var/list/images
var/list/raw_images
var/last_status
/obj/item/clothing/head/pilot/Initialize(mapload)
. = ..()
images = list()
raw_images = list()
pilot_hud = new(src)
pilot_hud.screen_loc = "1,1"
pilot_hud.icon = 'icons/obj/piloting_overlay.dmi'
pilot_hud.icon_state = "dimmer"
pilot_hud.layer = SCREEN_LAYER
pilot_hud.plane = PLANE_FULLSCREEN
pilot_hud.mouse_opacity = 0
pilot_hud.alpha = 0
var/image/I
I = image(pilot_hud.icon,pilot_hud,"top_bar",layer=SCREEN_LAYER+1)
I.appearance_flags = RESET_ALPHA
I.alpha = 145
images["top_bar"] = I
raw_images += I
I = image(pilot_hud.icon,pilot_hud,"top_dots",layer=SCREEN_LAYER+1)
I.appearance_flags = RESET_ALPHA
I.alpha = 200
images["topdots"] = I
raw_images += I
I = image(pilot_hud.icon,pilot_hud,"words_discon",layer=SCREEN_LAYER+1) //words_standby, words_flying, words_spool, words_discon
I.appearance_flags = RESET_ALPHA
I.alpha = 200
images["top_words"] = I
raw_images += I
I = image(pilot_hud.icon,pilot_hud,"",layer=SCREEN_LAYER+1)
I.appearance_flags = RESET_ALPHA
I.alpha = 200
images["charging"] = I
raw_images += I
I = image(pilot_hud.icon,pilot_hud,"left_bar",layer=SCREEN_LAYER+1)
I.appearance_flags = RESET_ALPHA
I.alpha = 0
images["left_bar"] = I
raw_images += I
I = image(pilot_hud.icon,pilot_hud,"right_bar",layer=SCREEN_LAYER+1)
I.appearance_flags = RESET_ALPHA
I.alpha = 0
images["right_bar"] = I
raw_images += I
I = image(pilot_hud.icon,pilot_hud,"flyboxes",layer=SCREEN_LAYER+1)
I.appearance_flags = RESET_ALPHA
I.alpha = 0
images["flyboxes"] = I
raw_images += I
I = image(pilot_hud.icon,pilot_hud,"horizon",layer=SCREEN_LAYER+1)
I.appearance_flags = RESET_ALPHA
I.alpha = 0
images["horizon"] = I
raw_images += I
/obj/item/clothing/head/pilot/proc/update_hud(var/status)
if(last_status == status)
return
last_status = status
if(status == SHUTTLE_INTRANSIT)
var/image/I = images["top_words"]
I.icon_state = "words_flying"
I = images["left_bar"]
I.alpha = 200
I = images["right_bar"]
I.alpha = 200
I = images["flyboxes"]
I.alpha = 200
I = images["horizon"]
I.alpha = 200
I = images["charging"]
I.icon_state = ""
animate(pilot_hud,alpha=255,time=3 SECONDS)
else if(status == SHUTTLE_IDLE)
var/image/I = images["top_words"]
I.icon_state = "words_standby"
I = images["left_bar"]
I.alpha = 0
I = images["right_bar"]
I.alpha = 0
I = images["flyboxes"]
I.alpha = 0
I = images["horizon"]
I.alpha = 0
I = images["charging"]
I.icon_state = ""
animate(pilot_hud,alpha=0,time=3 SECONDS)
else if(status == SHUTTLE_WARMUP)
var/image/I = images["top_words"]
I.icon_state = "words_spool"
I = images["left_bar"]
I.alpha = 200
I = images["right_bar"]
I.alpha = 200
I = images["flyboxes"]
I.alpha = 0
I = images["horizon"]
I.alpha = 0
I = images["charging"]
I.icon_state = "charging"
animate(pilot_hud,alpha=255,time=3 SECONDS)
else if(status == "discon")
var/image/I = images["top_words"]
I.icon_state = "words_discon"
I = images["left_bar"]
I.alpha = 0
I = images["right_bar"]
I.alpha = 0
I = images["flyboxes"]
I.alpha = 0
I = images["horizon"]
I.alpha = 0
I = images["charging"]
I.icon_state = ""
animate(pilot_hud,alpha=0,time=3 SECONDS)
/obj/item/clothing/head/pilot/verb/hud_colors()
set name = "Alter HUD color"
set desc = "Change the color of the piloting HUD."
set category = "Object"
set src in usr
var/newcolor = input(usr,"Pick a color!","HUD Color") as null|color
if(newcolor)
for(var/img in list("top_words","left_bar","right_bar","flyboxes"))
var/image/I = images[img]
I.color = newcolor
/obj/item/clothing/head/pilot/Destroy()
for(var/img in raw_images)
var/image/I = img
I.loc = null
shuttle_comp = null
qdel(pilot_hud)
return ..()
/obj/item/clothing/head/pilot/equipped(var/mob/user,var/slot)
. = ..()
if(slot == slot_head && user.client)
user.client.screen |= pilot_hud
user.client.images |= raw_images
/obj/item/clothing/head/pilot/dropped(var/mob/user)
. = ..()
if(user.client)
user.client.screen -= pilot_hud
user.client.images -= raw_images
/obj/item/clothing/head/pilot/alt
name = "pilot helmet"
desc = "Standard pilot gear. Protects the head from impacts. This one has a retractable visor"
icon_state = "pilot_helmet2"
action_button_name = "Toggle Visor"
/obj/item/clothing/head/pilot/alt/attack_self(mob/user as mob)
if(src.icon_state == initial(icon_state))
src.icon_state = "[icon_state]up"
to_chat(user, "You raise the visor on the pilot helmet.")
else
src.icon_state = initial(icon_state)
to_chat(user, "You lower the visor on the pilot helmet.")
update_clothing_icon() //so our mob-overlays update

View File

@@ -0,0 +1,13 @@
/obj/item/reagent_containers/spray/luminol
name = "luminol bottle"
desc = "A bottle containing an odourless, colorless liquid."
icon = 'icons/obj/forensics.dmi'
icon_state = "luminol"
item_state = "cleaner"
amount_per_transfer_from_this = 10
possible_transfer_amounts = list(5,10)
volume = 250
/obj/item/reagent_containers/spray/luminol/Initialize(mapload)
. = ..()
reagents.add_reagent("luminol", 250)

View File

@@ -0,0 +1,138 @@
/obj/item/material/fishing_rod
name = "crude fishing rod"
desc = "A crude rod made for catching fish."
description_info = "A tool usable on water-tiles to attempt to catch fish by swiping it over them.\
You can add or remove cable by wirecutter or coil respectively to allow its use.\
Any food containing things like protein, sugar, or standard nutriment can be attached to the rod, allowing for faster fishing based on the amount.\
You can examine the rod to check if it has bait attached, and examine it automatically if so.\
\
Ctrl clicking the rod will remove any attached bait from the rod."
description_antag = "Some fishing rods can be utilized as long-range, sharp weapons, though their pseudo ranged ability comes at the cost of slow speed."
icon = 'icons/obj/weapons.dmi'
icon_state = "fishing_rod"
item_state = "fishing_rod"
force_divisor = 0.02 //VOREStation Edit
throwforce = 1 //VOREStation Edit
sharp = TRUE
attack_verb = list("whipped", "battered", "slapped", "fished", "hooked")
hitsound = 'sound/weapons/punchmiss.ogg'
applies_material_colour = TRUE
default_material = "wood"
can_dull = FALSE
var/strung = TRUE
var/line_break = TRUE
var/obj/item/reagent_containers/food/snacks/Bait
var/bait_type = /obj/item/reagent_containers/food/snacks
var/cast = FALSE
attackspeed = 3 SECONDS
/obj/item/material/fishing_rod/built
strung = FALSE
/obj/item/material/fishing_rod/examine(mob/M as mob)
..()
if(Bait)
to_chat(M, "<span class='notice'>\The [src] has \the [Bait] hanging on its hook.</span>")
Bait.examine(M)
/obj/item/material/fishing_rod/CtrlClick(mob/user)
if((src.loc == user || Adjacent(user)) && Bait)
Bait.forceMove(get_turf(user))
to_chat(user, "<span class='notice'>You remove the bait from \the [src].</span>")
Bait = null
else
..()
/obj/item/material/fishing_rod/Initialize(mapload)
..()
update_icon()
/obj/item/material/fishing_rod/attackby(obj/item/I as obj, mob/user as mob)
if(I.is_wirecutter() && strung)
strung = FALSE
to_chat(user, "<span class='notice'>You cut \the [src]'s string!</span>")
update_icon()
return
else if(istype(I, /obj/item/stack/cable_coil) && !strung)
var/obj/item/stack/cable_coil/C = I
if(C.amount < 5)
to_chat(user, "<span class='warning'>You do not have enough length in \the [C] to string this!</span>")
return
if(do_after(user, rand(10 SECONDS, 20 SECONDS)))
C.use(5)
strung = TRUE
to_chat(user, "<span class='notice'>You string \the [src]!</span>")
update_icon()
return
else if(istype(I, bait_type))
if(Bait)
Bait.forceMove(get_turf(user))
to_chat(user, "<span class='notice'>You swap \the [Bait] with \the [I].</span>")
Bait = I
user.drop_from_inventory(Bait)
Bait.forceMove(src)
update_bait()
return ..()
/obj/item/material/fishing_rod/update_icon()
overlays.Cut()
..()
if(strung)
overlays += image(icon, "[icon_state]_string")
/obj/item/material/fishing_rod/proc/update_bait()
if(istype(Bait, bait_type))
var/foodvolume
for(var/datum/reagent/re in Bait.reagents.reagent_list)
if(re.id == "nutriment" || re.id == "protein" || re.id == "glucose" || re.id == "fishbait")
foodvolume += re.volume
toolspeed = initial(toolspeed) * min(0.75, (0.5 / max(0.5, (foodvolume / Bait.reagents.maximum_volume))))
else
toolspeed = initial(toolspeed)
/obj/item/material/fishing_rod/proc/consume_bait()
if(Bait)
qdel(Bait)
Bait = null
return TRUE
return FALSE
/obj/item/material/fishing_rod/attack(var/mob/M as mob, var/mob/user as mob, var/def_zone)
if(cast)
to_chat(user, "<span class='notice'>You cannot cast \the [src] when it is already in use!</span>")
return FALSE
update_bait()
return ..()
/obj/item/material/fishing_rod/modern
name = "fishing rod"
desc = "A refined rod for catching fish."
icon_state = "fishing_rod_modern"
item_state = "fishing_rod"
reach = 4
attackspeed = 2 SECONDS
default_material = "titanium"
toolspeed = 0.75
/obj/item/material/fishing_rod/modern/built
strung = FALSE
/obj/item/material/fishing_rod/modern/cheap //A rod sold by the fishing vendor. Done so that the rod sold by mining reward vendors doesn't loose its value.
name = "cheap fishing rod"
desc = "Mass produced, but somewhat reliable."
default_material = "plastic"
toolspeed = 0.9
/obj/item/material/fishing_rod/modern/strong
desc = "A extremely refined rod for catching fish."
default_material = "durasteel"
toolspeed = 0.5

View File

@@ -0,0 +1,166 @@
#define DRINK_ICON_FILE 'icons/pdrink.dmi'
/var/const/DRINK_FIZZ = "fizz"
/var/const/DRINK_ICE = "ice"
/var/const/DRINK_ICON_DEFAULT = ""
/var/const/DRINK_ICON_NOISY = "_noise"
/obj/item/reagent_containers/food/drinks/glass2
name = "glass" // Name when empty
var/base_name = "glass" // Name to put in front of drinks, i.e. "[base_name] of [contents]"
desc = "A generic drinking glass." // Description when empty
icon = DRINK_ICON_FILE
var/base_icon = "square" // Base icon name
volume = 30
var/list/filling_states // List of percentages full that have icons
var/list/extras = list() // List of extras. Two extras maximum
var/rim_pos
center_of_mass = list("x"=16, "y"=10)
amount_per_transfer_from_this = 5
possible_transfer_amounts = list(5,10,15,30)
flags = OPENCONTAINER
matter = list("glass" = 60)
/obj/item/reagent_containers/food/drinks/glass2/examine(mob/M as mob)
..()
for(var/I in extras)
if(istype(I, /obj/item/glass_extra))
to_chat(M, "There is \a [I] in \the [src].")
else if(istype(I, /obj/item/reagent_containers/food/snacks/fruit_slice))
to_chat(M, "There is \a [I] on the rim.")
else
to_chat(M, "There is \a [I] somewhere on the glass. Somehow.")
if(has_ice())
to_chat(M, "There is some ice floating in the drink.")
if(has_fizz())
to_chat(M, "It is fizzing slightly.")
/obj/item/reagent_containers/food/drinks/glass2/proc/has_ice()
if(reagents.reagent_list.len > 0)
var/datum/reagent/R = reagents.get_master_reagent()
if(!((R.id == "ice") || ("ice" in R.glass_special))) // if it's not a cup of ice, and it's not already supposed to have ice in, see if the bartender's put ice in it
if(reagents.has_reagent("ice", reagents.total_volume / 10)) // 10% ice by volume
return 1
return 0
/obj/item/reagent_containers/food/drinks/glass2/proc/has_fizz()
if(reagents.reagent_list.len > 0)
var/datum/reagent/R = reagents.get_master_reagent()
if(!("fizz" in R.glass_special))
var/totalfizzy = 0
for(var/datum/reagent/re in reagents.reagent_list)
if("fizz" in re.glass_special)
totalfizzy += re.volume
if(totalfizzy >= reagents.total_volume / 5) // 20% fizzy by volume
return 1
return 0
/obj/item/reagent_containers/food/drinks/glass2/Initialize(mapload)
..()
icon_state = base_icon
/obj/item/reagent_containers/food/drinks/glass2/on_reagent_change()
..()
update_icon()
/obj/item/reagent_containers/food/drinks/glass2/proc/can_add_extra(obj/item/glass_extra/GE)
if(!("[base_icon]_[GE.glass_addition]left" in icon_states(DRINK_ICON_FILE)))
return 0
if(!("[base_icon]_[GE.glass_addition]right" in icon_states(DRINK_ICON_FILE)))
return 0
return 1
/obj/item/reagent_containers/food/drinks/glass2/update_icon()
underlays.Cut()
if (reagents.reagent_list.len > 0)
var/datum/reagent/R = reagents.get_master_reagent()
name = "[base_name] of [R.glass_name ? R.glass_name : "something"]"
desc = R.glass_desc ? R.glass_desc : initial(desc)
var/list/under_liquid = list()
var/list/over_liquid = list()
var/amnt = 100
var/percent = round((reagents.total_volume / volume) * 100)
for(var/k in filling_states)
if(percent <= k)
amnt = k
break
if(has_ice())
over_liquid |= "[base_icon][amnt]_ice"
if(has_fizz())
over_liquid |= "[base_icon][amnt]_fizz"
for(var/S in R.glass_special)
if("[base_icon]_[S]" in icon_states(DRINK_ICON_FILE))
under_liquid |= "[base_icon]_[S]"
else if("[base_icon][amnt]_[S]" in icon_states(DRINK_ICON_FILE))
over_liquid |= "[base_icon][amnt]_[S]"
for(var/k in under_liquid)
underlays += image(DRINK_ICON_FILE, src, k, -3)
var/image/filling = image(DRINK_ICON_FILE, src, "[base_icon][amnt][R.glass_icon]", -2)
filling.color = reagents.get_color()
underlays += filling
for(var/k in over_liquid)
underlays += image(DRINK_ICON_FILE, src, k, -1)
else
name = initial(name)
desc = initial(desc)
var/side = "left"
for(var/item in extras)
if(istype(item, /obj/item/glass_extra))
var/obj/item/glass_extra/GE = item
var/image/I = image(DRINK_ICON_FILE, src, "[base_icon]_[GE.glass_addition][side]")
if(GE.glass_color)
I.color = GE.glass_color
underlays += I
else if(istype(item, /obj/item/reagent_containers/food/snacks/fruit_slice))
var/obj/FS = item
var/image/I = image(FS)
var/fsy = rim_pos[1] - 20
var/fsx = rim_pos[side == "left" ? 2 : 3] - 16
var/matrix/M = matrix()
M.Scale(0.5)
M.Translate(fsx, fsy)
I.transform = M
underlays += I
else continue
side = "right"
/obj/item/reagent_containers/food/drinks/glass2/afterattack(var/obj/target, var/mob/user, var/proximity)
if(user.a_intent == INTENT_HARM) //We only want splashing to be done if they are on harm intent.
if(!is_open_container() || !proximity)
return 1
if(standard_splash_mob(user, target))
return 1
if(reagents && reagents.total_volume) //They are on harm intent, aka wanting to spill it.
to_chat(user, "<span class='notice'>You splash the solution onto [target].</span>")
reagents.splash(target, reagents.total_volume)
return 1
..()
/obj/item/reagent_containers/food/drinks/glass2/standard_feed_mob(var/mob/user, var/mob/target)
if(afterattack(target, user)) //Check to see if harm intent & splash.
return
else
..() //If they're splashed, no need to do anything else.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,198 @@
// The base subtype for assemblies that can be worn. Certain pieces will have more or less capabilities
// E.g. Glasses have less room than something worn over the chest.
// Note that the electronic assembly is INSIDE the object that actually gets worn, in a similar way to implants.
/obj/item/electronic_assembly/clothing
name = "electronic clothing"
icon_state = "circuitry" // Needs to match the clothing's base icon_state.
desc = "It's a case, for building machines attached to clothing."
w_class = ITEMSIZE_SMALL
max_components = IC_COMPONENTS_BASE
max_complexity = IC_COMPLEXITY_BASE
var/obj/item/clothing/clothing = null
/obj/item/electronic_assembly/clothing/nano_host()
return clothing
/obj/item/electronic_assembly/clothing/resolve_nano_host()
return clothing
/obj/item/electronic_assembly/clothing/update_icon()
..()
clothing.icon_state = icon_state
// We don't need to update the mob sprite since it won't (and shouldn't) actually get changed.
// This is 'small' relative to the size of regular clothing assemblies.
/obj/item/electronic_assembly/clothing/small
max_components = IC_COMPONENTS_BASE / 2
max_complexity = IC_COMPLEXITY_BASE / 2
w_class = ITEMSIZE_TINY
// Ditto.
/obj/item/electronic_assembly/clothing/large
max_components = IC_COMPONENTS_BASE * 2
max_complexity = IC_COMPLEXITY_BASE * 2
w_class = ITEMSIZE_NORMAL
// This is defined higher up, in /clothing to avoid lots of copypasta.
/obj/item/clothing
var/obj/item/electronic_assembly/clothing/IC = null
var/obj/item/integrated_circuit/built_in/action_button/action_circuit = null // This gets pulsed when someone clicks the button on the hud.
/obj/item/clothing/emp_act(severity)
if(IC)
IC.emp_act(severity)
..()
/obj/item/clothing/examine(mob/user)
if(IC)
IC.examine(user)
..()
/obj/item/clothing/attackby(obj/item/I, mob/user)
if(IC)
// This needs to be done in a better way...
if(I.is_crowbar() || I.is_screwdriver() || istype(I, /obj/item/integrated_circuit) || istype(I, /obj/item/cell/device) || istype(I, /obj/item/integrated_electronics) )
IC.attackby(I, user)
else
..()
/obj/item/clothing/attack_self(mob/user)
if(IC)
if(IC.opened)
IC.attack_self(user)
else
action_circuit.do_work()
else
..()
/obj/item/clothing/Moved(oldloc)
if(IC)
IC.on_loc_moved(oldloc)
else
..()
/obj/item/clothing/on_loc_moved(oldloc)
if(IC)
IC.on_loc_moved(oldloc)
else
..()
// Does most of the repeatative setup.
/obj/item/clothing/proc/setup_integrated_circuit(new_type)
// Set up the internal circuit holder.
IC = new new_type(src)
IC.clothing = src
IC.name = name
// Clothing assemblies can be triggered by clicking on the HUD. This allows that to occur.
action_circuit = new(src.IC)
IC.force_add_circuit(action_circuit)
action_button_name = "Activate [name]"
/obj/item/clothing/Destroy()
if(IC)
IC.clothing = null
action_circuit = null // Will get deleted by qdel-ing the IC assembly.
qdel(IC)
return ..()
// Specific subtypes.
// Jumpsuit.
/obj/item/clothing/under/circuitry
name = "electronic jumpsuit"
desc = "It's a wearable case for electronics. This on is a black jumpsuit with wiring weaved into the fabric."
icon_state = "circuitry"
worn_state = "circuitry"
/obj/item/clothing/under/circuitry/Initialize(mapload)
setup_integrated_circuit(/obj/item/electronic_assembly/clothing)
return ..()
// Gloves.
/obj/item/clothing/gloves/circuitry
name = "electronic gloves"
desc = "It's a wearable case for electronics. This one is a pair of black gloves, with wires woven into them. A small \
device with a screen is attached to the left glove."
icon_state = "circuitry"
item_state = "circuitry"
/obj/item/clothing/gloves/circuitry/Initialize(mapload)
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small)
return ..()
// Watch.
/obj/item/clothing/gloves/ewatch
name = "electronic watch"
desc = "It's a wearable case for electronics. This one is a digital watch, with an antenna and button array attatched to it.\
Practical and stylish!"
icon_state = "communicator"
item_state = "ewatch"
/obj/item/clothing/gloves/circuitry/Initialize(mapload)
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small)
return ..()
// Glasses.
/obj/item/clothing/glasses/circuitry
name = "electronic goggles"
desc = "It's a wearable case for electronics. This one is a pair of goggles, with wiring sticking out. \
Could this augment your vision?" // Sadly it won't, or at least not yet.
icon_state = "circuitry"
item_state = "night" // The on-mob sprite would be identical anyways.
/obj/item/clothing/glasses/circuitry/Initialize(mapload)
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small)
return ..()
// Shoes
/obj/item/clothing/shoes/circuitry
name = "electronic boots"
desc = "It's a wearable case for electronics. This one is a pair of boots, with wires attached to a small \
cover."
icon_state = "circuitry"
item_state = "circuitry"
/obj/item/clothing/shoes/circuitry/Initialize(mapload)
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small)
return ..()
// Head
/obj/item/clothing/head/circuitry
name = "electronic headwear"
desc = "It's a wearable case for electronics. This one appears to be a very technical-looking piece that \
goes around the collar, with a heads-up-display attached on the right."
icon_state = "circuitry"
item_state = "circuitry"
/obj/item/clothing/head/circuitry/Initialize(mapload)
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small)
return ..()
// Ear
/obj/item/clothing/ears/circuitry
name = "electronic earwear"
desc = "It's a wearable case for electronics. This one appears to be a technical-looking headset."
icon = 'icons/obj/clothing/ears.dmi'
icon_state = "circuitry"
item_state = "circuitry"
/obj/item/clothing/ears/circuitry/Initialize(mapload)
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/small)
return ..()
// Exo-slot
/obj/item/clothing/suit/circuitry
name = "electronic chestpiece"
desc = "It's a wearable case for electronics. This one appears to be a very technical-looking vest, that \
almost looks professionally made, however the wiring popping out betrays that idea."
icon_state = "circuitry"
item_state = "circuitry"
/obj/item/clothing/suit/circuitry/Initialize(mapload)
setup_integrated_circuit(/obj/item/electronic_assembly/clothing/large)
return ..()

View File

@@ -0,0 +1,207 @@
var/global/list/total_extraction_beacons = list()
/obj/item/extraction_pack
name = "fulton extraction pack"
desc = "A balloon pack that can be used to extract equipment or personnel to a Fulton Recovery Beacon. Anything not bolted down can be moved. Link the pack to a beacon by using the pack in hand."
icon = 'icons/obj/fulton.dmi'
icon_state = "extraction_pack"
w_class = ITEMSIZE_NORMAL
var/obj/structure/extraction_point/beacon
var/list/beacon_networks = list("station")
var/uses_left = 3
var/can_use_indoors = FALSE
var/safe_for_living_creatures = 1
var/stuntime = 15
/obj/item/extraction_pack/wormhole
name = "wormhole fulton extraction pack"
desc = "A balloon pack with integrated wormhole technology and less disruptive movement that can be used to extract equipment or personnel to a Fulton Recovery Beacon. Anything not bolted down can be moved. Link the pack to a beacon by using the pack in hand."
can_use_indoors = TRUE
stuntime = 3
/obj/item/extraction_holdercrate
name = "extraction crate"
desc = "A regular old crate."
icon = 'icons/obj/storage.dmi'
icon_state = "phoroncrate"
/obj/item/extraction_pack/examine()
. = ..()
usr.show_message("It has [uses_left] use\s remaining.", 1)
/obj/item/extraction_pack/attack_self(mob/user)
var/list/possible_beacons = list()
for(var/B in global.total_extraction_beacons)
var/obj/structure/extraction_point/EP = B
if(EP.beacon_network in beacon_networks)
possible_beacons += EP
if(!possible_beacons.len)
to_chat(user, "There are no extraction beacons in existence!")
return
else
var/A
A = input("Select a beacon to connect to", "Balloon Extraction Pack", A) as null|anything in possible_beacons
if(!A)
return
beacon = A
to_chat(user, "You link the extraction pack to the beacon system.")
/obj/item/extraction_pack/afterattack(atom/movable/A, mob/living/carbon/user, flag, params)
if(!beacon)
to_chat(user, "[src] is not linked to a beacon, and cannot be used.")
return
if(!can_use_indoors)
var/turf/T = get_turf(A)
if(T && !T.outdoors)
to_chat(user, "[src] can only be used on things that are outdoors!")
return
if(!flag)
return
if(!istype(A))
return
else
if(!safe_for_living_creatures && check_for_living_mobs(A))
to_chat(user, "[src] is not safe for use with living creatures, they wouldn't survive the trip back!")
return
if(!isturf(A.loc)) // no extracting stuff inside other stuff
return
if(A.anchored)
return
to_chat(user, "<span class='notice'>You start attaching the pack to [A]...</span>")
if(do_after(user,50,target=A))
to_chat(user, "<span class='notice'>You attach the pack to [A] and activate it.</span>")
/* No components, sorry. No convienence for you!
if(loc == user && istype(user.back, /obj/item/storage/backpack))
var/obj/item/storage/backpack/B = user.back
B.SendSignal(COMSIG_TRY_STORAGE_INSERT, src, user, FALSE, FALSE)
*/
uses_left--
if(uses_left <= 0)
user.drop_from_inventory(src, A)
var/mutable_appearance/balloon
var/mutable_appearance/balloon2
var/mutable_appearance/balloon3
if(isliving(A))
var/mob/living/M = A
M.AdjustStunned(10) // Keep them from moving during the duration of the extraction
if(M.buckled)
M.buckled.unbuckle_mob(M)
else
A.anchored = TRUE
A.density = FALSE
var/obj/effect/extraction_holder/holder_obj = new(A.loc)
holder_obj.appearance = /obj/item/extraction_holdercrate
A.forceMove(holder_obj)
balloon2 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_expand")
balloon2.pixel_y = 18
balloon2.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
holder_obj.add_overlay(balloon2)
sleep(4)
balloon = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_balloon")
balloon.pixel_y = 18
balloon.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
holder_obj.cut_overlay(balloon2)
holder_obj.add_overlay(balloon)
playsound(holder_obj.loc, 'sound/items/fulext_deploy.wav', 50, 1, -3)
update_icon(A)
animate(holder_obj, pixel_z = 10, time = 20)
sleep(20)
animate(holder_obj, pixel_z = 15, time = 10)
sleep(10)
animate(holder_obj, pixel_z = 10, time = 10)
sleep(10)
animate(holder_obj, pixel_z = 15, time = 10)
sleep(10)
animate(holder_obj, pixel_z = 10, time = 10)
sleep(10)
playsound(holder_obj.loc, 'sound/items/fultext_launch.wav', 50, 1, -3)
animate(holder_obj, pixel_z = 1000, time = 30)
if(ishuman(A))
var/mob/living/carbon/L = A
L.AdjustStunned(stuntime)
L.drowsyness = 0
update_icon(A)
sleep(30)
var/list/flooring_near_beacon = list()
for(var/turf/simulated/floor/floor in orange(1, beacon))
flooring_near_beacon += floor
holder_obj.forceMove(pick(flooring_near_beacon))
animate(holder_obj, pixel_z = 10, time = 50)
sleep(50)
animate(holder_obj, pixel_z = 15, time = 10)
sleep(10)
animate(holder_obj, pixel_z = 10, time = 10)
sleep(10)
balloon3 = mutable_appearance('icons/obj/fulton_balloon.dmi', "fulton_retract")
balloon3.pixel_y = 10
balloon3.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM
holder_obj.cut_overlay(balloon)
holder_obj.add_overlay(balloon3)
sleep(4)
holder_obj.cut_overlay(balloon3)
A.anchored = FALSE // An item has to be unanchored to be extracted in the first place.
A.density = initial(A.density)
animate(holder_obj, pixel_z = 0, time = 5)
sleep(5)
A.forceMove(holder_obj.loc)
qdel(holder_obj)
if(uses_left <= 0)
qdel(src)
/obj/item/fulton_core
name = "extraction beacon signaller"
desc = "Emits a signal which fulton recovery devices can lock onto. Activate in hand to create a beacon."
icon = 'icons/obj/stock_parts.dmi'
icon_state = "subspace_amplifier"
/obj/item/fulton_core/attack_self(mob/user)
if(do_after(user,15,target = user) && !QDELETED(src))
new /obj/structure/extraction_point(get_turf(user))
qdel(src)
/obj/structure/extraction_point
name = "fulton recovery beacon"
desc = "A beacon for the fulton recovery system. Activate a pack in your hand to link it to a beacon."
icon = 'icons/obj/fulton.dmi'
icon_state = "extraction_point"
anchored = TRUE
density = FALSE
var/beacon_network = "station"
/obj/structure/extraction_point/Initialize(mapload)
. = ..()
name += " ([rand(100,999)]) ([get_area_name(src, TRUE)])"
global.total_extraction_beacons += src
/obj/structure/extraction_point/Destroy()
global.total_extraction_beacons -= src
..()
/obj/effect/extraction_holder
name = "extraction holder"
desc = "you shouldnt see this"
var/atom/movable/stored_obj
/obj/item/extraction_pack/proc/check_for_living_mobs(atom/A)
if(isliving(A))
var/mob/living/L = A
if(L.stat != DEAD)
return 1
for(var/thing in A.GetAllContents())
if(isliving(A))
var/mob/living/L = A
update_icon()
if(L.stat != DEAD)
return 1
return 0
/obj/effect/extraction_holder/singularity_pull()
return
/obj/effect/extraction_holder/singularity_pull()
return

View File

@@ -0,0 +1,117 @@
/obj/structure/outcrop
name = "outcrop"
desc = "A boring rocky outcrop."
icon = 'icons/obj/outcrop.dmi'
density = 1
throwpass = 1
climbable = 1
anchored = 1
icon_state = "outcrop"
var/mindrop = 5
var/upperdrop = 10
var/outcropdrop = /obj/item/ore/glass
/obj/structure/outcrop/Initialize(mapload)
. = ..()
if(prob(1))
overlays += image(icon, "[initial(icon_state)]-egg")
/obj/structure/outcrop/diamond
name = "shiny outcrop"
desc = "A shiny rocky outcrop."
icon_state = "outcrop-diamond"
mindrop = 2
upperdrop = 4
outcropdrop = /obj/item/ore/diamond
/obj/structure/outcrop/phoron
name = "shiny outcrop"
desc = "A shiny rocky outcrop."
icon_state = "outcrop-phoron"
mindrop = 4
upperdrop = 8
outcropdrop = /obj/item/ore/phoron
/obj/structure/outcrop/iron
name = "rugged outcrop"
desc = "A rugged rocky outcrop."
icon_state = "outcrop-iron"
mindrop = 10
upperdrop = 20
outcropdrop = /obj/item/ore/iron
/obj/structure/outcrop/coal
name = "rugged outcrop"
desc = "A rugged rocky outcrop."
icon_state = "outcrop-coal"
mindrop = 10
upperdrop = 20
outcropdrop = /obj/item/ore/coal
/obj/structure/outcrop/lead
name = "rugged outcrop"
desc = "A rugged rocky outcrop."
icon_state = "outcrop-lead"
mindrop = 2
upperdrop = 5
outcropdrop = /obj/item/ore/lead
/obj/structure/outcrop/gold
name = "hollow outcrop"
desc = "A hollow rocky outcrop."
icon_state = "outcrop-gold"
mindrop = 4
upperdrop = 6
outcropdrop = /obj/item/ore/gold
/obj/structure/outcrop/silver
name = "hollow outcrop"
desc = "A hollow rocky outcrop."
icon_state = "outcrop-silver"
mindrop = 6
upperdrop = 8
outcropdrop = /obj/item/ore/silver
/obj/structure/outcrop/platinum
name = "hollow outcrop"
desc = "A hollow rocky outcrop."
icon_state = "outcrop-platinum"
mindrop = 2
upperdrop = 5
outcropdrop = /obj/item/ore/osmium
/obj/structure/outcrop/uranium
name = "spiky outcrop"
desc = "A spiky rocky outcrop, it glows faintly."
icon_state = "outcrop-uranium"
mindrop = 4
upperdrop = 8
outcropdrop = /obj/item/ore/uranium
/obj/structure/outcrop/attackby(obj/item/W as obj, mob/user as mob)
if (istype(W, /obj/item/pickaxe))
to_chat(user, "<span class='notice'>[user] begins to hack away at \the [src].</span>")
if(do_after(user,40))
to_chat(user, "<span class='notice'>You have finished digging!</span>")
for(var/i=0;i<(rand(mindrop,upperdrop));i++)
new outcropdrop(get_turf(src))
qdel(src)
return
/obj/random/outcrop //In case you want an outcrop without pre-determining the type of ore.
name = "random rock outcrop"
desc = "This is a random rock outcrop."
icon = 'icons/obj/outcrop.dmi'
icon_state = "outcrop-random"
/obj/random/outcrop/item_to_spawn()
return pick(prob(100);/obj/structure/outcrop,
prob(100);/obj/structure/outcrop/iron,
prob(100);/obj/structure/outcrop/coal,
prob(65);/obj/structure/outcrop/silver,
prob(50);/obj/structure/outcrop/gold,
prob(30);/obj/structure/outcrop/uranium,
prob(30);/obj/structure/outcrop/phoron,
prob(7);/obj/structure/outcrop/diamond,
prob(15);/obj/structure/outcrop/platinum,
prob(15);/obj/structure/outcrop/lead)

View File

@@ -0,0 +1,259 @@
// TODO: remove the robot.mmi and robot.cell variables and completely rely on the robot component system
/datum/robot_component/var/name
/datum/robot_component/var/installed = 0
/datum/robot_component/var/powered = 0
/datum/robot_component/var/toggled = 1
/datum/robot_component/var/brute_damage = 0
/datum/robot_component/var/electronics_damage = 0
/datum/robot_component/var/idle_usage = 0 // Amount of power used every MC tick. In joules.
/datum/robot_component/var/active_usage = 0 // Amount of power used for every action. Actions are module-specific. Actuator for each tile moved, etc.
/datum/robot_component/var/max_damage = 30 // HP of this component.
/datum/robot_component/var/mob/living/silicon/robot/owner
// The actual device object that has to be installed for this.
/datum/robot_component/var/external_type = null
// The wrapped device(e.g. radio), only set if external_type isn't null
/datum/robot_component/var/obj/item/wrapped = null
/datum/robot_component/New(mob/living/silicon/robot/R)
src.owner = R
/datum/robot_component/proc/install()
/datum/robot_component/proc/uninstall()
/datum/robot_component/proc/destroy()
var/brokenstate = "broken" // Generic icon
if (istype(wrapped, /obj/item/robot_parts/robot_component))
var/obj/item/robot_parts/robot_component/comp = wrapped
brokenstate = comp.icon_state_broken
if(wrapped)
qdel(wrapped)
wrapped = new/obj/item/broken_device
wrapped.icon_state = brokenstate // Module-specific broken icons! Yay!
// The thing itself isn't there anymore, but some fried remains are.
installed = -1
uninstall()
/datum/robot_component/proc/take_damage(brute, electronics, sharp, edge)
if(installed != 1) return
brute_damage += brute
electronics_damage += electronics
if(brute_damage + electronics_damage >= max_damage) destroy()
/datum/robot_component/proc/heal_damage(brute, electronics)
if(installed != 1)
// If it's not installed, can't repair it.
return 0
brute_damage = max(0, brute_damage - brute)
electronics_damage = max(0, electronics_damage - electronics)
/datum/robot_component/proc/is_powered()
return (installed == 1) && (brute_damage + electronics_damage < max_damage) && (!idle_usage || powered)
/datum/robot_component/proc/update_power_state()
if(toggled == 0)
powered = 0
return
if(owner.cell && owner.cell.charge >= idle_usage)
owner.cell_use_power(idle_usage)
powered = 1
else
powered = 0
// ARMOUR
// Protects the cyborg from damage. Usually first module to be hit
// No power usage
/datum/robot_component/armour
name = "armour plating"
external_type = /obj/item/robot_parts/robot_component/armour
max_damage = 90
// ACTUATOR
// Enables movement.
// Uses no power when idle. Uses 200J for each tile the cyborg moves.
/datum/robot_component/actuator
name = "actuator"
idle_usage = 0
active_usage = 200
external_type = /obj/item/robot_parts/robot_component/actuator
max_damage = 50
//A fixed and much cleaner implementation of /tg/'s special snowflake code.
/datum/robot_component/actuator/is_powered()
return (installed == 1) && (brute_damage + electronics_damage < max_damage)
// POWER CELL
// Stores power (how unexpected..)
// No power usage
/datum/robot_component/cell
name = "power cell"
max_damage = 50
/datum/robot_component/cell/destroy()
..()
owner.cell = null
// RADIO
// Enables radio communications
// Uses no power when idle. Uses 10J for each received radio message, 50 for each transmitted message.
/datum/robot_component/radio
name = "radio"
external_type = /obj/item/robot_parts/robot_component/radio
idle_usage = 15 //it's not actually possible to tell when we receive a message over our radio, so just use 10W every tick for passive listening
active_usage = 75 //transmit power
max_damage = 40
// BINARY RADIO
// Enables binary communications with other cyborgs/AIs
// Uses no power when idle. Uses 10J for each received radio message, 50 for each transmitted message
/datum/robot_component/binary_communication
name = "binary communication device"
external_type = /obj/item/robot_parts/robot_component/binary_communication_device
idle_usage = 5
active_usage = 25
max_damage = 30
// CAMERA
// Enables cyborg vision. Can also be remotely accessed via consoles.
// Uses 10J constantly
/datum/robot_component/camera
name = "camera"
external_type = /obj/item/robot_parts/robot_component/camera
idle_usage = 10
max_damage = 40
var/obj/machinery/camera/camera
/datum/robot_component/camera/New(mob/living/silicon/robot/R)
..()
camera = R.camera
/datum/robot_component/camera/update_power_state()
..()
if (camera)
camera.status = powered
/datum/robot_component/camera/install()
if (camera)
camera.status = 1
/datum/robot_component/camera/uninstall()
if (camera)
camera.status = 0
/datum/robot_component/camera/destroy()
if (camera)
camera.status = 0
// SELF DIAGNOSIS MODULE
// Analyses cyborg's modules, providing damage readouts and basic information
// Uses 1kJ burst when analysis is done
/datum/robot_component/diagnosis_unit
name = "self-diagnosis unit"
active_usage = 1000
external_type = /obj/item/robot_parts/robot_component/diagnosis_unit
max_damage = 30
// HELPER STUFF
// Initializes cyborg's components. Technically, adds default set of components to new borgs
/mob/living/silicon/robot/proc/initialize_components()
components["actuator"] = new/datum/robot_component/actuator(src)
components["radio"] = new/datum/robot_component/radio(src)
components["power cell"] = new/datum/robot_component/cell(src)
components["diagnosis unit"] = new/datum/robot_component/diagnosis_unit(src)
components["camera"] = new/datum/robot_component/camera(src)
components["comms"] = new/datum/robot_component/binary_communication(src)
components["armour"] = new/datum/robot_component/armour(src)
// Checks if component is functioning
/mob/living/silicon/robot/proc/is_component_functioning(module_name)
var/datum/robot_component/C = components[module_name]
return C && C.installed == 1 && C.toggled && C.is_powered()
// Returns component by it's string name
/mob/living/silicon/robot/proc/get_component(var/component_name)
var/datum/robot_component/C = components[component_name]
return C
// COMPONENT OBJECTS
// Component Objects
// These objects are visual representation of modules
/obj/item/broken_device
name = "broken component"
icon = 'icons/obj/robot_component.dmi'
icon_state = "broken"
matter = list(DEFAULT_WALL_MATERIAL = 1000)
/obj/item/broken_device/random
var/list/possible_icons = list("binradio_broken",
"motor_broken",
"armor_broken",
"camera_broken",
"analyser_broken",
"radio_broken")
/obj/item/broken_device/random/Initialize(mapload)
icon_state = pick(possible_icons)
/obj/item/robot_parts/robot_component
icon = 'icons/obj/robot_component.dmi'
icon_state = "working"
var/brute = 0
var/burn = 0
var/icon_state_broken = "broken"
/obj/item/robot_parts/robot_component/binary_communication_device
name = "binary communication device"
icon_state = "binradio"
icon_state_broken = "binradio_broken"
/obj/item/robot_parts/robot_component/actuator
name = "actuator"
icon_state = "motor"
icon_state_broken = "motor_broken"
/obj/item/robot_parts/robot_component/armour
name = "armour plating"
icon_state = "armor"
icon_state_broken = "armor_broken"
/obj/item/robot_parts/robot_component/camera
name = "camera"
icon_state = "camera"
icon_state_broken = "camera_broken"
/obj/item/robot_parts/robot_component/diagnosis_unit
name = "diagnosis unit"
icon_state = "analyser"
icon_state_broken = "analyser_broken"
/obj/item/robot_parts/robot_component/radio
name = "radio"
icon_state = "radio"
icon_state_broken = "radio_broken"

View File

@@ -0,0 +1,34 @@
// Pepper spiders inject condensed capsaicin into their victims.
/datum/category_item/catalogue/fauna/giant_spider/pepper_spider
name = "Giant Spider - Pepper"
desc = "This specific spider has been catalogued as 'Pepper', \
and it belongs to the 'Guard' caste. \
Red makes up a majority of the spider's appearance, including its eyes, with some brown on its body as well. \
<br><br>\
Pepper spiders are named due to producing capsaicin, and using it as a venom to incapacitate their prey, in an \
incredibly painful way. Their raw strength is considerably less than some of the other spiders, however \
they share a similar level of endurance with the other spiders in their caste, making them difficult to put down."
value = CATALOGUER_REWARD_MEDIUM
/mob/living/simple_mob/animal/giant_spider/pepper
desc = "Red and brown, it makes you shudder to look at it. This one has glinting red eyes."
catalogue_data = list(/datum/category_item/catalogue/fauna/giant_spider/pepper_spider)
icon_state = "pepper"
icon_living = "pepper"
icon_dead = "pepper_dead"
maxHealth = 210
health = 210
melee_damage_lower = 8
melee_damage_upper = 15
poison_chance = 20
poison_per_bite = 5
poison_type = "condensedcapsaicin_v"
/mob/living/simple_mob/animal/giant_spider/pepper/Initialize(mapload)
adjust_scale(1.1)
return ..()

View File

@@ -0,0 +1,106 @@
// Shantaks are essentially sif wolves.
/datum/category_item/catalogue/fauna/shantak
name = "Sivian Fauna - Shantak"
desc = "Classification: S Choeros shantak\
<br><br>\
The Shantak is easily recognized by its iridescent, crystaline mane. \
The creature's specially adapted hairs are hardened by a natural hard mineral coating, \
thickest in the mane but present across the whole body. \
As well as giving the Shantak a coat nigh-inpenetrable to all but the most specialized predator, \
their hard, almost metallic coat gives them a slightly musical accent as they move. \
The Shantak uses its powerful foreclaws for both den-building and foraging. \
<br><br>\
Observed to share several square-mile territories with a small number of other individuals, \
the Shantak will rotate between several dens dug deep into the hard earth throughout the year, \
while deftly avoiding others of its species outwith mating season. While other wildlife makes use of these dens, \
the Shantak is fiercely territorial and will defend itself against any creature it perceives as a threat with reckless abandon. \
Their diet consists primarily of fungi and insects found just below the permafrost."
value = CATALOGUER_REWARD_MEDIUM
/mob/living/simple_mob/animal/sif/shantak
name = "shantak"
desc = "A piglike creature with a bright iridiscent mane that sparkles as though lit by an inner light. \
Don't be fooled by its beauty though."
tt_desc = "S Choeros shantak"
catalogue_data = list(/datum/category_item/catalogue/fauna/shantak)
faction = "shantak"
icon_state = "shantak"
icon_living = "shantak"
icon_dead = "shantak_dead"
icon = 'icons/jungle.dmi'
maxHealth = 75
armor_soak = list(
"melee" = 5,
"bullet" = 0,
"laser" = 0,
"energy" = 0,
"bomb" = 0,
"bio" = 0,
"rad" = 0
)
movement_cooldown = 5
melee_damage_lower = 6
melee_damage_upper = 14
base_attack_cooldown = 1 SECOND
melee_attack_delay = 0.5 SECONDS
attack_armor_pen = 5
attack_sharp = TRUE
attack_edge = TRUE
attacktext = list("gouged")
say_list_type = /datum/say_list/shantak
/datum/say_list/shantak
speak = list("Shuhn.","Shrunnph?","Shunpf.")
emote_see = list("scratches the ground", "shakes out its mane", "clinks gently as it moves")
// The pack leader.
// Will command other shantaks to follow it.
/mob/living/simple_mob/animal/sif/shantak/leader
name = "big shantak"
desc = "A piglike creature with a bright iridiscent mane that sparkles as though lit by an inner light. \
This one seems bigger than the others, and has a commanding presence."
icon_scale_x = 1.5
icon_scale_y = 1.5
maxHealth = 125
player_msg = "You have the ability to <b>command other shantaks to follow you</b>."
/mob/living/simple_mob/animal/sif/shantak/leader/verb/rally_pack()
set name = "Rally Pack"
set desc = "Commands your fellow packmembers to follow you, the leader."
set category = "Abilities"
for(var/mob/living/simple_mob/animal/sif/shantak/S in hearers(7, src))
if(istype(S, /mob/living/simple_mob/animal/sif/shantak/leader)) // Leaders won't follow other leaders. Also avoids trying to follow ourselves.
continue
if(!S.ai_holder)
continue
if(S.faction != src.faction)
continue
var/datum/ai_holder/AI = S.ai_holder
AI.set_follow(src)
// Variant that automatically commands nearby allies to follow it when created.
// Suggested to spawn last so it can rally up all the shantaks easily before hunting for tasty explorers.
/mob/living/simple_mob/animal/sif/shantak/leader/autofollow/Initialize(mapload)
rally_pack()
return ..()
// These ones only retaliate. Used for a PoI.
/mob/living/simple_mob/animal/sif/shantak/retaliate
ai_holder_type = /datum/ai_holder/simple_mob/retaliate
//Vorestation Addition
/mob/living/simple_mob/animal/sif/shantak/scruffy
name = "Scruffy"
ai_holder_type = /datum/ai_holder/simple_mob/passive
makes_dirt = 0
faction = "neutral"

View File

@@ -0,0 +1,41 @@
// Ranged, and capable of flight.
/datum/category_item/catalogue/technology/hoverpod
name = "Voidcraft - Hoverpod"
desc = "This is a small space-capable craft that has a round design. Can hold up to one pilot, \
and sometimes one or two passengers, with the right modifications made. \
Hoverpods have existed for a very long time, and the design has remained more or less consistant over its life. \
They carved out a niche in short ranged transportation of cargo or crew while in space, \
as they were more efficient compared to using a shuttle, and required less infrastructure to use due to being compact enough \
to use airlocks. As such, they acted as a sort of bridge between being EVA in a spacesuit, and being inside a 'real' spacecraft.\
<br><br>\
In recent times, the Hoverpod is seen as outdated by some, as newer solutions to that niche now exist, however it remains an ancient favorite."
value = CATALOGUER_REWARD_EASY
/mob/living/simple_mob/mechanical/mecha/hoverpod
name = "hover pod"
desc = "Stubby and round, this space-capable craft is an ancient favorite. It has a jury-rigged welder-laser."
catalogue_data = list(/datum/category_item/catalogue/technology/hoverpod)
icon_state = "engineering_pod"
movement_sound = 'sound/machines/hiss.ogg'
wreckage = /obj/structure/loot_pile/mecha/hoverpod
maxHealth = 150
hovering = TRUE // Can fly.
projectiletype = /obj/item/projectile/beam
base_attack_cooldown = 2 SECONDS
var/datum/effect_system/ion_trail_follow/ion_trail
/mob/living/simple_mob/mechanical/mecha/hoverpod/manned
pilot_type = /mob/living/simple_mob/humanoid/merc/ranged
/mob/living/simple_mob/mechanical/mecha/hoverpod/Initialize(mapload)
ion_trail = new /datum/effect_system/ion_trail_follow()
ion_trail.set_up(src)
ion_trail.start()
return ..()
/mob/living/simple_mob/mechanical/mecha/hoverpod/Process_Spacemove(var/check_drift = 0)
return TRUE

View File

@@ -0,0 +1,141 @@
// Mecha simple_mobs are essentially fake mechs. Generally tough and scary to fight.
// By default, they're automatically piloted by some kind of drone AI. They can be set to be "piloted" instead with a var.
// Tries to be as similar to the real deal as possible.
/mob/living/simple_mob/mechanical/mecha
name = "mecha"
desc = "A big stompy mech!"
icon = 'icons/mecha/mecha.dmi'
faction = "syndicate"
movement_cooldown = 5
movement_sound = "mechstep" // This gets fed into playsound(), which can also take strings as a 'group' of sound files.
turn_sound = 'sound/mecha/mechturn.ogg'
maxHealth = 300
mob_size = MOB_LARGE
// Very close to the base 'damage_absorption' var on the base mecha class.
armor = list(
"melee" = 20,
"bullet" = 10,
"laser" = 0,
"energy" = 0,
"bomb" = 0,
"bio" = 100,
"rad" = 100
)
response_help = "taps on"
response_disarm = "knocks on"
response_harm = "uselessly hits"
harm_intent_damage = 0
ai_holder_type = /datum/ai_holder/simple_mob/melee
say_list_type = /datum/say_list/malf_drone
var/datum/effect_system/spark_spread/sparks
var/wreckage = /obj/effect/decal/mecha_wreckage/gygax/dark
var/pilot_type = null // Set to spawn a pilot when destroyed. Setting this also makes the mecha vulnerable to things that affect sentient minds.
var/deflect_chance = 10 // Chance to outright stop an attack, just like a normal exosuit.
var/has_repair_droid = FALSE // If true, heals 2 damage every tick and gets a repair droid overlay.
/mob/living/simple_mob/mechanical/mecha/Initialize(mapload)
sparks = new (src)
sparks.set_up(3, 1, src)
sparks.attach(src)
if(!pilot_type)
name = "autonomous [initial(name)]"
desc = "[initial(desc)] It appears to be piloted by a drone intelligence."
else
say_list_type = /datum/say_list/merc
if(has_repair_droid)
update_icon()
return ..()
/mob/living/simple_mob/mechanical/mecha/Destroy()
qdel(sparks)
return ..()
/mob/living/simple_mob/mechanical/mecha/death()
..(0,"explodes!") // Do everything else first.
// Make the exploding more convincing with an actual explosion and some sparks.
sparks.start()
explosion(get_turf(src), 0, 0, 1, 3)
// 'Eject' our pilot, if one exists.
if(pilot_type)
var/mob/living/L = new pilot_type(loc)
L.faction = src.faction
new wreckage(loc) // Leave some wreckage.
qdel(src) // Then delete us since we don't actually have a body.
/mob/living/simple_mob/mechanical/mecha/handle_special()
if(has_repair_droid)
adjustBruteLoss(-2)
adjustFireLoss(-2)
adjustToxLoss(-2)
adjustOxyLoss(-2)
adjustCloneLoss(-2)
..()
/mob/living/simple_mob/mechanical/mecha/update_icon()
..() // Cuts everything else, so do that first.
if(has_repair_droid)
add_overlay(image(icon = 'icons/mecha/mecha_equipment.dmi', icon_state = "repair_droid"))
/mob/living/simple_mob/mechanical/mecha/bullet_act()
. = ..()
sparks.start()
/mob/living/simple_mob/mechanical/mecha/speech_bubble_appearance()
return pilot_type ? "" : ..()
// Piloted mechs are controlled by (presumably) something humanoid so they are vulnerable to certain things.
/mob/living/simple_mob/mechanical/mecha/is_sentient()
return pilot_type ? TRUE : FALSE
/*
// Real mechs can't turn and run at the same time. This tries to simulate that.
// Commented out because the AI can't handle it sadly.
/mob/living/simple_mob/mechanical/mecha/SelfMove(turf/n, direct)
if(direct != dir)
setDir(direct)
return FALSE // We didn't actually move, and returning FALSE means the mob can try to actually move almost immediately and not have to wait the full movement cooldown.
return ..()
*/
/mob/living/simple_mob/mechanical/mecha/bullet_act(obj/item/projectile/P)
if(prob(deflect_chance))
visible_message(span("warning", "\The [P] is deflected by \the [src]'s armor!"))
deflect_sprite()
return 0
return ..()
/mob/living/simple_mob/mechanical/mecha/proc/deflect_sprite()
var/image/deflect_image = image('icons/effects/effects.dmi', "deflect_static")
add_overlay(deflect_image)
sleep(1 SECOND)
cut_overlay(deflect_image)
qdel(deflect_image)
// flick_overlay_view(deflect_image, src, duration = 1 SECOND, gc_after = TRUE)
/mob/living/simple_mob/mechanical/mecha/attackby(obj/item/I, mob/user)
if(prob(deflect_chance))
visible_message(span("warning", "\The [user]'s [I] bounces off \the [src]'s armor!"))
deflect_sprite()
user.setClickCooldown(user.get_attack_speed(I))
return
..()
/mob/living/simple_mob/mechanical/mecha/ex_act(severity)
if(prob(deflect_chance))
severity++ // This somewhat misleadingly makes it less severe.
deflect_sprite()
..(severity)

View File

@@ -0,0 +1,225 @@
// The top-level slime defines. Xenobio slimes and feral slimes will inherit from this.
/mob/living/simple_mob/slime
name = "slime"
desc = "It's a slime."
tt_desc = "A Macrolimbus vulgaris"
icon = 'icons/mob/slime2.dmi'
icon_state = "slime baby"
icon_living = "slime baby"
icon_dead = "slime baby dead"
var/shiny = FALSE // If true, will add a 'shiny' overlay.
var/icon_state_override = null // Used for special slime appearances like the rainbow slime.
color = "#CACACA"
glow_range = 3
glow_intensity = 2
gender = NEUTER
faction = "slime" // Note that slimes are hostile to other slimes of different color regardless of faction (unless Unified).
maxHealth = 150
movement_cooldown = 0
pass_flags = PASSTABLE
makes_dirt = FALSE // Goop
mob_class = MOB_CLASS_SLIME
response_help = "pets"
// Atmos stuff.
minbodytemp = T0C-30
heat_damage_per_tick = 0
cold_damage_per_tick = 40
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
unsuitable_atoms_damage = 0
shock_resist = 0.5 // Slimes are resistant to electricity, and it actually charges them.
taser_kill = FALSE
water_resist = 0 // Slimes are very weak to water.
melee_damage_lower = 10
melee_damage_upper = 15
base_attack_cooldown = 10 // One attack a second.
attack_sound = 'sound/weapons/bite.ogg'
attacktext = list("glomped")
speak_emote = list("chirps")
friendly = list("pokes")
ai_holder_type = /datum/ai_holder/simple_mob/melee
say_list_type = /datum/say_list/slime
var/cores = 1 // How many cores you get when placed in a Processor.
var/obj/item/clothing/head/hat = null // The hat the slime may be wearing.
var/slime_color = "grey" // Used for updating the name and for slime color-ism.
var/unity = FALSE // If true, slimes will consider other colors as their own. Other slimes will see this slime as the same color as well.
var/coretype = /obj/item/slime_extract/grey // What core is inside the slime, and what you get from the processor.
var/reagent_injected = null // Some slimes inject reagents on attack. This tells the game what reagent to use.
var/injection_amount = 5 // This determines how much.
var/mood = ":3" // Icon to use to display 'mood', as an overlay.
can_enter_vent_with = list(/obj/item/clothing/head)
/datum/say_list/slime
speak = list("Blorp...", "Blop...")
emote_see = list("bounces", "jiggles", "sways")
emote_hear = list("squishes")
/mob/living/simple_mob/slime/Initialize(mapload)
verbs += /mob/living/proc/ventcrawl
update_mood()
glow_color = color
handle_light()
update_icon()
return ..()
/mob/living/simple_mob/slime/Destroy()
if(hat)
drop_hat()
return ..()
/mob/living/simple_mob/slime/death()
// Make dead slimes stop glowing.
glow_toggle = FALSE
handle_light()
..()
/mob/living/simple_mob/slime/revive()
// Make revived slimes resume glowing.
glow_toggle = initial(glow_toggle)
handle_light()
..()
/mob/living/simple_mob/slime/update_icon()
..() // Do the regular stuff first.
if(stat != DEAD)
// General slime shine.
var/image/I = image(icon, src, "slime light")
I.appearance_flags = RESET_COLOR
add_overlay(I)
// 'Shiny' overlay, for gemstone-slimes.
if(shiny)
I = image(icon, src, "slime shiny")
I.appearance_flags = RESET_COLOR
add_overlay(I)
// Mood overlay.
I = image(icon, src, "aslime-[mood]")
I.appearance_flags = RESET_COLOR
add_overlay(I)
// Hat simulator.
if(hat)
var/hat_state = hat.item_state ? hat.item_state : hat.icon_state
var/image/I = image('icons/mob/head.dmi', src, hat_state)
I.pixel_y = -7 // Slimes are small.
I.appearance_flags = RESET_COLOR
add_overlay(I)
// Controls the 'mood' overlay. Overrided in subtypes for specific behaviour.
/mob/living/simple_mob/slime/proc/update_mood()
mood = "feral" // This is to avoid another override in the /feral subtype.
/mob/living/simple_mob/slime/proc/unify()
unity = TRUE
// Interface override, because slimes are supposed to attack other slimes of different color regardless of faction.
// (unless Unified, of course).
/mob/living/simple_mob/slime/IIsAlly(mob/living/L)
. = ..()
if(istype(L, /mob/living/simple_mob/slime)) // Slimes should care about their color subfaction compared to another's.
var/mob/living/simple_mob/slime/S = L
if(S.unity || src.unity)
return TRUE
if(S.slime_color == src.slime_color)
return TRUE
else
return FALSE
// The other stuff was already checked in parent proc, and the . variable will implicitly return the correct value.
// Slimes regenerate passively.
/mob/living/simple_mob/slime/handle_special()
adjustOxyLoss(-1)
adjustToxLoss(-1)
adjustFireLoss(-1)
adjustCloneLoss(-1)
adjustBruteLoss(-1)
// Clicked on by empty hand.
/mob/living/simple_mob/slime/attack_hand(mob/living/L)
if(L.a_intent == INTENT_GRAB && hat)
remove_hat(L)
else
..()
// Clicked on while holding an object.
/mob/living/simple_mob/slime/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/clothing/head)) // Handle hat simulator.
give_hat(I, user)
return
//VOREStation Edit Start
var/can_miss = TRUE
for(var/item_type in allowed_attack_types)
if(istype(I, item_type))
can_miss = FALSE
break
//VOREStation Edit End
// Otherwise they're probably fighting the slime.
if(prob(25) && can_miss) //VOREStation Edit
visible_message(span("warning", "\The [user]'s [I] passes right through \the [src]!"))
user.setClickCooldown(user.get_attack_speed(I))
return
..()
// Called when hit with an active slimebaton (or xeno taser).
// Subtypes react differently.
/mob/living/simple_mob/slime/proc/slimebatoned(mob/living/user, amount)
return
// Hat simulator
/mob/living/simple_mob/slime/proc/give_hat(var/obj/item/clothing/head/new_hat, var/mob/living/user)
if(!istype(new_hat))
to_chat(user, span("warning", "\The [new_hat] isn't a hat."))
return
if(hat)
to_chat(user, span("warning", "\The [src] is already wearing \a [hat]."))
return
else
user.drop_item(new_hat)
hat = new_hat
new_hat.forceMove(src)
to_chat(user, span("notice", "You place \a [new_hat] on \the [src]. How adorable!"))
update_icon()
return
/mob/living/simple_mob/slime/proc/remove_hat(var/mob/living/user)
if(!hat)
to_chat(user, "<span class='warning'>\The [src] doesn't have a hat to remove.</span>")
else
hat.forceMove(get_turf(src))
user.put_in_hands(hat)
to_chat(user, "<span class='warning'>You take away \the [src]'s [hat.name]. How mean.</span>")
hat = null
update_icon()
/mob/living/simple_mob/slime/proc/drop_hat()
if(!hat)
return
hat.forceMove(get_turf(src))
hat = null
update_icon()
/mob/living/simple_mob/slime/speech_bubble_appearance()
return "slime"
/mob/living/simple_mob/slime/proc/squish()
playsound(src.loc, 'sound/effects/slime_squish.ogg', 50, 0)
visible_message("<b>\The [src]</b> squishes!")

View File

@@ -0,0 +1,55 @@
// If you add a more comprehensive system, just untick this file.
var/list/z_levels = list()// Each bit re... haha just kidding this is a list of bools now
// If the height is more than 1, we mark all contained levels as connected.
/obj/effect/landmark/map_data/New()
for(var/i = (z - height + 1) to (z-1))
if (z_levels.len <i)
z_levels.len = i
z_levels[i] = TRUE
/obj/effect/landmark/map_data/Initialize(mapload)
..()
return INITIALIZE_HINT_QDEL
// The storage of connections between adjacent levels means some bitwise magic is needed.
/proc/HasAbove(var/z)
if(z >= world.maxz || z < 1 || z > z_levels.len)
return 0
return z_levels[z]
/proc/HasBelow(var/z)
if(z > world.maxz || z < 2 || (z-1) > z_levels.len)
return 0
return z_levels[z-1]
// Thankfully, no bitwise magic is needed here.
/proc/GetAbove(var/atom/atom)
var/turf/turf = get_turf(atom)
if(!turf)
return null
return HasAbove(turf.z) ? get_step(turf, UP) : null
/proc/GetBelow(var/atom/atom)
var/turf/turf = get_turf(atom)
if(!turf)
return null
return HasBelow(turf.z) ? get_step(turf, DOWN) : null
/proc/GetConnectedZlevels(z)
. = list(z)
for(var/level = z, HasBelow(level), level--)
. |= level-1
for(var/level = z, HasAbove(level), level++)
. |= level+1
proc/AreConnectedZLevels(var/zA, var/zB)
return zA == zB || (zB in GetConnectedZlevels(zA))
/proc/get_zstep(ref, dir)
if(dir == UP)
. = GetAbove(ref)
else if (dir == DOWN)
. = GetBelow(ref)
else
. = get_step(ref, dir)

View File

@@ -0,0 +1,179 @@
// // // External Organs
/obj/item/organ/external/chest/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 50 // <-- This is different from the rest
min_broken_damage = 1000
vital = TRUE // <-- This is different from the rest
/obj/item/organ/external/groin/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 30 // <-- This is different from the rest
min_broken_damage = 1000 //Multiple
vital = FALSE
/obj/item/organ/external/head/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 10
min_broken_damage = 1000 //Inheritance
vital = FALSE
/obj/item/organ/external/arm/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 10
min_broken_damage = 1000 //Please
vital = FALSE
/obj/item/organ/external/arm/right/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 10
min_broken_damage = 1000
vital = FALSE
/obj/item/organ/external/leg/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 10
min_broken_damage = 1000
vital = FALSE
/obj/item/organ/external/leg/right/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 10
min_broken_damage = 1000
vital = FALSE
/obj/item/organ/external/hand/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 10
min_broken_damage = 1000
vital = FALSE
/obj/item/organ/external/hand/right/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 10
min_broken_damage = 1000
vital = FALSE
/obj/item/organ/external/foot/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 10
min_broken_damage = 1000
vital = FALSE
/obj/item/organ/external/foot/right/unbreakable/nano
robotic = ORGAN_NANOFORM
encased = FALSE
max_damage = 10
min_broken_damage = 1000
vital = FALSE
// // // Internal Organs
/obj/item/organ/internal/nano
robotic = ORGAN_ROBOT
/obj/item/organ/internal/nano/orchestrator
name = "orchestrator module"
desc = "A small computer, designed for highly parallel workloads."
icon = 'icons/mob/species/protean/protean.dmi'
icon_state = "orchestrator"
organ_tag = O_ORCH
parent_organ = BP_TORSO
vital = TRUE
/obj/item/organ/internal/nano/refactory
name = "refactory module"
desc = "A miniature metal processing unit and nanite factory."
icon = 'icons/mob/species/protean/protean.dmi'
icon_state = "refactory"
organ_tag = O_FACT
parent_organ = BP_TORSO
var/list/materials = list(DEFAULT_WALL_MATERIAL = 0)
var/max_storage = 10000
var/processingbuffs = FALSE
/obj/item/organ/internal/nano/refactory/proc/get_stored_material(var/material)
if(status & ORGAN_DEAD)
return 0
return materials[material] || 0
/obj/item/organ/internal/nano/refactory/proc/add_stored_material(var/material,var/amt)
if(status & ORGAN_DEAD)
return 0
var/increase = min(amt,max(max_storage-materials[material],0))
if(isnum(materials[material]))
materials[material] += increase
else
materials[material] = increase
return increase
/obj/item/organ/internal/nano/refactory/proc/use_stored_material(var/material,var/amt)
if(status & ORGAN_DEAD)
return 0
var/available = materials[material]
//Success
if(available >= amt)
var/new_amt = available-amt
if(new_amt == 0)
materials -= material
else
materials[material] = new_amt
return amt
//Failure
return 0
/obj/item/organ/internal/mmi_holder/posibrain/nano
name = "protean posibrain"
desc = "A more advanced version of the standard posibrain, typically found in protean bodies."
icon = 'icons/mob/species/protean/protean.dmi'
icon_state = "posi"
parent_organ = BP_TORSO
brain_type = /obj/item/mmi/digital/posibrain/nano
/obj/item/organ/internal/mmi_holder/posibrain/nano/robotize()
. = ..()
icon_state = "posi1"
/obj/item/organ/internal/mmi_holder/posibrain/nano/mechassist()
. = ..()
icon_state = "posi1"
/obj/item/organ/internal/mmi_holder/posibrain/nano/update_from_mmi()
. = ..()
icon = initial(icon)
icon_state = "posi1"
stored_mmi.icon_state = "posi1"
stored_mmi.brainmob.languages = owner.languages
// The 'out on the ground' object, not the organ holder
/obj/item/mmi/digital/posibrain/nano
name = "protean posibrain"
desc = "A more advanced version of the standard posibrain, typically found in protean bodies."
icon = 'icons/mob/species/protean/protean.dmi'
icon_state = "posi"
/obj/item/mmi/digital/posibrain/nano/Initialize(mapload)
. = ..()
icon_state = "posi"
/obj/item/mmi/digital/posibrain/nano/request_player()
icon_state = initial(icon_state)
return //We don't do this stuff
/obj/item/mmi/digital/posibrain/nano/reset_search()
icon_state = initial(icon_state)
return //Don't do this either because of the above
/obj/item/mmi/digital/posibrain/nano/transfer_personality()
. = ..()
icon_state = "posi1"
/obj/item/mmi/digital/posibrain/nano/transfer_identity()
. = ..()
icon_state = "posi1"

View File

@@ -0,0 +1,123 @@
/*
** /obj/effect/overmap/event - Actual instances of event hazards on the overmap map
*/
// TO-DO: We need to find a way to get BSAs ported or something to make weaknesses work so crew have a chance to *fight* tiles later - Enzo 9/9/2020
// We don't subtype /obj/effect/overmap/visitable because that'll create sections one can travel to
// and with them "existing" on the overmap Z-level things quickly get odd.
/obj/effect/overmap/event
name = "event"
icon = 'icons/obj/overmap.dmi'
icon_state = "event"
opacity = 1
var/list/events // List of event datum paths
var/list/event_icon_states // Randomly picked from
var/difficulty = EVENT_LEVEL_MODERATE
var/weaknesses // If the BSA can destroy them and with what
var/list/victims // Basically cached events on which Z level
color = "#FFFFFF"
/obj/effect/overmap/event/Initialize(mapload)
. = ..()
icon_state = pick(event_icon_states)
GLOB.overmap_event_handler.update_hazards(loc)
/obj/effect/overmap/event/Move()
var/turf/old_loc = loc
. = ..()
if(.)
GLOB.overmap_event_handler.update_hazards(old_loc)
GLOB.overmap_event_handler.update_hazards(loc)
/obj/effect/overmap/event/forceMove(atom/destination)
var/old_loc = loc
. = ..()
if(.)
GLOB.overmap_event_handler.update_hazards(old_loc)
GLOB.overmap_event_handler.update_hazards(loc)
/obj/effect/overmap/event/Destroy() // Takes a look at this one as well, make sure everything is A-OK
var/turf/T = loc
. = ..()
GLOB.overmap_event_handler.update_hazards(T)
//
// Definitions for specific types!
//
/obj/effect/overmap/event/meteor
name = "asteroid field"
events = list(/datum/event/meteor_wave/overmap)
event_icon_states = list("meteor1", "meteor2", "meteor3", "meteor4")
color = "#DD4444"
difficulty = EVENT_LEVEL_MAJOR
weaknesses = OVERMAP_WEAKNESS_MINING | OVERMAP_WEAKNESS_EXPLOSIVE
/obj/effect/overmap/event/electric
name = "electrical storm"
events = list(/datum/event/electrical_storm/overmap)
color = "#EEEEEE"
opacity = 0
event_icon_states = list("electrical1", "electrical2", "electrical3", "electrical4")
difficulty = EVENT_LEVEL_MAJOR
weaknesses = OVERMAP_WEAKNESS_EMP
/obj/effect/overmap/event/dust
name = "dust cloud"
events = list(/datum/event/dust/overmap)
event_icon_states = list("dust1", "dust2", "dust3", "dust4")
color = "#EEEEEE"
weaknesses = OVERMAP_WEAKNESS_MINING | OVERMAP_WEAKNESS_EXPLOSIVE | OVERMAP_WEAKNESS_FIRE
/obj/effect/overmap/event/ion
name = "ion cloud"
events = list(/datum/event/ionstorm/overmap)
opacity = 0
event_icon_states = list("ion1", "ion2", "ion3", "ion4")
color = "#EEEEEE"
difficulty = EVENT_LEVEL_MAJOR
weaknesses = OVERMAP_WEAKNESS_EMP
/obj/effect/overmap/event/carp
name = "carp shoal"
events = list(/datum/event/carp_migration/overmap)
opacity = 0
event_icon_states = list("carp1", "carp2")
color = "#EEEEEE"
difficulty = EVENT_LEVEL_MODERATE
weaknesses = OVERMAP_WEAKNESS_EXPLOSIVE | OVERMAP_WEAKNESS_FIRE
/obj/effect/overmap/event/carp_heavy
name = "carp school"
events = list(/datum/event/carp_migration/overmap)
opacity = 0
event_icon_states = list("carp3", "carp4")
color = "#DD4444"
difficulty = EVENT_LEVEL_MAJOR
weaknesses = OVERMAP_WEAKNESS_EXPLOSIVE | OVERMAP_WEAKNESS_FIRE
/obj/effect/overmap/event/hostile_migration
name = "unknown lifesigns"
events = list(/datum/event/hostile_migration/overmap)
opacity = 0
event_icon_states = list("rats1", "rats2")
color = "#DD4444"
difficulty = EVENT_LEVEL_MODERATE
weaknesses = OVERMAP_WEAKNESS_EXPLOSIVE | OVERMAP_WEAKNESS_FIRE
/obj/effect/overmap/event/communications_blackout
name = "Ionspheric Bubble"
events = list(/datum/event/communications_blackout/overmap)
opacity = 1
event_icon_states = list("comout1")
color = "#EEEEEE"
difficulty = EVENT_LEVEL_MODERATE
weaknesses = OVERMAP_WEAKNESS_EMP
/obj/effect/overmap/event/cult
name = "eerie signals"
events = list(/datum/event/cult/overmap)
opacity = 0
event_icon_states = list("cultist","cultist2")
color = "#DD4444"
difficulty = EVENT_LEVEL_MAJOR
weaknesses = OVERMAP_WEAKNESS_FIRE

View File

@@ -0,0 +1,67 @@
/obj/machinery/fusion_fuel_compressor
name = "fuel compressor"
icon = 'icons/obj/machines/power/fusion.dmi'
icon_state = "fuel_compressor1"
density = 1
anchored = 1
circuit = /obj/item/circuitboard/fusion_fuel_compressor
/obj/machinery/fusion_fuel_compressor/Initialize(mapload)
. = ..()
default_apply_parts()
/obj/machinery/fusion_fuel_compressor/MouseDrop_T(var/atom/movable/target, var/mob/user)
if(user.incapacitated() || !user.Adjacent(src))
return
return do_special_fuel_compression(target, user)
/obj/machinery/fusion_fuel_compressor/proc/do_special_fuel_compression(var/obj/item/thing, var/mob/user)
if(istype(thing) && thing.reagents && thing.reagents.total_volume && thing.is_open_container())
if(thing.reagents.reagent_list.len > 1)
to_chat(user, "<span class='warning'>The contents of \the [thing] are impure and cannot be used as fuel.</span>")
return 1
if(thing.reagents.total_volume < 50)
to_chat(user, "<span class='warning'>You need at least fifty units of material to form a fuel rod.</span>")
return 1
var/datum/reagent/R = thing.reagents.reagent_list[1]
visible_message("<span class='notice'>\The [src] compresses the contents of \the [thing] into a new fuel assembly.</span>")
var/obj/item/fuel_assembly/F = new(get_turf(src), R.id, R.color)
thing.reagents.remove_reagent(R.id, R.volume)
user.put_in_hands(F)
else if(istype(thing, /obj/machinery/power/supermatter))
var/obj/item/fuel_assembly/F = new(get_turf(src), "supermatter")
visible_message("<span class='notice'>\The [src] compresses \the [thing] into a new fuel assembly.</span>")
qdel(thing)
user.put_in_hands(F)
return 1
return 0
/obj/machinery/fusion_fuel_compressor/attackby(var/obj/item/thing, var/mob/user)
if(default_deconstruction_screwdriver(user, thing))
return
if(default_deconstruction_crowbar(user, thing))
return
if(default_part_replacement(user, thing))
return
if(istype(thing, /obj/item/stack/material))
var/obj/item/stack/material/M = thing
var/datum/material/mat = M.get_material()
if(!mat.is_fusion_fuel)
to_chat(user, "<span class='warning'>It would be pointless to make a fuel rod out of [mat.use_name].</span>")
return
if(M.get_amount() < 25)
to_chat(user, "<span class='warning'>You need at least 25 [mat.sheet_plural_name] to make a fuel rod.</span>")
return
var/obj/item/fuel_assembly/F = new(get_turf(src), mat.name)
visible_message("<span class='notice'>\The [src] compresses the [mat.use_name] into a new fuel assembly.</span>")
M.use(25)
user.put_in_hands(F)
else if(do_special_fuel_compression(thing, user))
return
return ..()

View File

@@ -0,0 +1,12 @@
/obj/item/reagent_containers/spray/windowsealant
name = "Krak-b-gone"
desc = "A spray bottle of silicate sealant for rapid window repair."
icon = 'icons/obj/items_vr.dmi'
icon_state = "windowsealant"
item_state = "spraycan"
possible_transfer_amounts = null
volume = 80
/obj/item/reagent_containers/spray/windowsealant/Initialize(mapload)
..()
reagents.add_reagent("silicate", 80)

View File

@@ -0,0 +1,43 @@
/obj/structure/anomaly_container
name = "anomaly container"
desc = "Used to safely contain and move anomalies."
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "anomaly_container"
density = 1
var/obj/machinery/artifact/contained
/obj/structure/anomaly_container/Initialize(mapload)
. = ..()
var/obj/machinery/artifact/A = locate() in loc
if(A)
contain(A)
/obj/structure/anomaly_container/attack_hand(var/mob/user)
release()
/obj/structure/anomaly_container/attack_robot(var/mob/user)
if(Adjacent(user))
release()
/obj/structure/anomaly_container/proc/contain(var/obj/machinery/artifact/artifact)
if(contained)
return
contained = artifact
artifact.forceMove(src)
underlays += image(artifact)
desc = "Used to safely contain and move anomalies. \The [contained] is kept inside."
/obj/structure/anomaly_container/proc/release()
if(!contained)
return
contained.dropInto(src)
contained = null
underlays.Cut()
desc = initial(desc)
/obj/machinery/artifact/MouseDrop(var/obj/structure/anomaly_container/over_object)
if(istype(over_object) && Adjacent(over_object) && CanMouseDrop(over_object, usr))
Bumped(usr)
over_object.contain(src)

View File

@@ -0,0 +1,128 @@
// Slime cube lives here. Makes Prometheans.
/obj/item/slime_cube
name = "slimy monkey cube"
desc = "Wonder what might come out of this."
icon = 'icons/mob/slime2.dmi'
icon_state = "slime cube"
description_info = "Use in your hand to attempt to create a Promethean. It functions similarly to a positronic brain, in that a ghost is needed to become the Promethean."
var/searching = 0
/obj/item/slime_cube/attack_self(mob/user as mob)
if(!searching)
to_chat(user, "<span class='warning'>You stare at the slimy cube, watching as some activity occurs.</span>")
icon_state = "slime cube active"
searching = 1
request_player()
spawn(60 SECONDS)
reset_search()
// Sometime down the road it would be great to make all of these 'ask ghosts if they want to be X' procs into a generic datum.
/obj/item/slime_cube/proc/request_player()
for(var/mob/observer/dead/O in player_list)
if(!O.MayRespawn())
continue
if(O.client)
if(O.client.prefs.be_special & BE_ALIEN)
question(O.client)
/obj/item/slime_cube/proc/question(var/client/C)
spawn(0)
if(!C)
return
var/response = alert(C, "Someone is requesting a soul for a promethean. Would you like to play as one?", "Promethean request", "Yes", "No", "Never for this round")
if(response == "Yes")
response = alert(C, "Are you sure you want to play as a promethean?", "Promethean request", "Yes", "No")
if(!C || 2 == searching)
return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located.
if(response == "Yes")
transfer_personality(C.mob)
else if(response == "Never for this round")
C.prefs.be_special ^= BE_ALIEN
/obj/item/slime_cube/proc/reset_search() //We give the players sixty seconds to decide, then reset the timer.
icon_state = "slime cube"
if(searching == 1)
searching = 0
var/turf/T = get_turf_or_move(src.loc)
for (var/mob/M in viewers(T))
M.show_message("<span class='warning'>The activity in the cube dies down. Maybe it will spark another time.</span>")
/obj/item/slime_cube/proc/transfer_personality(var/mob/candidate)
announce_ghost_joinleave(candidate, 0, "They are a promethean now.")
src.searching = 2
var/mob/living/carbon/human/S = new(get_turf(src))
S.client = candidate.client
to_chat(S, "<b>You are a promethean, brought into existence on [station_name()].</b>")
S.mind.assigned_role = "Promethean"
S.set_species("Promethean")
S.shapeshifter_set_colour("#2398FF")
visible_message("<span class='warning'>The monkey cube suddenly takes the shape of a humanoid!</span>")
var/newname = sanitize(input(S, "You are a Promethean. Would you like to change your name to something else?", "Name change") as null|text, MAX_NAME_LEN)
if(newname)
S.real_name = newname
S.name = S.real_name
S.dna.real_name = newname
if(S.mind)
S.mind.name = S.name
qdel(src)
// More or less functionally identical to the telecrystal tele.
/obj/item/slime_crystal
name = "lesser slime cystal"
desc = "A small, gooy crystal."
description_info = "This will teleport you to a mostly 'safe' tile when used in-hand, consuming the slime crystal. \
It can also teleport someone else, by throwing it at them or attacking them with it."
icon = 'icons/obj/objects.dmi'
icon_state = "slime_crystal_small"
w_class = ITEMSIZE_TINY
origin_tech = list(TECH_MAGNET = 6, TECH_BLUESPACE = 3)
force = 1 //Needs a token force to ensure you can attack because for some reason you can't attack with 0 force things
/obj/item/slime_crystal/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone)
target.visible_message("<span class='warning'>\The [target] has been teleported with \the [src] by \the [user]!</span>")
safe_blink(target, 14)
qdel(src)
/obj/item/slime_crystal/attack_self(mob/user)
user.visible_message("<span class='warning'>\The [user] teleports themselves with \the [src]!</span>")
safe_blink(user, 14)
qdel(src)
/obj/item/slime_crystal/throw_impact(atom/movable/AM)
if(!istype(AM))
return
if(AM.anchored)
return
AM.visible_message("<span class='warning'>\The [AM] has been teleported with \the [src]!</span>")
safe_blink(AM, 14)
qdel(src)
/obj/item/disposable_teleporter/slime
name = "greater slime crystal"
desc = "A larger, gooier crystal."
description_info = "This will teleport you to a specific area once, when used in-hand."
icon = 'icons/obj/objects.dmi'
icon_state = "slime_crystal_large"
uses = 1
w_class = ITEMSIZE_SMALL
origin_tech = list(TECH_MAGNET = 5, TECH_BLUESPACE = 4)
// Very filling food.
/obj/item/reagent_containers/food/snacks/slime
name = "slimy clump"
desc = "A glob of slime that is thick as honey. For the brave Xenobiologist."
icon_state = "honeycomb"
filling_color = "#FFBB00"
center_of_mass = list("x"=17, "y"=10)
nutriment_amt = 25 // Very filling.
nutriment_desc = list("slime" = 10, "sweetness" = 10, "bliss" = 5)
/obj/item/reagent_containers/food/snacks/slime/Initialize(mapload)
. = ..()
bitesize = 5

View File

@@ -0,0 +1,6 @@
// POI Init
/obj/away_mission_init/frozen_planet
name = "away mission initializer - Frozen Planet"
/obj/away_mission_init/frozen_planet/Initialize(mapload)
return INITIALIZE_HINT_QDEL

View File

@@ -0,0 +1,6 @@
// POI Init
/obj/away_mission_init/gaia_planet
name = "away mission initializer - Gaia Planet"
/obj/away_mission_init/gaia_planet/Initialize(mapload)
return INITIALIZE_HINT_QDEL

View File

@@ -0,0 +1,16 @@
// Shuttle Path for Class D Worlds
// -- Datums -- //
/*/obj/effect/overmap/visitable/sector/class_d
name = "Unknown Planet" // The name of the destination
desc = "Sensors indicate that this is a Class-D World. Those of which are largely barren planets or moons that lack any form of atmosphere and are among the most common types of planets."
icon_state = "globe"
color = "#4e4e4e" // Bright yellow
initial_generic_waypoints = list("poid_main")
*/
// POI Init
/obj/away_mission_init/poi_d
name = "away mission initializer - Class D World"
/obj/away_mission_init/poi_d/Initialize(mapload)
return INITIALIZE_HINT_QDEL

View File

@@ -1,33 +1,33 @@
"a" = (/turf/template_noop,/area/template_noop) "a" = (/turf/template_noop,/area/template_noop)
"q" = (/obj/random/roguemineloot,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "q" = (/obj/random/roguemineloot,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"s" = (/turf/simulated/mineral/vacuum,/area/poi_d/explored) "s" = (/turf/simulated/mineral/vacuum,/area/poi_d/explored)
"u" = (/obj/item/storage/bag/ore,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "u" = (/obj/item/storage/bag/ore,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"K" = (/obj/random/obstruction,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "K" = (/obj/random/obstruction,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"M" = (/obj/random/outcrop,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "M" = (/obj/random/outcrop,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"N" = (/obj/structure/closet/crate/miningcar,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "N" = (/obj/structure/closet/crate/miningcar,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"R" = (/obj/item/flashlight/lantern,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "R" = (/obj/item/flashlight/lantern,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"S" = (/obj/random/obstruction,/turf/simulated/mineral/vacuum,/area/poi_d/explored) "S" = (/obj/random/obstruction,/turf/simulated/mineral/vacuum,/area/poi_d/explored)
"W" = (/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "W" = (/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
(1,1,1) = {" (1,1,1) = {"
aaaaWWWWaaaaaWWWaaaa aaaaWWWWaaaaaWWWaaaa
aWWWWssWWWWWWWWWWaaa aWWWWssWWWWWWWWWWaaa
WWsssssssWWMssssMWaa WWsssssssWWMssssMWaa
WssssWMssWWssssssWWa WssssWMssWWssssssWWa
WsssWqWssWWssssssMWa WsssWqWssWWssssssMWa
WssMWWsssWWsssssssWa WssMWWsssWWsssssssWa
WssWWsssMWWWWWWsssWW WssWWsssMWWWWWWsssWW
WSsqWWMsWWRWMWWMssWW WSsqWWMsWWRWMWWMssWW
WssMWWWKWWNssWWWssWW WssMWWWKWWNssWWWssWW
WsssMWssWussssWKWssW WsssMWssWussssWKWssW
WssssssWWWWMsssWqssW WssssssWWWWMsssWqssW
WssssssWWsWWsssWWssW WssssssWWsWWsssWWssW
WssssWWKsssWWssWWsMW WssssWWKsssWWssWWsMW
WsssWWWssssWWMsMWWWW WsssWWWssssWWMsMWWWW
WssWWWsssssWWqssWWWW WssWWWsssssWWqssWWWW
WMsWWsssqMWWWMsssssW WMsWWsssqMWWWMsssssW
WWWWWssMWWWWsssssssW WWWWWssMWWWWsssssssW
aaWWssssWMWsssssssWW aaWWssssWMWsssssssWW
aaaWMsssssssssWMWWWa aaaWMsssssssssWMWWWa
aaaWWWWWWWWWWWWWWaaa aaaWWWWWWWWWWWWWWaaa
"} "}

View File

@@ -1,57 +1,57 @@
"a" = (/turf/template_noop,/area/template_noop) "a" = (/turf/template_noop,/area/template_noop)
"b" = (/obj/effect/alien/weeds,/mob/living/simple_mob/animal/space/alien/sentinel,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "b" = (/obj/effect/alien/weeds,/mob/living/simple_mob/animal/space/alien/sentinel,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"f" = (/obj/effect/alien/weeds,/mob/living/simple_mob/animal/space/alien/sentinel/praetorian,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "f" = (/obj/effect/alien/weeds,/mob/living/simple_mob/animal/space/alien/sentinel/praetorian,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"h" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds,/mob/living/simple_mob/animal/space/alien/queen/empress,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "h" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds,/mob/living/simple_mob/animal/space/alien/queen/empress,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"i" = (/obj/effect/alien/weeds,/obj/random/multiple/minevault,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "i" = (/obj/effect/alien/weeds,/obj/random/multiple/minevault,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"j" = (/obj/effect/alien/weeds,/obj/random/multiple/voidsuit/mining,/obj/random/humanoidremains,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "j" = (/obj/effect/alien/weeds,/obj/random/multiple/voidsuit/mining,/obj/random/humanoidremains,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"k" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds/node,/mob/living/simple_mob/animal/space/alien/drone,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "k" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds/node,/mob/living/simple_mob/animal/space/alien/drone,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"m" = (/obj/effect/alien/resin/wall,/obj/effect/alien/weeds,/obj/effect/alien/weeds,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "m" = (/obj/effect/alien/resin/wall,/obj/effect/alien/weeds,/obj/effect/alien/weeds,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"n" = (/obj/effect/alien/weeds,/obj/random/tetheraid,/obj/item/gun/energy/phasegun/pistol,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "n" = (/obj/effect/alien/weeds,/obj/random/tetheraid,/obj/item/gun/energy/phasegun/pistol,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"p" = (/turf/simulated/mineral/vacuum,/area/poi_d/explored) "p" = (/turf/simulated/mineral/vacuum,/area/poi_d/explored)
"q" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "q" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"r" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds,/obj/effect/alien/weeds,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "r" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds,/obj/effect/alien/weeds,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"s" = (/obj/effect/alien/weeds,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "s" = (/obj/effect/alien/weeds,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"t" = (/obj/structure/simple_door/resin,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "t" = (/obj/structure/simple_door/resin,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"v" = (/turf/simulated/mineral/floor/vacuum,/area/template_noop) "v" = (/turf/simulated/mineral/floor/vacuum,/area/template_noop)
"w" = (/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "w" = (/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"x" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds,/mob/living/simple_mob/animal/space/alien/sentinel,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "x" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds,/mob/living/simple_mob/animal/space/alien/sentinel,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"y" = (/obj/effect/alien/weeds,/obj/effect/alien/resin/wall,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "y" = (/obj/effect/alien/weeds,/obj/effect/alien/resin/wall,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"z" = (/obj/effect/alien/weeds,/mob/living/simple_mob/animal/space/alien,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "z" = (/obj/effect/alien/weeds,/mob/living/simple_mob/animal/space/alien,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"B" = (/obj/effect/alien/weeds,/obj/item/storage/secure/briefcase/money,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "B" = (/obj/effect/alien/weeds,/obj/item/storage/secure/briefcase/money,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"D" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds,/obj/random/humanoidremains,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "D" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds,/obj/random/humanoidremains,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"E" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds,/obj/random/energy,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "E" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds,/obj/random/energy,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"H" = (/obj/effect/alien/weeds,/obj/random/trash_pile,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "H" = (/obj/effect/alien/weeds,/obj/random/trash_pile,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"K" = (/obj/effect/alien/weeds,/obj/random/medical/pillbottle,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "K" = (/obj/effect/alien/weeds,/obj/random/medical/pillbottle,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"L" = (/obj/effect/alien/weeds,/obj/random/humanoidremains,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "L" = (/obj/effect/alien/weeds,/obj/random/humanoidremains,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"M" = (/obj/effect/alien/resin/wall,/obj/effect/alien/weeds,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "M" = (/obj/effect/alien/resin/wall,/obj/effect/alien/weeds,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"O" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds,/obj/random/tetheraid,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "O" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds,/obj/random/tetheraid,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"P" = (/obj/effect/alien/weeds,/obj/structure/mob_spawner/scanner/xenos,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "P" = (/obj/effect/alien/weeds,/obj/structure/mob_spawner/scanner/xenos,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"R" = (/obj/effect/alien/weeds,/obj/random/energy,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "R" = (/obj/effect/alien/weeds,/obj/random/energy,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"T" = (/obj/effect/alien/resin/wall,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "T" = (/obj/effect/alien/resin/wall,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"U" = (/obj/effect/alien/weeds,/mob/living/simple_mob/animal/space/alien/drone,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "U" = (/obj/effect/alien/weeds,/mob/living/simple_mob/animal/space/alien/drone,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"W" = (/obj/effect/alien/weeds,/obj/random/medical,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "W" = (/obj/effect/alien/weeds,/obj/random/medical,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"X" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds/node,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "X" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds/node,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"Z" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds,/obj/structure/simple_door/resin,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "Z" = (/obj/effect/alien/weeds,/obj/effect/alien/weeds,/obj/structure/simple_door/resin,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
(1,1,1) = {" (1,1,1) = {"
aaaapppppppppppppaaa aaaapppppppppppppaaa
aaapppppppppppppppaa aaapppppppppppppppaa
aapppWssTTTsXsspppaa aapppWssTTTsXsspppaa
apppKOsssqZssssbPppa apppKOsssqZssssbPppa
apppsqsppppppppssppa apppsqsppppppppssppa
appbrrHpppppppsqsppp appbrrHpppppppsqsppp
appsrxpppppiPybqbPpp appsrxpppppiPybqbPpp
appsspppppPRLyyZyypp appsspppppPRLyyZyypp
appXsppppPsfssqqkspp appXsppppPsfssqqkspp
appssppppBUsshqssPpp appssppppBUsshqssPpp
appssppppppPsqLfsppp appssppppppPsqLfsppp
appsDHppipppPEUiPppa appsDHppipppPEUiPppa
apppssMmjnpppppppppa apppssMmjnpppppppppa
apppsqUMpppppppppppa apppsqUMpppppppppppa
appppsXmMppTTpppppaa appppsXmMppTTpppppaa
aappppssstsssswwpwva aappppssstsssswwpwva
aapppppUstszwwwwwwva aapppppUstszwwwwwwva
aaaapppppppppppwwwvv aaaapppppppppppwwwvv
aaaaaappppppppppwwvv aaaaaappppppppppwwvv
aaaaaaaaaaaaaaaavvvv aaaaaaaaaaaaaaaavvvv
"} "}

View File

@@ -1,23 +1,23 @@
"a" = (/turf/template_noop,/area/template_noop) "a" = (/turf/template_noop,/area/template_noop)
"c" = (/turf/simulated/mineral/vacuum,/area/poi_d/explored) "c" = (/turf/simulated/mineral/vacuum,/area/poi_d/explored)
"h" = (/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "h" = (/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"l" = (/obj/random/humanoidremains,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "l" = (/obj/random/humanoidremains,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"n" = (/obj/structure/closet/crate/mimic/cointoss,/obj/random/drinkbottle,/obj/random/drinkbottle,/obj/random/drinkbottle,/turf/simulated/mineral/floor/cave,/area/poi_d/explored) "n" = (/obj/structure/closet/crate/mimic/cointoss,/obj/random/drinkbottle,/obj/random/drinkbottle,/obj/random/drinkbottle,/turf/simulated/mineral/floor/cave,/area/poi_d/explored)
"p" = (/obj/structure/closet/crate/mimic/cointoss,/obj/random/ammo_all,/obj/random/ammo_all,/obj/random/ammo_all,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "p" = (/obj/structure/closet/crate/mimic/cointoss,/obj/random/ammo_all,/obj/random/ammo_all,/obj/random/ammo_all,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"q" = (/obj/structure/closet/crate/mimic/cointoss,/obj/random/medical/pillbottle,/obj/random/medical/pillbottle,/obj/random/medical/pillbottle,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "q" = (/obj/structure/closet/crate/mimic/cointoss,/obj/random/medical/pillbottle,/obj/random/medical/pillbottle,/obj/random/medical/pillbottle,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"r" = (/obj/structure/closet/crate/mimic/cointoss,/obj/random/cash,/obj/random/cash,/obj/random/cash,/obj/random/cash,/obj/random/cash,/turf/simulated/mineral/floor/cave,/area/poi_d/explored) "r" = (/obj/structure/closet/crate/mimic/cointoss,/obj/random/cash,/obj/random/cash,/obj/random/cash,/obj/random/cash,/obj/random/cash,/turf/simulated/mineral/floor/cave,/area/poi_d/explored)
"z" = (/obj/random/humanoidremains,/turf/simulated/mineral/floor/cave,/area/poi_d/explored) "z" = (/obj/random/humanoidremains,/turf/simulated/mineral/floor/cave,/area/poi_d/explored)
"T" = (/turf/simulated/mineral/floor/cave,/area/poi_d/explored) "T" = (/turf/simulated/mineral/floor/cave,/area/poi_d/explored)
(1,1,1) = {" (1,1,1) = {"
aaccccccca aaccccccca
accccccccc accccccccc
acccTrTpcc acccTrTpcc
cccTTTThcc cccTTTThcc
cccnTTThlc cccnTTThlc
cccTTzchqc cccTTzchqc
acTTTccccc acTTTccccc
aTzccccccc aTzccccccc
aaccccccca aaccccccca
aaaaccccaa aaaaccccaa
"} "}

View File

@@ -1,101 +1,101 @@
"aV" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1},/turf/simulated/floor/plating,/area/poi_d/Mountain) "aV" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 1},/turf/simulated/floor/plating,/area/poi_d/Mountain)
"bD" = (/obj/machinery/door/airlock/multi_tile,/turf/simulated/floor/tiled/white,/area/poi_d/Mountain) "bD" = (/obj/machinery/door/airlock/multi_tile,/turf/simulated/floor/tiled/white,/area/poi_d/Mountain)
"da" = (/turf/simulated/mineral/vacuum,/area/poi_d/explored) "da" = (/turf/simulated/mineral/vacuum,/area/poi_d/explored)
"dI" = (/obj/random/trash_pile,/obj/structure/closet/cabinet,/turf/simulated/floor/airless,/area/poi_d/explored) "dI" = (/obj/random/trash_pile,/obj/structure/closet/cabinet,/turf/simulated/floor/airless,/area/poi_d/explored)
"ga" = (/obj/item/stool/padded,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "ga" = (/obj/item/stool/padded,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"gP" = (/obj/machinery/vending/cola,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "gP" = (/obj/machinery/vending/cola,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"gT" = (/obj/random/trash,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "gT" = (/obj/random/trash,/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"gW" = (/obj/machinery/door/airlock/multi_tile,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "gW" = (/obj/machinery/door/airlock/multi_tile,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"hw" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/wall,/area/poi_d/Mountain) "hw" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/wall,/area/poi_d/Mountain)
"hZ" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "hZ" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"is" = (/obj/machinery/light{dir = 8},/turf/simulated/floor/tiled,/area/poi_d/Mountain) "is" = (/obj/machinery/light{dir = 8},/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"js" = (/obj/structure/sign/warning{pixel_x = 32},/turf/simulated/floor/airless,/area/poi_d/explored) "js" = (/obj/structure/sign/warning{pixel_x = 32},/turf/simulated/floor/airless,/area/poi_d/explored)
"jx" = (/obj/random/trash_pile,/turf/simulated/floor/airless,/area/poi_d/explored) "jx" = (/obj/random/trash_pile,/turf/simulated/floor/airless,/area/poi_d/explored)
"jF" = (/obj/structure/table/reinforced,/obj/item/storage/box/shotgunshells/large,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "jF" = (/obj/structure/table/reinforced,/obj/item/storage/box/shotgunshells/large,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"jG" = (/turf/simulated/floor/tiled/kafel_full,/area/poi_d/Mountain) "jG" = (/turf/simulated/floor/tiled/kafel_full,/area/poi_d/Mountain)
"kp" = (/obj/machinery/vending/boozeomat,/turf/simulated/wall,/area/poi_d/Mountain) "kp" = (/obj/machinery/vending/boozeomat,/turf/simulated/wall,/area/poi_d/Mountain)
"kP" = (/obj/machinery/light,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "kP" = (/obj/machinery/light,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"mn" = (/turf/template_noop,/area/template_noop) "mn" = (/turf/template_noop,/area/template_noop)
"no" = (/obj/structure/table/marble,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "no" = (/obj/structure/table/marble,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"nC" = (/obj/machinery/door/airlock/external/glass{frequency = 804; icon_state = "door_locked"; id_tag = "bunkerD_internal"; locked = 1},/turf/simulated/floor/tiled,/area/poi_d/Mountain) "nC" = (/obj/machinery/door/airlock/external/glass{frequency = 804; icon_state = "door_locked"; id_tag = "bunkerD_internal"; locked = 1},/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"pq" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4},/turf/simulated/floor/plating,/area/poi_d/Mountain) "pq" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4},/turf/simulated/floor/plating,/area/poi_d/Mountain)
"pJ" = (/obj/machinery/vending/snack,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "pJ" = (/obj/machinery/vending/snack,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"qa" = (/obj/structure/toilet{pixel_y = 15},/turf/simulated/floor/tiled/white,/area/poi_d/Mountain) "qa" = (/obj/structure/toilet{pixel_y = 15},/turf/simulated/floor/tiled/white,/area/poi_d/Mountain)
"qm" = (/obj/structure/closet/secure_closet/freezer/meat,/turf/simulated/floor/tiled/kafel_full,/area/poi_d/Mountain) "qm" = (/obj/structure/closet/secure_closet/freezer/meat,/turf/simulated/floor/tiled/kafel_full,/area/poi_d/Mountain)
"rc" = (/turf/simulated/floor/tiled/white,/area/poi_d/Mountain) "rc" = (/turf/simulated/floor/tiled/white,/area/poi_d/Mountain)
"uD" = (/turf/simulated/floor/tiled,/area/poi_d/Mountain) "uD" = (/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"vP" = (/obj/structure/table/marble,/obj/item/reagent_containers/food/condiment/small/saltshaker,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "vP" = (/obj/structure/table/marble,/obj/item/reagent_containers/food/condiment/small/saltshaker,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"wt" = (/obj/structure/table/reinforced,/obj/item/rig/merc,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "wt" = (/obj/structure/table/reinforced,/obj/item/rig/merc,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"xq" = (/obj/structure/closet/gimmick/tacticool,/obj/item/material/knife/tacknife,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "xq" = (/obj/structure/closet/gimmick/tacticool,/obj/item/material/knife/tacknife,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"yw" = (/obj/structure/table/reinforced,/obj/item/ammo_magazine/m45tommy,/obj/item/ammo_magazine/m45tommy,/obj/item/ammo_magazine/m45tommy,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "yw" = (/obj/structure/table/reinforced,/obj/item/ammo_magazine/m45tommy,/obj/item/ammo_magazine/m45tommy,/obj/item/ammo_magazine/m45tommy,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"zH" = (/obj/machinery/appliance/cooker/fryer,/obj/item/reagent_containers/cooking_container/fryer,/obj/machinery/light{dir = 4},/turf/simulated/floor/tiled,/area/poi_d/Mountain) "zH" = (/obj/machinery/appliance/cooker/fryer,/obj/item/reagent_containers/cooking_container/fryer,/obj/machinery/light{dir = 4},/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"zZ" = (/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 804; id_tag = "bunkerD"},/turf/simulated/wall,/area/poi_d/Mountain) "zZ" = (/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 804; id_tag = "bunkerD"},/turf/simulated/wall,/area/poi_d/Mountain)
"Ac" = (/obj/machinery/door/airlock/freezer,/turf/simulated/floor/tiled/kafel_full,/area/poi_d/Mountain) "Ac" = (/obj/machinery/door/airlock/freezer,/turf/simulated/floor/tiled/kafel_full,/area/poi_d/Mountain)
"As" = (/obj/structure/curtain/open/shower,/obj/machinery/shower{pixel_y = 16},/turf/simulated/floor/tiled/white,/area/poi_d/Mountain) "As" = (/obj/structure/curtain/open/shower,/obj/machinery/shower{pixel_y = 16},/turf/simulated/floor/tiled/white,/area/poi_d/Mountain)
"BE" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/tiled/kafel_full,/area/poi_d/Mountain) "BE" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/tiled/kafel_full,/area/poi_d/Mountain)
"Ch" = (/turf/simulated/mineral/floor/vacuum,/area/poi_d/unexplored) "Ch" = (/turf/simulated/mineral/floor/vacuum,/area/poi_d/unexplored)
"CA" = (/obj/structure/table/reinforced,/obj/item/storage/firstaid/clotting,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "CA" = (/obj/structure/table/reinforced,/obj/item/storage/firstaid/clotting,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"Df" = (/obj/structure/bed,/obj/item/bedsheet,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "Df" = (/obj/structure/bed,/obj/item/bedsheet,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"Di" = (/obj/machinery/door/airlock/maintenance/common,/turf/simulated/floor/plating,/area/poi_d/Mountain) "Di" = (/obj/machinery/door/airlock/maintenance/common,/turf/simulated/floor/plating,/area/poi_d/Mountain)
"Ex" = (/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 804; id_tag = "bunkerD"; pixel_x = 24; pixel_y = -2},/obj/machinery/airlock_sensor{frequency = 804; id_tag = "bunkerD_sensor"; pixel_x = 24; pixel_y = 6},/turf/simulated/floor/tiled,/area/poi_d/Mountain) "Ex" = (/obj/machinery/embedded_controller/radio/airlock/docking_port{frequency = 804; id_tag = "bunkerD"; pixel_x = 24; pixel_y = -2},/obj/machinery/airlock_sensor{frequency = 804; id_tag = "bunkerD_sensor"; pixel_x = 24; pixel_y = 6},/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"FF" = (/obj/structure/table/reinforced,/obj/item/storage/firstaid/combat,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "FF" = (/obj/structure/table/reinforced,/obj/item/storage/firstaid/combat,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"Hi" = (/obj/structure/closet/crate/freezer/rations,/turf/simulated/floor/tiled/kafel_full,/area/poi_d/Mountain) "Hi" = (/obj/structure/closet/crate/freezer/rations,/turf/simulated/floor/tiled/kafel_full,/area/poi_d/Mountain)
"Hy" = (/mob/living/simple_mob/humanoid/merc/ranged/grenadier,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "Hy" = (/mob/living/simple_mob/humanoid/merc/ranged/grenadier,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"HQ" = (/obj/machinery/door/airlock/vault/bolted,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "HQ" = (/obj/machinery/door/airlock/vault/bolted,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"HS" = (/turf/simulated/floor/airless,/area/poi_d/Mountain) "HS" = (/turf/simulated/floor/airless,/area/poi_d/Mountain)
"HX" = (/turf/simulated/floor/airless,/area/poi_d/explored) "HX" = (/turf/simulated/floor/airless,/area/poi_d/explored)
"Ij" = (/obj/random/trash,/obj/random/trash,/turf/simulated/floor/airless,/area/poi_d/explored) "Ij" = (/obj/random/trash,/obj/random/trash,/turf/simulated/floor/airless,/area/poi_d/explored)
"JG" = (/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored) "JG" = (/turf/simulated/mineral/floor/vacuum,/area/poi_d/explored)
"KB" = (/turf/simulated/wall,/area/poi_d/Mountain) "KB" = (/turf/simulated/wall,/area/poi_d/Mountain)
"LA" = (/turf/simulated/wall/r_wall,/area/poi_d/Mountain) "LA" = (/turf/simulated/wall/r_wall,/area/poi_d/Mountain)
"LW" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor/plating,/area/poi_d/Mountain) "LW" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor/plating,/area/poi_d/Mountain)
"Mc" = (/obj/structure/sign/warning{pixel_x = 32},/obj/random/trash,/turf/simulated/floor/airless,/area/poi_d/explored) "Mc" = (/obj/structure/sign/warning{pixel_x = 32},/obj/random/trash,/turf/simulated/floor/airless,/area/poi_d/explored)
"Nd" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 8},/turf/simulated/wall,/area/poi_d/Mountain) "Nd" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 8},/turf/simulated/wall,/area/poi_d/Mountain)
"NS" = (/obj/machinery/appliance/cooker/oven,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "NS" = (/obj/machinery/appliance/cooker/oven,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"Ot" = (/obj/structure/table/standard{name = "plastic table frame"},/obj/machinery/microwave,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "Ot" = (/obj/structure/table/standard{name = "plastic table frame"},/obj/machinery/microwave,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"Pc" = (/obj/structure/table/rack/shelf,/obj/item/storage/toolbox/syndicate,/turf/simulated/floor/plating,/area/poi_d/Mountain) "Pc" = (/obj/structure/table/rack/shelf,/obj/item/storage/toolbox/syndicate,/turf/simulated/floor/plating,/area/poi_d/Mountain)
"Ph" = (/obj/machinery/vending/dinnerware,/turf/simulated/floor/tiled/kafel_full,/area/poi_d/Mountain) "Ph" = (/obj/machinery/vending/dinnerware,/turf/simulated/floor/tiled/kafel_full,/area/poi_d/Mountain)
"PI" = (/turf/simulated/wall{can_open = 1},/area/poi_d/Mountain) "PI" = (/turf/simulated/wall{can_open = 1},/area/poi_d/Mountain)
"QW" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/poi_d/Mountain) "QW" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/poi_d/Mountain)
"RE" = (/obj/structure/closet/secure_closet/freezer/fridge,/turf/simulated/floor/tiled/kafel_full,/area/poi_d/Mountain) "RE" = (/obj/structure/closet/secure_closet/freezer/fridge,/turf/simulated/floor/tiled/kafel_full,/area/poi_d/Mountain)
"Tf" = (/mob/living/simple_mob/humanoid/merc/melee/sword,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "Tf" = (/mob/living/simple_mob/humanoid/merc/melee/sword,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"TB" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8},/turf/simulated/floor/tiled,/area/poi_d/Mountain) "TB" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 8},/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"TI" = (/obj/structure/table/reinforced,/obj/item/gun/projectile/automatic/tommygun,/obj/machinery/light{dir = 4},/turf/simulated/floor/tiled,/area/poi_d/Mountain) "TI" = (/obj/structure/table/reinforced,/obj/item/gun/projectile/automatic/tommygun,/obj/machinery/light{dir = 4},/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"Us" = (/mob/living/simple_mob/humanoid/merc/ranged,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "Us" = (/mob/living/simple_mob/humanoid/merc/ranged,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"Vq" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/structure/table/rack/shelf,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/turf/simulated/floor/plating,/area/poi_d/Mountain) "Vq" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/structure/table/rack/shelf,/obj/item/clothing/gloves/yellow,/obj/item/clothing/gloves/yellow,/turf/simulated/floor/plating,/area/poi_d/Mountain)
"VY" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "rnd_s_airlock_pump"},/turf/simulated/floor/tiled,/area/poi_d/Mountain) "VY" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "rnd_s_airlock_pump"},/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"Wd" = (/obj/random/trash,/turf/simulated/floor/airless,/area/poi_d/explored) "Wd" = (/obj/random/trash,/turf/simulated/floor/airless,/area/poi_d/explored)
"Xh" = (/obj/structure/sink{dir = 8; pixel_x = -15},/obj/structure/mirror{pixel_x = -30},/turf/simulated/floor/tiled/white,/area/poi_d/Mountain) "Xh" = (/obj/structure/sink{dir = 8; pixel_x = -15},/obj/structure/mirror{pixel_x = -30},/turf/simulated/floor/tiled/white,/area/poi_d/Mountain)
"XL" = (/obj/structure/table/reinforced,/obj/random/ammo,/obj/random/ammo,/obj/random/ammo,/obj/random/ammo,/obj/random/ammo,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "XL" = (/obj/structure/table/reinforced,/obj/random/ammo,/obj/random/ammo,/obj/random/ammo,/obj/random/ammo,/obj/random/ammo,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"XU" = (/obj/machinery/door/airlock/external/glass{frequency = 804; icon_state = "door_locked"; id_tag = "bunkerD_internal"; locked = 1},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9},/turf/simulated/floor/tiled,/area/poi_d/Mountain) "XU" = (/obj/machinery/door/airlock/external/glass{frequency = 804; icon_state = "door_locked"; id_tag = "bunkerD_internal"; locked = 1},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9},/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"Ys" = (/obj/structure/bed,/obj/structure/bed,/obj/item/bedsheet,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "Ys" = (/obj/structure/bed,/obj/structure/bed,/obj/item/bedsheet,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"YM" = (/mob/living/simple_mob/humanoid/merc/ranged/smg,/turf/simulated/floor/tiled,/area/poi_d/Mountain) "YM" = (/mob/living/simple_mob/humanoid/merc/ranged/smg,/turf/simulated/floor/tiled,/area/poi_d/Mountain)
"Zm" = (/obj/machinery/door/airlock/external/glass{frequency = 804; icon_state = "door_locked"; id_tag = "bunkerD_external"; locked = 1},/turf/simulated/floor/tiled,/area/poi_d/Mountain) "Zm" = (/obj/machinery/door/airlock/external/glass{frequency = 804; icon_state = "door_locked"; id_tag = "bunkerD_external"; locked = 1},/turf/simulated/floor/tiled,/area/poi_d/Mountain)
(1,1,1) = {" (1,1,1) = {"
mnmnmnmnmnmnmnmnmnmnmnmnmnmnmndadadadadadadadamnmn mnmnmnmnmnmnmnmnmnmnmnmnmnmnmndadadadadadadadamnmn
mnmndadadadadadadadadadadadadadadadadadadadadadada mnmndadadadadadadadadadadadadadadadadadadadadadada
mndadadadadadadadadadadadadadadadadadadadadadadada mndadadadadadadadadadadadadadadadadadadadadadadada
dadadadadadajxHXjxdaKBdadaKBzZKBdadaKBKBKBKBKBdada dadadadadadajxHXjxdaKBdadaKBzZKBdadaKBKBKBKBKBdada
dadadadajxHXWdWdWdjsKBKBKBKBPIKBKBKBKBqmBEHiKBdada dadadadajxHXWdWdWdjsKBKBKBKBPIKBKBKBKBqmBEHiKBdada
dadadajxHXWdHXjxWdWdPIHSHSHSHSZmhZExKBqmjGHiKBdada dadadajxHXWdHXjxWdWdPIHSHSHSHSZmhZExKBqmjGHiKBdada
dadadaWdWdjxjxHXIjMcKBHSHSHSHSZmTBVYKBREjGHiKBdada dadadaWdWdjxjxHXIjMcKBHSHSHSHSZmTBVYKBREjGHiKBdada
dadadajxWdHXjxHXWdjxKBKBKBhwNdNdXUnCKBREjGPhKBdada dadadajxWdHXjxHXWdjxKBKBKBhwNdNdXUnCKBREjGPhKBdada
dadadadajxHXWdHXdIdaKBPcPcVqKBuDuDuDKBKBAcKBKBdada dadadadajxHXWdHXdIdaKBPcPcVqKBuDuDuDKBKBAcKBKBdada
dadadadadaWdWdWddadaKBQWaVpqDiuDuDuDganouDuDkpdada dadadadadaWdWdWddadaKBQWaVpqDiuDuDuDganouDuDkpdada
ChdadadadaHXWdWddadaKBLWLWLWKBisuDuDganouDzHKBdada ChdadadadaHXWdWddadaKBLWLWLWKBisuDuDganouDzHKBdada
ChdadadadagTJGJGdadaKBKBKBKBKBUsuDuDgavPuDNSKBdada ChdadadadagTJGJGdadaKBKBKBKBKBUsuDuDgavPuDNSKBdada
ChdadadadaJGJGdadadaKBAsqaKBpJuDuDuDuDUsuDOtKBdada ChdadadadaJGJGdadadaKBAsqaKBpJuDuDuDuDUsuDOtKBdada
ChdadadaJGJGJGJGdadaKBXhrcKBgPuDuDuDLALALALAKBdada ChdadadaJGJGJGJGdadaKBXhrcKBgPuDuDuDLALALALAKBdada
ChChdadaJGJGJGdadaKBKBKBbDKBKBKBgWLALAXLjFLALAdada ChChdadaJGJGJGdadaKBKBKBbDKBKBKBgWLALAXLjFLALAdada
ChChChJGJGJGdadadaKBuDuDuDuDuDuDuDLAHyuDuDwtLAdada ChChChJGJGJGdadadaKBuDuDuDuDuDuDuDLAHyuDuDwtLAdada
ChChChJGJGJGdadadaKBuDYMuDuDuDuDuDHQuDuDuDTILAdada ChChChJGJGJGdadadaKBuDYMuDuDuDuDuDHQuDuDuDTILAdada
ChChChJGJGdadadadaKBDfuDxqKBxqTfDfLAHyuDuDywLAdada ChChChJGJGdadadadaKBDfuDxqKBxqTfDfLAHyuDuDywLAdada
ChChChdadadadadadaKBYsuDxqKBxquDDfLALAFFCALALAdada ChChChdadadadadadaKBYsuDxqKBxquDDfLALAFFCALALAdada
ChChChdadadadadadaKBDfkPxqKBxqkPDfKBLALALALAdadada ChChChdadadadadadaKBDfkPxqKBxqkPDfKBLALALALAdadada
ChChChdadadadadadaKBKBKBKBKBKBKBKBKBdadadadadadada ChChChdadadadadadaKBKBKBKBKBKBKBKBKBdadadadadadada
ChChChdadadadadadadadadadadadadadadadadadadadadamn ChChChdadadadadadadadadadadadadadadadadadadadadamn
ChChChChdadadadadadadadadadadadadadadadadadadamnmn ChChChChdadadadadadadadadadadadadadadadadadadamnmn
ChChChChChChChdadadadadadadadadadadadadamnmnmnmnmn ChChChChChChChdadadadadadadadadadadadadamnmnmnmnmn
ChChChChChChChChChChChChChChChChChChChChmnmnmnmnmn ChChChChChChChChChChChChChChChChChChChChmnmnmnmnmn
"} "}

View File

@@ -1,46 +1,46 @@
"a" = (/turf/template_noop,/area/template_noop) "a" = (/turf/template_noop,/area/template_noop)
"b" = (/obj/machinery/door/airlock/maintenance/command{req_one_access = null},/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "b" = (/obj/machinery/door/airlock/maintenance/command{req_one_access = null},/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"c" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "c" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"d" = (/obj/mob_spawner/drone_spawner,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "d" = (/obj/mob_spawner/drone_spawner,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"g" = (/turf/simulated/floor/airless,/area/poi_d/POIs/landing_pad) "g" = (/turf/simulated/floor/airless,/area/poi_d/POIs/landing_pad)
"i" = (/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "i" = (/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"k" = (/obj/machinery/drone_fabricator/derelict,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "k" = (/obj/machinery/drone_fabricator/derelict,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"l" = (/obj/structure/sink{dir = 8; pixel_x = -15},/obj/structure/mirror/raider{pixel_x = -30},/turf/simulated/floor/tiled/white,/area/poi_d/POIs/landing_pad) "l" = (/obj/structure/sink{dir = 8; pixel_x = -15},/obj/structure/mirror/raider{pixel_x = -30},/turf/simulated/floor/tiled/white,/area/poi_d/POIs/landing_pad)
"m" = (/obj/machinery/light{dir = 4},/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "m" = (/obj/machinery/light{dir = 4},/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"n" = (/turf/simulated/mineral/floor/vacuum,/area/template_noop) "n" = (/turf/simulated/mineral/floor/vacuum,/area/template_noop)
"p" = (/obj/machinery/door/airlock/maintenance/int,/turf/simulated/floor/tiled/white,/area/poi_d/POIs/landing_pad) "p" = (/obj/machinery/door/airlock/maintenance/int,/turf/simulated/floor/tiled/white,/area/poi_d/POIs/landing_pad)
"q" = (/obj/machinery/door/blast/shutters{dir = 8; id = "matdropcargo"},/turf/simulated/floor/airless,/area/poi_d/POIs/landing_pad) "q" = (/obj/machinery/door/blast/shutters{dir = 8; id = "matdropcargo"},/turf/simulated/floor/airless,/area/poi_d/POIs/landing_pad)
"r" = (/obj/structure/closet/crate,/obj/machinery/light{dir = 8},/obj/item/stack/cable_coil,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "r" = (/obj/structure/closet/crate,/obj/machinery/light{dir = 8},/obj/item/stack/cable_coil,/obj/item/stack/cable_coil,/obj/item/stack/cable_coil,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"t" = (/obj/structure/closet/crate,/obj/fiftyspawner/wood,/obj/fiftyspawner/wood,/obj/fiftyspawner/wood,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "t" = (/obj/structure/closet/crate,/obj/fiftyspawner/wood,/obj/fiftyspawner/wood,/obj/fiftyspawner/wood,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"u" = (/obj/machinery/door/airlock/maintenance/cargo{req_one_access = null},/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "u" = (/obj/machinery/door/airlock/maintenance/cargo{req_one_access = null},/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"w" = (/obj/structure/closet/crate,/obj/item/airlock_electronics,/obj/item/airlock_electronics,/obj/item/airlock_electronics,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "w" = (/obj/structure/closet/crate,/obj/item/airlock_electronics,/obj/item/airlock_electronics,/obj/item/airlock_electronics,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"x" = (/obj/structure/window/reinforced/full,/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/turf/simulated/floor/airless,/area/poi_d/POIs/landing_pad) "x" = (/obj/structure/window/reinforced/full,/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/turf/simulated/floor/airless,/area/poi_d/POIs/landing_pad)
"B" = (/obj/structure/closet/crate,/obj/fiftyspawner/steel,/obj/fiftyspawner/steel,/obj/fiftyspawner/steel,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "B" = (/obj/structure/closet/crate,/obj/fiftyspawner/steel,/obj/fiftyspawner/steel,/obj/fiftyspawner/steel,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"D" = (/obj/machinery/power/port_gen/pacman,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "D" = (/obj/machinery/power/port_gen/pacman,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"E" = (/obj/machinery/door/airlock/maintenance/int,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "E" = (/obj/machinery/door/airlock/maintenance/int,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"F" = (/obj/structure/table/standard,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "F" = (/obj/structure/table/standard,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"H" = (/obj/machinery/door/airlock/glass_external{frequency = null; icon_state = "door_locked"; id_tag = "matdrop"; locked = 1},/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "H" = (/obj/machinery/door/airlock/glass_external{frequency = null; icon_state = "door_locked"; id_tag = "matdrop"; locked = 1},/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"J" = (/obj/item/modular_computer/console{dir = 8; icon_state = "broken"},/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "J" = (/obj/item/modular_computer/console{dir = 8; icon_state = "broken"},/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"M" = (/obj/structure/closet/crate,/obj/fiftyspawner/phoron,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "M" = (/obj/structure/closet/crate,/obj/fiftyspawner/phoron,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"N" = (/turf/simulated/wall/titanium,/area/poi_d/POIs/landing_pad) "N" = (/turf/simulated/wall/titanium,/area/poi_d/POIs/landing_pad)
"P" = (/obj/structure/bed,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "P" = (/obj/structure/bed,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"R" = (/obj/machinery/light/small,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "R" = (/obj/machinery/light/small,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"S" = (/obj/machinery/button/remote/airlock/survival_pod{id = "matdrop"; pixel_y = 25},/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "S" = (/obj/machinery/button/remote/airlock/survival_pod{id = "matdrop"; pixel_y = 25},/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"T" = (/obj/machinery/button/remote/airlock/survival_pod{dir = 4; id = "matdropcargo"; pixel_x = -25},/obj/structure/closet/crate,/obj/fiftyspawner/rods,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "T" = (/obj/machinery/button/remote/airlock/survival_pod{dir = 4; id = "matdropcargo"; pixel_x = -25},/obj/structure/closet/crate,/obj/fiftyspawner/rods,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"V" = (/obj/machinery/door/blast/shutters{dir = 8; id = "matdropcargo"},/obj/machinery/door/blast/shutters{dir = 8; id = "matdropcargo"},/turf/simulated/floor/airless,/area/poi_d/POIs/landing_pad) "V" = (/obj/machinery/door/blast/shutters{dir = 8; id = "matdropcargo"},/obj/machinery/door/blast/shutters{dir = 8; id = "matdropcargo"},/turf/simulated/floor/airless,/area/poi_d/POIs/landing_pad)
"W" = (/obj/structure/closet/crate,/obj/fiftyspawner/rglass,/obj/fiftyspawner/rglass,/obj/fiftyspawner/rglass,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad) "W" = (/obj/structure/closet/crate,/obj/fiftyspawner/rglass,/obj/fiftyspawner/rglass,/obj/fiftyspawner/rglass,/turf/simulated/floor/tiled,/area/poi_d/POIs/landing_pad)
"X" = (/obj/structure/grille,/obj/structure/window/reinforced/full,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/airless,/area/poi_d/POIs/landing_pad) "X" = (/obj/structure/grille,/obj/structure/window/reinforced/full,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/airless,/area/poi_d/POIs/landing_pad)
"Y" = (/obj/structure/toilet{pixel_y = 15},/obj/structure/loot_pile/surface/medicine_cabinet/fresh{pixel_x = -30},/turf/simulated/floor/tiled/white,/area/poi_d/POIs/landing_pad) "Y" = (/obj/structure/toilet{pixel_y = 15},/obj/structure/loot_pile/surface/medicine_cabinet/fresh{pixel_x = -30},/turf/simulated/floor/tiled/white,/area/poi_d/POIs/landing_pad)
(1,1,1) = {" (1,1,1) = {"
aaaaaannnnnaaaa aaaaaannnnnaaaa
aaNNNNNNggNNNNn aaNNNNNNggNNNNn
aNNkidDNNHNiJxn aNNkidDNNHNiJxn
nNTMiiiuSibiJxn nNTMiiiuSibiJxn
nqWtiimNRiNRJxn nqWtiimNRiNRJxn
nVwBiiNNNENNNNn nVwBiiNNNENNNNn
nNrBiiNYNicFXnn nNrBiiNYNicFXnn
aNNkidNlpdiPNna aNNkidNlpdiPNna
aaNNNNNNNNNNNaa aaNNNNNNNNNNNaa
aaaaaaaaaaaaaaa aaaaaaaaaaaaaaa
"} "}

View File

@@ -0,0 +1,18 @@
//AWAY MISSION Init
/obj/away_mission_init/poi_h
name = "away mission initializer - Desert Planet"
/obj/away_mission_init/poi_h/Initialize(mapload)
return INITIALIZE_HINT_QDEL
//Intializer
/obj/away_mission_init/poi_h/Initialize(mapload)
return INITIALIZE_HINT_QDEL
/obj/away_mission_init/poi_h
name = "away mission initializer - Class h World"
/obj/away_mission_init/poi_h/Initialize(mapload)
return INITIALIZE_HINT_QDEL

View File

@@ -0,0 +1,32 @@
// -- Objs -- //
/obj/effect/step_trigger/teleporter/debrisfield_loop/north/New()
..()
teleport_x = x
teleport_y = 2
teleport_z = z
/obj/effect/step_trigger/teleporter/debrisfield_loop/south/New()
..()
teleport_x = x
teleport_y = world.maxy - 1
teleport_z = z
/obj/effect/step_trigger/teleporter/debrisfield_loop/west/New()
..()
teleport_x = world.maxx - 1
teleport_y = y
teleport_z = z
/obj/effect/step_trigger/teleporter/debrisfield_loop/east/New()
..()
teleport_x = 2
teleport_y = y
teleport_z = z
//This does nothing right now, but is framework if we do POIs for this place
/obj/away_mission_init/debrisfield
name = "away mission initializer - debrisfield"
/obj/away_mission_init/debrisfield/Initialize(mapload)
return INITIALIZE_HINT_QDEL

View File

@@ -0,0 +1,32 @@
// -- Objs -- //
/obj/effect/step_trigger/teleporter/piratebase_loop/north/New()
..()
teleport_x = x
teleport_y = 2
teleport_z = z
/obj/effect/step_trigger/teleporter/piratebase_loop/south/New()
..()
teleport_x = x
teleport_y = world.maxy - 1
teleport_z = z
/obj/effect/step_trigger/teleporter/piratebase_loop/west/New()
..()
teleport_x = world.maxx - 1
teleport_y = y
teleport_z = z
/obj/effect/step_trigger/teleporter/piratebase_loop/east/New()
..()
teleport_x = 2
teleport_y = y
teleport_z = z
//This does nothing right now, but is framework if we do POIs for this place
/obj/away_mission_init/piratebase
name = "away mission initializer - piratebase"
/obj/away_mission_init/piratebase/Initialize(mapload)
return INITIALIZE_HINT_QDEL

View File

@@ -0,0 +1,32 @@
// -- Objs -- //
/obj/effect/step_trigger/teleporter/tradeport_loop/north/New()
..()
teleport_x = x
teleport_y = 2
teleport_z = z
/obj/effect/step_trigger/teleporter/tradeport_loop/south/New()
..()
teleport_x = x
teleport_y = world.maxy - 1
teleport_z = z
/obj/effect/step_trigger/teleporter/tradeport_loop/west/New()
..()
teleport_x = world.maxx - 1
teleport_y = y
teleport_z = z
/obj/effect/step_trigger/teleporter/tradeport_loop/east/New()
..()
teleport_x = 2
teleport_y = y
teleport_z = z
//This does nothing right now, but is framework if we do POIs for this place
/obj/away_mission_init/tradeport
name = "away mission initializer - tradeport"
/obj/away_mission_init/tradeport/Initialize(mapload)
return INITIALIZE_HINT_QDEL

View File

@@ -0,0 +1,293 @@
// To be filled out when more progress on the new map occurs.
#define Z_LEVEL_STATION_ONE 1
#define Z_LEVEL_STATION_TWO 2
#define Z_LEVEL_STATION_THREE 3
#define Z_LEVEL_EMPTY_SPACE 4
#define Z_LEVEL_SURFACE 5
#define Z_LEVEL_SURFACE_MINE 6
#define Z_LEVEL_MISC 7
#define Z_LEVEL_CENTCOM 8
#define Z_LEVEL_TRANSIT 9
#define Z_LEVEL_SURFACE_WILD 10
/datum/map/southern_cross
name = "Southern Cross"
full_name = "Southern Cross"
path = "southern_cross"
lobby_icon = 'icons/misc/title.dmi'
lobby_screens = list("mockingjay00") // New lobby screen if possible.
holomap_smoosh = list(list(
Z_LEVEL_STATION_ONE,
Z_LEVEL_STATION_TWO,
Z_LEVEL_STATION_THREE))
zlevel_datum_type = /datum/map_z_level/southern_cross
station_name = "NLS Southern Cross"
station_short = "Southern Cross"
dock_name = "NCS Northern Star" // Now we're the centcom!
boss_name = "Central Command"
boss_short = "Centcom"
company_name = "NanoTrasen"
company_short = "NT"
starsys_name = "Vir"
shuttle_docked_message = "The scheduled shuttle to the %dock_name% has docked with the station at docks one and two. It will depart in approximately %ETD%."
shuttle_leaving_dock = "The Crew Transfer Shuttle has left the station. Estimate %ETA% until the shuttle docks at %dock_name%."
shuttle_called_message = "A crew transfer to %dock_name% has been scheduled. The shuttle has been called. Those leaving should proceed to docks one and two in approximately %ETA%."
shuttle_recall_message = "The scheduled crew transfer has been cancelled."
emergency_shuttle_docked_message = "The Emergency Shuttle has docked with the station at docks one and two. You have approximately %ETD% to board the Emergency Shuttle."
emergency_shuttle_leaving_dock = "The Emergency Shuttle has left the station. Estimate %ETA% until the shuttle docks at %dock_name%."
emergency_shuttle_called_message = "An emergency evacuation shuttle has been called. It will arrive at docks one and two in approximately %ETA%."
emergency_shuttle_recall_message = "The emergency shuttle has been recalled."
// Networks that will show up as options in the camera monitor program
station_networks = list(
NETWORK_CARGO,
NETWORK_CIRCUITS,
NETWORK_CIVILIAN,
NETWORK_COMMAND,
NETWORK_ENGINE,
NETWORK_ENGINEERING,
NETWORK_ENGINEERING_OUTPOST,
NETWORK_FIRST_DECK,
NETWORK_SECOND_DECK,
NETWORK_THIRD_DECK,
NETWORK_MAIN_OUTPOST,
NETWORK_MEDICAL,
NETWORK_MINE,
NETWORK_RESEARCH,
NETWORK_RESEARCH_OUTPOST,
NETWORK_ROBOTS,
NETWORK_PRISON,
NETWORK_SECURITY,
NETWORK_TELECOM
)
// Camera networks that exist, but don't show on regular camera monitors.
secondary_networks = list(
NETWORK_ERT,
NETWORK_MERCENARY,
NETWORK_THUNDER,
NETWORK_COMMUNICATORS,
NETWORK_ALARM_ATMOS,
NETWORK_ALARM_POWER,
NETWORK_ALARM_FIRE,
NETWORK_SUPPLY
)
usable_email_tlds = list("freemail.nt")
allowed_spawns = list("Arrivals Shuttle","Gateway", "Cryogenic Storage", "Cyborg Storage")
unit_test_exempt_areas = list(/area/ninja_dojo, /area/ninja_dojo/firstdeck, /area/ninja_dojo/arrivals_dock)
unit_test_exempt_from_atmos = list(/area/tcomm/chamber)
// Short range computers see only the six main levels, others can see the surrounding surface levels.
/datum/map/southern_cross/get_map_levels(var/srcz, var/long_range = TRUE)
if (long_range && (srcz in map_levels))
return map_levels
else if (srcz == Z_LEVEL_TRANSIT)
return list() // Nothing on these z-levels- sensors won't show, and GPSes won't see each other.
else if (srcz >= Z_LEVEL_STATION_ONE && srcz <= Z_LEVEL_STATION_THREE) // Station can see other decks.
return list(
Z_LEVEL_STATION_ONE,
Z_LEVEL_STATION_TWO,
Z_LEVEL_STATION_THREE,
Z_LEVEL_SURFACE,
Z_LEVEL_SURFACE_MINE,
Z_LEVEL_SURFACE_WILD)
else if(srcz in list(Z_LEVEL_SURFACE, Z_LEVEL_SURFACE_MINE, Z_LEVEL_SURFACE_WILD)) // Being on the surface lets you see other surface Zs.
return list(
Z_LEVEL_SURFACE,
Z_LEVEL_SURFACE_MINE,
Z_LEVEL_SURFACE_WILD)
else
return list(srcz) //prevents runtimes when using CMC. any Z-level not defined above will be 'isolated' and only show to GPSes/CMCs on that same Z (e.g. CentCom).
/datum/map/southern_cross/perform_map_generation()
// First, place a bunch of submaps. This comes before tunnel/forest generation as to not interfere with the submap.
// Cave submaps are first.
seed_submaps(list(Z_LEVEL_SURFACE_MINE), 75, /area/surface/cave/unexplored/normal, /datum/map_template/surface/mountains/normal)
seed_submaps(list(Z_LEVEL_SURFACE_MINE), 75, /area/surface/cave/unexplored/deep, /datum/map_template/surface/mountains/deep)
// Plains to make them less plain.
seed_submaps(list(Z_LEVEL_SURFACE), 100, /area/surface/outside/plains/normal, /datum/map_template/surface/plains) // Center area is WIP until map editing settles down.
// Wilderness is next.
seed_submaps(list(Z_LEVEL_SURFACE_WILD), 75, /area/surface/outside/wilderness/normal, /datum/map_template/surface/wilderness/normal)
seed_submaps(list(Z_LEVEL_SURFACE_WILD), 75, /area/surface/outside/wilderness/deep, /datum/map_template/surface/wilderness/deep)
// If Space submaps are made, add a line to make them here as well.
// Now for the tunnels.
new /datum/random_map/automata/cave_system/no_cracks(null, 1, 1, Z_LEVEL_SURFACE_MINE, world.maxx, world.maxy) // Create the mining Z-level.
new /datum/random_map/noise/ore(null, 1, 1, Z_LEVEL_SURFACE_MINE, 64, 64) // Create the mining ore distribution map.
// Todo: Forest generation.
return 1
// For making the 6-in-1 holomap, we calculate some offsets
#define SOUTHERN_CROSS_MAP_SIZE 160 // Width and height of compiled in Southern Cross z levels.
#define SOUTHERN_CROSS_HOLOMAP_CENTER_GUTTER 40 // 40px central gutter between columns
#define SOUTHERN_CROSS_HOLOMAP_MARGIN_X ((HOLOMAP_ICON_SIZE - (2*SOUTHERN_CROSS_MAP_SIZE) - SOUTHERN_CROSS_HOLOMAP_CENTER_GUTTER) / 2) // 100
#define SOUTHERN_CROSS_HOLOMAP_MARGIN_Y ((HOLOMAP_ICON_SIZE - (3*SOUTHERN_CROSS_MAP_SIZE)) / 2) // 60
/datum/map_z_level/southern_cross/station
flags = MAP_LEVEL_STATION|MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_CONSOLES
holomap_legend_x = 220
holomap_legend_y = 160
/datum/map_z_level/southern_cross/station/station_one
z = Z_LEVEL_STATION_ONE
name = "Deck 1"
base_turf = /turf/space
transit_chance = 6
holomap_offset_x = SOUTHERN_CROSS_HOLOMAP_MARGIN_X - 40
holomap_offset_y = SOUTHERN_CROSS_HOLOMAP_MARGIN_Y + SOUTHERN_CROSS_MAP_SIZE*0
/datum/map_z_level/southern_cross/station/station_two
z = Z_LEVEL_STATION_TWO
name = "Deck 2"
base_turf = /turf/simulated/open
transit_chance = 6
holomap_offset_x = SOUTHERN_CROSS_HOLOMAP_MARGIN_X - 40
holomap_offset_y = SOUTHERN_CROSS_HOLOMAP_MARGIN_Y + SOUTHERN_CROSS_MAP_SIZE*1
/datum/map_z_level/southern_cross/station/station_three
z = Z_LEVEL_STATION_THREE
name = "Deck 3"
base_turf = /turf/simulated/open
transit_chance = 6
holomap_offset_x = HOLOMAP_ICON_SIZE - SOUTHERN_CROSS_HOLOMAP_MARGIN_X - SOUTHERN_CROSS_MAP_SIZE - 40
holomap_offset_y = SOUTHERN_CROSS_HOLOMAP_MARGIN_Y + SOUTHERN_CROSS_MAP_SIZE*1
/datum/map_z_level/southern_cross/empty_space
z = Z_LEVEL_EMPTY_SPACE
name = "Empty"
flags = MAP_LEVEL_PLAYER
transit_chance = 76
/datum/map_z_level/southern_cross/surface
z = Z_LEVEL_SURFACE
name = "Plains"
flags = MAP_LEVEL_STATION|MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_SEALED
base_turf = /turf/simulated/floor/outdoors/rocks
/datum/map_z_level/southern_cross/surface_mine
z = Z_LEVEL_SURFACE_MINE
name = "Mountains"
flags = MAP_LEVEL_STATION|MAP_LEVEL_CONTACT|MAP_LEVEL_PLAYER|MAP_LEVEL_SEALED
base_turf = /turf/simulated/floor/outdoors/rocks
/datum/map_z_level/southern_cross/surface_wild
z = Z_LEVEL_SURFACE_WILD
name = "Wilderness"
flags = MAP_LEVEL_PLAYER|MAP_LEVEL_SEALED
base_turf = /turf/simulated/floor/outdoors/rocks
/datum/map_z_level/southern_cross/misc
z = Z_LEVEL_MISC
name = "Misc"
flags = MAP_LEVEL_PLAYER
transit_chance = 6
/datum/map_z_level/southern_cross/centcom
z = Z_LEVEL_CENTCOM
name = "Centcom"
flags = MAP_LEVEL_ADMIN|MAP_LEVEL_CONTACT
/datum/map_z_level/southern_cross/transit
z = Z_LEVEL_TRANSIT
name = "Transit"
flags = MAP_LEVEL_ADMIN|MAP_LEVEL_SEALED|MAP_LEVEL_PLAYER|MAP_LEVEL_CONTACT
//Teleport to Mine
/obj/effect/step_trigger/teleporter/mine/to_mining/New()
..()
teleport_x = src.x
teleport_y = 2
teleport_z = Z_LEVEL_SURFACE_MINE
/obj/effect/step_trigger/teleporter/mine/from_mining/New()
..()
teleport_x = src.x
teleport_y = world.maxy - 1
teleport_z = Z_LEVEL_SURFACE
//Teleport to Wild
/obj/effect/step_trigger/teleporter/wild/to_wild/New()
..()
teleport_x = src.x
teleport_y = 2
teleport_z = Z_LEVEL_SURFACE_WILD
/obj/effect/step_trigger/teleporter/wild/from_wild/New()
..()
teleport_x = src.x
teleport_y = world.maxy - 1
teleport_z = Z_LEVEL_SURFACE_MINE
/datum/planet/sif
expected_z_levels = list(
Z_LEVEL_SURFACE,
Z_LEVEL_SURFACE_MINE,
Z_LEVEL_SURFACE_WILD,
Z_LEVEL_TRANSIT
)
/obj/effect/step_trigger/teleporter/bridge/east_to_west/Initialize(mapload)
teleport_x = src.x - 4
teleport_y = src.y
teleport_z = src.z
return ..()
/obj/effect/step_trigger/teleporter/bridge/east_to_west/small/Initialize(mapload)
teleport_x = src.x - 3
teleport_y = src.y
teleport_z = src.z
return ..()
/obj/effect/step_trigger/teleporter/bridge/west_to_east/Initialize(mapload)
teleport_x = src.x + 4
teleport_y = src.y
teleport_z = src.z
return ..()
/obj/effect/step_trigger/teleporter/bridge/west_to_east/small/Initialize(mapload)
teleport_x = src.x + 3
teleport_y = src.y
teleport_z = src.z
return ..()
/obj/effect/step_trigger/teleporter/bridge/north_to_south/Initialize(mapload)
teleport_x = src.x
teleport_y = src.y - 4
teleport_z = src.z
return ..()
/obj/effect/step_trigger/teleporter/bridge/south_to_north/Initialize(mapload)
teleport_x = src.x
teleport_y = src.y + 4
teleport_z = src.z
return ..()
/datum/planet/sif
expected_z_levels = list(
Z_LEVEL_SURFACE,
Z_LEVEL_SURFACE_MINE,
Z_LEVEL_SURFACE_WILD
)
//Suit Storage Units
/obj/machinery/suit_cycler/exploration
name = "Explorer suit cycler"
model_text = "Exploration"
req_one_access = list(access_pilot,access_explorer)
/obj/machinery/suit_cycler/pilot
name = "Pilot suit cycler"
model_text = "Pilot"
req_access = null
req_one_access = list(access_pilot,access_explorer)

View File

@@ -0,0 +1,57 @@
/obj/item/camerabug
var/obj/item/radio/radio
/obj/item/camerabug/Destroy()
. = ..()
listening_objects -= src
qdel(src.radio)
radio = null
/obj/item/camerabug/Initialize(mapload)
. = ..()
listening_objects += src
radio = new(src)
radio.broadcasting = 0
radio.listening = 0
radio.canhear_range = 6
radio.icon = src.icon
radio.icon_state = src.icon_state
update_icon()
/obj/item/camerabug/reset()
. = ..()
radio.broadcasting = 0
/obj/item/camerabug/attackby(obj/item/W as obj, mob/living/user as mob)
. = ..()
if(istype(W, /obj/item/bug_monitor))
var/obj/item/bug_monitor/SM = W
if(!linkedmonitor)
radio.broadcasting = 0
else if (linkedmonitor == SM)
radio.broadcasting = 1
radio.set_frequency(SM.radio.frequency)
/obj/item/bug_monitor
var/obj/item/radio/radio
var/global/list/freqblacklist
/obj/item/bug_monitor/Initialize(mapload)
. = ..()
listening_objects += src
if(!freqblacklist)
for (var/chan in radiochannels)
freqblacklist |= radiochannels[chan]
radio = new(src)
radio.broadcasting = 0
radio.listening = 1
radio.canhear_range = 0
do
radio.set_frequency( rand(RADIO_LOW_FREQ, RADIO_HIGH_FREQ) )
while (radio.frequency in freqblacklist || (radio.frequency % 2 == 0))
/obj/item/bug_monitor/Destroy()
. = ..()
listening_objects -= src
qdel(src.radio)
radio = null