mirror of
https://github.com/Citadel-Station-13/Citadel-Station-13-RP.git
synced 2025-12-10 23:51:22 +00:00
line endings
This commit is contained in:
@@ -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)
|
||||||
|
..()
|
||||||
|
|||||||
@@ -0,0 +1,133 @@
|
|||||||
|
/obj/mecha/medical/odysseus/
|
||||||
|
desc = "These exosuits are developed and produced by Vey-Med. (© 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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
. = ..()
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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]!")
|
||||||
|
|||||||
@@ -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
|
||||||
|
)
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
. = ..()
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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 ..()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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 ..()
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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!")
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 ..()
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
"}
|
"}
|
||||||
|
|||||||
@@ -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
|
||||||
"}
|
"}
|
||||||
|
|||||||
@@ -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
|
||||||
"}
|
"}
|
||||||
|
|||||||
@@ -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
|
||||||
"}
|
"}
|
||||||
|
|||||||
@@ -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
|
||||||
"}
|
"}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user