mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-29 19:11:51 +00:00
* March into Mapness - Traveller's Rest (Space structure) (#73905) ## About The Pull Request I thought it would be fun to learn mapping with [this guide](https://hackmd.io/QBaz0CaTRhOp7pEnUlXnzQ), and perhaps along the way I could make a bit of content that I would like to see in space some day. I wanted to create an only recently abandoned space structure that is relatively small but could be used as a pitstop for space-travelling spessmen to rest and recharge, perhaps even be used as a second base for further exploration. The structure starts unpowered, but after you break in, you can turn on the APC (starts unlocked) and set the solar panels to generate power. With all it's amenities, it's similar to the "Space Bunker" (deepstorage.dmm), but of course much smaller. There is not much in terms of loot, just a random toolbox, night vision goggles and a better capacitator for the charger. With all the new space ruins upcoming, perhaps its not the worst idea to have a place like this.   _Since this is my first map, I might have missed some things. I am a little bit torn between "it does not look abandonded enough" and "it should look nice because its a resting point"._ ### Mapping March Ckey to recieve rewards: LordVollkorn ## Changelog 🆑 LordVollkorn / Gage Gaebler add: Added Traveler's Rest, a tiny space structure for space travellers to relax and to prepare for the explorations ahead. /🆑 * March into Mapness - Traveller's Rest (Space structure) --------- Co-authored-by: LordVollkorn <66637090+LordVollkorn@users.noreply.github.com>
502 lines
15 KiB
Plaintext
502 lines
15 KiB
Plaintext
#define HOLOPAD_MAX_DIAL_TIME 200
|
|
|
|
#define HOLORECORD_DELAY "delay"
|
|
#define HOLORECORD_SAY "say"
|
|
#define HOLORECORD_SOUND "sound"
|
|
#define HOLORECORD_LANGUAGE "lang"
|
|
#define HOLORECORD_PRESET "preset"
|
|
#define HOLORECORD_RENAME "rename"
|
|
|
|
#define HOLORECORD_MAX_LENGTH 200
|
|
|
|
/mob/camera/ai_eye/remote/holo/setLoc(turf/destination, force_update = FALSE)
|
|
. = ..()
|
|
var/obj/machinery/holopad/H = origin
|
|
H?.move_hologram(eye_user, loc)
|
|
|
|
/obj/machinery/holopad/remove_eye_control(mob/living/user)
|
|
if(user.client)
|
|
user.reset_perspective(null)
|
|
user.remote_control = null
|
|
|
|
//this datum manages it's own references
|
|
|
|
/datum/holocall
|
|
///the one that called
|
|
var/mob/living/user
|
|
///the holopad that sent the call to another holopad
|
|
var/obj/machinery/holopad/calling_holopad
|
|
///the one that answered the call (may be null)
|
|
var/obj/machinery/holopad/connected_holopad
|
|
///populated with all holopads that are either being dialed or have that have answered us, will be cleared out to just connected_holopad once answered
|
|
var/list/dialed_holopads
|
|
|
|
///user's eye, once connected
|
|
var/mob/camera/ai_eye/remote/holo/eye
|
|
///user's hologram, once connected
|
|
var/obj/effect/overlay/holo_pad_hologram/hologram
|
|
///hangup action
|
|
var/datum/action/innate/end_holocall/hangup
|
|
|
|
var/call_start_time
|
|
///calls from a head of staff autoconnect, if the receiving pad is not secure.
|
|
var/head_call = FALSE
|
|
|
|
//creates a holocall made by `caller` from `calling_pad` to `callees`
|
|
/datum/holocall/New(mob/living/caller, obj/machinery/holopad/calling_pad, list/callees, elevated_access = FALSE)
|
|
call_start_time = world.time
|
|
user = caller
|
|
calling_pad.outgoing_call = src
|
|
calling_holopad = calling_pad
|
|
head_call = elevated_access
|
|
dialed_holopads = list()
|
|
|
|
for(var/obj/machinery/holopad/connected_holopad as anything in callees)
|
|
if(!QDELETED(connected_holopad) && connected_holopad.is_operational)
|
|
dialed_holopads += connected_holopad
|
|
if(head_call)
|
|
if(connected_holopad.secure)
|
|
calling_pad.say("Auto-connection refused, falling back to call mode.")
|
|
connected_holopad.say("Incoming call.")
|
|
else
|
|
connected_holopad.say("Incoming connection.")
|
|
else
|
|
connected_holopad.say("Incoming call.")
|
|
connected_holopad.set_holocall(src)
|
|
|
|
if(!dialed_holopads.len)
|
|
calling_pad.say("Connection failure.")
|
|
qdel(src)
|
|
return
|
|
|
|
testing("Holocall started")
|
|
|
|
//cleans up ALL references :)
|
|
/datum/holocall/Destroy()
|
|
QDEL_NULL(hangup)
|
|
|
|
if(!QDELETED(eye))
|
|
QDEL_NULL(eye)
|
|
|
|
if(connected_holopad && !QDELETED(hologram))
|
|
hologram = null
|
|
connected_holopad.clear_holo(user)
|
|
|
|
user = null
|
|
|
|
//Hologram survived holopad destro
|
|
if(!QDELETED(hologram))
|
|
hologram.HC = null
|
|
QDEL_NULL(hologram)
|
|
hologram = null
|
|
|
|
for(var/obj/machinery/holopad/dialed_holopad as anything in dialed_holopads)
|
|
dialed_holopad.set_holocall(src, FALSE)
|
|
|
|
dialed_holopads.Cut()
|
|
|
|
if(calling_holopad)//if the call is answered, then calling_holopad wont be in dialed_holopads and thus wont have set_holocall(src, FALSE) called
|
|
calling_holopad.callee_hung_up()
|
|
calling_holopad = null
|
|
if(connected_holopad)
|
|
connected_holopad.SetLightsAndPower()
|
|
connected_holopad = null
|
|
|
|
testing("Holocall destroyed")
|
|
|
|
return ..()
|
|
|
|
//Gracefully disconnects a holopad `H` from a call. Pads not in the call are ignored. Notifies participants of the disconnection
|
|
/datum/holocall/proc/Disconnect(obj/machinery/holopad/H)
|
|
testing("Holocall disconnect")
|
|
if(H == connected_holopad)
|
|
var/area/A = get_area(connected_holopad)
|
|
calling_holopad.say("[A] holopad disconnected.")
|
|
else if(H == calling_holopad && connected_holopad)
|
|
connected_holopad.say("[user] disconnected.")
|
|
|
|
ConnectionFailure(H, TRUE)
|
|
|
|
//Forcefully disconnects disconnected_holopad from a call. Pads not in the call are ignored.
|
|
/datum/holocall/proc/ConnectionFailure(obj/machinery/holopad/disconnected_holopad, graceful = FALSE)
|
|
testing("Holocall connection failure: graceful [graceful]")
|
|
if(disconnected_holopad == connected_holopad || disconnected_holopad == calling_holopad)
|
|
if(!graceful && disconnected_holopad != calling_holopad)
|
|
calling_holopad.say("Connection failure.")
|
|
qdel(src)
|
|
return
|
|
|
|
disconnected_holopad.set_holocall(src, FALSE)
|
|
|
|
dialed_holopads -= disconnected_holopad
|
|
if(!dialed_holopads.len)
|
|
if(graceful)
|
|
calling_holopad.say("Call rejected.")
|
|
testing("No recipients, terminating")
|
|
qdel(src)
|
|
|
|
///Answers a call made to answering_holopad which cannot be the calling holopad. Pads not in the call are ignored
|
|
/datum/holocall/proc/Answer(obj/machinery/holopad/answering_holopad)
|
|
testing("Holocall answer")
|
|
if(answering_holopad == calling_holopad)
|
|
CRASH("How cute, a holopad tried to answer itself.")
|
|
|
|
if(!(answering_holopad in dialed_holopads))
|
|
return
|
|
|
|
if(connected_holopad)
|
|
CRASH("Multi-connection holocall")
|
|
|
|
for(var/obj/machinery/holopad/other_dialed_holopad as anything in dialed_holopads)
|
|
if(other_dialed_holopad == answering_holopad)
|
|
continue
|
|
Disconnect(other_dialed_holopad)
|
|
|
|
for(var/datum/holocall/previously_answered_holocall as anything in answering_holopad.holo_calls)//disconnect the other holocalls answering_holopad is occupied with
|
|
if(previously_answered_holocall != src)
|
|
previously_answered_holocall.Disconnect(answering_holopad)
|
|
|
|
connected_holopad = answering_holopad
|
|
|
|
if(!Check())
|
|
return
|
|
|
|
calling_holopad.callee_picked_up()
|
|
hologram = answering_holopad.activate_holo(user)
|
|
hologram.HC = src
|
|
|
|
//eyeobj code is horrid, this is the best copypasta I could make
|
|
eye = new
|
|
eye.origin = answering_holopad
|
|
eye.eye_initialized = TRUE
|
|
eye.eye_user = user
|
|
eye.name = "Camera Eye ([user.name])"
|
|
user.remote_control = eye
|
|
user.reset_perspective(eye)
|
|
eye.setLoc(answering_holopad.loc)
|
|
|
|
hangup = new(eye, src)
|
|
hangup.Grant(user)
|
|
playsound(answering_holopad, 'sound/machines/ping.ogg', 100)
|
|
answering_holopad.say("Connection established.")
|
|
|
|
//Checks the validity of a holocall and qdels itself if it's not. Returns TRUE if valid, FALSE otherwise
|
|
/datum/holocall/proc/Check()
|
|
for(var/obj/machinery/holopad/dialed_holopad as anything in dialed_holopads)
|
|
if(!dialed_holopad.is_operational)
|
|
ConnectionFailure(dialed_holopad)
|
|
|
|
if(QDELETED(src))
|
|
return FALSE
|
|
|
|
. = !QDELETED(user) && !user.incapacitated() && !QDELETED(calling_holopad) && calling_holopad.is_operational && user.loc == calling_holopad.loc
|
|
|
|
if(.)
|
|
if(!connected_holopad)
|
|
. = world.time < (call_start_time + HOLOPAD_MAX_DIAL_TIME)
|
|
if(!.)
|
|
calling_holopad.say("No answer received.")
|
|
|
|
if(!.)
|
|
testing("Holocall Check fail")
|
|
qdel(src)
|
|
|
|
/datum/action/innate/end_holocall
|
|
name = "End Holocall"
|
|
button_icon = 'icons/mob/actions/actions_silicon.dmi'
|
|
button_icon_state = "camera_off"
|
|
var/datum/holocall/hcall
|
|
|
|
/datum/action/innate/end_holocall/New(Target, datum/holocall/HC)
|
|
..()
|
|
hcall = HC
|
|
|
|
/datum/action/innate/end_holocall/Activate()
|
|
hcall.Disconnect(hcall.calling_holopad)
|
|
|
|
|
|
//RECORDS
|
|
/datum/holorecord
|
|
var/caller_name = "Unknown" //Caller name
|
|
var/image/caller_image
|
|
var/list/entries = list()
|
|
var/language = /datum/language/common //Initial language, can be changed by HOLORECORD_LANGUAGE entries
|
|
|
|
/datum/holorecord/proc/set_caller_image(mob/user)
|
|
var/olddir = user.dir
|
|
user.setDir(SOUTH)
|
|
caller_image = image(user)
|
|
user.setDir(olddir)
|
|
|
|
/obj/item/disk/holodisk
|
|
name = "holorecord disk"
|
|
desc = "Stores recorder holocalls."
|
|
icon_state = "holodisk"
|
|
obj_flags = UNIQUE_RENAME
|
|
custom_materials = list(/datum/material/iron = 100, /datum/material/glass = 100)
|
|
var/datum/holorecord/record
|
|
//Preset variables
|
|
var/preset_image_type
|
|
var/preset_record_text
|
|
|
|
/obj/item/disk/holodisk/Initialize(mapload)
|
|
. = ..()
|
|
if(preset_record_text)
|
|
INVOKE_ASYNC(src, PROC_REF(build_record))
|
|
|
|
/obj/item/disk/holodisk/Destroy()
|
|
QDEL_NULL(record)
|
|
return ..()
|
|
|
|
/obj/item/disk/holodisk/attackby(obj/item/W, mob/user, params)
|
|
if(istype(W, /obj/item/disk/holodisk))
|
|
var/obj/item/disk/holodisk/holodiskOriginal = W
|
|
if (holodiskOriginal.record)
|
|
if (!record)
|
|
record = new
|
|
record.caller_name = holodiskOriginal.record.caller_name
|
|
record.caller_image = holodiskOriginal.record.caller_image
|
|
record.entries = holodiskOriginal.record.entries.Copy()
|
|
record.language = holodiskOriginal.record.language
|
|
to_chat(user, span_notice("You copy the record from [holodiskOriginal] to [src] by connecting the ports!"))
|
|
name = holodiskOriginal.name
|
|
else
|
|
to_chat(user, span_warning("[holodiskOriginal] has no record on it!"))
|
|
..()
|
|
|
|
/obj/item/disk/holodisk/proc/build_record()
|
|
record = new
|
|
var/list/lines = splittext(preset_record_text,"\n")
|
|
for(var/line in lines)
|
|
var/prepared_line = trim(line)
|
|
if(!length(prepared_line))
|
|
continue
|
|
var/splitpoint = findtext(prepared_line," ")
|
|
if(!splitpoint)
|
|
continue
|
|
var/command = copytext(prepared_line, 1, splitpoint)
|
|
var/value = copytext(prepared_line, splitpoint + length(prepared_line[splitpoint]))
|
|
switch(command)
|
|
if("DELAY")
|
|
var/delay_value = text2num(value)
|
|
if(!delay_value)
|
|
continue
|
|
record.entries += list(list(HOLORECORD_DELAY,delay_value))
|
|
if("NAME")
|
|
if(!record.caller_name)
|
|
record.caller_name = value
|
|
else
|
|
record.entries += list(list(HOLORECORD_RENAME,value))
|
|
if("SAY")
|
|
record.entries += list(list(HOLORECORD_SAY,value))
|
|
if("SOUND")
|
|
record.entries += list(list(HOLORECORD_SOUND,value))
|
|
if("LANGUAGE")
|
|
var/lang_type = text2path(value)
|
|
if(ispath(lang_type,/datum/language))
|
|
record.entries += list(list(HOLORECORD_LANGUAGE,lang_type))
|
|
if("PRESET")
|
|
var/preset_type = text2path(value)
|
|
if(ispath(preset_type,/datum/preset_holoimage))
|
|
record.entries += list(list(HOLORECORD_PRESET,preset_type))
|
|
if(!preset_image_type)
|
|
record.caller_image = image('icons/mob/simple/animal.dmi',"old")
|
|
else
|
|
var/datum/preset_holoimage/H = new preset_image_type
|
|
record.caller_image = H.build_image()
|
|
|
|
//These build caller image from outfit and some additional data, for use by mappers for ruin holorecords
|
|
/datum/preset_holoimage
|
|
var/nonhuman_mobtype //Fill this if you just want something nonhuman
|
|
var/outfit_type
|
|
var/species_type = /datum/species/human
|
|
|
|
/datum/preset_holoimage/proc/build_image()
|
|
if(nonhuman_mobtype)
|
|
var/mob/living/L = nonhuman_mobtype
|
|
. = image(initial(L.icon),initial(L.icon_state))
|
|
else
|
|
var/mob/living/carbon/human/dummy/mannequin = generate_or_wait_for_human_dummy("HOLODISK_PRESET")
|
|
if(species_type)
|
|
mannequin.set_species(species_type)
|
|
if(outfit_type)
|
|
mannequin.equipOutfit(outfit_type,TRUE)
|
|
mannequin.setDir(SOUTH)
|
|
. = image(mannequin)
|
|
unset_busy_human_dummy("HOLODISK_PRESET")
|
|
|
|
/datum/preset_holoimage/clown
|
|
outfit_type = /datum/outfit/job/clown
|
|
|
|
/datum/preset_holoimage/engineer
|
|
outfit_type = /datum/outfit/job/engineer
|
|
|
|
/datum/preset_holoimage/corgi
|
|
nonhuman_mobtype = /mob/living/basic/pet/dog/corgi
|
|
|
|
/datum/preset_holoimage/engineer/mod
|
|
outfit_type = /datum/outfit/job/engineer/mod
|
|
|
|
/datum/preset_holoimage/engineer/ce
|
|
outfit_type = /datum/outfit/job/ce
|
|
|
|
/datum/preset_holoimage/engineer/ce/mod
|
|
outfit_type = /datum/outfit/job/ce/mod
|
|
|
|
/datum/preset_holoimage/engineer/atmos
|
|
outfit_type = /datum/outfit/job/atmos
|
|
|
|
/datum/preset_holoimage/engineer/atmos/mod
|
|
outfit_type = /datum/outfit/job/atmos/mod
|
|
|
|
/datum/preset_holoimage/researcher
|
|
outfit_type = /datum/outfit/job/scientist
|
|
|
|
/datum/preset_holoimage/captain
|
|
outfit_type = /datum/outfit/job/captain
|
|
|
|
/datum/preset_holoimage/nanotrasenprivatesecurity
|
|
outfit_type = /datum/outfit/nanotrasensoldiercorpse
|
|
|
|
/datum/preset_holoimage/hivebot
|
|
nonhuman_mobtype = /mob/living/simple_animal/hostile/hivebot
|
|
|
|
/datum/preset_holoimage/ai
|
|
nonhuman_mobtype = /mob/living/silicon/ai
|
|
|
|
/datum/preset_holoimage/robot
|
|
nonhuman_mobtype = /mob/living/silicon/robot
|
|
|
|
/obj/item/disk/holodisk/example
|
|
preset_image_type = /datum/preset_holoimage/clown
|
|
preset_record_text = {"
|
|
NAME Clown
|
|
DELAY 10
|
|
SAY Why did the chaplain cross the maint ?
|
|
DELAY 20
|
|
SAY He wanted to get to the other side!
|
|
SOUND clownstep
|
|
DELAY 30
|
|
LANGUAGE /datum/language/narsie
|
|
SAY Helped him get there!
|
|
DELAY 10
|
|
SAY ALSO IM SECRETLY A GORILLA
|
|
DELAY 10
|
|
PRESET /datum/preset_holoimage/gorilla
|
|
NAME Gorilla
|
|
LANGUAGE /datum/language/common
|
|
SAY OOGA
|
|
DELAY 20"}
|
|
|
|
/obj/item/disk/holodisk/donutstation/whiteship
|
|
name = "Blackbox Print-out #DS024"
|
|
desc = "A holodisk containing the last viable recording of DS024's blackbox."
|
|
preset_image_type = /datum/preset_holoimage/engineer/ce
|
|
preset_record_text = {"
|
|
NAME Geysr Shorthalt
|
|
SAY Engine renovations complete and the ships been loaded. We all ready?
|
|
DELAY 25
|
|
PRESET /datum/preset_holoimage/engineer
|
|
NAME Jacob Ullman
|
|
SAY Lets blow this popsicle stand of a station.
|
|
DELAY 20
|
|
PRESET /datum/preset_holoimage/engineer/atmos
|
|
NAME Lindsey Cuffler
|
|
SAY Uh, sir? Shouldn't we call for a secondary shuttle? The bluespace drive on this thing made an awfully weird noise when we jumped here..
|
|
DELAY 30
|
|
PRESET /datum/preset_holoimage/engineer/ce
|
|
NAME Geysr Shorthalt
|
|
SAY Pah! Ship techie at the dock said to give it a good few kicks if it started acting up, let me just..
|
|
DELAY 25
|
|
SOUND punch
|
|
SOUND sparks
|
|
DELAY 10
|
|
SOUND punch
|
|
SOUND sparks
|
|
DELAY 10
|
|
SOUND punch
|
|
SOUND sparks
|
|
SOUND warpspeed
|
|
DELAY 15
|
|
PRESET /datum/preset_holoimage/engineer/atmos
|
|
NAME Lindsey Cuffler
|
|
SAY Uhh.. is it supposed to be doing that??
|
|
DELAY 15
|
|
PRESET /datum/preset_holoimage/engineer/ce
|
|
NAME Geysr Shorthalt
|
|
SAY See? Working as intended. Now, are we all ready?
|
|
DELAY 10
|
|
PRESET /datum/preset_holoimage/engineer
|
|
NAME Jacob Ullman
|
|
SAY Is it supposed to be glowing like that?
|
|
DELAY 20
|
|
SOUND explosion
|
|
|
|
"}
|
|
|
|
/obj/item/disk/holodisk/ruin/snowengieruin
|
|
name = "Blackbox Print-out #EB412"
|
|
desc = "A holodisk containing the last moments of EB412. There's a bloody fingerprint on it."
|
|
preset_image_type = /datum/preset_holoimage/engineer
|
|
preset_record_text = {"
|
|
NAME Dave Tundrale
|
|
SAY Maria, how's Build?
|
|
DELAY 10
|
|
NAME Maria Dell
|
|
PRESET /datum/preset_holoimage/engineer/atmos
|
|
SAY It's fine, don't worry. I've got Plastic on it. And frankly, i'm kinda busy with, the, uhhm, incinerator.
|
|
DELAY 30
|
|
NAME Dave Tundrale
|
|
PRESET /datum/preset_holoimage/engineer
|
|
SAY Aight, wonderful. The science mans been kinda shit though. No RCDs-
|
|
DELAY 20
|
|
NAME Maria Dell
|
|
PRESET /datum/preset_holoimage/engineer/atmos
|
|
SAY Enough about your RCDs. They're not even that important, just bui-
|
|
DELAY 15
|
|
SOUND explosion
|
|
DELAY 10
|
|
SAY Oh, shit!
|
|
DELAY 10
|
|
PRESET /datum/preset_holoimage/engineer/atmos/mod
|
|
LANGUAGE /datum/language/narsie
|
|
NAME Unknown
|
|
SAY RISE, MY LORD!!
|
|
DELAY 10
|
|
LANGUAGE /datum/language/common
|
|
NAME Plastic
|
|
PRESET /datum/preset_holoimage/engineer/mod
|
|
SAY Fuck, fuck, fuck!
|
|
DELAY 20
|
|
NAME Maria Dell
|
|
PRESET /datum/preset_holoimage/engineer/atmos
|
|
SAY GEORGE, WAIT-
|
|
DELAY 10
|
|
PRESET /datum/preset_holoimage/corgi
|
|
NAME Blackbox Automated Message
|
|
SAY Connection lost. Dumping audio logs to disk.
|
|
DELAY 50"}
|
|
|
|
/obj/item/disk/holodisk/ruin/space/travelers_rest
|
|
name = "Owner's memo"
|
|
desc = "A holodisk containing a small memo from the previous owner, addressed to someone else."
|
|
preset_image_type = /datum/preset_holoimage/engineer/atmos
|
|
preset_record_text = {"
|
|
NAME Space Adventurer
|
|
SOUND PING
|
|
DELAY 20
|
|
SAY Hey, I left you this message for when you come back.
|
|
DELAY 50
|
|
SAY I picked up an emergency signal from a freighter and I'm going there to search for some goodies.
|
|
DELAY 50
|
|
SAY You can crash here if you need to, but make sure to check the anchor cables before you leave.
|
|
DELAY 50
|
|
SAY If you don't, this thing might drift off into space.
|
|
DELAY 50
|
|
SAY Then some weirdo could find it and potentially claim it as their own.
|
|
DELAY 50
|
|
SAY Anyway, gotta go, see ya!
|
|
DELAY 40
|
|
SOUND sparks
|
|
"}
|