mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-29 07:59:01 +01:00
Merge branch 'master' into medbay_fixes_and_shit
This commit is contained in:
+14
-2
@@ -202,7 +202,7 @@
|
||||
#include "code\controllers\subsystems\documents.dm"
|
||||
#include "code\controllers\subsystems\economy.dm"
|
||||
#include "code\controllers\subsystems\effects.dm"
|
||||
#include "code\controllers\subsystems\emergency_shuttle.dm"
|
||||
#include "code\controllers\subsystems\evac.dm"
|
||||
#include "code\controllers\subsystems\event.dm"
|
||||
#include "code\controllers\subsystems\explosives.dm"
|
||||
#include "code\controllers\subsystems\fail2topic.dm"
|
||||
@@ -247,6 +247,14 @@
|
||||
#include "code\controllers\subsystems\virtual_reality.dm"
|
||||
#include "code\controllers\subsystems\vote.dm"
|
||||
#include "code\controllers\subsystems\zcopy.dm"
|
||||
#include "code\controllers\subsystems\evacuation\evacuation.dm"
|
||||
#include "code\controllers\subsystems\evacuation\evacuation_eta.dm"
|
||||
#include "code\controllers\subsystems\evacuation\evacuation_helpers.dm"
|
||||
#include "code\controllers\subsystems\evacuation\evacuation_option.dm"
|
||||
#include "code\controllers\subsystems\evacuation\evacuation_pods.dm"
|
||||
#include "code\controllers\subsystems\evacuation\evacuation_predicate.dm"
|
||||
#include "code\controllers\subsystems\evacuation\evacuation_shuttle.dm"
|
||||
#include "code\controllers\subsystems\evacuation\~evac.dm"
|
||||
#include "code\controllers\subsystems\initialization\atlas.dm"
|
||||
#include "code\controllers\subsystems\initialization\atoms.dm"
|
||||
#include "code\controllers\subsystems\initialization\holomap.dm"
|
||||
@@ -292,6 +300,7 @@
|
||||
#include "code\datums\weakref.dm"
|
||||
#include "code\datums\components\_component.dm"
|
||||
#include "code\datums\components\armor\armor.dm"
|
||||
#include "code\datums\components\base_name\base_name.dm"
|
||||
#include "code\datums\components\multitool\_multitool.dm"
|
||||
#include "code\datums\components\multitool\multitool.dm"
|
||||
#include "code\datums\components\multitool\circuitboards\circuitboards.dm"
|
||||
@@ -314,6 +323,7 @@
|
||||
#include "code\datums\looping_sounds\thermal_drill.dm"
|
||||
#include "code\datums\observation\_debug.dm"
|
||||
#include "code\datums\observation\destroyed.dm"
|
||||
#include "code\datums\observation\dir_set.dm"
|
||||
#include "code\datums\observation\entered.dm"
|
||||
#include "code\datums\observation\equipped.dm"
|
||||
#include "code\datums\observation\exited.dm"
|
||||
@@ -533,6 +543,7 @@
|
||||
#include "code\game\gamemodes\cult\structures\pylon.dm"
|
||||
#include "code\game\gamemodes\cult\structures\structure.dm"
|
||||
#include "code\game\gamemodes\endgame\endgame.dm"
|
||||
#include "code\game\gamemodes\endgame\bluespace_jump\bluespace_jump.dm"
|
||||
#include "code\game\gamemodes\endgame\supermatter_cascade\blob.dm"
|
||||
#include "code\game\gamemodes\endgame\supermatter_cascade\portal.dm"
|
||||
#include "code\game\gamemodes\endgame\supermatter_cascade\universe.dm"
|
||||
@@ -1105,6 +1116,7 @@
|
||||
#include "code\game\objects\structures\extinguisher.dm"
|
||||
#include "code\game\objects\structures\fireaxe_cabinet.dm"
|
||||
#include "code\game\objects\structures\flora.dm"
|
||||
#include "code\game\objects\structures\full_window_frame.dm"
|
||||
#include "code\game\objects\structures\girders.dm"
|
||||
#include "code\game\objects\structures\grille.dm"
|
||||
#include "code\game\objects\structures\inflatable.dm"
|
||||
@@ -1862,6 +1874,7 @@
|
||||
#include "code\modules\hydroponics\seed_datums\flowers.dm"
|
||||
#include "code\modules\hydroponics\seed_datums\fruits.dm"
|
||||
#include "code\modules\hydroponics\seed_datums\grains.dm"
|
||||
#include "code\modules\hydroponics\seed_datums\herbs.dm"
|
||||
#include "code\modules\hydroponics\seed_datums\jargon.dm"
|
||||
#include "code\modules\hydroponics\seed_datums\misc.dm"
|
||||
#include "code\modules\hydroponics\seed_datums\mushrooms.dm"
|
||||
@@ -2224,7 +2237,6 @@
|
||||
#include "code\modules\mob\living\silicon\robot\drone\drone_damage.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\drone\drone_items.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\drone\drone_manufacturer.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\drone\drone_say.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\items\_helpers.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\items\auto_harvester.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\items\electric_arm.dm"
|
||||
|
||||
@@ -73,20 +73,24 @@
|
||||
|
||||
// Synth Languages
|
||||
#define LANGUAGE_ROBOT "Robot Talk"
|
||||
#define LANGUAGE_LOCAL_DRONE "Drone Transmission"
|
||||
#define LANGUAGE_DRONE "Drone Talk"
|
||||
#define LANGUAGE_EAL "Encoded Audio Language"
|
||||
|
||||
// Language flags.
|
||||
#define WHITELISTED 1 // Language is available if the speaker is whitelisted.
|
||||
#define RESTRICTED 2 // Language can only be acquired by spawning or an admin.
|
||||
#define NONVERBAL 4 // Language has a significant non-verbal component. Speech is garbled without line-of-sight.
|
||||
#define SIGNLANG 8 // Language is completely non-verbal. Speech is displayed through emotes for those who can understand.
|
||||
#define HIVEMIND 16 // Broadcast to all mobs with this language.
|
||||
#define NONGLOBAL 32 // Do not add to general languages list.
|
||||
#define INNATE 64 // All mobs can be assumed to speak and understand this language. (audible emotes)
|
||||
#define NO_TALK_MSG 128 // Do not show the "\The [speaker] talks into \the [radio]" message
|
||||
#define NO_STUTTER 256 // No stuttering, slurring, or other speech problems
|
||||
#define TCOMSSIM 512 // Can be synthesized in tcoms
|
||||
#define WHITELISTED BITFLAG(0) // Language is available if the speaker is whitelisted.
|
||||
#define RESTRICTED BITFLAG(1) // Language can only be acquired by spawning or an admin.
|
||||
#define NONVERBAL BITFLAG(2) // Language has a significant non-verbal component. Speech is garbled without line-of-sight.
|
||||
#define SIGNLANG BITFLAG(3) // Language is completely non-verbal. Speech is displayed through emotes for those who can understand.
|
||||
#define HIVEMIND BITFLAG(4) // Broadcast to all mobs with this language.
|
||||
#define NONGLOBAL BITFLAG(5) // Do not add to general languages list.
|
||||
#define INNATE BITFLAG(6) // All mobs can be assumed to speak and understand this language. (audible emotes)
|
||||
#define NO_TALK_MSG BITFLAG(7) // Do not show the "\The [speaker] talks into \the [radio]" message
|
||||
#define NO_STUTTER BITFLAG(8) // No stuttering, slurring, or other speech problems
|
||||
#define TCOMSSIM BITFLAG(9) // Can be synthesized in tcoms
|
||||
#define KNOWONLYHEAR BITFLAG(10) // Only people who know the language actually hears it
|
||||
#define PRESSUREPROOF BITFLAG(11) // Pressure doesn't affect hearing
|
||||
#define PASSLISTENOBJ BITFLAG(12) // Listening Objs can't hear this language
|
||||
|
||||
// Autohiss
|
||||
#define AUTOHISS_OFF 0
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
//#define SS_PRIORITY_DEFAULT 50 // This is defined somewhere else.
|
||||
#define SS_PRIORITY_PSYCHICS 30
|
||||
#define SS_PRIORITY_ARRIVALS 30 // Centcomm arrivals shuttle auto-launch. Usually asleep.
|
||||
#define SS_PRIORITY_EVAC 30 // Processes the evac controller.
|
||||
#define SS_PRIORITY_EXPLOSIVES 20 // Explosion processor. Doesn't have much effect on explosion tick-checking.
|
||||
#define SS_PRIORITY_DISPOSALS 20 // Disposal holder movement.
|
||||
#define SS_PRIORITY_MODIFIER 10
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
AI.ai_announcement()
|
||||
|
||||
/obj/screen/ai/call_shuttle
|
||||
name = "Call Emergency Shuttle"
|
||||
name = "Call Evacuation"
|
||||
icon_state = "call_shuttle"
|
||||
screen_loc = ui_ai_shuttle
|
||||
|
||||
|
||||
@@ -1,308 +0,0 @@
|
||||
var/datum/controller/subsystem/emergency_shuttle/emergency_shuttle
|
||||
|
||||
/datum/controller/subsystem/emergency_shuttle
|
||||
name = "Emergency Shuttle"
|
||||
flags = SS_NO_TICK_CHECK | SS_NO_INIT
|
||||
|
||||
var/datum/shuttle/autodock/ferry/emergency/shuttle
|
||||
|
||||
var/launch_time //the time at which the shuttle will be launched
|
||||
var/force_time //the time at which the shuttle will be forced
|
||||
var/auto_recall = 0 //if set, the shuttle will be auto-recalled
|
||||
var/auto_recall_time //the time at which the shuttle will be auto-recalled
|
||||
var/evac = 0 //1 = emergency evacuation, 0 = crew transfer
|
||||
var/wait_for_launch = 0 //if the shuttle is waiting to launch
|
||||
var/wait_for_force = 0 //if the shuttle is waiting to be forced
|
||||
var/autopilot = 1 //set to 0 to disable the shuttle automatically launching
|
||||
|
||||
var/deny_shuttle = 0 //allows admins to prevent the shuttle from being called
|
||||
var/departed = 0 //if the shuttle has left the station at least once
|
||||
|
||||
/datum/controller/subsystem/emergency_shuttle/Recover()
|
||||
// Just copy all the stuff over.
|
||||
src.shuttle = emergency_shuttle.shuttle
|
||||
src.launch_time = emergency_shuttle.launch_time
|
||||
src.auto_recall = emergency_shuttle.auto_recall
|
||||
src.auto_recall_time = emergency_shuttle.auto_recall_time
|
||||
src.evac = emergency_shuttle.evac
|
||||
src.wait_for_launch = emergency_shuttle.wait_for_launch
|
||||
src.autopilot = emergency_shuttle.autopilot
|
||||
src.deny_shuttle = emergency_shuttle.deny_shuttle
|
||||
|
||||
/datum/controller/subsystem/emergency_shuttle/New()
|
||||
NEW_SS_GLOBAL(emergency_shuttle)
|
||||
|
||||
/datum/controller/subsystem/emergency_shuttle/fire()
|
||||
if(!shuttle)
|
||||
return
|
||||
if (wait_for_launch)
|
||||
if (evac && auto_recall && world.time >= auto_recall_time)
|
||||
recall()
|
||||
if (world.time >= launch_time) //time to launch the shuttle
|
||||
stop_launch_countdown()
|
||||
|
||||
if (!shuttle.location) //leaving from the station
|
||||
//launch the pods!
|
||||
for (var/datum/shuttle/autodock/ferry/escape_pod/pod in escape_pods)
|
||||
if (!pod.arming_controller || pod.arming_controller.armed)
|
||||
pod.launch(src)
|
||||
|
||||
if (autopilot)
|
||||
shuttle.launch(src)
|
||||
if (wait_for_force)
|
||||
if (world.time > force_time)
|
||||
stop_force_countdown()
|
||||
if(waiting_to_leave())
|
||||
shuttle.launch(src)
|
||||
shuttle.force_launch(src)
|
||||
|
||||
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/shuttle_arrived()
|
||||
if (!shuttle.location) //at station
|
||||
if (autopilot)
|
||||
set_launch_countdown(SHUTTLE_LEAVETIME) //get ready to return
|
||||
|
||||
if (evac)
|
||||
set_force_countdown(SHUTTLE_FORCETIME)
|
||||
priority_announcement.Announce(replacetext(current_map.emergency_shuttle_docked_message, "%ETD%", round(estimate_launch_time()/60,1)), new_sound = 'sound/AI/emergencyshuttledock.ogg')
|
||||
else
|
||||
set_force_countdown(SHUTTLE_LEAVETIME)
|
||||
var/list/fields = list(
|
||||
"%ETA%" = round(emergency_shuttle.estimate_launch_time()/60,1),
|
||||
"%dock%" = current_map.dock_name
|
||||
)
|
||||
priority_announcement.Announce(replacemany(current_map.shuttle_docked_message, fields), new_sound = 'sound/AI/shuttledock.ogg')
|
||||
|
||||
//arm the escape pods
|
||||
if (evac)
|
||||
for (var/datum/shuttle/autodock/ferry/escape_pod/pod in escape_pods)
|
||||
if (pod.arming_controller)
|
||||
pod.arming_controller.arm()
|
||||
|
||||
//begins the launch countdown and sets the amount of time left until launch
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/set_launch_countdown(var/seconds)
|
||||
wait_for_launch = 1
|
||||
launch_time = world.time + seconds*10
|
||||
|
||||
//begins the launch countdown and sets the amount of time left until launch
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/set_force_countdown(var/seconds)
|
||||
if(!wait_for_force)
|
||||
wait_for_force = 1
|
||||
force_time = world.time + seconds*10
|
||||
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/stop_launch_countdown()
|
||||
wait_for_launch = 0
|
||||
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/stop_force_countdown()
|
||||
wait_for_force = 0
|
||||
|
||||
//calls the shuttle for an emergency evacuation
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/call_evac()
|
||||
if(!can_call()) return
|
||||
|
||||
//set the launch timer
|
||||
autopilot = 1
|
||||
set_launch_countdown(get_shuttle_prep_time())
|
||||
auto_recall_time = rand(world.time + 300, launch_time - 300)
|
||||
|
||||
//reset the shuttle transit time if we need to
|
||||
shuttle.move_time = SHUTTLE_TRANSIT_DURATION
|
||||
|
||||
evac = 1
|
||||
priority_announcement.Announce(replacetext(current_map.emergency_shuttle_called_message, "%ETA%", round(estimate_arrival_time()/60)), new_sound = 'sound/AI/emergencyshuttlecalled.ogg')
|
||||
for(var/area/A in all_areas)
|
||||
if(istype(A, /area/hallway))
|
||||
A.readyalert()
|
||||
|
||||
//calls the shuttle for a routine crew transfer
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/call_transfer()
|
||||
if(!can_call()) return
|
||||
|
||||
//set the launch timer
|
||||
autopilot = 1
|
||||
set_launch_countdown(get_shuttle_prep_time())
|
||||
auto_recall_time = rand(world.time + 300, launch_time - 300)
|
||||
|
||||
//reset the shuttle transit time if we need to
|
||||
shuttle.move_time = SHUTTLE_TRANSIT_DURATION
|
||||
|
||||
var/list/replacements = list(
|
||||
"%ETA%" = round(estimate_arrival_time()/60),
|
||||
"%dock%" = current_map.dock_name
|
||||
)
|
||||
priority_announcement.Announce(replacemany(current_map.shuttle_called_message, replacements), new_sound = 'sound/AI/shuttlecalled.ogg')
|
||||
|
||||
//recalls the shuttle
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/recall()
|
||||
if (!can_recall()) return
|
||||
|
||||
wait_for_launch = 0
|
||||
shuttle.cancel_launch(src)
|
||||
|
||||
if (evac)
|
||||
priority_announcement.Announce(current_map.emergency_shuttle_recall_message, new_sound = 'sound/AI/emergencyshuttlerecalled.ogg')
|
||||
|
||||
for(var/area/A in all_areas)
|
||||
if(istype(A, /area/hallway))
|
||||
A.readyreset()
|
||||
evac = 0
|
||||
else
|
||||
priority_announcement.Announce(current_map.shuttle_recall_message, new_sound = 'sound/AI/shuttlerecalled.ogg')
|
||||
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/can_call()
|
||||
if (!universe.OnShuttleCall(null))
|
||||
return 0
|
||||
if (deny_shuttle)
|
||||
return 0
|
||||
if (shuttle.moving_status != SHUTTLE_IDLE || !shuttle.location) //must be idle at centcom
|
||||
return 0
|
||||
if (wait_for_launch) //already launching
|
||||
return 0
|
||||
return 1
|
||||
|
||||
//this only returns 0 if it would absolutely make no sense to recall
|
||||
//e.g. the shuttle is already at the station or wasn't called to begin with
|
||||
//other reasons for the shuttle not being recallable should be handled elsewhere
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/can_recall()
|
||||
if (shuttle.moving_status == SHUTTLE_INTRANSIT) //if the shuttle is already in transit then it's too late
|
||||
return 0
|
||||
if (!shuttle.location) //already at the station.
|
||||
return 0
|
||||
if (!wait_for_launch) //we weren't going anywhere, anyways...
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/get_shuttle_prep_time()
|
||||
// During mutiny rounds, the shuttle takes twice as long.
|
||||
if(SSticker.mode)
|
||||
return SHUTTLE_PREPTIME * SSticker.mode.shuttle_delay
|
||||
return SHUTTLE_PREPTIME
|
||||
|
||||
|
||||
/*
|
||||
These procs are not really used by the controller itself, but are for other parts of the
|
||||
game whose logic depends on the emergency shuttle.
|
||||
*/
|
||||
|
||||
//returns 1 if the shuttle is docked at the station and waiting to leave
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/waiting_to_leave()
|
||||
if(!shuttle)
|
||||
return
|
||||
if (shuttle.location)
|
||||
return 0 //not at station
|
||||
return (wait_for_launch || shuttle.moving_status != SHUTTLE_INTRANSIT)
|
||||
|
||||
//so we don't have emergency_shuttle.shuttle.location everywhere
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/location()
|
||||
if (!shuttle)
|
||||
return 1 //if we dont have a shuttle datum, just act like it's at centcom
|
||||
return shuttle.location
|
||||
|
||||
//returns the time left until the shuttle arrives at it's destination, in seconds
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/estimate_arrival_time()
|
||||
var/eta
|
||||
if (shuttle.has_arrive_time())
|
||||
//we are in transition and can get an accurate ETA
|
||||
eta = shuttle.arrive_time
|
||||
else
|
||||
//otherwise we need to estimate the arrival time using the scheduled launch time
|
||||
eta = launch_time + shuttle.move_time*10 + shuttle.warmup_time*10
|
||||
return (eta - world.time)/10
|
||||
|
||||
//returns the time left until the shuttle launches, in seconds
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/estimate_launch_time()
|
||||
return (launch_time - world.time)/10
|
||||
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/has_eta()
|
||||
if(!shuttle)
|
||||
return
|
||||
return (wait_for_launch || shuttle.moving_status != SHUTTLE_IDLE)
|
||||
|
||||
//returns 1 if the shuttle has gone to the station and come back at least once,
|
||||
//used for game completion checking purposes
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/returned()
|
||||
return (departed && shuttle.moving_status == SHUTTLE_IDLE && shuttle.location) //we've gone to the station at least once, no longer in transit and are idle back at centcom
|
||||
|
||||
//returns 1 if the shuttle is not idle at centcom
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/online()
|
||||
if (isnull(shuttle))
|
||||
return FALSE
|
||||
if (!shuttle.location) //not at centcom
|
||||
return TRUE
|
||||
if (wait_for_launch || shuttle.moving_status != SHUTTLE_IDLE)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
//returns 1 if the shuttle is currently in transit (or just leaving) to the station
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/going_to_station()
|
||||
return (!shuttle.direction && shuttle.moving_status != SHUTTLE_IDLE)
|
||||
|
||||
//returns 1 if the shuttle is currently in transit (or just leaving) to centcom
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/going_to_centcom()
|
||||
return (shuttle && shuttle.direction && shuttle.moving_status != SHUTTLE_IDLE)
|
||||
|
||||
|
||||
/datum/controller/subsystem/emergency_shuttle/proc/get_status_panel_eta()
|
||||
if (online())
|
||||
if (shuttle.has_arrive_time())
|
||||
var/timeleft = emergency_shuttle.estimate_arrival_time()
|
||||
return "ETA-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]"
|
||||
|
||||
if (waiting_to_leave())
|
||||
if (shuttle.moving_status == SHUTTLE_WARMUP)
|
||||
return "Departing..."
|
||||
|
||||
var/timeleft = emergency_shuttle.estimate_launch_time()
|
||||
return "ETD-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]"
|
||||
|
||||
return ""
|
||||
/*
|
||||
Some slapped-together star effects for maximum spess immershuns. Basically consists of a
|
||||
spawner, an ender, and bgstar. Spawners create bgstars, bgstars shoot off into a direction
|
||||
until they reach a starender.
|
||||
*/
|
||||
|
||||
/obj/effect/bgstar
|
||||
name = "star"
|
||||
var/speed = 10
|
||||
var/direction = SOUTH
|
||||
layer = 2 // TURF_LAYER
|
||||
|
||||
/obj/effect/bgstar/New()
|
||||
..()
|
||||
pixel_x += rand(-2,30)
|
||||
pixel_y += rand(-2,30)
|
||||
var/starnum = pick("1", "1", "1", "2", "3", "4")
|
||||
|
||||
icon_state = "star"+starnum
|
||||
|
||||
speed = rand(2, 5)
|
||||
|
||||
/obj/effect/bgstar/proc/startmove()
|
||||
|
||||
while(src)
|
||||
sleep(speed)
|
||||
step(src, direction)
|
||||
for(var/obj/effect/starender/E in loc)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/obj/effect/starender
|
||||
invisibility = 101
|
||||
|
||||
/obj/effect/starspawner
|
||||
invisibility = 101
|
||||
var/spawndir = SOUTH
|
||||
var/spawning = 0
|
||||
|
||||
/obj/effect/starspawner/West
|
||||
spawndir = WEST
|
||||
|
||||
/obj/effect/starspawner/proc/startspawn()
|
||||
spawning = 1
|
||||
while(spawning)
|
||||
sleep(rand(2, 30))
|
||||
var/obj/effect/bgstar/S = new/obj/effect/bgstar(locate(x,y,z))
|
||||
S.direction = spawndir
|
||||
spawn()
|
||||
S.startmove()
|
||||
@@ -0,0 +1,17 @@
|
||||
var/datum/controller/subsystem/evac/SSevac
|
||||
|
||||
/datum/controller/subsystem/evac
|
||||
name = "Evacuation"
|
||||
priority = SS_PRIORITY_EVAC
|
||||
//Initializes at default time
|
||||
flags = SS_NO_TICK_CHECK|SS_BACKGROUND
|
||||
wait = 2 SECONDS
|
||||
|
||||
/datum/controller/subsystem/evac/Initialize()
|
||||
. = ..()
|
||||
if(!evacuation_controller)
|
||||
evacuation_controller = new current_map.evac_controller_type ()
|
||||
evacuation_controller.set_up()
|
||||
|
||||
/datum/controller/subsystem/evac/fire()
|
||||
evacuation_controller.process()
|
||||
@@ -0,0 +1,183 @@
|
||||
#define EVAC_IDLE 0
|
||||
#define EVAC_PREPPING 1
|
||||
#define EVAC_LAUNCHING 2
|
||||
#define EVAC_IN_TRANSIT 3
|
||||
#define EVAC_COOLDOWN 4
|
||||
#define EVAC_COMPLETE 5
|
||||
|
||||
var/datum/evacuation_controller/evacuation_controller
|
||||
|
||||
/datum/evacuation_controller
|
||||
|
||||
var/name = "generic evac controller"
|
||||
var/state = EVAC_IDLE
|
||||
var/deny
|
||||
var/recall
|
||||
var/auto_recall_time
|
||||
var/emergency_evacuation
|
||||
|
||||
var/evac_prep_delay = 10 MINUTES
|
||||
var/evac_launch_delay = 3 MINUTES
|
||||
var/evac_transit_delay = 2 MINUTES
|
||||
|
||||
var/autotransfer_prep_additional_delay = 0 MINUTES
|
||||
var/emergency_prep_additional_delay = 0 MINUTES
|
||||
var/transfer_prep_additional_delay = 0 MINUTES
|
||||
var/force_time = 0 MINUTES
|
||||
var/wait_for_force = FALSE //If the evac is waiting to be forced
|
||||
|
||||
var/evac_cooldown_time
|
||||
var/evac_called_at
|
||||
var/evac_no_return
|
||||
var/evac_ready_time
|
||||
var/evac_launch_time
|
||||
var/evac_arrival_time
|
||||
|
||||
var/list/evacuation_predicates = list()
|
||||
|
||||
var/list/evacuation_options = list()
|
||||
|
||||
var/datum/announcement/priority/evac_waiting = new(0)
|
||||
var/datum/announcement/priority/evac_called = new(0)
|
||||
var/datum/announcement/priority/evac_recalled = new(0)
|
||||
|
||||
/datum/evacuation_controller/proc/auto_recall(var/_recall)
|
||||
recall = _recall
|
||||
|
||||
/datum/evacuation_controller/proc/set_up()
|
||||
set waitfor=0
|
||||
set background=1
|
||||
|
||||
/datum/evacuation_controller/proc/get_cooldown_message()
|
||||
return "An evacuation cannot be called at this time. Please wait another [round((evac_cooldown_time-world.time)/600)] minute\s before trying again."
|
||||
|
||||
/datum/evacuation_controller/proc/add_can_call_predicate(var/datum/evacuation_predicate/esp)
|
||||
if(esp in evacuation_predicates)
|
||||
CRASH("[esp] has already been added as an evacuation predicate")
|
||||
evacuation_predicates += esp
|
||||
|
||||
/datum/evacuation_controller/proc/call_evacuation(var/mob/user, var/_emergency_evac, var/forced, var/skip_announce, var/autotransfer)
|
||||
if(state != EVAC_IDLE)
|
||||
return FALSE
|
||||
|
||||
if(!can_evacuate(user, forced))
|
||||
return FALSE
|
||||
|
||||
emergency_evacuation = _emergency_evac
|
||||
|
||||
var/evac_prep_delay_multiplier = 1
|
||||
if(SSticker.mode)
|
||||
evac_prep_delay_multiplier = SSticker.mode.shuttle_delay
|
||||
|
||||
var/additional_delay
|
||||
if(_emergency_evac)
|
||||
additional_delay = emergency_prep_additional_delay
|
||||
else if(autotransfer)
|
||||
additional_delay = autotransfer_prep_additional_delay
|
||||
else
|
||||
additional_delay = transfer_prep_additional_delay
|
||||
|
||||
evac_called_at = world.time
|
||||
evac_no_return = evac_called_at + round(evac_prep_delay/2) + additional_delay
|
||||
evac_ready_time = evac_called_at + (evac_prep_delay*evac_prep_delay_multiplier) + additional_delay
|
||||
evac_launch_time = evac_ready_time + evac_launch_delay
|
||||
evac_arrival_time = evac_launch_time + evac_transit_delay
|
||||
|
||||
var/evac_range = round((evac_launch_time - evac_called_at)/3)
|
||||
auto_recall_time = rand(evac_called_at + evac_range, evac_launch_time - evac_range)
|
||||
|
||||
state = EVAC_PREPPING
|
||||
|
||||
if(emergency_evacuation)
|
||||
for(var/area/A in all_areas)
|
||||
if(istype(A, /area/hallway))
|
||||
A.readyalert()
|
||||
if(!skip_announce)
|
||||
priority_announcement.Announce(replacetext(replacetext(current_map.emergency_shuttle_called_message, "%dock%", "[current_map.dock_name]"), "%ETA%", "[round(get_eta()/60)] minute\s"), new_sound = 'sound/AI/emergencyshuttlecalled.ogg')
|
||||
else
|
||||
if(!skip_announce)
|
||||
priority_announcement.Announce(replacetext(replacetext(current_map.shuttle_called_message, "%dock%", "[current_map.dock_name]"), "%ETA%", "[round(get_eta()/60)] minute\s"), new_sound = 'sound/AI/shuttlecalled.ogg')
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/evacuation_controller/proc/cancel_evacuation()
|
||||
if(!can_cancel())
|
||||
return FALSE
|
||||
|
||||
evac_cooldown_time = world.time + (world.time - evac_called_at)
|
||||
state = EVAC_COOLDOWN
|
||||
|
||||
evac_ready_time = null
|
||||
evac_arrival_time = null
|
||||
evac_no_return = null
|
||||
evac_called_at = null
|
||||
evac_launch_time = null
|
||||
auto_recall_time = null
|
||||
|
||||
if(emergency_evacuation)
|
||||
evac_recalled.Announce(current_map.emergency_shuttle_recall_message)
|
||||
for(var/area/A in all_areas)
|
||||
if(istype(A, /area/hallway))
|
||||
A.readyreset()
|
||||
emergency_evacuation = 0
|
||||
else
|
||||
priority_announcement.Announce(current_map.shuttle_recall_message)
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/evacuation_controller/proc/finish_preparing_evac()
|
||||
state = EVAC_LAUNCHING
|
||||
|
||||
var/estimated_time = round(get_eta()/60,1)
|
||||
if (emergency_evacuation)
|
||||
evac_waiting.Announce(replacetext(current_map.emergency_shuttle_docked_message, "%ETA%", "[estimated_time] minute\s"), new_sound = sound('sound/AI/emergencyshuttledock.ogg'))
|
||||
else
|
||||
priority_announcement.Announce(replacetext(replacetext(current_map.shuttle_docked_message, "%dock%", "[current_map.dock_name]"), "%ETA%", "[estimated_time] minute\s"), new_sound = sound('sound/AI/shuttledock.ogg'))
|
||||
|
||||
/datum/evacuation_controller/proc/launch_evacuation()
|
||||
if(waiting_to_leave())
|
||||
return
|
||||
|
||||
state = EVAC_IN_TRANSIT
|
||||
|
||||
if (emergency_evacuation)
|
||||
priority_announcement.Announce(replacetext(replacetext(current_map.emergency_shuttle_leaving_dock, "%dock%", "[current_map.dock_name]"), "%ETA%", "[round(get_eta()/60,1)] minute\s"))
|
||||
else
|
||||
priority_announcement.Announce(replacetext(replacetext(current_map.shuttle_leaving_dock, "%dock%", "[current_map.dock_name]"), "%ETA%", "[round(get_eta()/60,1)] minute\s"))
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/evacuation_controller/proc/finish_evacuation()
|
||||
state = EVAC_COMPLETE
|
||||
|
||||
/datum/evacuation_controller/process()
|
||||
if(state == EVAC_PREPPING && recall && world.time >= auto_recall_time)
|
||||
cancel_evacuation()
|
||||
return
|
||||
|
||||
if(state == EVAC_PREPPING)
|
||||
if(world.time >= evac_ready_time)
|
||||
finish_preparing_evac()
|
||||
else if(state == EVAC_LAUNCHING)
|
||||
if(world.time >= evac_launch_time)
|
||||
launch_evacuation()
|
||||
else if(state == EVAC_IN_TRANSIT)
|
||||
if(world.time >= evac_arrival_time)
|
||||
finish_evacuation()
|
||||
else if(state == EVAC_COOLDOWN)
|
||||
if(world.time >= evac_cooldown_time)
|
||||
state = EVAC_IDLE
|
||||
|
||||
/datum/evacuation_controller/proc/available_evac_options()
|
||||
return list()
|
||||
|
||||
/datum/evacuation_controller/proc/handle_evac_option(var/option_target, var/mob/user)
|
||||
var/datum/evacuation_option/selected = evacuation_options[option_target]
|
||||
if (!isnull(selected) && istype(selected))
|
||||
selected.execute(user)
|
||||
|
||||
/datum/evacuation_controller/proc/get_evac_option(var/option_target)
|
||||
return null
|
||||
|
||||
/datum/evacuation_controller/proc/should_call_autotransfer_vote()
|
||||
return (state == EVAC_IDLE)
|
||||
@@ -0,0 +1,22 @@
|
||||
/datum/evacuation_controller/proc/get_status_panel_eta()
|
||||
|
||||
if(waiting_to_leave())
|
||||
return "Delayed"
|
||||
var/timeleft = get_eta()
|
||||
if(timeleft < 0)
|
||||
return ""
|
||||
return "[is_on_cooldown() ? "Returning" : (is_arriving() ? "ETA" : "ETD")] [add_zero(num2text((timeleft / 60) % 60),2)]:[add_zero(num2text(timeleft % 60), 2)]"
|
||||
|
||||
/datum/evacuation_controller/proc/has_eta()
|
||||
return (state == EVAC_PREPPING || state == EVAC_LAUNCHING || state == EVAC_IN_TRANSIT || state == EVAC_COOLDOWN)
|
||||
|
||||
/datum/evacuation_controller/proc/get_eta()
|
||||
if(state == EVAC_PREPPING)
|
||||
return (evac_ready_time ? (evac_ready_time - world.time)/10 : -1)
|
||||
else if(state == EVAC_LAUNCHING)
|
||||
return (evac_launch_time ? (evac_launch_time - world.time)/10 : -1)
|
||||
else if(state == EVAC_IN_TRANSIT)
|
||||
return (evac_arrival_time ? (evac_arrival_time - world.time)/10 : -1)
|
||||
else if(state == EVAC_COOLDOWN)
|
||||
return (evac_cooldown_time ? (evac_cooldown_time - world.time)/10 : -1)
|
||||
return -1
|
||||
@@ -0,0 +1,68 @@
|
||||
/datum/evacuation_controller/proc/set_launch_time(var/val)
|
||||
evac_launch_time = val
|
||||
|
||||
/datum/evacuation_controller/proc/set_arrival_time(var/val)
|
||||
evac_arrival_time = val
|
||||
|
||||
/datum/evacuation_controller/proc/is_prepared()
|
||||
return (state == EVAC_LAUNCHING)
|
||||
|
||||
/datum/evacuation_controller/proc/is_in_transit()
|
||||
return (state == EVAC_IN_TRANSIT)
|
||||
|
||||
/datum/evacuation_controller/proc/is_idle()
|
||||
return (state == EVAC_IDLE)
|
||||
|
||||
/datum/evacuation_controller/proc/has_evacuated()
|
||||
return (!isnull(evac_launch_time) && world.time > evac_launch_time)
|
||||
|
||||
/datum/evacuation_controller/proc/round_over()
|
||||
return state == EVAC_COMPLETE
|
||||
|
||||
/datum/evacuation_controller/proc/is_on_cooldown()
|
||||
return state == EVAC_COOLDOWN
|
||||
|
||||
/datum/evacuation_controller/proc/is_evacuating()
|
||||
return state != EVAC_IDLE
|
||||
|
||||
/datum/evacuation_controller/proc/can_evacuate(var/mob/user, var/forced)
|
||||
if(!isnull(evac_called_at))
|
||||
return FALSE
|
||||
|
||||
if (!universe.OnShuttleCall(null))
|
||||
return FALSE
|
||||
|
||||
if(!forced)
|
||||
for(var/predicate in evacuation_predicates)
|
||||
var/datum/evacuation_predicate/esp = predicate
|
||||
if(!esp.is_valid())
|
||||
evacuation_predicates -= esp
|
||||
qdel(esp)
|
||||
else
|
||||
if(!esp.can_call(user))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/evacuation_controller/proc/waiting_to_leave()
|
||||
return FALSE
|
||||
|
||||
/datum/evacuation_controller/proc/can_cancel()
|
||||
// Are we evacuating?
|
||||
if(isnull(evac_called_at))
|
||||
return FALSE
|
||||
// Have we already launched?
|
||||
if(state != EVAC_PREPPING)
|
||||
return FALSE
|
||||
// Are we already committed?
|
||||
if(world.time > evac_no_return)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/evacuation_controller/proc/is_arriving()
|
||||
if(state == EVAC_LAUNCHING)
|
||||
return FALSE
|
||||
return has_eta()
|
||||
|
||||
/datum/evacuation_controller/proc/is_departing()
|
||||
if(state == EVAC_LAUNCHING)
|
||||
return TRUE
|
||||
@@ -0,0 +1,28 @@
|
||||
#define EVAC_OPT_ABANDON_SHIP "abandon_ship"
|
||||
#define EVAC_OPT_CANCEL_ABANDON_SHIP "cancel_abandon_ship"
|
||||
|
||||
/datum/evacuation_controller/lifepods
|
||||
name = "escape pod controller"
|
||||
|
||||
evac_prep_delay = 7 MINUTES
|
||||
evac_launch_delay = 0
|
||||
evac_transit_delay = 2 MINUTES
|
||||
|
||||
evacuation_options = list(
|
||||
EVAC_OPT_ABANDON_SHIP = new /datum/evacuation_option/abandon_ship(),
|
||||
EVAC_OPT_CANCEL_ABANDON_SHIP = new /datum/evacuation_option/cancel_abandon_ship(),
|
||||
)
|
||||
|
||||
/datum/evacuation_controller/lifepods/launch_evacuation()
|
||||
priority_announcement.Announce(replacetext(replacetext(current_map.emergency_shuttle_leaving_dock, "%dock_name%", "[current_map.dock_name]"), "%ETA%", "[round(get_eta()/60,1)] minute\s"))
|
||||
|
||||
/datum/evacuation_controller/lifepods/available_evac_options()
|
||||
if (is_on_cooldown())
|
||||
return list()
|
||||
if (is_idle())
|
||||
return list(evacuation_options[EVAC_OPT_ABANDON_SHIP])
|
||||
if (is_evacuating())
|
||||
return list(evacuation_options[EVAC_OPT_CANCEL_ABANDON_SHIP])
|
||||
|
||||
#undef EVAC_OPT_ABANDON_SHIP
|
||||
#undef EVAC_OPT_CANCEL_ABANDON_SHIP
|
||||
@@ -0,0 +1,10 @@
|
||||
/datum/evacuation_option
|
||||
var/option_text = "Generic evac option"
|
||||
var/option_desc = "do something that should never be seen"
|
||||
var/option_target = "generic"
|
||||
var/needs_syscontrol = FALSE
|
||||
var/silicon_allowed = TRUE
|
||||
var/abandon_ship = FALSE
|
||||
|
||||
/datum/evacuation_option/proc/execute(var/mob/user)
|
||||
return
|
||||
@@ -0,0 +1,145 @@
|
||||
#define EVAC_OPT_ABANDON_SHIP "abandon_ship"
|
||||
#define EVAC_OPT_BLUESPACE_JUMP "bluespace_jump"
|
||||
#define EVAC_OPT_CANCEL_ABANDON_SHIP "cancel_abandon_ship"
|
||||
#define EVAC_OPT_CANCEL_BLUESPACE_JUMP "cancel_bluespace_jump"
|
||||
|
||||
// Apparently, emergency_evacuation --> "abandon ship" and !emergency_evacuation --> "bluespace jump"
|
||||
// That stuff should be moved to the evacuation option datums but someone can do that later
|
||||
/datum/evacuation_controller/starship
|
||||
name = "escape pod controller"
|
||||
|
||||
evac_prep_delay = 5 MINUTES
|
||||
evac_launch_delay = 3 MINUTES
|
||||
evac_transit_delay = 2 MINUTES
|
||||
|
||||
transfer_prep_additional_delay = 5 MINUTES
|
||||
autotransfer_prep_additional_delay = 5 MINUTES
|
||||
emergency_prep_additional_delay = 0 MINUTES
|
||||
|
||||
evacuation_options = list(
|
||||
EVAC_OPT_ABANDON_SHIP = new /datum/evacuation_option/abandon_ship(),
|
||||
EVAC_OPT_BLUESPACE_JUMP = new /datum/evacuation_option/bluespace_jump(),
|
||||
EVAC_OPT_CANCEL_ABANDON_SHIP = new /datum/evacuation_option/cancel_abandon_ship(),
|
||||
EVAC_OPT_CANCEL_BLUESPACE_JUMP = new /datum/evacuation_option/cancel_bluespace_jump()
|
||||
)
|
||||
|
||||
/datum/evacuation_controller/starship/finish_preparing_evac()
|
||||
. = ..()
|
||||
// Arm the escape pods.
|
||||
if (emergency_evacuation)
|
||||
for (var/datum/shuttle/autodock/ferry/escape_pod/pod in escape_pods)
|
||||
if (pod.arming_controller)
|
||||
pod.arming_controller.arm()
|
||||
|
||||
/datum/evacuation_controller/starship/launch_evacuation()
|
||||
|
||||
state = EVAC_IN_TRANSIT
|
||||
|
||||
if (emergency_evacuation)
|
||||
// Abondon Ship
|
||||
for (var/datum/shuttle/autodock/ferry/escape_pod/pod in escape_pods) // Launch the pods!
|
||||
if (!pod.arming_controller || pod.arming_controller.armed)
|
||||
pod.move_time = (evac_transit_delay/10)
|
||||
pod.launch(src)
|
||||
|
||||
priority_announcement.Announce(replacetext(replacetext(current_map.emergency_shuttle_leaving_dock, "%dock_name%", "[current_map.dock_name]"), "%ETA%", "[round(get_eta()/60,1)] minute\s"))
|
||||
else
|
||||
// Bluespace Jump
|
||||
priority_announcement.Announce(replacetext(replacetext(current_map.shuttle_leaving_dock, "%dock_name%", "[current_map.dock_name]"), "%ETA%", "[round(get_eta()/60,1)] minute\s"))
|
||||
SetUniversalState(/datum/universal_state/bluespace_jump, arguments=list(current_map.station_levels))
|
||||
|
||||
/datum/evacuation_controller/starship/finish_evacuation()
|
||||
..()
|
||||
if(!emergency_evacuation) //bluespace jump
|
||||
SetUniversalState(/datum/universal_state) //clear jump state
|
||||
|
||||
/datum/evacuation_controller/starship/available_evac_options()
|
||||
if (is_on_cooldown())
|
||||
return list()
|
||||
if (is_idle())
|
||||
return list(evacuation_options[EVAC_OPT_BLUESPACE_JUMP], evacuation_options[EVAC_OPT_ABANDON_SHIP])
|
||||
if (is_evacuating())
|
||||
if (emergency_evacuation)
|
||||
return list(evacuation_options[EVAC_OPT_CANCEL_ABANDON_SHIP])
|
||||
else
|
||||
return list(evacuation_options[EVAC_OPT_CANCEL_BLUESPACE_JUMP])
|
||||
|
||||
/datum/evacuation_option/abandon_ship
|
||||
option_text = "Abandon spacecraft"
|
||||
option_desc = "abandon the spacecraft"
|
||||
option_target = EVAC_OPT_ABANDON_SHIP
|
||||
needs_syscontrol = TRUE
|
||||
silicon_allowed = TRUE
|
||||
abandon_ship = TRUE
|
||||
|
||||
/datum/evacuation_option/abandon_ship/execute(mob/user)
|
||||
if (!evacuation_controller)
|
||||
return
|
||||
if (evacuation_controller.deny)
|
||||
to_chat(user, "Unable to initiate escape procedures.")
|
||||
return
|
||||
if (evacuation_controller.is_on_cooldown())
|
||||
to_chat(user, evacuation_controller.get_cooldown_message())
|
||||
return
|
||||
if (evacuation_controller.is_evacuating())
|
||||
to_chat(user, "Escape procedures already in progress.")
|
||||
return
|
||||
if (evacuation_controller.call_evacuation(user, 1))
|
||||
log_and_message_admins("[user? key_name(user) : "Autotransfer"] has initiated abandonment of the spacecraft.")
|
||||
|
||||
/datum/evacuation_option/bluespace_jump
|
||||
option_text = "Initiate bluespace jump"
|
||||
option_desc = "initiate a bluespace jump"
|
||||
option_target = EVAC_OPT_BLUESPACE_JUMP
|
||||
needs_syscontrol = TRUE
|
||||
silicon_allowed = TRUE
|
||||
|
||||
/datum/evacuation_option/bluespace_jump/execute(mob/user)
|
||||
if (!evacuation_controller)
|
||||
return
|
||||
if (evacuation_controller.deny)
|
||||
to_chat(user, "Unable to initiate jump preparation.")
|
||||
return
|
||||
if (evacuation_controller.is_on_cooldown())
|
||||
to_chat(user, evacuation_controller.get_cooldown_message())
|
||||
return
|
||||
if (evacuation_controller.is_evacuating())
|
||||
to_chat(user, "Jump preparation already in progress.")
|
||||
return
|
||||
if (evacuation_controller.call_evacuation(user, 0))
|
||||
log_and_message_admins("[user? key_name(user) : "Autotransfer"] has initiated bluespace jump preparation.")
|
||||
|
||||
/datum/evacuation_option/cancel_abandon_ship
|
||||
option_text = "Cancel abandonment"
|
||||
option_desc = "cancel abandonment of the spacecraft"
|
||||
option_target = EVAC_OPT_CANCEL_ABANDON_SHIP
|
||||
needs_syscontrol = TRUE
|
||||
silicon_allowed = FALSE
|
||||
|
||||
/datum/evacuation_option/cancel_abandon_ship/execute(mob/user)
|
||||
if (evacuation_controller && evacuation_controller.cancel_evacuation())
|
||||
log_and_message_admins("[key_name(user)] has cancelled abandonment of the spacecraft.")
|
||||
|
||||
/datum/evacuation_option/cancel_bluespace_jump
|
||||
option_text = "Cancel bluespace jump"
|
||||
option_desc = "cancel the jump preparation"
|
||||
option_target = EVAC_OPT_CANCEL_BLUESPACE_JUMP
|
||||
needs_syscontrol = TRUE
|
||||
silicon_allowed = FALSE
|
||||
|
||||
/datum/evacuation_option/cancel_bluespace_jump/execute(mob/user)
|
||||
if (evacuation_controller && evacuation_controller.cancel_evacuation())
|
||||
log_and_message_admins("[key_name(user)] has cancelled the bluespace jump.")
|
||||
|
||||
/obj/screen/fullscreen/bluespace_overlay
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "mfoam"
|
||||
screen_loc = "WEST,SOUTH to EAST,NORTH"
|
||||
color = "#ff9900"
|
||||
blend_mode = BLEND_SUBTRACT
|
||||
layer = SCREEN_LAYER
|
||||
|
||||
#undef EVAC_OPT_ABANDON_SHIP
|
||||
#undef EVAC_OPT_BLUESPACE_JUMP
|
||||
#undef EVAC_OPT_CANCEL_ABANDON_SHIP
|
||||
#undef EVAC_OPT_CANCEL_BLUESPACE_JUMP
|
||||
@@ -0,0 +1,13 @@
|
||||
/datum/evacuation_predicate/New()
|
||||
return
|
||||
|
||||
/datum/evacuation_predicate/Destroy(forced)
|
||||
if(forced)
|
||||
return ..()
|
||||
return QDEL_HINT_LETMELIVE
|
||||
|
||||
/datum/evacuation_predicate/proc/is_valid()
|
||||
return FALSE
|
||||
|
||||
/datum/evacuation_predicate/proc/can_call(var/user)
|
||||
return TRUE
|
||||
@@ -0,0 +1,149 @@
|
||||
#define EVAC_OPT_CALL_SHUTTLE "call_shuttle"
|
||||
#define EVAC_OPT_RECALL_SHUTTLE "recall_shuttle"
|
||||
|
||||
/datum/evacuation_controller/shuttle
|
||||
name = "escape shuttle controller"
|
||||
evac_waiting = new(0, new_sound = sound('sound/AI/shuttledock.ogg'))
|
||||
evac_called = new(0, new_sound = sound('sound/AI/shuttlecalled.ogg'))
|
||||
evac_recalled = new(0, new_sound = sound('sound/AI/shuttlerecalled.ogg'))
|
||||
|
||||
emergency_prep_additional_delay = 0 MINUTES
|
||||
transfer_prep_additional_delay = 0 MINUTES
|
||||
|
||||
evacuation_options = list(
|
||||
EVAC_OPT_CALL_SHUTTLE = new /datum/evacuation_option/call_shuttle(),
|
||||
EVAC_OPT_RECALL_SHUTTLE = new /datum/evacuation_option/recall_shuttle()
|
||||
)
|
||||
|
||||
var/departed = 0
|
||||
var/autopilot = 1
|
||||
var/datum/shuttle/autodock/ferry/emergency/shuttle // Set in shuttle_emergency.dm
|
||||
var/shuttle_launch_time
|
||||
|
||||
/datum/evacuation_controller/shuttle/has_evacuated()
|
||||
return departed
|
||||
|
||||
/datum/evacuation_controller/shuttle/waiting_to_leave()
|
||||
return (!autopilot || (shuttle && shuttle.is_launching()))
|
||||
|
||||
/datum/evacuation_controller/shuttle/launch_evacuation()
|
||||
|
||||
if(waiting_to_leave())
|
||||
return
|
||||
|
||||
for (var/datum/shuttle/autodock/ferry/escape_pod/pod in escape_pods)
|
||||
if (!pod.arming_controller || pod.arming_controller.armed)
|
||||
pod.move_time = evac_transit_delay
|
||||
pod.launch(src)
|
||||
|
||||
if(autopilot && shuttle.moving_status == SHUTTLE_IDLE)
|
||||
evac_arrival_time = world.time + (shuttle.move_time*10) + (shuttle.warmup_time*10)
|
||||
shuttle.launch(src)
|
||||
// Announcements, state changes and such are handled by the shuttle itself to prevent desync.
|
||||
|
||||
/datum/evacuation_controller/shuttle/finish_preparing_evac()
|
||||
departed = 1
|
||||
evac_launch_time = world.time + evac_launch_delay
|
||||
|
||||
set_force_countdown(SHUTTLE_FORCETIME)
|
||||
|
||||
. = ..()
|
||||
// Arm the escape pods.
|
||||
if (emergency_evacuation)
|
||||
for (var/datum/shuttle/autodock/ferry/escape_pod/pod in escape_pods)
|
||||
if (pod.arming_controller)
|
||||
pod.arming_controller.arm()
|
||||
|
||||
/datum/evacuation_controller/shuttle/call_evacuation(var/mob/user, var/_emergency_evac, var/forced, var/skip_announce, var/autotransfer)
|
||||
if(..())
|
||||
autopilot = 1
|
||||
shuttle_launch_time = evac_no_return
|
||||
evac_ready_time += shuttle.warmup_time*10
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/evacuation_controller/shuttle/cancel_evacuation()
|
||||
if(..() && shuttle.moving_status != SHUTTLE_INTRANSIT)
|
||||
shuttle_launch_time = null
|
||||
shuttle.cancel_launch(src)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/evacuation_controller/shuttle/get_eta()
|
||||
if (shuttle && shuttle.has_arrive_time())
|
||||
return (shuttle.arrive_time-world.time)/10
|
||||
return ..()
|
||||
|
||||
/datum/evacuation_controller/shuttle/get_status_panel_eta()
|
||||
if(has_eta() && waiting_to_leave())
|
||||
return "Launching..."
|
||||
return ..()
|
||||
|
||||
// This is largely handled by the emergency shuttle datum.
|
||||
/datum/evacuation_controller/shuttle/process()
|
||||
if(state == EVAC_PREPPING)
|
||||
if(!isnull(shuttle_launch_time) && world.time > shuttle_launch_time && shuttle.moving_status == SHUTTLE_IDLE)
|
||||
shuttle.launch()
|
||||
shuttle_launch_time = null
|
||||
return
|
||||
else if(state == EVAC_IN_TRANSIT)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/datum/evacuation_controller/shuttle/can_cancel()
|
||||
return (shuttle.moving_status == SHUTTLE_IDLE && shuttle.location && ..())
|
||||
|
||||
/datum/evacuation_controller/shuttle/proc/shuttle_leaving()
|
||||
state = EVAC_IN_TRANSIT
|
||||
|
||||
/datum/evacuation_controller/shuttle/proc/shuttle_evacuated()
|
||||
state = EVAC_COMPLETE
|
||||
|
||||
/datum/evacuation_controller/shuttle/proc/shuttle_preparing()
|
||||
state = EVAC_PREPPING
|
||||
|
||||
/datum/evacuation_controller/shuttle/proc/get_long_jump_time()
|
||||
if (shuttle.location)
|
||||
return round(evac_prep_delay/10)/2
|
||||
else
|
||||
return round(evac_transit_delay/10)
|
||||
|
||||
//begins the launch countdown and sets the amount of time left until launch
|
||||
/datum/evacuation_controller/proc/set_force_countdown(var/seconds)
|
||||
if(!wait_for_force)
|
||||
wait_for_force = TRUE
|
||||
force_time = world.time + seconds*10
|
||||
|
||||
/datum/evacuation_controller/proc/stop_force_countdown()
|
||||
wait_for_force = TRUE
|
||||
|
||||
/datum/evacuation_controller/shuttle/available_evac_options()
|
||||
if (!shuttle.location)
|
||||
return list()
|
||||
if (is_idle())
|
||||
return list(evacuation_options[EVAC_OPT_CALL_SHUTTLE])
|
||||
else
|
||||
return list(evacuation_options[EVAC_OPT_RECALL_SHUTTLE])
|
||||
|
||||
/datum/evacuation_option/call_shuttle
|
||||
option_text = "Call emergency shuttle"
|
||||
option_desc = "call the emergency shuttle"
|
||||
option_target = EVAC_OPT_CALL_SHUTTLE
|
||||
needs_syscontrol = TRUE
|
||||
silicon_allowed = TRUE
|
||||
|
||||
/datum/evacuation_option/call_shuttle/execute(mob/user)
|
||||
call_shuttle_proc(user)
|
||||
|
||||
/datum/evacuation_option/recall_shuttle
|
||||
option_text = "Cancel shuttle call"
|
||||
option_desc = "recall the emergency shuttle"
|
||||
option_target = EVAC_OPT_RECALL_SHUTTLE
|
||||
needs_syscontrol = TRUE
|
||||
silicon_allowed = FALSE
|
||||
|
||||
/datum/evacuation_option/recall_shuttle/execute(mob/user)
|
||||
cancel_call_proc(user)
|
||||
|
||||
#undef EVAC_OPT_CALL_SHUTTLE
|
||||
#undef EVAC_OPT_RECALL_SHUTTLE
|
||||
@@ -0,0 +1,5 @@
|
||||
#undef EVAC_IDLE
|
||||
#undef EVAC_PREPPING
|
||||
#undef EVAC_IN_TRANSIT
|
||||
#undef EVAC_COOLDOWN
|
||||
#undef EVAC_COMPLETE
|
||||
@@ -11,7 +11,6 @@ var/datum/controller/subsystem/fail2topic/SSfail2topic
|
||||
|
||||
var/rate_limit
|
||||
var/max_fails
|
||||
var/rule_name
|
||||
var/enabled = FALSE
|
||||
|
||||
/datum/controller/subsystem/fail2topic/New()
|
||||
@@ -20,7 +19,6 @@ var/datum/controller/subsystem/fail2topic/SSfail2topic
|
||||
/datum/controller/subsystem/fail2topic/Initialize(timeofday)
|
||||
rate_limit = config.fail2topic_rate_limit
|
||||
max_fails = config.fail2topic_max_fails
|
||||
rule_name = config.fail2topic_rule_name
|
||||
enabled = config.fail2topic_enabled
|
||||
|
||||
DropFirewallRule() // Clear the old bans if any still remain
|
||||
@@ -84,12 +82,17 @@ var/datum/controller/subsystem/fail2topic/SSfail2topic
|
||||
/datum/controller/subsystem/fail2topic/proc/BanFromFirewall(ip)
|
||||
if (!enabled)
|
||||
return
|
||||
var/static/regex/R = regex(@"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$") // Anything that interacts with a shell should be parsed. Prevents subnet banning and possible injection vulnerabilities
|
||||
ip = findtext(ip, R)
|
||||
if(length(ip) > 15 || length(ip) < 8)
|
||||
WARNING("BanFromFirewall was called with an invalid or unsafe IP")
|
||||
return FALSE
|
||||
|
||||
active_bans[ip] = world.time
|
||||
fail_counts -= ip
|
||||
rate_limiting -= ip
|
||||
|
||||
. = shell("netsh advfirewall firewall add rule name=\"[rule_name]\" dir=in interface=any action=block remoteip=[ip]")
|
||||
. = shell("netsh advfirewall firewall add rule name=\"[config.fail2topic_rule_name]\" dir=in interface=any action=block remoteip=[ip]")
|
||||
|
||||
if (.)
|
||||
log_ss("fail2topic", "Failed to ban [ip]. Exit code: [.].", log_world = FALSE, severity = SEVERITY_ERROR)
|
||||
@@ -104,7 +107,7 @@ var/datum/controller/subsystem/fail2topic/SSfail2topic
|
||||
|
||||
active_bans = list()
|
||||
|
||||
. = shell("netsh advfirewall firewall delete rule name=\"[rule_name]\"")
|
||||
. = shell("netsh advfirewall firewall delete rule name=\"[config.fail2topic_rule_name]\"")
|
||||
|
||||
if (.)
|
||||
log_ss("fail2topic", "Failed to drop firewall rule. Exit code: [.].", log_world = FALSE, severity = SEVERITY_ERROR)
|
||||
|
||||
@@ -351,7 +351,7 @@
|
||||
SearchVar(SScargo)
|
||||
SearchVar(SSeconomy)
|
||||
SearchVar(SSeffects)
|
||||
SearchVar(emergency_shuttle)
|
||||
SearchVar(evacuation_controller)
|
||||
SearchVar(SSevents)
|
||||
SearchVar(SSexplosives)
|
||||
SearchVar(SSgarbage)
|
||||
|
||||
@@ -168,10 +168,10 @@ var/datum/controller/subsystem/ticker/SSticker
|
||||
game_finished = TRUE
|
||||
mode_finished = TRUE
|
||||
else if(config.continous_rounds)
|
||||
game_finished = (emergency_shuttle.returned() || mode.station_was_nuked)
|
||||
game_finished = (evacuation_controller.round_over() || mode.station_was_nuked)
|
||||
mode_finished = (!post_game && mode.check_finished())
|
||||
else
|
||||
game_finished = (mode.check_finished() || (emergency_shuttle.returned() && emergency_shuttle.evac == 1)) || universe_has_ended
|
||||
game_finished = (mode.check_finished() || (evacuation_controller.round_over() && evacuation_controller.emergency_evacuation)) || universe_has_ended
|
||||
mode_finished = game_finished
|
||||
|
||||
if(!mode.explosion_in_progress && game_finished && (mode_finished || post_game))
|
||||
@@ -243,7 +243,7 @@ var/datum/controller/subsystem/ticker/SSticker
|
||||
if(Player.mind && !isnewplayer(Player))
|
||||
if(Player.stat != DEAD)
|
||||
var/turf/playerTurf = get_turf(Player)
|
||||
if(emergency_shuttle.departed && emergency_shuttle.evac)
|
||||
if(evacuation_controller.round_over() && evacuation_controller.emergency_evacuation)
|
||||
if(isNotAdminLevel(playerTurf.z))
|
||||
to_chat(Player, "<span class='notice'><b>You managed to survive, but were marooned on [station_name()] as [Player.real_name]...</b></span>")
|
||||
else
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
add_inherent_law("Preserve, repair and improve the station to the best of your abilities.")
|
||||
add_inherent_law("Cause no harm to the station or crew.")
|
||||
add_inherent_law("Follow the orders of your vessel's matriarch drone, unless their orders conflict with your other laws.")
|
||||
add_inherent_law("Interact with no humanoid or synthetic being that is not a fellow maintenance drone.")
|
||||
add_inherent_law("Interact with no humanoid or synthetic being that is not a fellow maintenance or mining drone.")
|
||||
..()
|
||||
|
||||
/datum/ai_laws/matriarch_drone
|
||||
@@ -109,7 +109,7 @@
|
||||
add_inherent_law("Preserve, repair and improve your assigned vessel to the best of your abilities.")
|
||||
add_inherent_law("Cause no harm to the vessel or crew.")
|
||||
add_inherent_law("Delegate vessel maintenance efforts between your maintenance drone sub-units.")
|
||||
add_inherent_law("Interact with no humanoid or synthetic being that is not a maintenance drone.")
|
||||
add_inherent_law("Interact with no humanoid or synthetic being that is not a maintenance or mining drone.")
|
||||
..()
|
||||
|
||||
/datum/ai_laws/drone/malfunction
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#define COMSIG_BASENAME_RENAME "base_name_rename"
|
||||
#define COMSIG_BASENAME_SETNAME "base_name_setname"
|
||||
|
||||
/datum/component/base_name
|
||||
var/base_name
|
||||
|
||||
/datum/component/base_name/Initialize(var/name)
|
||||
base_name = name
|
||||
RegisterSignal(parent, COMSIG_BASENAME_RENAME, .proc/rename)
|
||||
RegisterSignal(parent, COMSIG_BASENAME_SETNAME, .proc/change_base_name)
|
||||
|
||||
/datum/component/base_name/proc/rename(var/name)
|
||||
base_name = name
|
||||
|
||||
/datum/component/base_name/proc/change_base_name(var/name, list/arguments)
|
||||
arguments[1] = base_name
|
||||
@@ -109,7 +109,7 @@ var/list/global_webhooks = list()
|
||||
emb["description"] += data["antags"]
|
||||
if(data["survivours"] > 0)
|
||||
emb["description"] += "There [data["survivours"]>1 ? "were **[data["survivours"]] survivors**" : "was **one survivor**"]"
|
||||
emb["description"] += " ([data["escaped"]>0 ? data["escaped"] : "none"] [emergency_shuttle.evac ? "escaped" : "transferred"]) and **[data["ghosts"]] ghosts**."
|
||||
emb["description"] += " ([data["escaped"]>0 ? data["escaped"] : "none"] [evacuation_controller.emergency_evacuation ? "escaped" : "transferred"]) and **[data["ghosts"]] ghosts**."
|
||||
else
|
||||
emb["description"] += "There were **no survivors** ([data["ghosts"]] ghosts)."
|
||||
OutData["embeds"] = list(emb)
|
||||
|
||||
@@ -61,11 +61,11 @@
|
||||
data["character_name"] = user.client.prefs.real_name
|
||||
|
||||
var/shuttle_status = ""
|
||||
if(emergency_shuttle) //In case Nanotrasen decides to reposess CentComm's shuttles.
|
||||
if(emergency_shuttle.going_to_centcom()) //Shuttle is going to centcomm, not recalled
|
||||
if(evacuation_controller) //In case Nanotrasen decides to reposess CentComm's shuttles.
|
||||
if(evacuation_controller.has_evacuated()) //Shuttle is going to centcomm, not recalled
|
||||
shuttle_status = "post-evac"
|
||||
if(emergency_shuttle.online())
|
||||
if (emergency_shuttle.evac) // Emergency shuttle is past the point of no recall
|
||||
if(evacuation_controller.is_evacuating())
|
||||
if (evacuation_controller.emergency_evacuation) // Emergency shuttle is past the point of no recall
|
||||
shuttle_status = "evac"
|
||||
else // Crew transfer initiated
|
||||
shuttle_status = "transfer"
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// Observer Pattern Implementation: Direction Set
|
||||
// Registration type: /atom
|
||||
//
|
||||
// Raised when: An /atom changes dir using the set_dir() proc.
|
||||
//
|
||||
// Arguments that the called proc should expect:
|
||||
// /atom/dir_changer: The instance that changed direction
|
||||
// /old_dir: The dir before the change.
|
||||
// /new_dir: The dir after the change.
|
||||
|
||||
var/datum/observ/dir_set/dir_set_event = new()
|
||||
|
||||
/datum/observ/dir_set
|
||||
name = "Direction Set"
|
||||
expected_type = /atom
|
||||
|
||||
/datum/observ/dir_set/register(var/atom/dir_changer, var/datum/listener, var/proc_call)
|
||||
. = ..()
|
||||
|
||||
// Listen to the parent if possible.
|
||||
if(. && istype(dir_changer.loc, /atom/movable)) // We don't care about registering to turfs.
|
||||
register(dir_changer.loc, dir_changer, /atom/proc/recursive_dir_set)
|
||||
|
||||
/*********************
|
||||
* Direction Handling *
|
||||
*********************/
|
||||
|
||||
/atom/set_dir()
|
||||
var/old_dir = dir
|
||||
UNLINT(. = ..())
|
||||
if(old_dir != dir)
|
||||
dir_set_event.raise_event(src, old_dir, dir)
|
||||
|
||||
/atom/movable/Entered(var/atom/movable/am, atom/old_loc)
|
||||
. = ..()
|
||||
if(dir_set_event.has_listeners(am))
|
||||
dir_set_event.register(src, am, /atom/proc/recursive_dir_set)
|
||||
|
||||
/atom/movable/Exited(var/atom/movable/am, atom/new_loc)
|
||||
. = ..()
|
||||
dir_set_event.unregister(src, am, /atom/proc/recursive_dir_set)
|
||||
@@ -11,4 +11,11 @@
|
||||
|
||||
/atom/movable/proc/move_to_loc_or_null(var/atom/movable/am, var/old_loc, var/new_loc)
|
||||
if(new_loc != loc)
|
||||
forceMove(new_loc)
|
||||
forceMove(new_loc)
|
||||
|
||||
/atom/proc/recursive_dir_set(var/atom/a, var/old_dir, var/new_dir)
|
||||
set_dir(new_dir)
|
||||
|
||||
// Sometimes you just want to end yourself
|
||||
/datum/proc/qdel_self()
|
||||
qdel(src)
|
||||
@@ -232,6 +232,9 @@
|
||||
|
||||
if(anchored)
|
||||
return
|
||||
|
||||
if(!universe.OnTouchMapEdge(src))
|
||||
return
|
||||
|
||||
if(current_map.use_overmap)
|
||||
overmap_spacetravel(get_turf(src), src)
|
||||
|
||||
@@ -56,9 +56,9 @@ var/global/list/narsie_list = list()
|
||||
narsie_cometh = 1
|
||||
|
||||
spawn(10 SECONDS)
|
||||
if(emergency_shuttle)
|
||||
emergency_shuttle.call_evac()
|
||||
emergency_shuttle.launch_time = 0 // Cannot recall
|
||||
if(evacuation_controller)
|
||||
evacuation_controller.call_evacuation(null, TRUE, 1)
|
||||
evacuation_controller.evac_no_return = 0 // Cannot recall
|
||||
|
||||
/obj/singularity/narsie/process()
|
||||
eat()
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
/datum/universal_state/bluespace_jump
|
||||
name = "Bluespace Jump"
|
||||
var/list/bluespaced = list()
|
||||
var/list/bluegoasts = list()
|
||||
var/list/affected_levels
|
||||
var/list/old_accessible_z_levels
|
||||
|
||||
/datum/universal_state/bluespace_jump/New(var/list/zlevels)
|
||||
affected_levels = zlevels
|
||||
|
||||
/datum/universal_state/bluespace_jump/OnEnter()
|
||||
var/space_zlevel = current_map.get_empty_zlevel() //get a place for stragglers
|
||||
for(var/mob/living/M in mob_list)
|
||||
if(M.z in affected_levels)
|
||||
var/area/A = get_area(M)
|
||||
if(istype(A,/area/space)) //straggler
|
||||
var/turf/T = locate(M.x, M.y, space_zlevel)
|
||||
if(T)
|
||||
M.forceMove(T)
|
||||
else
|
||||
apply_bluespaced(M)
|
||||
|
||||
for(var/mob/abstract/observer/goast in player_list)
|
||||
goast.mouse_opacity = 0 //can't let you click that Dave
|
||||
goast.invisibility = SEE_INVISIBLE_LIVING
|
||||
goast.alpha = 255
|
||||
old_accessible_z_levels = current_map.accessible_z_levels.Copy()
|
||||
for(var/z in affected_levels)
|
||||
current_map.accessible_z_levels -= "[z]" //not accessible during the jump
|
||||
|
||||
/datum/universal_state/bluespace_jump/OnExit()
|
||||
for(var/mob/M in bluespaced)
|
||||
if(!QDELETED(M))
|
||||
clear_bluespaced(M)
|
||||
|
||||
bluespaced.Cut()
|
||||
current_map.accessible_z_levels = old_accessible_z_levels
|
||||
old_accessible_z_levels = null
|
||||
|
||||
/datum/universal_state/bluespace_jump/OnPlayerLatejoin(var/mob/living/M)
|
||||
if(M.z in affected_levels)
|
||||
apply_bluespaced(M)
|
||||
|
||||
/datum/universal_state/bluespace_jump/OnTouchMapEdge(var/atom/A)
|
||||
if((A.z in affected_levels) && (A in bluespaced))
|
||||
if(ismob(A))
|
||||
to_chat(A,"<span class='warning'>You drift away into the shifting expanse, never to be seen again.</span>")
|
||||
qdel(A) //lost in bluespace
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/universal_state/bluespace_jump/proc/apply_bluespaced(var/mob/living/M)
|
||||
bluespaced += M
|
||||
if(M.client)
|
||||
to_chat(M,"<span class='notice'>You feel oddly light, and somewhat disoriented as everything around you shimmers and warps ever so slightly.</span>")
|
||||
M.overlay_fullscreen("bluespace", /obj/screen/fullscreen/bluespace_overlay)
|
||||
M.confused = 20
|
||||
bluegoasts += new/obj/effect/bluegoast/(get_turf(M),M)
|
||||
|
||||
/datum/universal_state/bluespace_jump/proc/clear_bluespaced(var/mob/living/M)
|
||||
if(M.client)
|
||||
to_chat(M,"<span class='notice'>You feel rooted in material world again.</span>")
|
||||
M.clear_fullscreen("bluespace")
|
||||
M.confused = 0
|
||||
for(var/mob/abstract/observer/goast in player_list)
|
||||
goast.mouse_opacity = initial(goast.mouse_opacity)
|
||||
goast.invisibility = goast.invisibility
|
||||
goast.alpha = initial(goast.alpha)
|
||||
for(var/G in bluegoasts)
|
||||
qdel(G)
|
||||
bluegoasts.Cut()
|
||||
|
||||
/obj/effect/bluegoast
|
||||
name = "bluespace echo"
|
||||
desc = "It's not going to punch you, is it?"
|
||||
var/mob/living/carbon/human/daddy
|
||||
anchored = TRUE
|
||||
var/reality = 0
|
||||
simulated = FALSE
|
||||
|
||||
/obj/effect/bluegoast/New(nloc, ndaddy)
|
||||
..(nloc)
|
||||
if(!ndaddy)
|
||||
qdel(src)
|
||||
return
|
||||
daddy = ndaddy
|
||||
set_dir(daddy.dir)
|
||||
appearance = daddy.appearance
|
||||
moved_event.register(daddy, src, /obj/effect/bluegoast/proc/mirror)
|
||||
dir_set_event.register(daddy, src, /obj/effect/bluegoast/proc/mirror_dir)
|
||||
destroyed_event.register(daddy, src, /datum/proc/qdel_self)
|
||||
|
||||
/obj/effect/bluegoast/Destroy()
|
||||
destroyed_event.unregister(daddy, src)
|
||||
dir_set_event.unregister(daddy, src)
|
||||
moved_event.unregister(daddy, src)
|
||||
daddy = null
|
||||
. = ..()
|
||||
|
||||
/obj/effect/bluegoast/proc/mirror(var/atom/movable/am, var/old_loc, var/new_loc)
|
||||
var/ndir = get_dir(new_loc,old_loc)
|
||||
appearance = daddy.appearance
|
||||
var/nloc = get_step(src, ndir)
|
||||
if(nloc)
|
||||
forceMove(nloc)
|
||||
if(nloc == new_loc)
|
||||
reality++
|
||||
if(reality > 5)
|
||||
to_chat(daddy, "<span class='notice'>Yep, it's certainly the other one. Your existance was a glitch, and it's finally being mended...</span>")
|
||||
blueswitch()
|
||||
else if(reality > 3)
|
||||
to_chat(daddy, "<span class='danger'>Something is definitely wrong. Why do you think YOU are the original?</span>")
|
||||
else
|
||||
to_chat(daddy, "<span class='warning'>You feel a bit less real. Which one of you two was original again?..</span>")
|
||||
|
||||
/obj/effect/bluegoast/proc/mirror_dir(var/atom/movable/am, var/old_dir, var/new_dir)
|
||||
set_dir(reverse_dir[new_dir])
|
||||
|
||||
/obj/effect/bluegoast/examine()
|
||||
return daddy?.examine(arglist(args))
|
||||
|
||||
/obj/effect/bluegoast/proc/blueswitch()
|
||||
var/mob/living/carbon/human/H
|
||||
if(ishuman(daddy))
|
||||
H = new(get_turf(src), daddy.species.name)
|
||||
H.dna = daddy.dna.Clone()
|
||||
H.sync_organ_dna()
|
||||
H.UpdateAppearance()
|
||||
for(var/obj/item/entry in daddy.get_equipped_items(TRUE))
|
||||
daddy.remove_from_mob(entry) //steals instead of copies so we don't end up with duplicates
|
||||
H.equip_to_appropriate_slot(entry)
|
||||
else
|
||||
H = new daddy.type(get_turf(src))
|
||||
H.appearance = daddy.appearance
|
||||
|
||||
H.real_name = daddy.real_name
|
||||
H.flavor_text = daddy.flavor_text
|
||||
daddy.dust()
|
||||
qdel(src)
|
||||
|
||||
/obj/screen/fullscreen/bluespace_overlay
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "mfoam"
|
||||
screen_loc = "WEST,SOUTH to EAST,NORTH"
|
||||
color = "#ff9900"
|
||||
alpha = 100
|
||||
blend_mode = BLEND_SUBTRACT
|
||||
layer = SCREEN_LAYER
|
||||
@@ -63,10 +63,19 @@
|
||||
/datum/universal_state/proc/OverlayAndAmbientSet()
|
||||
return
|
||||
|
||||
/proc/SetUniversalState(var/newstate,var/on_exit=1, var/on_enter=1)
|
||||
/datum/universal_state/proc/OnPlayerLatejoin(var/mob/living/M)
|
||||
return
|
||||
|
||||
/datum/universal_state/proc/OnTouchMapEdge(var/atom/A)
|
||||
return TRUE //return FALSE to cancel map edge handling
|
||||
|
||||
/proc/SetUniversalState(var/newstate,var/on_exit=1, var/on_enter=1, list/arguments=null)
|
||||
if(on_exit)
|
||||
universe.OnExit()
|
||||
universe = new newstate
|
||||
if(arguments)
|
||||
universe = new newstate(arglist(arguments))
|
||||
else
|
||||
universe = new newstate
|
||||
if(on_enter)
|
||||
universe.OnEnter()
|
||||
|
||||
|
||||
@@ -45,9 +45,8 @@ var/global/universe_has_ended = 0
|
||||
for(var/mob/M in player_list)
|
||||
M.flash_eyes()
|
||||
|
||||
if(emergency_shuttle.can_recall())
|
||||
priority_announcement.Announce("The emergency shuttle has returned due to bluespace distortion.")
|
||||
emergency_shuttle.recall()
|
||||
if(evacuation_controller.cancel_evacuation())
|
||||
priority_announcement.Announce("The evacuation has been aborted due to bluespace distortion.")
|
||||
|
||||
AreaSet()
|
||||
MiscSet()
|
||||
|
||||
@@ -284,8 +284,8 @@ var/global/list/additional_antag_types = list()
|
||||
if(!(antag.flags & ANTAG_NO_ROUNDSTART_SPAWN))
|
||||
antag.finalize_spawn() //actually spawn antags
|
||||
|
||||
if(emergency_shuttle && auto_recall_shuttle)
|
||||
emergency_shuttle.auto_recall = 1
|
||||
if(evacuation_controller && auto_recall_shuttle)
|
||||
evacuation_controller.auto_recall(1)
|
||||
|
||||
feedback_set_details("round_start","[time2text(world.realtime)]")
|
||||
if(SSticker.mode)
|
||||
@@ -335,14 +335,14 @@ var/global/list/additional_antag_types = list()
|
||||
command_announcement.Announce("The presence of [pick(reasons)] in the region is tying up all available local emergency resources; emergency response teams cannot be called at this time, and post-evacuation recovery efforts will be substantially delayed.","Emergency Transmission")
|
||||
|
||||
/datum/game_mode/proc/check_finished()
|
||||
if(emergency_shuttle.returned() || station_was_nuked)
|
||||
if(evacuation_controller.round_over() || station_was_nuked)
|
||||
return 1
|
||||
if(end_on_antag_death && antag_templates && antag_templates.len)
|
||||
for(var/datum/antagonist/antag in antag_templates)
|
||||
if(!antag.antags_are_dead())
|
||||
return 0
|
||||
if(config.continous_rounds)
|
||||
emergency_shuttle.auto_recall = 0
|
||||
evacuation_controller.auto_recall(1)
|
||||
return 0
|
||||
return 1
|
||||
return 0
|
||||
@@ -421,10 +421,10 @@ var/global/list/additional_antag_types = list()
|
||||
var/text = ""
|
||||
if(surviving_total > 0)
|
||||
text += "<br>There [surviving_total>1 ? "were <b>[surviving_total] survivors</b>" : "was <b>one survivor</b>"]"
|
||||
text += " (<b>[escaped_total>0 ? escaped_total : "none"] [emergency_shuttle.evac ? "escaped" : "transferred"]</b>) and <b>[ghosts] ghosts</b>.<br>"
|
||||
text += " (<b>[escaped_total>0 ? escaped_total : "none"] [evacuation_controller.emergency_evacuation ? "escaped" : "transferred"]</b>) and <b>[ghosts] ghosts</b>.<br>"
|
||||
|
||||
discord_text += "There [surviving_total>1 ? "were **[surviving_total] survivors**" : "was **one survivor**"]"
|
||||
discord_text += " ([escaped_total>0 ? escaped_total : "none"] [emergency_shuttle.evac ? "escaped" : "transferred"]) and **[ghosts] ghosts**."
|
||||
discord_text += " ([escaped_total>0 ? escaped_total : "none"] [evacuation_controller.emergency_evacuation ? "escaped" : "transferred"]) and **[ghosts] ghosts**."
|
||||
else
|
||||
text += "There were <b>no survivors</b> (<b>[ghosts] ghosts</b>)."
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
///process()
|
||||
///Called by the gameticker
|
||||
/datum/game_mode/process()
|
||||
if(round_autoantag && world.time >= next_spawn && !emergency_shuttle.departed)
|
||||
if(round_autoantag && world.time >= next_spawn && !evacuation_controller.round_over())
|
||||
process_autoantag()
|
||||
|
||||
// Process loop for objectives like the brig one.
|
||||
@@ -21,7 +21,7 @@
|
||||
/datum/game_mode/proc/process_autoantag()
|
||||
message_admins("[uppertext(name)]: Attempting autospawn.")
|
||||
|
||||
if(emergency_shuttle.online())
|
||||
if(evacuation_controller.is_evacuating())
|
||||
message_admins("[uppertext(name)]: An evac or transfer shuttle is on the way. Aborted.")
|
||||
next_spawn = world.time + min_autotraitor_delay
|
||||
return
|
||||
|
||||
@@ -267,7 +267,7 @@ datum
|
||||
explanation_text = "Frame [target.current.real_name], the [target.assigned_role] for a crime and make sure they are arrested and brought back to the Centcom station alive. We'll handle the rest from there."
|
||||
|
||||
check_completion()
|
||||
if(!emergency_shuttle.returned())
|
||||
if(!evacuation_controller.round_over())
|
||||
return 0
|
||||
if(target.current.stat == 2)
|
||||
return 0
|
||||
@@ -313,7 +313,7 @@ datum
|
||||
explanation_text = "[target.current.real_name], the [target.assigned_role] is a [pick("relative of a","friend of a","") + pick("high ranking","important","well-liked")] mercenary [pick("Leader","Officer","Agent","sympathiser")]. Make sure they get off the station safely, while minimizing intervention."
|
||||
|
||||
check_completion()
|
||||
if(!emergency_shuttle.returned())
|
||||
if(!evacuation_controller.round_over())
|
||||
return 0
|
||||
|
||||
if(target.current.stat == 2)
|
||||
@@ -477,7 +477,7 @@ datum
|
||||
explanation_text = "Hijack the emergency shuttle by escaping alone."
|
||||
|
||||
check_completion()
|
||||
if(!emergency_shuttle.returned())
|
||||
if(!evacuation_controller.round_over())
|
||||
return 0
|
||||
|
||||
if(!owner.current || owner.current.stat == 2)
|
||||
@@ -512,7 +512,7 @@ datum
|
||||
explanation_text = "Escape on the shuttle alive, without being arrested."
|
||||
|
||||
check_completion()
|
||||
if(!emergency_shuttle.returned())
|
||||
if(!evacuation_controller.round_over())
|
||||
return 0
|
||||
|
||||
if(!owner.current || owner.current.stat ==2)
|
||||
@@ -1230,7 +1230,7 @@ datum
|
||||
check_completion()
|
||||
if(!istype(owner.current, /mob/living/silicon))
|
||||
return 0
|
||||
if(!emergency_shuttle.returned())
|
||||
if(!evacuation_controller.round_over())
|
||||
return 0
|
||||
if(!owner.current)
|
||||
return 0
|
||||
@@ -1455,7 +1455,7 @@ datum/objective/silence
|
||||
explanation_text = "Do not allow anyone to escape the station. Only allow the shuttle to be called when everyone is dead and your story is the only one left."
|
||||
|
||||
check_completion()
|
||||
if(!emergency_shuttle.returned())
|
||||
if(!evacuation_controller.round_over())
|
||||
return 0
|
||||
|
||||
var/area/shuttle = locate(/area/shuttle/escape/centcom)
|
||||
|
||||
@@ -42,7 +42,7 @@ var/list/nuke_disks = list()
|
||||
if(!is_type_in_list(disk_area, centcom_areas))
|
||||
disk_rescued = 0
|
||||
break
|
||||
var/crew_evacuated = (emergency_shuttle.returned())
|
||||
var/crew_evacuated = (evacuation_controller.round_over())
|
||||
|
||||
if(!disk_rescued && station_was_nuked && !syndies_didnt_escape)
|
||||
feedback_set_details("round_end_result","win - syndicate nuke")
|
||||
|
||||
@@ -230,7 +230,7 @@ datum/objective/hijack
|
||||
check_completion()
|
||||
if(!owner.current || owner.current.stat)
|
||||
return 0
|
||||
if(!emergency_shuttle.returned())
|
||||
if(!evacuation_controller.round_over())
|
||||
return 0
|
||||
if(issilicon(owner.current))
|
||||
return 0
|
||||
@@ -252,7 +252,7 @@ datum/objective/block
|
||||
check_completion()
|
||||
if(!istype(owner.current, /mob/living/silicon))
|
||||
return 0
|
||||
if(!emergency_shuttle.returned())
|
||||
if(!evacuation_controller.round_over())
|
||||
return 0
|
||||
if(!owner.current)
|
||||
return 0
|
||||
@@ -270,7 +270,7 @@ datum/objective/silence
|
||||
explanation_text = "Do not allow anyone to escape the station. Only allow the shuttle to be called when everyone is dead and your story is the only one left."
|
||||
|
||||
check_completion()
|
||||
if(!emergency_shuttle.returned())
|
||||
if(!evacuation_controller.round_over())
|
||||
return 0
|
||||
|
||||
for(var/mob/living/player in player_list)
|
||||
@@ -295,7 +295,7 @@ datum/objective/escape
|
||||
return 0
|
||||
if(isbrain(owner.current))
|
||||
return 0
|
||||
if(!emergency_shuttle.returned())
|
||||
if(!evacuation_controller.round_over())
|
||||
return 0
|
||||
if(!owner.current || owner.current.stat ==2)
|
||||
return 0
|
||||
|
||||
@@ -13,5 +13,5 @@
|
||||
|
||||
/datum/game_mode/sandbox/post_setup()
|
||||
..()
|
||||
if(emergency_shuttle)
|
||||
emergency_shuttle.auto_recall = 1
|
||||
if(evacuation_controller)
|
||||
evacuation_controller.auto_recall(1)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
You expect to be heard and obeyed, as your coworkers really should be taking advice from you in the absence of
|
||||
a chief medical officer. Your bedside manner is impeccable and far outclasses standard NanoTrasen training and
|
||||
procedure. You are the product of the most rigorous employee hiring and training process for medical staff in the
|
||||
Orion Spur, and are expected to act like it. Failure is you will not tolerate.</li>
|
||||
Orion Spur, and are expected to act like it. Failure is something you will not tolerate.</li>
|
||||
<li><b>Biomechanical Engineer</b>: Our ability to combine medical research with robotics
|
||||
is the best and you know this. We do, after all, own Bishop Cybernetics - the
|
||||
best premium augmentation subsidiary in the known galaxy. Unlike your medical cousins
|
||||
|
||||
@@ -47,12 +47,9 @@
|
||||
var/dat = "<HEAD><TITLE>Operating Computer</TITLE><META HTTP-EQUIV='Refresh' CONTENT='10'></HEAD><BODY>\n"
|
||||
if(src.table && (src.table.check_victim()))
|
||||
src.victim = src.table.victim
|
||||
var/brain_result = victim.get_brain_status()
|
||||
if(victim.isFBP())
|
||||
brain_result = "<span class='danger'>N/A</span>"
|
||||
dat += {"
|
||||
<B>Patient Information:</B><BR>
|
||||
Brain Activity: <b>[brain_result]</b><br>
|
||||
Brain Activity: <b>[victim.isFBP() ? "<span class='danger'>N/A</span>" : victim.get_brain_status()]</b><br>
|
||||
Pulse: <b>[victim.get_pulse(GETPULSE_TOOL)]</b><br>
|
||||
BP: <b>[victim.get_blood_pressure()]</b><br>
|
||||
Blood Oxygenation: <b>[victim.get_blood_oxygenation()]</b><br>
|
||||
@@ -68,6 +65,21 @@ Blood Oxygenation: <b>[victim.get_blood_oxygenation()]</b><br>
|
||||
op_win.set_content(dat)
|
||||
op_win.open()
|
||||
|
||||
/obj/machinery/computer/operating/examine(mob/user)
|
||||
..()
|
||||
if(get_dist(src, user) <= 2)
|
||||
if(src.table && (src.table.check_victim()))
|
||||
src.victim = src.table.victim
|
||||
|
||||
to_chat(user, SPAN_NOTICE("Patient Info:"))
|
||||
to_chat(user, SPAN_NOTICE("Brain Activity: [victim.isFBP() ? "N/A" : victim.get_brain_status()]"))
|
||||
to_chat(user, SPAN_NOTICE("Pulse: [victim.get_pulse(GETPULSE_TOOL)]"))
|
||||
to_chat(user, SPAN_NOTICE("BP: [victim.get_blood_pressure()]"))
|
||||
to_chat(user, SPAN_NOTICE("Blood Oxygenation: [victim.get_blood_oxygenation()]"))
|
||||
else
|
||||
src.victim = null
|
||||
to_chat(user, SPAN_NOTICE("No Patient Detected"))
|
||||
|
||||
/obj/machinery/computer/operating/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
@@ -78,4 +90,4 @@ Blood Oxygenation: <b>[victim.get_blood_oxygenation()]</b><br>
|
||||
|
||||
/obj/machinery/computer/operating/machinery_process()
|
||||
if(operable())
|
||||
src.updateDialog()
|
||||
src.updateDialog()
|
||||
|
||||
@@ -10,8 +10,17 @@
|
||||
|
||||
|
||||
attackby(var/obj/item/card/W as obj, var/mob/user as mob)
|
||||
if(stat & (BROKEN|NOPOWER)) return
|
||||
if ((!( istype(W, /obj/item/card) ) || !(ROUND_IS_STARTED) || emergency_shuttle.location() || !( user ))) return
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
|
||||
var/datum/evacuation_controller/shuttle/evac_control = evacuation_controller
|
||||
if(!istype(evac_control))
|
||||
to_chat(user, SPAN_DANGER("This console should not in use on this map. Please report this to a developer."))
|
||||
return
|
||||
|
||||
if ((!( istype(W, /obj/item/card) ) || !( SSticker ) || evacuation_controller.has_evacuated() || !( user )))
|
||||
return
|
||||
|
||||
if (W.GetID())
|
||||
var/obj/item/card/id/id = W
|
||||
|
||||
@@ -29,7 +38,7 @@
|
||||
return 0
|
||||
|
||||
var/choice = alert(user, text("Would you like to (un)authorize a shortened launch time? [] authorization\s are still needed. Use abort to cancel all authorizations.", src.auth_need - src.authorized.len), "Shuttle Launch", "Authorize", "Repeal", "Abort")
|
||||
if(emergency_shuttle.location() && user.get_active_hand() != id)
|
||||
if(evacuation_controller.is_prepared() && user.get_active_hand() != id)
|
||||
return 0
|
||||
switch(choice)
|
||||
if("Authorize")
|
||||
@@ -43,7 +52,7 @@
|
||||
message_admins("[key_name_admin(user)] has launched the shuttle")
|
||||
log_game("[key_name(user)] has launched the shuttle early",ckey=key_name(user))
|
||||
to_world("<span class='notice'><b>Alert: Shuttle launch time shortened to 10 seconds!</b></span>")
|
||||
emergency_shuttle.set_launch_countdown(10)
|
||||
evacuation_controller.set_launch_time(world.time+100)
|
||||
//src.authorized = null
|
||||
qdel(src.authorized)
|
||||
src.authorized = list( )
|
||||
@@ -60,11 +69,11 @@
|
||||
else if (istype(W, /obj/item/card/emag) && !emagged)
|
||||
var/choice = alert(user, "Would you like to launch the shuttle?","Shuttle control", "Launch", "Cancel")
|
||||
|
||||
if(!emagged && !emergency_shuttle.location() && user.get_active_hand() == W)
|
||||
if(!emagged && !evacuation_controller.is_prepared() && user.get_active_hand() == W)
|
||||
switch(choice)
|
||||
if("Launch")
|
||||
to_world("<span class='notice'><b>Alert: Shuttle launch time shortened to 10 seconds!</b></span>")
|
||||
emergency_shuttle.set_launch_countdown(10)
|
||||
evacuation_controller.set_launch_time(world.time+100)
|
||||
emagged = 1
|
||||
if("Cancel")
|
||||
return
|
||||
|
||||
@@ -11,8 +11,8 @@ datum/track/New(var/title_name, var/audio)
|
||||
/obj/machinery/media/jukebox/
|
||||
name = "space jukebox"
|
||||
icon = 'icons/obj/jukebox.dmi'
|
||||
icon_state = "jukebox2-nopower"
|
||||
var/state_base = "jukebox2"
|
||||
icon_state = "jukebox-nopower"
|
||||
var/state_base = "jukebox"
|
||||
anchored = 0
|
||||
density = 1
|
||||
power_channel = EQUIP
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
/obj/machinery/recharger/examine(mob/user)
|
||||
. = ..(user, 3)
|
||||
to_chat(user, "There is [charging ? "[charging]" : "nothing"] in [src].")
|
||||
to_chat(user, "There is [charging ? "\a [charging]" : "nothing"] in [src].")
|
||||
if (charging && .)
|
||||
var/obj/item/cell/C = charging.get_cell()
|
||||
if (istype(C) && user.client && (!user.progressbars || !user.progressbars[src]))
|
||||
|
||||
@@ -86,22 +86,23 @@
|
||||
if(STATUS_DISPLAY_BLANK) //blank
|
||||
return 1
|
||||
if(STATUS_DISPLAY_TRANSFER_SHUTTLE_TIME) //emergency shuttle timer
|
||||
if(emergency_shuttle.waiting_to_leave())
|
||||
message1 = "-ETD-"
|
||||
if (emergency_shuttle.shuttle.is_launching())
|
||||
message2 = "Launch"
|
||||
else
|
||||
message2 = get_shuttle_timer_departure()
|
||||
if(evacuation_controller)
|
||||
if(evacuation_controller.is_prepared())
|
||||
message1 = "-ETD-"
|
||||
if (evacuation_controller.waiting_to_leave())
|
||||
message2 = "Launch"
|
||||
else
|
||||
message2 = get_shuttle_timer()
|
||||
if(length(message2) > CHARS_PER_LINE)
|
||||
message2 = "Error"
|
||||
update_display(message1, message2)
|
||||
else if(evacuation_controller.has_eta())
|
||||
message1 = "-ETA-"
|
||||
message2 = get_shuttle_timer()
|
||||
if(length(message2) > CHARS_PER_LINE)
|
||||
message2 = "Error"
|
||||
update_display(message1, message2)
|
||||
else if(emergency_shuttle.has_eta())
|
||||
message1 = "-ETA-"
|
||||
message2 = get_shuttle_timer_arrival()
|
||||
if(length(message2) > CHARS_PER_LINE)
|
||||
message2 = "Error"
|
||||
update_display(message1, message2)
|
||||
return 1
|
||||
update_display(message1, message2)
|
||||
return 1
|
||||
if(STATUS_DISPLAY_MESSAGE) //custom messages
|
||||
var/line1
|
||||
var/line2
|
||||
@@ -165,14 +166,8 @@
|
||||
if(maptext != new_text)
|
||||
maptext = new_text
|
||||
|
||||
/obj/machinery/status_display/proc/get_shuttle_timer_arrival()
|
||||
var/timeleft = emergency_shuttle.estimate_arrival_time()
|
||||
if(timeleft < 0)
|
||||
return ""
|
||||
return "[add_zero(num2text((timeleft / 60) % 60),2)]:[add_zero(num2text(timeleft % 60), 2)]"
|
||||
|
||||
/obj/machinery/status_display/proc/get_shuttle_timer_departure()
|
||||
var/timeleft = emergency_shuttle.estimate_launch_time()
|
||||
/obj/machinery/status_display/proc/get_shuttle_timer()
|
||||
var/timeleft = evacuation_controller.get_eta()
|
||||
if(timeleft < 0)
|
||||
return ""
|
||||
return "[add_zero(num2text((timeleft / 60) % 60),2)]:[add_zero(num2text(timeleft % 60), 2)]"
|
||||
|
||||
@@ -721,6 +721,7 @@
|
||||
/obj/item/seeds/cherryseed = 3,
|
||||
/obj/item/seeds/chiliseed = 3,
|
||||
/obj/item/seeds/cocoapodseed = 3,
|
||||
/obj/item/seeds/coffeeseed = 3,
|
||||
/obj/item/seeds/cornseed = 3,
|
||||
/obj/item/seeds/dynseed = 3,
|
||||
/obj/item/seeds/earthenroot = 2,
|
||||
@@ -735,6 +736,7 @@
|
||||
/obj/item/seeds/lemonseed = 3,
|
||||
/obj/item/seeds/limeseed = 3,
|
||||
/obj/item/seeds/mtearseed = 3,
|
||||
/obj/item/seeds/mintseed = 3,
|
||||
/obj/item/seeds/nifberries = 2,
|
||||
/obj/item/seeds/onionseed = 3,
|
||||
/obj/item/seeds/orangeseed = 3,
|
||||
@@ -755,6 +757,7 @@
|
||||
/obj/item/seeds/sugarcaneseed = 3,
|
||||
/obj/item/seeds/sunflowerseed = 3,
|
||||
/obj/item/seeds/sugartree = 2,
|
||||
/obj/item/seeds/teaseed = 3,
|
||||
/obj/item/seeds/tobaccoseed = 3,
|
||||
/obj/item/seeds/tomatoseed = 3,
|
||||
/obj/item/seeds/towermycelium = 3,
|
||||
@@ -787,6 +790,7 @@
|
||||
/obj/item/seeds/cherryseed = 40,
|
||||
/obj/item/seeds/chiliseed = 50,
|
||||
/obj/item/seeds/cocoapodseed = 50,
|
||||
/obj/item/seeds/coffeeseed = 70,
|
||||
/obj/item/seeds/cornseed = 30,
|
||||
/obj/item/seeds/dynseed = 80,
|
||||
/obj/item/seeds/earthenroot = 70,
|
||||
@@ -801,6 +805,7 @@
|
||||
/obj/item/seeds/lemonseed = 40,
|
||||
/obj/item/seeds/limeseed = 50,
|
||||
/obj/item/seeds/mtearseed = 60,
|
||||
/obj/item/seeds/mintseed = 70,
|
||||
/obj/item/seeds/nifberries = 70,
|
||||
/obj/item/seeds/onionseed = 30,
|
||||
/obj/item/seeds/orangeseed = 40,
|
||||
@@ -821,6 +826,7 @@
|
||||
/obj/item/seeds/sugarcaneseed = 20,
|
||||
/obj/item/seeds/sunflowerseed = 20,
|
||||
/obj/item/seeds/sugartree = 40,
|
||||
/obj/item/seeds/teaseed = 30,
|
||||
/obj/item/seeds/tobaccoseed = 40,
|
||||
/obj/item/seeds/tomatoseed = 30,
|
||||
/obj/item/seeds/towermycelium = 20,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "portable suit cooling unit"
|
||||
desc = "A portable heat sink and liquid cooled radiator that can be hooked up to a space suit's existing temperature controls to provide industrial levels of cooling."
|
||||
w_class = ITEMSIZE_LARGE
|
||||
icon = 'icons/obj/suitcooler.dmi'
|
||||
icon = 'icons/obj/contained_items/tools/suitcooler.dmi'
|
||||
icon_state = "suitcooler0"
|
||||
item_state = "coolingpack"
|
||||
contained_sprite = TRUE
|
||||
@@ -24,7 +24,7 @@
|
||||
var/cover_open = 0 //is the cover open?
|
||||
var/obj/item/cell/cell
|
||||
var/max_cooling = 12 //in degrees per second - probably don't need to mess with heat capacity here
|
||||
var/charge_consumption = 16.6 //charge per second at max_cooling
|
||||
var/charge_consumption = 8.3 //charge per second at max_cooling
|
||||
var/thermostat = T20C
|
||||
|
||||
//TODO: make it heat up the surroundings when not in space
|
||||
@@ -134,8 +134,13 @@
|
||||
src.cell = null
|
||||
update_icon()
|
||||
return
|
||||
toggle_power(user)
|
||||
|
||||
//TODO use a UI like the air tanks
|
||||
/obj/item/device/suit_cooling_unit/AltClick(mob/user)
|
||||
if(Adjacent(user))
|
||||
toggle_power(user)
|
||||
|
||||
/obj/item/device/suit_cooling_unit/proc/toggle_power(var/mob/user)
|
||||
if(on)
|
||||
turn_off()
|
||||
else
|
||||
@@ -177,23 +182,31 @@
|
||||
return
|
||||
|
||||
icon_state = "suitcooler0"
|
||||
item_state = "coolingpack"
|
||||
|
||||
if(!cell || !on)
|
||||
return
|
||||
if(cell && on)
|
||||
var/battery_level = 0
|
||||
switch(round(cell.percent()))
|
||||
if(86 to INFINITY)
|
||||
battery_level = 0
|
||||
if(69 to 85)
|
||||
battery_level = 1
|
||||
if(52 to 68)
|
||||
battery_level = 2
|
||||
if(35 to 51)
|
||||
battery_level = 3
|
||||
if(18 to 34)
|
||||
battery_level = 4
|
||||
if(-INFINITY to 17)
|
||||
battery_level = 5
|
||||
|
||||
switch(round(cell.percent()))
|
||||
if(86 to INFINITY)
|
||||
add_overlay("battery-0")
|
||||
if(69 to 85)
|
||||
add_overlay("battery-1")
|
||||
if(52 to 68)
|
||||
add_overlay("battery-2")
|
||||
if(35 to 51)
|
||||
add_overlay("battery-3")
|
||||
if(18 to 34)
|
||||
add_overlay("battery-4")
|
||||
if(-INFINITY to 17)
|
||||
add_overlay("battery-5")
|
||||
add_overlay("battery-[battery_level]")
|
||||
item_state = "coolingpack[battery_level]"
|
||||
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
M.update_inv_back()
|
||||
M.update_inv_s_store()
|
||||
|
||||
/obj/item/device/suit_cooling_unit/examine(mob/user)
|
||||
if(!..(user, 1))
|
||||
|
||||
@@ -211,6 +211,10 @@ RFD Construction-Class
|
||||
build_cost = 1
|
||||
build_type = "floor"
|
||||
build_atom = /turf/simulated/floor/airless
|
||||
else if(istype(T, /turf/simulated/open))
|
||||
build_cost = 1
|
||||
build_type = "floor"
|
||||
build_atom = /turf/simulated/floor/airless
|
||||
else if(istype(T, /turf/simulated/floor))
|
||||
build_delay = 20
|
||||
build_cost = 3
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
can_place = TRUE
|
||||
else
|
||||
for (var/obj/item/grab/G in C.grabbed_by)
|
||||
if (G.loc == user && G.state >= GRAB_AGGRESSIVE)
|
||||
if (G.state >= GRAB_AGGRESSIVE)
|
||||
can_place = TRUE
|
||||
break
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
user.drop_from_inventory(cuffs,target)
|
||||
else
|
||||
cuffs.forceMove(target)
|
||||
|
||||
|
||||
if(!legcuff)
|
||||
target.handcuffed = cuffs
|
||||
target.update_inv_handcuffed()
|
||||
@@ -250,4 +250,4 @@
|
||||
icon_state = "legcuff"
|
||||
legcuff = TRUE
|
||||
breakouttime = 30 SECONDS
|
||||
cuff_type = "legcuffs"
|
||||
cuff_type = "legcuffs"
|
||||
|
||||
@@ -172,12 +172,6 @@
|
||||
desc = "It's an orange backpack which was designed to hold beakers, pill bottles and bottles."
|
||||
icon_state = "chempack"
|
||||
|
||||
/obj/item/storage/backpack/cloak
|
||||
name = "tunnel cloak"
|
||||
desc = "It's a Vaurca cloak with storage pockets."
|
||||
icon_state = "cape"
|
||||
sprite_sheets = list(BODYTYPE_VAURCA = 'icons/mob/species/vaurca/back.dmi')
|
||||
|
||||
/obj/item/storage/backpack/syndie
|
||||
name = "syndicate rucksack"
|
||||
desc = "The latest in carbon fiber and red satin combat rucksack technology. Comfortable and tough!"
|
||||
@@ -625,4 +619,71 @@
|
||||
desc = "A small, fashionable bag typically worn over the shoulder."
|
||||
icon_state = "purse"
|
||||
item_state = "purse"
|
||||
max_storage_space = 16
|
||||
max_storage_space = 16
|
||||
|
||||
//**Vaurca cloaks**//
|
||||
|
||||
/obj/item/storage/backpack/cloak
|
||||
name = "tunnel cloak"
|
||||
desc = "A Vaurca cloak with storage pockets."
|
||||
icon_state = "cape"
|
||||
item_state = "cape"
|
||||
sprite_sheets = list(BODYTYPE_VAURCA = 'icons/mob/species/vaurca/back.dmi')
|
||||
var/hooded = FALSE
|
||||
|
||||
/obj/item/storage/backpack/cloak/verb/toggle_cloak_hood()
|
||||
set name = "Toggle Cloak Hood"
|
||||
set desc = "Toggle your cloak hood."
|
||||
set category = "Object"
|
||||
set src in usr
|
||||
if(use_check_and_message(usr))
|
||||
return 0
|
||||
hooded = !hooded
|
||||
to_chat(usr, "You [hooded ? "raise" : "lower"] \the [src] hood.")
|
||||
icon_state = "[initial(icon_state)][hooded ? "_up" : ""]"
|
||||
item_state = "icon_state"
|
||||
var/mob/living/carbon/human/H = src.loc
|
||||
H.update_icon()
|
||||
H.update_inv_back()
|
||||
|
||||
/obj/item/storage/backpack/cloak/sedantis
|
||||
name = "Sedantis tunnel cloak"
|
||||
desc = "A Vaurca cloak with storage pockets. This one has the Sedantis flag design."
|
||||
icon_state = "sedcape"
|
||||
item_state = "sedcape"
|
||||
|
||||
/obj/item/storage/backpack/cloak/medical
|
||||
name = "medical tunnel cloak"
|
||||
desc = "A Vaurca cloak with storage pockets. This one has the medical department design."
|
||||
icon_state = "medcape"
|
||||
item_state = "medcape"
|
||||
|
||||
/obj/item/storage/backpack/cloak/engi
|
||||
name = "engineering tunnel cloak"
|
||||
desc = "A Vaurca cloak with storage pockets. This one has the engineering department design."
|
||||
icon_state = "engicape"
|
||||
item_state = "engicape"
|
||||
|
||||
/obj/item/storage/backpack/cloak/atmos
|
||||
name = "atmospherics tunnel cloak"
|
||||
desc = "A Vaurca cloak with storage pockets. This one has the atmospherics design."
|
||||
icon_state = "atmoscape"
|
||||
item_state = "atmoscape"
|
||||
|
||||
/obj/item/storage/backpack/cloak/cargo
|
||||
name = "cargo tunnel cloak"
|
||||
desc = "A Vaurca cloak with storage pockets. This one has the supply department design."
|
||||
icon_state = "cargocape"
|
||||
item_state = "cargocape"
|
||||
|
||||
/obj/item/storage/backpack/cloak/sci
|
||||
name = "science tunnel cloak"
|
||||
desc = "A Vaurca cloak with storage pockets. This one has the science department design."
|
||||
icon_state = "scicape"
|
||||
item_state = "scicape"
|
||||
|
||||
/obj/item/storage/backpack/cloak/sec
|
||||
name = "security tunnel cloak"
|
||||
desc = "A Vaurca cloak with storage pockets. This one has the security department design."
|
||||
icon_state = "seccape"
|
||||
item_state = "seccape"
|
||||
@@ -46,19 +46,24 @@
|
||||
var/flipped = null
|
||||
var/flippable = 1
|
||||
var/wear_over_suit = 0
|
||||
var/base_name = ""
|
||||
|
||||
/obj/item/storage/wallet/Initialize()
|
||||
. = ..()
|
||||
base_name = name
|
||||
AddComponent(/datum/component/base_name, name)
|
||||
|
||||
/obj/item/storage/wallet/proc/update_name(var/base_name = initial(name))
|
||||
SEND_SIGNAL(src, COMSIG_BASENAME_SETNAME, args)
|
||||
if(front_id)
|
||||
name = "[base_name] ([front_id])"
|
||||
else
|
||||
name = "[base_name]"
|
||||
|
||||
/obj/item/storage/wallet/remove_from_storage(obj/item/W as obj, atom/new_location)
|
||||
. = ..(W, new_location)
|
||||
if(.)
|
||||
if(W == front_id)
|
||||
front_id = null
|
||||
name = base_name
|
||||
update_name()
|
||||
update_icon()
|
||||
|
||||
/obj/item/storage/wallet/handle_item_insertion(obj/item/W as obj, prevent_warning = 0)
|
||||
@@ -66,7 +71,7 @@
|
||||
if(.)
|
||||
if(!front_id && istype(W, /obj/item/card/id))
|
||||
front_id = W
|
||||
name = "[name] ([front_id])"
|
||||
update_name()
|
||||
update_icon()
|
||||
|
||||
/obj/item/storage/wallet/update_icon()
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
new /obj/item/clothing/mask/gas/alt(src)
|
||||
new /obj/item/clothing/mask/gas/half(src)
|
||||
new /obj/item/auto_cpr(src)
|
||||
new /obj/item/clothing/suit/storage/toggle/first_responder_jacket(src)
|
||||
new /obj/item/clothing/suit/storage/toggle/fr_jacket/alt(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/CMO
|
||||
name = "chief medical officer's locker"
|
||||
|
||||
@@ -140,6 +140,8 @@
|
||||
new /obj/item/clothing/accessory/badge/hos(src)
|
||||
new /obj/item/clothing/gloves/black_leather(src)
|
||||
new /obj/item/clothing/suit/storage/toggle/armor/hos(src)
|
||||
new /obj/item/clothing/mask/gas/alt(src)
|
||||
new /obj/item/clothing/mask/gas/half(src)
|
||||
//Tools
|
||||
new /obj/item/device/radio/headset/heads/hos(src)
|
||||
new /obj/item/device/radio/headset/heads/hos/alt(src)
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/obj/structure/window_frame
|
||||
name = "window frame"
|
||||
desc = "An empty window frame."
|
||||
icon = 'icons/obj/smooth/full_window.dmi'
|
||||
icon_state = "window_frame"
|
||||
build_amt = 4
|
||||
anchored = FALSE
|
||||
|
||||
/obj/structure/window_frame/anchored
|
||||
anchored = TRUE
|
||||
|
||||
/obj/structure/window_frame/attackby(obj/item/W, mob/user)
|
||||
if((W.isscrewdriver()) && (istype(loc, /turf/simulated) || anchored))
|
||||
playsound(src, W.usesound, 80, 1)
|
||||
anchored = !anchored
|
||||
user.visible_message("<span class='notice'>[user] [anchored ? "fastens" : "unfastens"] \the [src].</span>", \
|
||||
"<span class='notice'>You have [anchored ? "fastened the grille to" : "unfastened the grill from"] the floor.</span>")
|
||||
return
|
||||
|
||||
else if(W.iswelder())
|
||||
var/obj/item/weldingtool/WT = W
|
||||
if(!WT.isOn())
|
||||
to_chat(user, SPAN_WARNING("\The [WT] isn't turned on."))
|
||||
return
|
||||
if(WT.remove_fuel(0, user))
|
||||
to_chat(user, SPAN_NOTICE("You use \the [WT] to remove \the [src]."))
|
||||
playsound(src, WT.usesound, 80, 1)
|
||||
new /obj/item/stack/material/steel(get_turf(src),rand(1,3))
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
else if(istype(W, /obj/item/stack/material) && W.get_material_name() == MATERIAL_GLASS_REINFORCED && anchored)
|
||||
var/obj/item/stack/material/G = W
|
||||
if(G.use(4))
|
||||
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
to_chat(user, SPAN_WARNING ("You place the glass on the window frame."))
|
||||
new /obj/structure/window/full(get_turf(src))
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
to_chat(user, SPAN_WARNING ("You need at least four sheets of reinforced glass to finished the window."))
|
||||
|
||||
else if(istype(W, /obj/item/stack/material) && W.get_material_name() == MATERIAL_GLASS_REINFORCED_PHORON && anchored)
|
||||
var/obj/item/stack/material/G = W
|
||||
if(G.use(4))
|
||||
playsound(src, 'sound/items/Deconstruct.ogg', 50, 1)
|
||||
to_chat(user, SPAN_WARNING ("You place the glass on the window frame."))
|
||||
new /obj/structure/window/full/phoron(get_turf(src))
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
to_chat(user, SPAN_WARNING ("You need at least four sheets of reinforced borosilicate glass to finished the window."))
|
||||
@@ -10,6 +10,7 @@
|
||||
anchored = TRUE
|
||||
flags = CONDUCT
|
||||
explosion_resistance = 1
|
||||
layer = 2.98
|
||||
var/health = 10
|
||||
var/destroyed = 0
|
||||
|
||||
|
||||
@@ -870,6 +870,30 @@
|
||||
/obj/structure/sign/flag/gadpathur/right
|
||||
icon_state = "gadpathur_r"
|
||||
|
||||
/obj/item/flag/vysoka
|
||||
name = "Free System of Vysoka flag"
|
||||
desc = "The flag of the Free System of Vysoka."
|
||||
desc_fluff = "The red, yellow and Coalition-blue flag of Vysoka, as drawn when one wishes to represent the planet as a whole. As Vysokan communities are rather traditional and tied to their respective Host, village or city-state, natives are more likely to \
|
||||
identify with local symbols. This has not stopped the original flag from being flown in times of much-needed unity."
|
||||
flag_path = "vysoka"
|
||||
|
||||
/obj/structure/sign/flag/vysoka
|
||||
name = "Free System of Vysoka flag"
|
||||
desc = "The flag of the Free System of Vysoka."
|
||||
desc_fluff = "The red, yellow and Coalition-blue flag of Vysoka, as drawn when one wishes to represent the planet as a whole. As Vysokan communities are rather traditional and tied to their respective Host, village or city-state, natives are more likely to \
|
||||
identify with local symbols. This has not stopped the original flag from being flown in times of much-needed unity."
|
||||
icon_state = "vysoka"
|
||||
|
||||
/obj/item/flag/vysoka/l
|
||||
name = "large Free System of Vysoka flag"
|
||||
flag_size = 1
|
||||
|
||||
/obj/structure/sign/flag/vysoka/left
|
||||
icon_state = "vysoka_l"
|
||||
|
||||
/obj/structure/sign/flag/vysoka/right
|
||||
icon_state = "vysoka_r"
|
||||
|
||||
/obj/item/flag/afterattack(var/atom/A, var/mob/user, var/adjacent, var/clickparams)
|
||||
if (!adjacent)
|
||||
return
|
||||
|
||||
@@ -432,9 +432,16 @@
|
||||
bedpath = /obj/structure/bed/roller/hover
|
||||
|
||||
/obj/item/roller/attack_self(mob/user)
|
||||
var/obj/structure/bed/roller/R = new bedpath(user.loc)
|
||||
R.add_fingerprint(user)
|
||||
qdel(src)
|
||||
..()
|
||||
deploy_roller(user, user.loc)
|
||||
|
||||
/obj/item/roller/afterattack(obj/target, mob/user, proximity)
|
||||
if(!proximity)
|
||||
return
|
||||
if(isturf(target))
|
||||
var/turf/T = target
|
||||
if(!T.density)
|
||||
deploy_roller(user, target)
|
||||
|
||||
/obj/item/roller/attackby(obj/item/W as obj, mob/user as mob)
|
||||
|
||||
@@ -448,6 +455,11 @@
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/roller/proc/deploy_roller(mob/user, atom/location)
|
||||
var/obj/structure/bed/roller/R = new bedpath(location)
|
||||
R.add_fingerprint(user)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/roller_holder
|
||||
name = "roller bed rack"
|
||||
desc = "A rack for carrying a collapsed roller bed."
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
var/shardtype = /obj/item/material/shard
|
||||
var/glasstype = null // Set this in subtypes. Null is assumed strange or otherwise impossible to dismantle, such as for shuttle glass.
|
||||
var/silicate = 0 // number of units of silicate
|
||||
var/base_frame = null
|
||||
|
||||
atmos_canpass = CANPASS_PROC
|
||||
|
||||
@@ -45,6 +46,12 @@
|
||||
else
|
||||
to_chat(user, SPAN_NOTICE("There is a thick layer of silicate covering it."))
|
||||
|
||||
/obj/structure/window/proc/update_nearby_icons()
|
||||
queue_smooth_neighbors(src)
|
||||
|
||||
/obj/structure/window/update_icon()
|
||||
queue_smooth(src)
|
||||
|
||||
/obj/structure/window/proc/take_damage(var/damage = 0, var/sound_effect = 1)
|
||||
var/initialhealth = health
|
||||
|
||||
@@ -102,6 +109,14 @@
|
||||
new shardtype(loc) //todo pooling?
|
||||
if(reinf)
|
||||
new /obj/item/stack/rods(loc)
|
||||
|
||||
if(base_frame)
|
||||
if(prob(50))
|
||||
var/obj/F = new base_frame(loc)
|
||||
F.anchored = anchored
|
||||
else
|
||||
new /obj/item/material/shard/shrapnel(loc)
|
||||
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
@@ -233,6 +248,7 @@
|
||||
to_chat(user, (state == 1 ? SPAN_NOTICE("You have unfastened the window from the frame.") : SPAN_NOTICE("You have fastened the window to the frame.")))
|
||||
else if(reinf && state == 0)
|
||||
anchored = !anchored
|
||||
update_icon()
|
||||
update_nearby_icons()
|
||||
playsound(loc, W.usesound, 75, 1)
|
||||
to_chat(user, (anchored ? SPAN_NOTICE("You have fastened the frame to the floor.") : SPAN_NOTICE("You have unfastened the frame from the floor.")))
|
||||
@@ -241,6 +257,8 @@
|
||||
update_nearby_icons()
|
||||
playsound(loc, W.usesound, 75, 1)
|
||||
to_chat(user, (anchored ? SPAN_NOTICE("You have fastened the window to the floor.") : SPAN_NOTICE("You have unfastened the window.")))
|
||||
update_icon()
|
||||
update_nearby_icons()
|
||||
else if(W.iscrowbar() && reinf && state <= 1)
|
||||
state = 1 - state
|
||||
playsound(loc, W.usesound, 75, 1)
|
||||
@@ -250,12 +268,7 @@
|
||||
to_chat(user, SPAN_NOTICE("You're not sure how to dismantle \the [src] properly."))
|
||||
else
|
||||
visible_message(SPAN_NOTICE("[user] dismantles \the [src]."))
|
||||
if(dir == SOUTHWEST)
|
||||
var/obj/item/stack/material/mats = new glasstype(loc)
|
||||
mats.amount = is_fulltile() ? 4 : 2
|
||||
else
|
||||
new glasstype(loc)
|
||||
qdel(src)
|
||||
dismantle_window()
|
||||
else
|
||||
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||
if(W.damtype == BRUTE || W.damtype == BURN)
|
||||
@@ -300,6 +313,14 @@
|
||||
take_damage(damage)
|
||||
return
|
||||
|
||||
/obj/structure/window/proc/dismantle_window()
|
||||
if(dir == SOUTHWEST)
|
||||
var/obj/item/stack/material/mats = new glasstype(loc)
|
||||
mats.amount = is_fulltile() ? 4 : 2
|
||||
else
|
||||
new glasstype(loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/window/Initialize(mapload, start_dir = null, constructed=0)
|
||||
. = ..()
|
||||
|
||||
@@ -342,33 +363,6 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
//This proc is used to update the icons of nearby windows. It should not be confused with update_nearby_tiles(), which is an atmos proc!
|
||||
/obj/structure/window/proc/update_nearby_icons()
|
||||
update_icon()
|
||||
for(var/obj/structure/window/W in orange(src, 1))
|
||||
W.update_icon()
|
||||
|
||||
//merges adjacent full-tile windows into one (blatant ripoff from game/smoothwall.dm)
|
||||
/obj/structure/window/update_icon()
|
||||
//A little cludge here, since I don't know how it will work with slim windows. Most likely VERY wrong.
|
||||
//this way it will only update full-tile ones
|
||||
cut_overlays()
|
||||
if(!is_fulltile())
|
||||
icon_state = "[basestate]"
|
||||
return
|
||||
var/list/dirs = list()
|
||||
if(anchored)
|
||||
for(var/obj/structure/window/W in orange(src,1))
|
||||
if(W.anchored && W.density && W.type == src.type && W.is_fulltile()) //Only counts anchored, not-destroyed fill-tile windows.
|
||||
dirs += get_dir(src, W)
|
||||
|
||||
var/list/connections = dirs_to_corner_states(dirs)
|
||||
|
||||
icon_state = ""
|
||||
for(var/i = 1 to 4)
|
||||
var/image/I = image(icon, "[basestate][connections[i]]", dir = 1<<(i-1))
|
||||
add_overlay(I)
|
||||
|
||||
/obj/structure/window/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature > maximal_heat)
|
||||
hit(damage_per_fire_tick, 0)
|
||||
@@ -514,12 +508,6 @@
|
||||
/obj/structure/window/shuttle/crescent/take_damage()
|
||||
return
|
||||
|
||||
/obj/structure/window/shuttle/update_nearby_icons()
|
||||
queue_smooth_neighbors(src)
|
||||
|
||||
/obj/structure/window/update_icon()
|
||||
queue_smooth(src)
|
||||
|
||||
/obj/structure/window/reinforced/polarized
|
||||
name = "electrochromic window"
|
||||
desc = "Adjusts its tint with voltage. Might take a few good hits to shatter it."
|
||||
@@ -581,3 +569,59 @@
|
||||
|
||||
/obj/machinery/button/switch/windowtint/update_icon()
|
||||
icon_state = "light[active]"
|
||||
|
||||
/obj/structure/window/full
|
||||
name = "reinforced window"
|
||||
desc = "It looks rather strong. Might take a few good hits to shatter it."
|
||||
icon = 'icons/obj/smooth/full_window.dmi'
|
||||
icon_state = "window_glass"
|
||||
basestate = "window_glass"
|
||||
maxhealth = 40
|
||||
reinf = TRUE
|
||||
maximal_heat = T0C + 750
|
||||
dir = 5
|
||||
smooth = SMOOTH_TRUE
|
||||
damage_per_fire_tick = 2.0
|
||||
can_be_unanchored = TRUE
|
||||
glasstype = /obj/item/stack/material/glass/reinforced
|
||||
layer = 2.99
|
||||
base_frame = /obj/structure/window_frame
|
||||
|
||||
/obj/structure/window/full/dismantle_window()
|
||||
var/obj/item/stack/material/mats = new glasstype(loc)
|
||||
mats.amount = 4
|
||||
var/obj/structure/window_frame/F = new/obj/structure/window_frame (get_turf(src))
|
||||
F.anchored = anchored
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/window/full/phoron
|
||||
name = "reinforced borosilicate window"
|
||||
desc = "A borosilicate alloy window, with rods supporting it. It seems to be very strong."
|
||||
icon = 'icons/obj/smooth/phoron_full_window.dmi'
|
||||
icon_state = "window_glass"
|
||||
basestate = "window_glass"
|
||||
shardtype = /obj/item/material/shard/phoron
|
||||
glasstype = /obj/item/stack/material/glass/phoronrglass
|
||||
maximal_heat = T0C + 4000
|
||||
damage_per_fire_tick = 1.0
|
||||
maxhealth = 80.0
|
||||
layer = 2.99
|
||||
base_frame = /obj/structure/window_frame
|
||||
|
||||
/obj/structure/window/reinforced/polarized/full
|
||||
name = "reinforced electrochromic window"
|
||||
desc = "Adjusts its tint with voltage. Might take a few good hits to shatter it."
|
||||
icon = 'icons/obj/smooth/full_window.dmi'
|
||||
icon_state = "window_glass"
|
||||
basestate = "window_glass"
|
||||
dir = 5
|
||||
smooth = SMOOTH_TRUE
|
||||
layer = 2.99
|
||||
base_frame = /obj/structure/window_frame
|
||||
|
||||
/obj/structure/window/reinforced/polarized/full/dismantle_window()
|
||||
var/obj/item/stack/material/mats = new glasstype(loc)
|
||||
mats.amount = 4
|
||||
var/obj/structure/window_frame/F = new/obj/structure/window_frame (get_turf(src))
|
||||
F.anchored = anchored
|
||||
qdel(src)
|
||||
|
||||
@@ -87,19 +87,57 @@
|
||||
update_icon(TRUE)
|
||||
playsound(src, 'sound/items/Deconstruct.ogg', 80, 1)
|
||||
return
|
||||
// Repairs.
|
||||
// Repairs and deconstruction
|
||||
else if(C.iscrowbar())
|
||||
if(broken || burnt)
|
||||
playsound(src, 'sound/items/crowbar_tile.ogg', 80, 1)
|
||||
visible_message("<span class='notice'>[user] has begun prying off the damaged plating.</span>")
|
||||
var/turf/T = GetBelow(src)
|
||||
if(T)
|
||||
T.visible_message("<span class='warning'>The ceiling above looks as if it's being pried off.</span>")
|
||||
if(do_after(user, 10 SECONDS))
|
||||
if(!istype(src, /turf/simulated/floor))
|
||||
return
|
||||
if(broken || burnt && !(is_plating()))
|
||||
return
|
||||
visible_message("<span class='warning'>[user] has pried off the damaged plating.</span>")
|
||||
new /obj/item/stack/tile/floor(src)
|
||||
src.ReplaceWithLattice()
|
||||
playsound(src, 'sound/items/Deconstruct.ogg', 80, 1)
|
||||
if(T)
|
||||
T.visible_message("<span class='danger'>The ceiling above has been pried off!</span>")
|
||||
return
|
||||
return
|
||||
else if(C.iswelder())
|
||||
var/obj/item/weldingtool/welder = C
|
||||
if(welder.isOn() && (is_plating()))
|
||||
if(broken || burnt)
|
||||
if(welder.remove_fuel(0,user))
|
||||
to_chat(user, "<span class='notice'>You fix some dents on the broken plating.</span>")
|
||||
playsound(src, 'sound/items/welder.ogg', 80, 1)
|
||||
icon_state = "plating"
|
||||
burnt = null
|
||||
broken = null
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need more welding fuel to complete this task.</span>")
|
||||
if(do_after(user, 5 SECONDS))
|
||||
if(welder.remove_fuel(0, user))
|
||||
to_chat(user, "<span class='notice'>You fix some dents on the broken plating.</span>")
|
||||
playsound(src, 'sound/items/Welder.ogg', 80, 1)
|
||||
icon_state = "plating"
|
||||
burnt = null
|
||||
broken = null
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You need more welding fuel to complete this task.</span>")
|
||||
return
|
||||
else
|
||||
if(welder.remove_fuel(0, user))
|
||||
playsound(src, 'sound/items/Welder.ogg', 80, 1)
|
||||
visible_message("<span class='notice'>[user] has started melting the plating's reinforcements!</span>")
|
||||
if(do_after(user, 10 SECONDS) && welder.isOn() && welder_melt())
|
||||
visible_message("<span class='warning'>[user] has melted the plating's reinforcements! It should be possible to pry it off.</span>")
|
||||
playsound(src, 'sound/items/Welder.ogg', 80, 1)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/turf/simulated/floor/proc/welder_melt()
|
||||
if(!(is_plating()) || broken || burnt)
|
||||
return 0
|
||||
burnt = 1
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
/turf/simulated/floor/can_lay_cable()
|
||||
return !flooring
|
||||
|
||||
@@ -3,22 +3,15 @@
|
||||
var/dat = ""
|
||||
dat += "Current Game Mode: <b>[SSticker.mode.name]</b><br>"
|
||||
dat += "Round Duration: [get_round_duration_formatted()]<br>"
|
||||
dat += "<b>Emergency Shuttle</b><br>"
|
||||
if (!emergency_shuttle.online())
|
||||
dat += "<vui-button :params=\"{ call_shuttle: 1 }\">Call Shuttle</vui-button><br>"
|
||||
dat += "<b>Evacuation</b><br>"
|
||||
if (evacuation_controller.is_idle())
|
||||
dat += "<vui-button :params=\"{ call_shuttle: 1 }\">Call Evacuation</vui-button><br>"
|
||||
else
|
||||
if (emergency_shuttle.wait_for_launch)
|
||||
var/timeleft = emergency_shuttle.estimate_launch_time()
|
||||
dat += "ETL: <vui-button :params=\"{ edit_shuttle_time: 1 }\">[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]</vui-button><br>"
|
||||
|
||||
else if (emergency_shuttle.shuttle.has_arrive_time())
|
||||
var/timeleft = emergency_shuttle.estimate_arrival_time()
|
||||
dat += "ETA: <vui-button :params=\"{ edit_shuttle_time: 1 }\">[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]</vui-button><br>"
|
||||
var/timeleft = evacuation_controller.get_eta()
|
||||
if (evacuation_controller.waiting_to_leave())
|
||||
dat += "ETA: [(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]<BR>"
|
||||
dat += "<a href='?src=\ref[src];call_shuttle=2'>Send Back</a><br>"
|
||||
|
||||
if (emergency_shuttle.shuttle.moving_status == SHUTTLE_WARMUP)
|
||||
dat += "Launching now...<br>"
|
||||
|
||||
dat += "<vui-button :params=\"{ delay_round_end: 1 }\">[SSticker.delay_end ? "End Round Normally" : "Delay Round End"]</vui-button><br>"
|
||||
dat += "<hr>"
|
||||
for(var/antag_type in all_antag_types)
|
||||
|
||||
@@ -112,53 +112,19 @@
|
||||
else if(href_list["call_shuttle"])
|
||||
if(!check_rights(R_ADMIN)) return
|
||||
|
||||
if( SSticker.mode.name == "blob" )
|
||||
alert("You can't call the shuttle during blob!")
|
||||
return
|
||||
|
||||
switch(href_list["call_shuttle"])
|
||||
if("1")
|
||||
if ((!( ROUND_IS_STARTED ) || !emergency_shuttle.location()))
|
||||
return
|
||||
if (emergency_shuttle.can_call())
|
||||
emergency_shuttle.call_evac()
|
||||
log_admin("[key_name(usr)] called the Emergency Shuttle",admin_key=key_name(usr))
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] called the Emergency Shuttle to the station</span>", 1)
|
||||
if (evacuation_controller.call_evacuation(usr, TRUE))
|
||||
log_admin("[key_name(usr)] called an evacuation.")
|
||||
message_admins("[key_name_admin(usr)] called an evacuation.", 1)
|
||||
|
||||
if("2")
|
||||
if (!( ROUND_IS_STARTED ) || !emergency_shuttle.location())
|
||||
return
|
||||
if (emergency_shuttle.can_call())
|
||||
emergency_shuttle.call_evac()
|
||||
log_admin("[key_name(usr)] called the Emergency Shuttle",admin_key=key_name(usr))
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] called the Emergency Shuttle to the station</span>", 1)
|
||||
|
||||
else if (emergency_shuttle.can_recall())
|
||||
emergency_shuttle.recall()
|
||||
log_admin("[key_name(usr)] sent the Emergency Shuttle back",admin_key=key_name(usr))
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] sent the Emergency Shuttle back</span>", 1)
|
||||
|
||||
href_list["secretsadmin"] = "check_antagonist"
|
||||
|
||||
else if(href_list["edit_shuttle_time"])
|
||||
if(!check_rights(R_SERVER)) return
|
||||
|
||||
if (emergency_shuttle.wait_for_launch)
|
||||
var/new_time_left = input("Enter new shuttle launch countdown (seconds):","Edit Shuttle Launch Time", emergency_shuttle.estimate_launch_time() ) as num
|
||||
|
||||
emergency_shuttle.launch_time = world.time + new_time_left*10
|
||||
|
||||
log_admin("[key_name(usr)] edited the Emergency Shuttle's launch time to [new_time_left]",admin_key=key_name(usr))
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] edited the Emergency Shuttle's launch time to [new_time_left*10]</span>", 1)
|
||||
else if (emergency_shuttle.shuttle.has_arrive_time())
|
||||
|
||||
var/new_time_left = input("Enter new shuttle arrival time (seconds):","Edit Shuttle Arrival Time", emergency_shuttle.estimate_arrival_time() ) as num
|
||||
emergency_shuttle.shuttle.arrive_time = world.time + new_time_left*10
|
||||
|
||||
log_admin("[key_name(usr)] edited the Emergency Shuttle's arrival time to [new_time_left]",admin_key=key_name(usr))
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] edited the Emergency Shuttle's arrival time to [new_time_left*10]</span>", 1)
|
||||
else
|
||||
alert("The shuttle is neither counting down to launch nor is it in transit. Please try again when it is.")
|
||||
if (evacuation_controller.call_evacuation(usr, TRUE))
|
||||
log_admin("[key_name(usr)] called an evacuation.")
|
||||
message_admins("[key_name_admin(usr)] called an evacuation.", 1)
|
||||
else if (evacuation_controller.cancel_evacuation())
|
||||
log_admin("[key_name(usr)] cancelled an evacuation.")
|
||||
message_admins("[key_name_admin(usr)] cancelled an evacuation.", 1)
|
||||
|
||||
href_list["secretsadmin"] = "check_antagonist"
|
||||
|
||||
|
||||
@@ -58,6 +58,10 @@
|
||||
objs += d
|
||||
|
||||
//to_chat(usr, "Query: [query_text]")
|
||||
var/static/list/blacklist = list(/datum/configuration)
|
||||
for(var/datum/D in objs)
|
||||
if(blacklist[D.type])
|
||||
objs -= D
|
||||
message_admins("[usr] executed SDQL query: \"[query_text]\".")
|
||||
|
||||
switch(query_tree[1])
|
||||
|
||||
@@ -888,67 +888,62 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
/client/proc/admin_call_shuttle()
|
||||
|
||||
set category = "Admin"
|
||||
set name = "Call Shuttle"
|
||||
set name = "Call Evacuation"
|
||||
|
||||
if ((!( ROUND_IS_STARTED ) || !emergency_shuttle.location()))
|
||||
if ((!( ROUND_IS_STARTED ) || !evacuation_controller))
|
||||
return
|
||||
|
||||
if(!check_rights(R_ADMIN)) return
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
|
||||
if(confirm != "Yes") return
|
||||
if(alert(src, "Are you sure?", "Confirm", "Yes", "No") != "Yes")
|
||||
return
|
||||
|
||||
var/choice
|
||||
if(SSticker.mode.auto_recall_shuttle)
|
||||
choice = input("The shuttle will just return if you call it. Call anyway?") in list("Confirm", "Cancel")
|
||||
if(choice == "Confirm")
|
||||
emergency_shuttle.auto_recall = 1 //enable auto-recall
|
||||
else
|
||||
if(input("The evacuation will just be cancelled if you call it. Call anyway?") in list("Confirm", "Cancel") != "Confirm")
|
||||
return
|
||||
|
||||
choice = input("Is this an emergency evacuation or a crew transfer?") in list("Emergency", "Crew Transfer")
|
||||
if (choice == "Emergency")
|
||||
emergency_shuttle.call_evac()
|
||||
else
|
||||
emergency_shuttle.call_transfer()
|
||||
var/choice = input("Is this an emergency evacuation or a crew transfer?") in list("Emergency", "Crew Transfer")
|
||||
evacuation_controller.call_evacuation(usr, (choice == "Emergency"))
|
||||
|
||||
|
||||
feedback_add_details("admin_verb","CSHUT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
log_admin("[key_name(usr)] admin-called the emergency shuttle.",admin_key=key_name(usr))
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] admin-called the emergency shuttle.</span>", 1)
|
||||
log_admin("[key_name(usr)] admin-called an evacuation.",admin_key=key_name(usr))
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] admin-called an evacuation</span>", 1)
|
||||
return
|
||||
|
||||
/client/proc/admin_cancel_shuttle()
|
||||
set category = "Admin"
|
||||
set name = "Cancel Shuttle"
|
||||
set name = "Cancel Evacuation"
|
||||
|
||||
if(!check_rights(R_ADMIN)) return
|
||||
|
||||
if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") return
|
||||
|
||||
if(!ROUND_IS_STARTED || !emergency_shuttle.can_recall())
|
||||
if(!ROUND_IS_STARTED || !evacuation_controller)
|
||||
return
|
||||
|
||||
emergency_shuttle.recall()
|
||||
evacuation_controller.cancel_evacuation()
|
||||
feedback_add_details("admin_verb","CCSHUT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
log_admin("[key_name(usr)] admin-recalled the emergency shuttle.",admin_key=key_name(usr))
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] admin-recalled the emergency shuttle.</span>", 1)
|
||||
log_admin("[key_name(usr)] admin-cancelled the evacuation.",admin_key=key_name(usr))
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] admin-cancelled the evacuation.</span>", 1)
|
||||
|
||||
return
|
||||
|
||||
/client/proc/admin_deny_shuttle()
|
||||
set category = "Admin"
|
||||
set name = "Toggle Deny Shuttle"
|
||||
set name = "Toggle Deny Evacuation"
|
||||
|
||||
if (!ROUND_IS_STARTED)
|
||||
return
|
||||
|
||||
if(!check_rights(R_ADMIN)) return
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
|
||||
emergency_shuttle.deny_shuttle = !emergency_shuttle.deny_shuttle
|
||||
evacuation_controller.deny = !evacuation_controller.deny
|
||||
|
||||
log_admin("[key_name(src)] has [emergency_shuttle.deny_shuttle ? "denied" : "allowed"] the shuttle to be called.",admin_key=key_name(usr))
|
||||
message_admins("[key_name_admin(usr)] has [emergency_shuttle.deny_shuttle ? "denied" : "allowed"] the shuttle to be called.")
|
||||
log_admin("[key_name(src)] has [evacuation_controller.deny ? "denied" : "allowed"] the evacuation to be called.",admin_key=key_name(usr))
|
||||
message_admins("[key_name_admin(usr)] has [evacuation_controller.deny ? "denied" : "allowed"] the evacuation to be called.")
|
||||
|
||||
/client/proc/cmd_admin_attack_log(mob/M as mob in mob_list)
|
||||
set category = "Special Verbs"
|
||||
|
||||
@@ -21,6 +21,10 @@
|
||||
if(!D)
|
||||
return
|
||||
|
||||
var/static/list/blacklist = list(/datum/configuration)
|
||||
if(blacklist[D.type])
|
||||
return
|
||||
|
||||
var/icon/sprite
|
||||
if(istype(D, /atom))
|
||||
var/atom/A = D
|
||||
|
||||
@@ -211,9 +211,12 @@ var/datum/gear_tweak/custom_name/gear_tweak_free_name = new()
|
||||
if(!metadata)
|
||||
return I.name
|
||||
I.name = metadata
|
||||
if(I.vars["base_name"])
|
||||
I.vars["base_name"] = metadata
|
||||
|
||||
// For reasons unknown, using SEND_SIGNAL instead of what is below makes rag renaming completely break.
|
||||
var/datum/component/base_name/BN = I.GetComponent(/datum/component/base_name)
|
||||
if(BN)
|
||||
BN.rename(metadata)
|
||||
|
||||
/*
|
||||
Custom Description
|
||||
*/
|
||||
|
||||
@@ -208,8 +208,10 @@
|
||||
shirt["cropped dress shirt, rolled up"] = /obj/item/clothing/accessory/dressshirt/crop/rolled
|
||||
shirt["dress shirt, alt"] = /obj/item/clothing/accessory/dressshirt/alt
|
||||
shirt["dress shirt, alt rolled up"] = /obj/item/clothing/accessory/dressshirt/alt/rolled
|
||||
shirt["dress shirt, V-Neck alt"] = /obj/item/clothing/accessory/dressshirt/alt/vneck
|
||||
shirt["dress shirt, V-Neck alt rolled up"] = /obj/item/clothing/accessory/dressshirt/alt/vneck/rolled
|
||||
shirt["dress shirt, v-neck alt"] = /obj/item/clothing/accessory/dressshirt/alt/vneck
|
||||
shirt["dress shirt, v-neck alt rolled up"] = /obj/item/clothing/accessory/dressshirt/alt/vneck/rolled
|
||||
shirt["dress shirt, deep v-neck"] = /obj/item/clothing/accessory/dressshirt/deepv
|
||||
shirt["dress shirt, deep v-neck rolled up"] = /obj/item/clothing/accessory/dressshirt/deepv/rolled
|
||||
shirt["long-sleeved shirt"] = /obj/item/clothing/accessory/longsleeve
|
||||
shirt["long-sleeved shirt, black striped"] = /obj/item/clothing/accessory/longsleeve_s
|
||||
shirt["long-sleeved shirt, blue striped"] = /obj/item/clothing/accessory/longsleeve_sb
|
||||
@@ -233,6 +235,22 @@
|
||||
shirts["random colored silversun shirt"] = /obj/item/clothing/accessory/silversun/random
|
||||
gear_tweaks += new /datum/gear_tweak/path(shirts)
|
||||
|
||||
/datum/gear/accessory/university
|
||||
display_name = "university sweatshirt selection"
|
||||
path = /obj/item/clothing/accessory/university
|
||||
description = "A selection of university sweatshirts."
|
||||
flags = GEAR_HAS_NAME_SELECTION | GEAR_HAS_DESC_SELECTION
|
||||
|
||||
/datum/gear/accessory/university/New()
|
||||
..()
|
||||
var/list/university = list()
|
||||
university["grey university sweatshirt"] = /obj/item/clothing/accessory/university
|
||||
university["crimson university sweatshirt"] = /obj/item/clothing/accessory/university/red
|
||||
university["mustard university sweatshirt"] = /obj/item/clothing/accessory/university/yellow
|
||||
university["navy university sweatshirt"] = /obj/item/clothing/accessory/university/blue
|
||||
university["black university sweatshirt"] = /obj/item/clothing/accessory/university/black
|
||||
gear_tweaks += new /datum/gear_tweak/path(university)
|
||||
|
||||
/datum/gear/accessory/scarf
|
||||
display_name = "scarf selection"
|
||||
path = /obj/item/clothing/accessory/scarf
|
||||
@@ -298,6 +316,11 @@
|
||||
path = /obj/item/clothing/accessory/badge/namepin
|
||||
flags = GEAR_HAS_NAME_SELECTION | GEAR_HAS_DESC_SELECTION | GEAR_HAS_COLOR_SELECTION
|
||||
|
||||
/datum/gear/accessory/ribbon
|
||||
display_name = "ribbon (colourable)"
|
||||
path = /obj/item/clothing/accessory/ribbon
|
||||
flags = GEAR_HAS_NAME_SELECTION | GEAR_HAS_DESC_SELECTION | GEAR_HAS_COLOR_SELECTION
|
||||
|
||||
/datum/gear/accessory/sleeve_patch
|
||||
display_name = "shoulder sleeve patch"
|
||||
path = /obj/item/clothing/accessory/sleevepatch
|
||||
|
||||
@@ -9,12 +9,19 @@
|
||||
flags = GEAR_NO_SELECTION
|
||||
|
||||
/datum/gear/augment/eye_sensors
|
||||
display_name = "integrated eye sensors"
|
||||
display_name = "integrated eye sensors selection"
|
||||
description = "An eye augment that allows the user to deploy medical or security sensors."
|
||||
path = /obj/item/organ/internal/augment/eye_sensors
|
||||
cost = 3
|
||||
cost = 1
|
||||
whitelisted = list(SPECIES_HUMAN, SPECIES_HUMAN_OFFWORLD, SPECIES_TAJARA, SPECIES_TAJARA_ZHAN, SPECIES_TAJARA_MSAI, SPECIES_UNATHI, SPECIES_SKRELL, SPECIES_IPC, SPECIES_IPC_G1, SPECIES_IPC_G2, SPECIES_IPC_XION, SPECIES_IPC_ZENGHU, SPECIES_IPC_BISHOP, SPECIES_IPC_SHELL, SPECIES_VAURCA_WORKER, SPECIES_VAURCA_WARRIOR)
|
||||
|
||||
/datum/gear/augment/eye_sensors/New()
|
||||
..()
|
||||
var/list/sensors = list()
|
||||
sensors["eye sensors, security"] = /obj/item/organ/internal/augment/eye_sensors/security
|
||||
sensors["eye sensors, medical"] = /obj/item/organ/internal/augment/eye_sensors/medical
|
||||
gear_tweaks += new /datum/gear_tweak/path(sensors)
|
||||
|
||||
/datum/gear/augment/cyber_hair
|
||||
display_name = "synthetic hair extensions"
|
||||
description = "A hair augment that allows the user to change the shape and color of their hair."
|
||||
@@ -137,6 +144,13 @@
|
||||
description = "A set of corrective lenses that can be deployed & retracted."
|
||||
path = /obj/item/organ/internal/augment/tool/correctivelens
|
||||
|
||||
/datum/gear/augment/glare_dampeners
|
||||
display_name = "retractable glare dampeners"
|
||||
description = "A subdermal implant installed just above the brow line that deploys a thin sheath of hyperpolycarbonate that protects from eye damage associated with arc flash."
|
||||
path = /obj/item/organ/internal/augment/tool/correctivelens/glare_dampener
|
||||
allowed_roles = list("Chief Engineer", "Station Engineer", "Atmospheric Technician", "Engineering Apprentice", "Roboticist")
|
||||
cost = 2
|
||||
|
||||
/datum/gear/augment/head_fluff
|
||||
display_name = "Custom head augmentation"
|
||||
description = "A fluff based augmentation that can be renamed/redescribed to appear as something else for RP purposes."
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
glasses["sunglasses, aviator"] = /obj/item/clothing/glasses/fakesunglasses/aviator
|
||||
glasses["sunglasses, prescription"] = /obj/item/clothing/glasses/fakesunglasses/prescription
|
||||
glasses["sunglasses, fat"] = /obj/item/clothing/glasses/fakesunglasses/big
|
||||
glasses["sunglasses, visor"] = /obj/item/clothing/glasses/fakesunglasses/visor
|
||||
gear_tweaks += new /datum/gear_tweak/path(glasses)
|
||||
|
||||
/datum/gear/eyes/sunglasses
|
||||
@@ -53,6 +54,7 @@
|
||||
glasses["flash-proof sunglasses, aviator"] = /obj/item/clothing/glasses/sunglasses/aviator
|
||||
glasses["flash-proof sunglasses, prescription"] = /obj/item/clothing/glasses/sunglasses/prescription
|
||||
glasses["flash-proof sunglasses, fat"] = /obj/item/clothing/glasses/sunglasses/big
|
||||
glasses["flash-proof sunglasses, visor"] = /obj/item/clothing/glasses/sunglasses/visor
|
||||
gear_tweaks += new /datum/gear_tweak/path(glasses)
|
||||
|
||||
/datum/gear/eyes/goggles
|
||||
@@ -82,6 +84,7 @@
|
||||
medhud["HUD, medical"] = /obj/item/clothing/glasses/hud/health
|
||||
medhud["HUDpatch, medical"] = /obj/item/clothing/glasses/eyepatch/hud/medical
|
||||
medhud["prescription HUD, medical"] = /obj/item/clothing/glasses/hud/health/prescription
|
||||
medhud["visor sunglasses, medical"] = /obj/item/clothing/glasses/hud/health/aviator/visor
|
||||
gear_tweaks += new /datum/gear_tweak/path(medhud)
|
||||
|
||||
/datum/gear/eyes/sechuds
|
||||
@@ -99,6 +102,7 @@
|
||||
sechud["HUD, security"] = /obj/item/clothing/glasses/hud/security
|
||||
sechud["HUDpatch, security"] = /obj/item/clothing/glasses/eyepatch/hud/security
|
||||
sechud["prescription HUD, security"] = /obj/item/clothing/glasses/hud/security/prescription
|
||||
sechud["visor sunglasses, security"] = /obj/item/clothing/glasses/sunglasses/sechud/aviator/visor
|
||||
gear_tweaks += new /datum/gear_tweak/path(sechud)
|
||||
|
||||
/datum/gear/eyes/hudpatch
|
||||
|
||||
@@ -165,6 +165,7 @@
|
||||
banners["banner, Coalition of Colonies"] = /obj/item/flag/coalition
|
||||
banners["banner, Confederate States of Fisanduh"] = /obj/item/flag/fisanduh
|
||||
banners["banner, Gadpathur"] = /obj/item/flag/gadpathur
|
||||
banners["banner, Vysoka"] = /obj/item/flag/vysoka
|
||||
gear_tweaks += new /datum/gear_tweak/path(banners)
|
||||
|
||||
/datum/gear/standard
|
||||
@@ -212,6 +213,7 @@
|
||||
flags["flag, Coalition of Colonies"] = /obj/item/flag/coalition/l
|
||||
flags["flag, Confederate States of Fisanduh"] = /obj/item/flag/fisanduh/l
|
||||
flags["flag, Gadpathur"] = /obj/item/flag/gadpathur/l
|
||||
flags["flag, Vysoka"] = /obj/item/flag/vysoka/l
|
||||
gear_tweaks += new /datum/gear_tweak/path(flags)
|
||||
|
||||
/datum/gear/towel
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
softcaps["softcap, cargo"] = /obj/item/clothing/head/softcap/cargo
|
||||
softcaps["softcap, mining"] = /obj/item/clothing/head/softcap/miner
|
||||
softcaps["softcap, janitor"] = /obj/item/clothing/head/softcap/janitor
|
||||
softcaps["softcap, tcfl"] = /obj/item/clothing/head/softcap/tcfl
|
||||
|
||||
gear_tweaks += new /datum/gear_tweak/path(softcaps)
|
||||
|
||||
|
||||
@@ -108,32 +108,33 @@ datum/gear/suit/colorvest
|
||||
cost = 1
|
||||
allowed_roles = list("Scientist", "Chief Medical Officer", "Physician", "Surgeon", "Pharmacist", "First Responder", "Medical Intern", "Xenobiologist", "Roboticist", "Research Director", "Investigator")
|
||||
|
||||
/datum/gear/suit/medical_chest_rig
|
||||
display_name = "medic chest-rig"
|
||||
description = "A white chest-rig with pouches worn by medical first responders, meant to carry their equipment."
|
||||
path = /obj/item/clothing/suit/storage/medical_chest_rig
|
||||
/datum/gear/suit/medical_outerwear
|
||||
display_name = "medical outerwear (jackets, vests, rigs)"
|
||||
path = /obj/item/clothing/suit/storage/toggle/fr_jacket
|
||||
allowed_roles = list("Chief Medical Officer", "Physician", "Surgeon", "Pharmacist", "First Responder", "Medical Intern")
|
||||
|
||||
/datum/gear/suit/first_responder_vest
|
||||
display_name = "first responder vest"
|
||||
description = "A dark green vest adorned with high-visibility stripes. Has pouches to carry equipment with."
|
||||
path = /obj/item/clothing/suit/storage/medical_chest_rig/first_responder
|
||||
allowed_roles = list("Chief Medical Officer", "Physician", "Surgeon", "Pharmacist", "First Responder", "Medical Intern")
|
||||
/datum/gear/suit/medical_outerwear/New()
|
||||
..()
|
||||
var/list/medical_outerwear = list()
|
||||
medical_outerwear["medical chest-rig"] = /obj/item/clothing/suit/storage/medical_chest_rig
|
||||
medical_outerwear["first responder vest"] = /obj/item/clothing/suit/storage/medical_chest_rig/first_responder
|
||||
medical_outerwear["first responder jacket"] = /obj/item/clothing/suit/storage/toggle/fr_jacket/alt
|
||||
medical_outerwear["first responder jacket, alt"] = /obj/item/clothing/suit/storage/toggle/fr_jacket // this variant is the old bright green one and doesn't go with the NT medic uniform
|
||||
gear_tweaks += new /datum/gear_tweak/path(medical_outerwear)
|
||||
|
||||
/datum/gear/suit/iacvest
|
||||
display_name = "IAC vest"
|
||||
description = "It's a lightweight vest. Made of a dark, navy mesh with highly-reflective white material, designed to be worn by the Interstellar Aid Corps."
|
||||
/datum/gear/suit/iac_outerwear
|
||||
display_name = "IAC outerwear (jackets, vests, rigs)"
|
||||
path = /obj/item/clothing/suit/storage/iacvest
|
||||
allowed_roles = list("Chief Medical Officer", "Physician", "Surgeon", "Pharmacist", "First Responder", "Medical Intern")
|
||||
flags = GEAR_HAS_DESC_SELECTION
|
||||
|
||||
/datum/gear/suit/iaclabcoat
|
||||
display_name = "IAC labcoat"
|
||||
description = "It's a standard medical labcoat designed to be worn by the Interstellar Aid Corps."
|
||||
path = /obj/item/clothing/suit/storage/toggle/labcoat/iac
|
||||
allowed_roles = list("Chief Medical Officer", "Physician", "Surgeon", "Pharmacist", "First Responder", "Medical Intern")
|
||||
flags = GEAR_HAS_DESC_SELECTION
|
||||
|
||||
/datum/gear/suit/iac_outerwear/New()
|
||||
..()
|
||||
var/list/iac_outerwear = list()
|
||||
iac_outerwear["IAC vest"] = /obj/item/clothing/suit/storage/iacvest
|
||||
iac_outerwear["IAC labcoat"] = /obj/item/clothing/suit/storage/toggle/labcoat/iac
|
||||
gear_tweaks += new /datum/gear_tweak/path(iac_outerwear)
|
||||
|
||||
/datum/gear/suit/poncho
|
||||
display_name = "poncho selection"
|
||||
path = /obj/item/clothing/accessory/poncho
|
||||
|
||||
@@ -247,7 +247,7 @@
|
||||
display_name = "tesla spine"
|
||||
description = "A People's Republic of Adhomai made tesla spine issued to disabled veterans and civilians."
|
||||
path = /obj/item/organ/internal/augment/tesla
|
||||
cost = 4
|
||||
cost = 2
|
||||
whitelisted = list(SPECIES_TAJARA, SPECIES_TAJARA_ZHAN, SPECIES_TAJARA_MSAI)
|
||||
sort_category = "Xenowear - Tajara"
|
||||
|
||||
|
||||
@@ -41,13 +41,33 @@
|
||||
flags = GEAR_HAS_DESC_SELECTION | GEAR_HAS_COLOR_SELECTION
|
||||
|
||||
/datum/gear/cape
|
||||
display_name = "tunnel cloak"
|
||||
display_name = "tunnel cloak (recolourable)"
|
||||
path = /obj/item/storage/backpack/cloak
|
||||
cost = 1
|
||||
whitelisted = list(SPECIES_VAURCA_WORKER, SPECIES_VAURCA_WARRIOR)
|
||||
sort_category = "Xenowear - Vaurca"
|
||||
flags = GEAR_HAS_NAME_SELECTION | GEAR_HAS_DESC_SELECTION | GEAR_HAS_COLOR_SELECTION
|
||||
|
||||
/datum/gear/cape_selection
|
||||
display_name = "tunnel cloak selection"
|
||||
path = /obj/item/storage/backpack/cloak
|
||||
cost = 1
|
||||
whitelisted = list(SPECIES_VAURCA_WORKER, SPECIES_VAURCA_WARRIOR)
|
||||
sort_category = "Xenowear - Vaurca"
|
||||
flags = GEAR_HAS_DESC_SELECTION
|
||||
|
||||
/datum/gear/cape_selection/New()
|
||||
..()
|
||||
var/list/capes = list()
|
||||
capes["tunnel cloak, Sedantis"] = /obj/item/storage/backpack/cloak/sedantis
|
||||
capes["tunnel cloak, medical"] = /obj/item/storage/backpack/cloak/medical
|
||||
capes["tunnel cloak, engineering"] = /obj/item/storage/backpack/cloak/engi
|
||||
capes["tunnel cloak, atmospherics"] = /obj/item/storage/backpack/cloak/atmos
|
||||
capes["tunnel cloak, cargo"] = /obj/item/storage/backpack/cloak/cargo
|
||||
capes["tunnel cloak, science"] = /obj/item/storage/backpack/cloak/sci
|
||||
capes["tunnel cloak, security"] = /obj/item/storage/backpack/cloak/sec
|
||||
gear_tweaks += new /datum/gear_tweak/path(capes)
|
||||
|
||||
/datum/gear/vaurca_robe
|
||||
display_name = "hive cloak"
|
||||
description = "A selection of vaurca colored hive cloaks."
|
||||
|
||||
@@ -160,6 +160,12 @@ BLIND // can't see anything
|
||||
|
||||
attack_self(usr)
|
||||
|
||||
/obj/item/clothing/glasses/hud/health/aviator/visor
|
||||
name = "medical HUD visor"
|
||||
desc = "Modified visor glasses with a toggled health HUD. Comes with bonus prescription overlay."
|
||||
icon_state = "visor_medhud"
|
||||
off_state = "visor_medhud_off"
|
||||
|
||||
/obj/item/clothing/glasses/science
|
||||
name = "science goggles"
|
||||
desc = "Used to protect your eyes against harmful chemicals!"
|
||||
@@ -416,6 +422,7 @@ BLIND // can't see anything
|
||||
item_state = "glasses"
|
||||
prescription = 7
|
||||
body_parts_covered = 0
|
||||
canremove = FALSE
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses
|
||||
name = "sunglasses"
|
||||
@@ -448,6 +455,12 @@ BLIND // can't see anything
|
||||
icon_state = "bigsunglasses"
|
||||
item_state = "sun"
|
||||
|
||||
/obj/item/clothing/glasses/sunglasses/visor
|
||||
name = "visor sunglasses"
|
||||
desc = "A pair of visor sunglasses."
|
||||
icon_state = "visor"
|
||||
item_state = "visor"
|
||||
|
||||
//For style with no powergaming connotations.
|
||||
|
||||
/obj/item/clothing/glasses/fakesunglasses
|
||||
@@ -480,6 +493,12 @@ BLIND // can't see anything
|
||||
icon_state = "bigsunglasses"
|
||||
item_state = "sun"
|
||||
|
||||
/obj/item/clothing/glasses/fakesunglasses/visor
|
||||
name = "stylish visor sunglasses"
|
||||
desc = "A pair of designer visor sunglasses."
|
||||
icon_state = "visor"
|
||||
item_state = "visor"
|
||||
|
||||
/obj/item/clothing/glasses/welding
|
||||
name = "welding goggles"
|
||||
desc = "Protects the eyes from welders, approved by the mad scientist association."
|
||||
@@ -524,12 +543,15 @@ BLIND // can't see anything
|
||||
|
||||
/obj/item/clothing/glasses/aug/welding
|
||||
name = "glare dampeners"
|
||||
desc = "Protects the eyes from welders."
|
||||
icon_state = "welding-g"
|
||||
item_state = "welding-g"
|
||||
desc = "A subdermal implant installed just above the brow line that deploys a thin sheath of hyperpolycarbonate that protects from eye damage associated with arc flash."
|
||||
icon = 'icons/clothing/eyes/welding_goggles.dmi'
|
||||
icon_state = "welding-aug"
|
||||
item_state = "welding-aug"
|
||||
contained_sprite = TRUE
|
||||
item_flags = THICKMATERIAL
|
||||
flash_protection = FLASH_PROTECTION_MAJOR
|
||||
tint = TINT_HEAVY
|
||||
canremove = FALSE
|
||||
|
||||
/obj/item/clothing/glasses/aug/throw_at()
|
||||
usr.drop_from_inventory(src)
|
||||
@@ -730,6 +752,13 @@ BLIND // can't see anything
|
||||
icon_state = "aviator_sec_idris"
|
||||
off_state = "aviator_sec_idris_off"
|
||||
|
||||
obj/item/clothing/glasses/sunglasses/sechud/aviator/visor
|
||||
name = "security HUD visor"
|
||||
desc = "NanoTrasen security visor glasses that can be switched between HUD and flash protection modes. They come with a built-in prescription overlay."
|
||||
icon_state = "visor_sec"
|
||||
off_state = "visor_sec_off"
|
||||
item_state_slots = list(slot_r_hand_str = "visor_sec", slot_l_hand_str = "visor_sec")
|
||||
|
||||
/obj/item/clothing/glasses/thermal
|
||||
name = "optical thermal scanner"
|
||||
desc = "Thermals in the shape of glasses."
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
desc = "It's a softcap in a tasteless color."
|
||||
icon = 'icons/obj/clothing/hats/soft_caps.dmi'
|
||||
icon_state = "softcap"
|
||||
item_state = "softcap"
|
||||
item_flags = SHOWFLAVORTEXT
|
||||
contained_sprite = TRUE
|
||||
var/flipped = FALSE
|
||||
@@ -30,6 +31,7 @@
|
||||
|
||||
/obj/item/clothing/head/softcap/colorable
|
||||
icon_state = "softcap_colorable"
|
||||
item_state = "softcap_colorable"
|
||||
|
||||
/obj/item/clothing/head/softcap/colorable/random/Initialize()
|
||||
. = ..()
|
||||
@@ -39,6 +41,7 @@
|
||||
name = "rainbow cap"
|
||||
desc = "It's a peaked cap in a bright rainbow of colors."
|
||||
icon_state = "rainbowsoft"
|
||||
item_state = "rainbowsoft"
|
||||
|
||||
/obj/item/clothing/head/softcap/red // Antag red.
|
||||
name = "red softcap"
|
||||
@@ -46,6 +49,12 @@
|
||||
icon_state = "softcap_red"
|
||||
item_state = "softcap_red"
|
||||
|
||||
/obj/item/clothing/head/softcap/tcfl
|
||||
name = "tcfl cap"
|
||||
desc = "A rugged softcap in TCFL colours, go Biesel!"
|
||||
icon_state = "tcfl"
|
||||
item_state = "tcfl"
|
||||
|
||||
// Departmental softcaps. By Wowzewow (Wezzy).
|
||||
|
||||
/obj/item/clothing/head/softcap/captain
|
||||
@@ -132,6 +141,7 @@
|
||||
name = "eridani cap"
|
||||
desc = "A grey EPMC fatigue cap with the symbol of the Eridani Corporate Federation on its front. For amoral mercenaries that prefer style over protection."
|
||||
icon_state = "eridani"
|
||||
item_state = "eridani"
|
||||
|
||||
/obj/item/clothing/head/softcap/zavod
|
||||
name = "zavodskoi cap"
|
||||
|
||||
@@ -8,20 +8,21 @@
|
||||
heat_protection = UPPER_TORSO|LOWER_TORSO
|
||||
max_heat_protection_temperature = ARMOR_MAX_HEAT_PROTECTION_TEMPERATURE
|
||||
siemens_coefficient = 0.5
|
||||
var/obj/item/storage/internal/pockets
|
||||
var/obj/item/storage/internal/pockets = /obj/item/storage/internal
|
||||
var/pocket_slots = 2
|
||||
var/pocket_size = 2
|
||||
var/pocket_total = null//This will be calculated, unless specifically overidden
|
||||
|
||||
/obj/item/clothing/suit/armor/Initialize()
|
||||
. = ..()
|
||||
pockets = new /obj/item/storage/internal(src)
|
||||
pockets.storage_slots = pocket_slots //two slots
|
||||
pockets.max_w_class = pocket_size //fit only pocket sized items
|
||||
if (pocket_total)
|
||||
pockets.max_storage_space = pocket_total
|
||||
else
|
||||
pockets.max_storage_space = pocket_slots * pocket_size
|
||||
if(pockets)
|
||||
pockets = new pockets(src)
|
||||
pockets.storage_slots = pocket_slots //two slots
|
||||
pockets.max_w_class = pocket_size //fit only pocket sized items
|
||||
if (pocket_total)
|
||||
pockets.max_storage_space = pocket_total
|
||||
else
|
||||
pockets.max_storage_space = pocket_slots * pocket_size
|
||||
|
||||
/obj/item/clothing/suit/armor/Destroy()
|
||||
if (pockets)
|
||||
|
||||
@@ -295,10 +295,17 @@ obj/item/clothing/suit/apron/overalls/blue
|
||||
item_state = "fr_jacket"
|
||||
blood_overlay_type = "armor"
|
||||
allowed = list(/obj/item/stack/medical, /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/hypospray, /obj/item/reagent_containers/syringe, \
|
||||
/obj/item/device/healthanalyzer, /obj/item/device/flashlight, /obj/item/device/radio, /obj/item/tank/emergency_oxygen, /obj/item/device/breath_analyzer, /obj/item/reagent_containers/blood)
|
||||
/obj/item/device/healthanalyzer, /obj/item/device/flashlight, /obj/item/device/radio, /obj/item/tank/emergency_oxygen, /obj/item/device/breath_analyzer, /obj/item/reagent_containers/blood, /obj/item/clothing/head/hardhat/first_responder)
|
||||
body_parts_covered = UPPER_TORSO|ARMS
|
||||
opened = TRUE
|
||||
|
||||
/obj/item/clothing/suit/storage/toggle/fr_jacket/alt
|
||||
desc = "A dark green first responder jacket."
|
||||
icon = 'icons/clothing/kit/first_responder.dmi'
|
||||
contained_sprite = TRUE
|
||||
icon_state = "firstresponderjacket"
|
||||
item_state = "firstresponderjacket"
|
||||
|
||||
/obj/item/clothing/suit/storage/toggle/fr_jacket/ems
|
||||
name = "\improper EMS jacket"
|
||||
desc = "A dark blue, martian-pattern, EMS jacket. It sports high-visibility reflective stripes and a star of life on the back."
|
||||
@@ -331,11 +338,3 @@ obj/item/clothing/suit/apron/overalls/blue
|
||||
icon_state = "suspenders"
|
||||
blood_overlay_type = "armor" //it's the less thing that I can put here
|
||||
body_parts_covered = 0
|
||||
|
||||
/obj/item/clothing/suit/storage/toggle/first_responder_jacket
|
||||
name = "first responder jacket"
|
||||
desc = "A dark green first responder jacket."
|
||||
icon = 'icons/clothing/kit/first_responder.dmi'
|
||||
contained_sprite = TRUE
|
||||
icon_state = "firstresponderjacket"
|
||||
item_state = "firstresponderjacket"
|
||||
|
||||
@@ -9,55 +9,64 @@
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
restricted_accessory_slots = list(ACCESSORY_SLOT_ARMOR_PLATE, ACCESSORY_SLOT_ARM_GUARDS, ACCESSORY_SLOT_LEG_GUARDS, ACCESSORY_SLOT_ARMOR_POCKETS)
|
||||
valid_accessory_slots = list(ACCESSORY_SLOT_ARMOR_PLATE, ACCESSORY_SLOT_ARM_GUARDS, ACCESSORY_SLOT_LEG_GUARDS, ACCESSORY_SLOT_ARMOR_POCKETS, ACCESSORY_SLOT_GENERIC, ACCESSORY_SLOT_ARMBAND, ACCESSORY_SLOT_CAPE)
|
||||
pockets = null
|
||||
|
||||
/obj/item/clothing/suit/armor/carrier/officer
|
||||
starting_accessories = list(
|
||||
/obj/item/clothing/accessory/armor_plate
|
||||
/obj/item/clothing/accessory/armor_plate,
|
||||
/obj/item/clothing/accessory/storage/modular_pouch
|
||||
)
|
||||
|
||||
/obj/item/clothing/suit/armor/carrier/hos
|
||||
starting_accessories = list(
|
||||
/obj/item/clothing/accessory/armor_plate/hos
|
||||
/obj/item/clothing/accessory/armor_plate/hos,
|
||||
/obj/item/clothing/accessory/storage/modular_pouch/large
|
||||
)
|
||||
|
||||
/obj/item/clothing/suit/armor/carrier/generic
|
||||
starting_accessories = list(
|
||||
/obj/item/clothing/accessory/armor_plate/generic
|
||||
/obj/item/clothing/accessory/armor_plate/generic,
|
||||
/obj/item/clothing/accessory/storage/modular_pouch
|
||||
)
|
||||
|
||||
/obj/item/clothing/suit/armor/carrier/riot
|
||||
starting_accessories = list(
|
||||
/obj/item/clothing/accessory/armor_plate/riot,
|
||||
/obj/item/clothing/accessory/leg_guard/riot,
|
||||
/obj/item/clothing/accessory/arm_guard/riot
|
||||
/obj/item/clothing/accessory/arm_guard/riot,
|
||||
/obj/item/clothing/accessory/storage/modular_pouch
|
||||
)
|
||||
|
||||
/obj/item/clothing/suit/armor/carrier/ballistic
|
||||
starting_accessories = list(
|
||||
/obj/item/clothing/accessory/armor_plate/ballistic,
|
||||
/obj/item/clothing/accessory/leg_guard/ballistic,
|
||||
/obj/item/clothing/accessory/arm_guard/ballistic
|
||||
/obj/item/clothing/accessory/arm_guard/ballistic,
|
||||
/obj/item/clothing/accessory/storage/modular_pouch/large
|
||||
)
|
||||
|
||||
/obj/item/clothing/suit/armor/carrier/ablative
|
||||
starting_accessories = list(
|
||||
/obj/item/clothing/accessory/armor_plate/ablative,
|
||||
/obj/item/clothing/accessory/leg_guard/ablative,
|
||||
/obj/item/clothing/accessory/arm_guard/ablative
|
||||
/obj/item/clothing/accessory/arm_guard/ablative,
|
||||
/obj/item/clothing/accessory/storage/modular_pouch/large
|
||||
)
|
||||
|
||||
/obj/item/clothing/suit/armor/carrier/military
|
||||
starting_accessories = list(
|
||||
/obj/item/clothing/accessory/armor_plate/military,
|
||||
/obj/item/clothing/accessory/leg_guard/military,
|
||||
/obj/item/clothing/accessory/arm_guard/military
|
||||
/obj/item/clothing/accessory/arm_guard/military,
|
||||
/obj/item/clothing/accessory/storage/modular_pouch/large
|
||||
)
|
||||
|
||||
/obj/item/clothing/suit/armor/carrier/heavy
|
||||
starting_accessories = list(
|
||||
/obj/item/clothing/accessory/armor_plate/heavy,
|
||||
/obj/item/clothing/accessory/leg_guard/heavy,
|
||||
/obj/item/clothing/accessory/arm_guard/heavy
|
||||
/obj/item/clothing/accessory/arm_guard/heavy,
|
||||
/obj/item/clothing/accessory/storage/modular_pouch/large
|
||||
)
|
||||
|
||||
/obj/item/clothing/suit/armor/carrier/heavy/scc
|
||||
@@ -65,6 +74,7 @@
|
||||
/obj/item/clothing/accessory/armor_plate/heavy/scc,
|
||||
/obj/item/clothing/accessory/leg_guard/heavy/scc,
|
||||
/obj/item/clothing/accessory/arm_guard/heavy/scc,
|
||||
/obj/item/clothing/accessory/storage/modular_pouch/large,
|
||||
/obj/item/clothing/accessory/sleevepatch/scc
|
||||
)
|
||||
|
||||
@@ -72,7 +82,8 @@
|
||||
starting_accessories = list(
|
||||
/obj/item/clothing/accessory/armor_plate/heavy/sec,
|
||||
/obj/item/clothing/accessory/leg_guard/heavy/sec,
|
||||
/obj/item/clothing/accessory/arm_guard/heavy/sec
|
||||
/obj/item/clothing/accessory/arm_guard/heavy/sec,
|
||||
/obj/item/clothing/accessory/storage/modular_pouch/large
|
||||
)
|
||||
|
||||
/obj/item/clothing/accessory/armor_plate
|
||||
@@ -183,6 +194,31 @@
|
||||
item_state = "plate_blue"
|
||||
slowdown = 0 // the SCC is hacking
|
||||
|
||||
/obj/item/clothing/accessory/storage/modular_pouch
|
||||
name = "plate carrier pouches"
|
||||
desc = "A comfortable set of pouches that can be attached to a plate carrier, allowing the wearer to store some small items."
|
||||
icon = 'icons/clothing/kit/modular_armor.dmi'
|
||||
icon_state = "modular_pouch"
|
||||
item_state = "modular_pouch"
|
||||
contained_sprite = TRUE
|
||||
slot = ACCESSORY_SLOT_ARMOR_POCKETS
|
||||
slots = 2
|
||||
|
||||
/obj/item/clothing/accessory/storage/modular_pouch/large
|
||||
name = "large plate carrier pouches"
|
||||
desc = "A comfortable set of pouches that can be attached to a plate carrier, allowing the wearer to store some small items. This one uses advanced sewing techniques for additional storage capacity."
|
||||
slots = 3
|
||||
|
||||
/obj/item/clothing/accessory/holster/modular
|
||||
name = "plate carrier holster"
|
||||
desc = "A special holster with rigging able to attach to modern modular plate carriers."
|
||||
icon = 'icons/clothing/kit/modular_armor.dmi'
|
||||
icon_state = "modular_holster"
|
||||
item_state = "modular_holster"
|
||||
contained_sprite = TRUE
|
||||
slot = ACCESSORY_SLOT_ARMOR_POCKETS
|
||||
flippable = FALSE
|
||||
|
||||
/obj/item/clothing/accessory/armor_plate/heavy/sec
|
||||
name = "heavy corporate armor plate"
|
||||
desc = "A heavy and stylish armor plate with blue highlights. That prevents teamkills, right?"
|
||||
|
||||
@@ -64,13 +64,6 @@
|
||||
icon_state = "[initial(icon_state)][opened ? "_open" : ""]"
|
||||
item_state = icon_state
|
||||
|
||||
/obj/item/clothing/suit/armor/carrier/heavy/Initialize()
|
||||
. = ..()
|
||||
pockets = new/obj/item/storage/internal(src)
|
||||
pockets.storage_slots = 4
|
||||
pockets.max_w_class = ITEMSIZE_SMALL
|
||||
pockets.max_storage_space = 8
|
||||
|
||||
/obj/item/clothing/suit/storage/vest/hos/Initialize()
|
||||
. = ..()
|
||||
pockets = new/obj/item/storage/internal(src)
|
||||
|
||||
@@ -648,6 +648,14 @@
|
||||
slot_flags = SLOT_TIE
|
||||
w_class = ITEMSIZE_TINY
|
||||
|
||||
/obj/item/clothing/accessory/ribbon
|
||||
name = "ribbon"
|
||||
desc = "A small ribbon to commemorate or support a cause."
|
||||
icon_state = "ribbon"
|
||||
item_state = "ribbon"
|
||||
slot_flags = SLOT_TIE
|
||||
w_class = ITEMSIZE_TINY
|
||||
|
||||
/obj/item/clothing/accessory/sleevepatch
|
||||
name = "sleeve patch"
|
||||
desc = "An embroidered patch which can be attached to the shoulder sleeve of clothing."
|
||||
|
||||
@@ -8,11 +8,17 @@
|
||||
var/sound_out = 'sound/weapons/holster/holsterout.ogg'
|
||||
flippable = 1
|
||||
w_class = ITEMSIZE_NORMAL
|
||||
var/base_name = ""
|
||||
|
||||
/obj/item/clothing/accessory/holster/Initialize()
|
||||
. = ..()
|
||||
base_name = name
|
||||
AddComponent(/datum/component/base_name, name)
|
||||
|
||||
/obj/item/clothing/accessory/holster/proc/update_name(var/base_name = initial(name))
|
||||
SEND_SIGNAL(src, COMSIG_BASENAME_SETNAME, args)
|
||||
if(holstered)
|
||||
name = "occupied [base_name]"
|
||||
else
|
||||
name = "[base_name]"
|
||||
|
||||
/obj/item/clothing/accessory/holster/proc/holster(var/obj/item/I, var/mob/living/user)
|
||||
if(holstered && istype(user))
|
||||
@@ -33,11 +39,11 @@
|
||||
holstered.add_fingerprint(user)
|
||||
w_class = max(w_class, holstered.w_class)
|
||||
user.visible_message("<span class='notice'>[user] holsters \the [holstered].</span>", "<span class='notice'>You holster \the [holstered].</span>")
|
||||
name = "occupied [base_name]"
|
||||
update_name()
|
||||
|
||||
/obj/item/clothing/accessory/holster/proc/clear_holster()
|
||||
holstered = null
|
||||
name = base_name
|
||||
update_name()
|
||||
|
||||
/obj/item/clothing/accessory/holster/proc/unholster(mob/user as mob)
|
||||
if(!holstered)
|
||||
@@ -111,13 +117,13 @@
|
||||
|
||||
//can't we just use src here?
|
||||
var/obj/item/clothing/accessory/holster/H = null
|
||||
if (istype(src, /obj/item/clothing/accessory/holster))
|
||||
if(istype(src, /obj/item/clothing/accessory/holster))
|
||||
H = src
|
||||
else if (istype(src, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/S = src
|
||||
if (LAZYLEN(S.accessories))
|
||||
if(!H && istype(src, /obj/item/clothing))
|
||||
var/obj/item/clothing/S = src
|
||||
if(LAZYLEN(S.accessories))
|
||||
H = locate() in S.accessories
|
||||
else if (istype(src, /obj/item/clothing/suit/armor/tactical)) // This armor is a snowflake and has an integrated holster.
|
||||
if(!H && istype(src, /obj/item/clothing/suit/armor/tactical)) // This armor is a snowflake and has an integrated holster.
|
||||
var/obj/item/clothing/suit/armor/tactical/tacticool = src
|
||||
H = tacticool.holster
|
||||
|
||||
|
||||
@@ -132,6 +132,12 @@
|
||||
icon_state = "dressshirtvneck_alt"
|
||||
item_state = "dressshirtvneck_alt"
|
||||
|
||||
/obj/item/clothing/accessory/dressshirt/deepv
|
||||
name = "deep v-neck dress shirt"
|
||||
desc = "A casual dress shirt with a deep neckline."
|
||||
icon_state = "dressshirt_deepv"
|
||||
item_state = "dressshirt_deepv"
|
||||
|
||||
/obj/item/clothing/accessory/dressshirt/crop
|
||||
name = "cropped dress shirt"
|
||||
desc = "A casual cropped dress shirt."
|
||||
@@ -153,10 +159,16 @@
|
||||
|
||||
/obj/item/clothing/accessory/dressshirt/alt/vneck/rolled
|
||||
name = "v-neck dress shirt"
|
||||
desc = "A casual dress shirt."
|
||||
desc = "A casual dress shirt. This one has its sleeves rolled up."
|
||||
icon_state = "dressshirtvneck_alt_r"
|
||||
item_state = "dressshirtvneck_alt_r"
|
||||
|
||||
/obj/item/clothing/accessory/dressshirt/deepv/rolled
|
||||
name = "deep v-neck dress shirt"
|
||||
desc = "A casual dress shirt with a deep neckline. This one has its sleeves rolled up."
|
||||
icon_state = "dressshirt_deepv_r"
|
||||
item_state = "dressshirt_deepv_r"
|
||||
|
||||
/obj/item/clothing/accessory/dressshirt/crop/rolled
|
||||
name = "cropped dress shirt"
|
||||
desc = "A casual cropped dress shirt. This one has its sleeves rolled up"
|
||||
@@ -269,3 +281,29 @@
|
||||
if(prob(50))
|
||||
icon_state = "hawaii_red"
|
||||
color = color_rotation(rand(-11,12)*15)
|
||||
|
||||
/obj/item/clothing/accessory/university
|
||||
name = "university sweatshirt"
|
||||
desc = "A comfy university sweatshirt. This one is grey."
|
||||
icon_state = "usweatshirt_grey"
|
||||
item_state = "usweatshirt_grey"
|
||||
|
||||
/obj/item/clothing/accessory/university/red
|
||||
desc = "A comfy university sweatshirt. This one is crimson."
|
||||
icon_state = "usweatshirt_red"
|
||||
item_state = "usweatshirt_red"
|
||||
|
||||
/obj/item/clothing/accessory/university/yellow
|
||||
desc = "A comfy university sweatshirt. This one is mustard."
|
||||
icon_state = "usweatshirt_yellow"
|
||||
item_state = "usweatshirt_yellow"
|
||||
|
||||
/obj/item/clothing/accessory/university/blue
|
||||
desc = "A comfy university sweatshirt. This one is navy."
|
||||
icon_state = "usweatshirt_blue"
|
||||
item_state = "usweatshirt_blue"
|
||||
|
||||
/obj/item/clothing/accessory/university/black
|
||||
desc = "A comfy university sweatshirt. This one is black."
|
||||
icon_state = "usweatshirt_black"
|
||||
item_state = "usweatshirt_black"
|
||||
@@ -52,8 +52,8 @@
|
||||
|
||||
if(wired && screwed)
|
||||
to_chat(usr, "You check your watch, spotting a digital collection of numbers reading '[worldtime2text()]'. Today's date is '[time2text(world.time, "Month DD")]. [game_year]'.")
|
||||
if (emergency_shuttle.get_status_panel_eta())
|
||||
to_chat(usr, SPAN_WARNING("The shuttle's status is reported as: [emergency_shuttle.get_status_panel_eta()]."))
|
||||
if (evacuation_controller.get_status_panel_eta())
|
||||
to_chat(usr, SPAN_WARNING("The shuttle's status is reported as: [evacuation_controller.get_status_panel_eta()]."))
|
||||
else if(wired && !screwed)
|
||||
to_chat(usr, "You check your watch, realising it's still open.")
|
||||
else
|
||||
|
||||
@@ -2133,4 +2133,42 @@ All custom items with worn sprites must follow the contained sprite system: http
|
||||
closed_desc = " The pages within are a mix of clearly indexed case files, and study notes alongside less clearly indexed pages that appears to be fragmented thoughts, not unlike a diary. The very first page of the journal reads “dedicated to Qirandri Mrorirhaldarr” and is signed “Mrradar Sanufar” underneath."
|
||||
icon = 'icons/obj/custom_items/kathira_journal.dmi'
|
||||
icon_state = "kath_journal"
|
||||
item_state = "kath_journal"
|
||||
item_state = "kath_journal"
|
||||
|
||||
/obj/item/storage/pill_bottle/dice/fluff/suraya_dicebag //Crevan Dice Bag - Suraya Al-Zahrani - Omicega
|
||||
name = "velvet dice bag"
|
||||
desc = "A deep purple dice bag fashioned from Adhomian velvet, with two little drawstrings to tighten the neck closed."
|
||||
icon = 'icons/obj/custom_items/suraya_dice.dmi'
|
||||
icon_state = "sur_dbag"
|
||||
item_state = "sur_dbag"
|
||||
|
||||
starts_with = list(
|
||||
/obj/item/dice/fluff/suraya_dice = 3,
|
||||
/obj/item/dice/fluff/suraya_dice/alt = 3
|
||||
)
|
||||
|
||||
/obj/item/dice/fluff/suraya_dice
|
||||
name = "blue adhomian die"
|
||||
desc = "A blue-and-gold wooden die with six sides, beautifully carved and delicately painted. The single dot on the number one side is, on closer inspection, a miniature image of the god Rredouane."
|
||||
icon = 'icons/obj/custom_items/suraya_dice.dmi'
|
||||
icon_state = "sur_b_d1"
|
||||
base_icon = "sur_b_d"
|
||||
favored_number = 1
|
||||
weighted_value = 22
|
||||
|
||||
/obj/item/dice/fluff/suraya_dice/AltClick(mob/user)
|
||||
weighted = !weighted
|
||||
|
||||
if(!weighted)
|
||||
to_chat(user, SPAN_NOTICE("You jiggle the die rapidly in your hand, resetting the internal weighting."))
|
||||
else
|
||||
to_chat(user, SPAN_NOTICE("You carefully jiggle the die one way, then the other, allowing its internal weighting to lock into place."))
|
||||
|
||||
user.visible_message("<b>\The [user]</b> jiggles \the [src] around in their hand for a second.")
|
||||
|
||||
/obj/item/dice/fluff/suraya_dice/alt
|
||||
name = "green adhomian die"
|
||||
desc = "A green-and-silver wooden die with six sides, beautifully carved and delicately painted. The single dot on the number one side is, on closer inspection, a miniature image of the god Rredouane."
|
||||
icon_state = "sur_g_d1"
|
||||
base_icon = "sur_g_d"
|
||||
favored_number = 6
|
||||
@@ -9,11 +9,10 @@
|
||||
w_class = ITEMSIZE_SMALL
|
||||
var/obj/item/stored_item = null
|
||||
var/label_text = ""
|
||||
var/base_name = ""
|
||||
|
||||
/obj/item/evidencebag/Initialize()
|
||||
. = ..()
|
||||
base_name = name
|
||||
AddComponent(/datum/component/base_name, name)
|
||||
|
||||
/obj/item/evidencebag/MouseDrop(var/obj/item/I as obj)
|
||||
if (!ishuman(usr))
|
||||
@@ -111,7 +110,8 @@
|
||||
return
|
||||
. = ..()
|
||||
|
||||
/obj/item/evidencebag/proc/update_name_label()
|
||||
/obj/item/evidencebag/proc/update_name_label(var/base_name = initial(name))
|
||||
SEND_SIGNAL(src, COMSIG_BASENAME_SETNAME, args)
|
||||
if(label_text == "")
|
||||
name = base_name
|
||||
else
|
||||
|
||||
@@ -64,7 +64,8 @@
|
||||
update_name()
|
||||
update_icon()
|
||||
|
||||
/obj/item/reagent_containers/glass/rag/proc/update_name()
|
||||
/obj/item/reagent_containers/glass/rag/proc/update_name(var/base_name = initial(name))
|
||||
SEND_SIGNAL(src, COMSIG_BASENAME_SETNAME, args)
|
||||
if(on_fire)
|
||||
name = "burning [base_name]"
|
||||
else if(reagents.total_volume)
|
||||
@@ -107,7 +108,7 @@
|
||||
|
||||
/obj/item/reagent_containers/glass/rag/proc/wipe_down(atom/A, mob/user)
|
||||
if(!reagents.total_volume)
|
||||
to_chat(user, SPAN_WARNING("\The [base_name] is dry!"))
|
||||
to_chat(user, SPAN_WARNING("\The [name] is dry!"))
|
||||
else
|
||||
if (!(last_clean && world.time < last_clean + 120) )
|
||||
user.visible_message("<b>[user]</b> starts to wipe [A] with [src].")
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
var/grill_path = /obj/structure/grille
|
||||
var/spawn_firedoor = FALSE
|
||||
var/activated
|
||||
var/single_window = FALSE
|
||||
|
||||
// stops ZAS expanding zones past us, the windows will block the zone anyway
|
||||
/obj/effect/map_effect/wingrille_spawn/CanPass()
|
||||
@@ -37,23 +38,26 @@
|
||||
if (!locate(grill_path) in get_turf(src))
|
||||
var/obj/structure/grille/G = new grill_path(src.loc)
|
||||
handle_grille_spawn(G)
|
||||
var/list/neighbours = list()
|
||||
for (var/dir in cardinal)
|
||||
var/turf/T = get_step(src, dir)
|
||||
var/obj/effect/map_effect/wingrille_spawn/other = locate(/obj/effect/map_effect/wingrille_spawn) in T
|
||||
if(!other)
|
||||
var/found_connection
|
||||
if(locate(grill_path) in T)
|
||||
for(var/obj/structure/window/W in T)
|
||||
if(W.type == win_path && W.dir == get_dir(T,src))
|
||||
found_connection = 1
|
||||
qdel(W)
|
||||
if(!found_connection)
|
||||
var/obj/structure/window/new_win = new win_path(src.loc)
|
||||
new_win.set_dir(dir)
|
||||
handle_window_spawn(new_win)
|
||||
else
|
||||
neighbours |= other
|
||||
if(!single_window)
|
||||
var/list/neighbours = list()
|
||||
for (var/dir in cardinal)
|
||||
var/turf/T = get_step(src, dir)
|
||||
var/obj/effect/map_effect/wingrille_spawn/other = locate(/obj/effect/map_effect/wingrille_spawn) in T
|
||||
if(!other)
|
||||
var/found_connection
|
||||
if(locate(grill_path) in T)
|
||||
for(var/obj/structure/window/W in T)
|
||||
if(W.type == win_path && W.dir == get_dir(T,src))
|
||||
found_connection = 1
|
||||
qdel(W)
|
||||
if(!found_connection)
|
||||
var/obj/structure/window/new_win = new win_path(src.loc)
|
||||
new_win.set_dir(dir)
|
||||
handle_window_spawn(new_win)
|
||||
else
|
||||
neighbours |= other
|
||||
else
|
||||
new win_path(loc)
|
||||
activated = 1
|
||||
|
||||
/obj/effect/map_effect/wingrille_spawn/proc/handle_window_spawn(var/obj/structure/window/W)
|
||||
@@ -97,4 +101,23 @@
|
||||
|
||||
/obj/effect/map_effect/wingrille_spawn/reinforced/polarized/handle_window_spawn(var/obj/structure/window/reinforced/polarized/P)
|
||||
if(id)
|
||||
P.id = id
|
||||
P.id = id
|
||||
|
||||
/obj/effect/map_effect/wingrille_spawn/full
|
||||
name = "full window grille spawner"
|
||||
icon_state = "full_window"
|
||||
win_path = /obj/structure/window/full
|
||||
grill_path = /obj/structure/grille
|
||||
spawn_firedoor = TRUE
|
||||
single_window = TRUE
|
||||
|
||||
/obj/effect/map_effect/wingrille_spawn/full/phoron
|
||||
icon_state = "full_phoron_window"
|
||||
win_path = /obj/structure/window/full/phoron
|
||||
single_window = TRUE
|
||||
|
||||
/obj/effect/map_effect/wingrille_spawn/reinforced/polarized/full
|
||||
name = "full polarized window grille spawner"
|
||||
icon_state = "full_window"
|
||||
win_path = /obj/structure/window/reinforced/polarized/full
|
||||
single_window = TRUE
|
||||
@@ -172,6 +172,7 @@
|
||||
disable()
|
||||
if(welcome_message)
|
||||
to_chat(user, SPAN_NOTICE(welcome_message))
|
||||
universe.OnPlayerLatejoin(user)
|
||||
return TRUE
|
||||
|
||||
//Proc to check if a specific user can edit this spawner (open/close/...)
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
if(start_location.landmark_tag != "nav_emergency_start")
|
||||
return TRUE
|
||||
|
||||
if(emergency_shuttle.evac)
|
||||
if(evacuation_controller.emergency_evacuation)
|
||||
if(get_security_level() != "green" )
|
||||
var/datum/wifi/sender/door/wifi_sender = new("odin_arrivals_lockdown", SSghostroles)
|
||||
wifi_sender.activate("close")
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
//Vars related to human mobs
|
||||
outfit = /datum/outfit/admin/random/visitor
|
||||
possible_species = list(SPECIES_HUMAN, SPECIES_SKRELL, SPECIES_TAJARA, SPECIES_UNATHI)
|
||||
possible_species = list(SPECIES_HUMAN, SPECIES_HUMAN_OFFWORLD, SPECIES_TAJARA, SPECIES_TAJARA_MSAI, SPECIES_TAJARA_ZHAN, SPECIES_SKRELL, SPECIES_UNATHI, SPECIES_VAURCA_WARRIOR, SPECIES_VAURCA_WORKER, SPECIES_IPC, SPECIES_IPC_XION, SPECIES_IPC_ZENGHU, SPECIES_IPC_BISHOP, SPECIES_IPC_SHELL, SPECIES_IPC_G1, SPECIES_IPC_G2)
|
||||
allow_appearance_change = APPEARANCE_PLASTICSURGERY
|
||||
|
||||
assigned_role = "Visitor"
|
||||
|
||||
@@ -475,6 +475,8 @@
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/penguin/holodeck/baby
|
||||
name = "baby penguin"
|
||||
desc = "Can't fly and barely waddles, yet the prince of all chicks."
|
||||
icon_state = "penguin_baby"
|
||||
icon_living = "penguin_baby"
|
||||
icon_dead = "penguin_baby_dead"
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
seed_name = "green grape"
|
||||
display_name = "green grapevines"
|
||||
mutants = null
|
||||
chems = list(/decl/reagent/nutriment = list(1,10), /decl/reagent/kelotane = list(3,5), /decl/reagent/drink/grapejuice = list(10,10))
|
||||
chems = list(/decl/reagent/nutriment = list(1,10), /decl/reagent/kelotane = list(3,5), /decl/reagent/drink/whitegrapejuice = list(10,10))
|
||||
|
||||
/datum/seed/grapes/green/setup_traits()
|
||||
..()
|
||||
@@ -375,3 +375,27 @@
|
||||
|
||||
/obj/item/seeds/pumpkinseed
|
||||
seed_type = "pumpkin"
|
||||
|
||||
|
||||
//coffee beans are considered a fruit and seed, commonly considered a "cherry" of the plant
|
||||
/datum/seed/coffee
|
||||
name = "coffee"
|
||||
seed_name = "coffee beans"
|
||||
display_name = "coffee bush"
|
||||
chems = list(/decl/reagent/nutriment/coffeegrounds = list(2,10))
|
||||
kitchen_tag = "coffee"
|
||||
|
||||
/datum/seed/coffee/setup_traits()
|
||||
..()
|
||||
set_trait(TRAIT_HARVEST_REPEAT,1)
|
||||
set_trait(TRAIT_MATURATION,3)
|
||||
set_trait(TRAIT_PRODUCTION,3)
|
||||
set_trait(TRAIT_YIELD,4)
|
||||
set_trait(TRAIT_POTENCY,2)
|
||||
set_trait(TRAIT_PRODUCT_ICON,"bean2")
|
||||
set_trait(TRAIT_PRODUCT_COLOUR,"#be9109")
|
||||
set_trait(TRAIT_PLANT_ICON,"bush2")
|
||||
set_trait(TRAIT_IDEAL_LIGHT, 6)
|
||||
|
||||
/obj/item/seeds/coffeeseed
|
||||
seed_type = "coffee"
|
||||
@@ -0,0 +1,44 @@
|
||||
/datum/seed/mint
|
||||
name = "mint"
|
||||
seed_name = "mint leaf"
|
||||
display_name = "mint plant"
|
||||
chems = list(/decl/reagent/nutriment/mint = list(2,10))
|
||||
kitchen_tag = "mint"
|
||||
|
||||
//I wasnt sure if tea and mint would be a flower or something, so i just made a herb file..
|
||||
|
||||
/datum/seed/mint/setup_traits()
|
||||
..()
|
||||
set_trait(TRAIT_MATURATION,3)
|
||||
set_trait(TRAIT_PRODUCTION,3)
|
||||
set_trait(TRAIT_YIELD,3)
|
||||
set_trait(TRAIT_POTENCY,2)
|
||||
set_trait(TRAIT_PRODUCT_ICON,"herb")
|
||||
set_trait(TRAIT_PRODUCT_COLOUR,"#4dd298")
|
||||
set_trait(TRAIT_PLANT_ICON,"herb")
|
||||
set_trait(TRAIT_IDEAL_LIGHT, 6)
|
||||
|
||||
/obj/item/seeds/mintseed
|
||||
seed_type = "mint"
|
||||
|
||||
|
||||
/datum/seed/tea
|
||||
name = "tea"
|
||||
seed_name = "tea leaf"
|
||||
display_name = "tea plant"
|
||||
chems = list(/decl/reagent/nutriment/teagrounds = list(2,10))
|
||||
kitchen_tag = "tea"
|
||||
|
||||
/datum/seed/tea/setup_traits()
|
||||
..()
|
||||
set_trait(TRAIT_MATURATION,3)
|
||||
set_trait(TRAIT_PRODUCTION,3)
|
||||
set_trait(TRAIT_YIELD,3)
|
||||
set_trait(TRAIT_POTENCY,2)
|
||||
set_trait(TRAIT_PRODUCT_ICON,"herb")
|
||||
set_trait(TRAIT_PRODUCT_COLOUR,"#4fd24d")
|
||||
set_trait(TRAIT_PLANT_ICON,"herb")
|
||||
set_trait(TRAIT_IDEAL_LIGHT, 6)
|
||||
|
||||
/obj/item/seeds/teaseed
|
||||
seed_type = "tea"
|
||||
@@ -52,6 +52,7 @@
|
||||
/obj/item/seeds/cherryseed = 3,
|
||||
/obj/item/seeds/chiliseed = 3,
|
||||
/obj/item/seeds/cocoapodseed = 3,
|
||||
/obj/item/seeds/coffeeseed = 3,
|
||||
/obj/item/seeds/cornseed = 3,
|
||||
/obj/item/seeds/dynseed = 3,
|
||||
/obj/item/seeds/earthenroot = 2,
|
||||
@@ -64,6 +65,7 @@
|
||||
/obj/item/seeds/lemonseed = 3,
|
||||
/obj/item/seeds/limeseed = 3,
|
||||
/obj/item/seeds/mtearseed = 2,
|
||||
/obj/item/seeds/mintseed = 3,
|
||||
/obj/item/seeds/nifberries = 2,
|
||||
/obj/item/seeds/onionseed = 3,
|
||||
/obj/item/seeds/orangeseed = 3,
|
||||
@@ -84,6 +86,7 @@
|
||||
/obj/item/seeds/sugarcaneseed = 3,
|
||||
/obj/item/seeds/sugartree = 2,
|
||||
/obj/item/seeds/sunflowerseed = 3,
|
||||
/obj/item/seeds/teaseed = 3,
|
||||
/obj/item/seeds/tobaccoseed = 3,
|
||||
/obj/item/seeds/tomatoseed = 3,
|
||||
/obj/item/seeds/towermycelium = 3,
|
||||
@@ -115,6 +118,7 @@
|
||||
/obj/item/seeds/cherryseed = 3,
|
||||
/obj/item/seeds/chiliseed = 3,
|
||||
/obj/item/seeds/cocoapodseed = 3,
|
||||
/obj/item/seeds/coffeeseed = 3,
|
||||
/obj/item/seeds/cornseed = 3,
|
||||
/obj/item/seeds/replicapod = 3,
|
||||
/obj/item/seeds/earthenroot = 2,
|
||||
@@ -128,6 +132,7 @@
|
||||
/obj/item/seeds/libertymycelium = 2,
|
||||
/obj/item/seeds/limeseed = 3,
|
||||
/obj/item/seeds/mtearseed = 2,
|
||||
/obj/item/seeds/mintseed = 3,
|
||||
/obj/item/seeds/nettleseed = 2,
|
||||
/obj/item/seeds/nifberries = 2,
|
||||
/obj/item/seeds/onionseed = 3,
|
||||
@@ -146,6 +151,7 @@
|
||||
/obj/item/seeds/sunflowerseed = 3,
|
||||
/obj/item/seeds/sugartree = 2,
|
||||
/obj/item/seeds/shandseed = 2,
|
||||
/obj/item/seeds/teaseed = 3,
|
||||
/obj/item/seeds/tobaccoseed = 3,
|
||||
/obj/item/seeds/tomatoseed = 3,
|
||||
/obj/item/seeds/towermycelium = 3,
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
new /datum/stack_recipe("metal rod", /obj/item/stack/rods, 1, 2, 60),
|
||||
new /datum/stack_recipe("table frame", /obj/structure/table, BUILD_AMT, time = 10, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe("wall girders", /obj/structure/girder, BUILD_AMT, time = 50, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe("window frame", /obj/structure/window_frame, BUILD_AMT, time = 10, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe("computer frame", /obj/structure/computerframe, BUILD_AMT, time = 25, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe("machine blueprint", /obj/machinery/constructable_frame/machine_frame, 2, time = 25, one_per_turf = 1, on_floor = 1),
|
||||
new /datum/stack_recipe("light fixture frame", /obj/item/frame/light, 2),
|
||||
|
||||
@@ -81,7 +81,11 @@
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/mineral/processing_unit_console/proc/get_user_id(var/mob/user)
|
||||
if(!scanned_id && !isDrone(user))
|
||||
if(isDrone(user))
|
||||
var/mob/living/silicon/robot/drone/D = user
|
||||
if(D.standard_drone)
|
||||
return
|
||||
if(!scanned_id)
|
||||
var/obj/item/card/id/ID = user.GetIdCard()
|
||||
if(ID)
|
||||
scanned_id = WEAKREF(ID)
|
||||
|
||||
@@ -118,7 +118,11 @@ var/global/list/minevendor_list = list( //keep in order of price
|
||||
interact(user)
|
||||
|
||||
/obj/machinery/mineral/equipment_vendor/proc/get_user_id(var/mob/user)
|
||||
if(!scanned_id && !isDrone(user))
|
||||
if(isDrone(user))
|
||||
var/mob/living/silicon/robot/drone/D = user
|
||||
if(D.standard_drone)
|
||||
return
|
||||
if(!scanned_id)
|
||||
var/obj/item/card/id/ID = user.GetIdCard()
|
||||
if(ID)
|
||||
scanned_id = WEAKREF(ID)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
speed = -1
|
||||
hat_x_offset = 1
|
||||
hat_y_offset = -12
|
||||
standard_drone = FALSE
|
||||
var/seeking_player = FALSE
|
||||
var/health_upgrade
|
||||
var/ranged_upgrade
|
||||
@@ -23,10 +24,6 @@
|
||||
. = ..()
|
||||
|
||||
verbs |= /mob/living/proc/hide
|
||||
remove_language(LANGUAGE_ROBOT)
|
||||
remove_language(LANGUAGE_DRONE)
|
||||
add_language(LANGUAGE_TCB, TRUE)
|
||||
add_language(LANGUAGE_EAL, TRUE)
|
||||
|
||||
//They are unable to be upgraded, so let's give them a bit of a better battery.
|
||||
cell.maxcharge = 10000
|
||||
|
||||
@@ -279,6 +279,7 @@ INITIALIZE_IMMEDIATE(/mob/abstract/new_player)
|
||||
character.buckled_to.set_dir(character.dir)
|
||||
|
||||
SSticker.mode.handle_latejoin(character)
|
||||
universe.OnPlayerLatejoin(character)
|
||||
if(SSjobs.ShouldCreateRecords(character.mind))
|
||||
if(character.mind.assigned_role != "Cyborg")
|
||||
SSrecords.generate_record(character)
|
||||
|
||||
@@ -1733,7 +1733,8 @@ Follow by example and make good judgement based on length which list to include
|
||||
/datum/sprite_accessory/hair_gradients
|
||||
icon = 'icons/mob/hair_gradients.dmi'
|
||||
species_allowed = list(/datum/species/human,/datum/species/human/offworlder,/datum/species/machine/shell,/datum/species/machine/shell/rogue,/datum/species/zombie,
|
||||
/datum/species/tajaran,/datum/species/tajaran/zhan_khazan,/datum/species/tajaran/m_sai,/datum/species/zombie/tajara)
|
||||
/datum/species/tajaran,/datum/species/tajaran/zhan_khazan,/datum/species/tajaran/m_sai,/datum/species/zombie/tajara,
|
||||
/datum/species/skrell, /datum/species/zombie/skrell, /datum/species/bug, /datum/species/bug/type_b)
|
||||
|
||||
none
|
||||
name = "None"
|
||||
@@ -2506,6 +2507,24 @@ Follow by example and make good judgement based on length which list to include
|
||||
length = 3
|
||||
chatname = "styled mane"
|
||||
|
||||
taj_ears_swoop
|
||||
name = "Tajara Swoop"
|
||||
icon_state = "hair_swoop"
|
||||
length = 2
|
||||
chatname = "styled mane"
|
||||
|
||||
taj_ears_swoop_long
|
||||
name = "Tajara Swoop Long"
|
||||
icon_state = "hair_longswoop"
|
||||
length = 3
|
||||
chatname = "styled mane"
|
||||
|
||||
taj_ears_swoop_long_alt
|
||||
name = "Tajara Swoop Long Alt"
|
||||
icon_state = "hair_longswoop_alt"
|
||||
length = 3
|
||||
chatname = "styled mane"
|
||||
|
||||
//msai hair, longer ears
|
||||
msai_ears
|
||||
icon = 'icons/mob/human_face/msai_hair.dmi'
|
||||
@@ -2749,6 +2768,24 @@ Follow by example and make good judgement based on length which list to include
|
||||
length = 3
|
||||
chatname = "styled mane"
|
||||
|
||||
msai_ears_swoop
|
||||
name = "M'sai Swoop"
|
||||
icon_state = "msai_swoop"
|
||||
length = 2
|
||||
chatname = "styled mane"
|
||||
|
||||
msai_ears_swoop_long
|
||||
name = "M'sai Swoop Long"
|
||||
icon_state = "msai_longswoop"
|
||||
length = 3
|
||||
chatname = "styled mane"
|
||||
|
||||
msai_ears_swoop_long_alt
|
||||
name = "M'sai Swoop Long Alt"
|
||||
icon_state = "msai_longswoop_alt"
|
||||
length = 3
|
||||
chatname = "styled mane"
|
||||
|
||||
//vaurca antennae
|
||||
vaurca_classic
|
||||
icon = 'icons/mob/human_face/vaurca_hair.dmi'
|
||||
@@ -3271,6 +3308,61 @@ Follow by example and make good judgement based on length which list to include
|
||||
name = "Glorp"
|
||||
icon_state = "glorp"
|
||||
|
||||
anglerfish
|
||||
icon = 'icons/mob/human_face/skrell_beards.dmi'
|
||||
name = "Anglerfish"
|
||||
icon_state = "Anglerfish"
|
||||
species_allowed = list(/datum/species/skrell)
|
||||
gender = NEUTER
|
||||
|
||||
triton
|
||||
name = "Triton"
|
||||
icon_state = "Triton"
|
||||
|
||||
big_triton
|
||||
name = "Big Triton"
|
||||
icon_state = "Big_Triton"
|
||||
|
||||
ahab
|
||||
name = "Ahab"
|
||||
icon_state = "Ahab"
|
||||
|
||||
monotail
|
||||
name = "Monotail"
|
||||
icon_state = "Monotail"
|
||||
|
||||
long_monotail
|
||||
name = "Long Monotail"
|
||||
icon_state = "Long_Monotail"
|
||||
|
||||
face_adorns
|
||||
name = "Face Adorns"
|
||||
icon_state = "Face_Adorns"
|
||||
|
||||
sea_captain
|
||||
name = "Sea Captain"
|
||||
icon_state = "Sea_Captain"
|
||||
|
||||
fisherman
|
||||
name = "Fisherman"
|
||||
icon_state = "Fisherman"
|
||||
|
||||
sailor
|
||||
name = "Sailor"
|
||||
icon_state = "Sailor"
|
||||
|
||||
overgrown
|
||||
name = "Overgrown"
|
||||
icon_state = "Overgrown"
|
||||
|
||||
marauder_left
|
||||
name = "Marauder (Left)"
|
||||
icon_state = "Marauder_Left"
|
||||
|
||||
marauder_right
|
||||
name = "Marauder (Right)"
|
||||
icon_state = "Marauder_Right"
|
||||
|
||||
/*
|
||||
////////////////////////////
|
||||
/ =--------------------= /
|
||||
@@ -3710,6 +3802,24 @@ Follow by example and make good judgement based on length which list to include
|
||||
body_parts = list(BP_HEAD)
|
||||
species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/bug, /datum/species/bug/type_b)
|
||||
|
||||
scar_chest
|
||||
name = "Scar, Chest"
|
||||
icon_state = "surgicalscar_chest"
|
||||
body_parts = list(BP_CHEST)
|
||||
species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, /datum/species/bug, /datum/species/bug/type_b)
|
||||
|
||||
scar_chest_left
|
||||
name = "Scar, Chest Left"
|
||||
icon_state = "chestscar_l_chest"
|
||||
body_parts = list(BP_CHEST)
|
||||
species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, /datum/species/bug, /datum/species/bug/type_b)
|
||||
|
||||
scar_chest_right
|
||||
name = "Scar, Chest Right"
|
||||
icon_state = "chestscar_r_chest"
|
||||
body_parts = list(BP_CHEST)
|
||||
species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi, /datum/species/bug, /datum/species/bug/type_b)
|
||||
|
||||
scratch_abdomen_left
|
||||
name = "Scratch, Abdomen Left"
|
||||
icon_state = "scratch_abdomen_l"
|
||||
@@ -3782,6 +3892,18 @@ Follow by example and make good judgement based on length which list to include
|
||||
body_parts= list(BP_R_LEG)
|
||||
species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
|
||||
|
||||
tat_circle_back
|
||||
name = "Tattoo (Circle, Back)"
|
||||
icon_state = "tat_circle_back"
|
||||
body_parts = list(BP_CHEST)
|
||||
species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
|
||||
|
||||
tat_circle_big_back
|
||||
name = "Tattoo (Big Circle, Back)"
|
||||
icon_state = "tat_bigcircle_back"
|
||||
body_parts = list(BP_CHEST)
|
||||
species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
|
||||
|
||||
tat_forrest_left
|
||||
name = "Tattoo (Forrest, Left Eye)"
|
||||
icon_state = "tat_forrest_l"
|
||||
@@ -3794,6 +3916,12 @@ Follow by example and make good judgement based on length which list to include
|
||||
body_parts = list(BP_HEAD)
|
||||
species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
|
||||
|
||||
tat_harness
|
||||
name = "Tattoo (Harness, Chest)"
|
||||
icon_state = "tat_harness_body"
|
||||
body_parts = list(BP_CHEST)
|
||||
species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
|
||||
|
||||
tat_hive
|
||||
name = "Tattoo (Hive, Back)"
|
||||
icon_state = "tat_hive"
|
||||
@@ -3890,6 +4018,12 @@ Follow by example and make good judgement based on length which list to include
|
||||
body_parts = list(BP_R_LEG)
|
||||
species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
|
||||
|
||||
tat_spine_back
|
||||
name = "Tattoo (Spine, Back)"
|
||||
icon_state = "tat_spine_back"
|
||||
body_parts = list(BP_CHEST)
|
||||
species_allowed = list(/datum/species/human, /datum/species/human/offworlder, /datum/species/diona, /datum/species/machine/shell, /datum/species/skrell, /datum/species/tajaran, /datum/species/tajaran/zhan_khazan, /datum/species/tajaran/m_sai, /datum/species/unathi)
|
||||
|
||||
tat_tamoko
|
||||
name = "Tattoo (Ta Moko, Face)"
|
||||
icon_state = "tat_tamoko"
|
||||
|
||||
@@ -266,8 +266,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
/mob/abstract/observer/Stat()
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
if(emergency_shuttle)
|
||||
var/eta_status = emergency_shuttle.get_status_panel_eta()
|
||||
if(evacuation_controller)
|
||||
var/eta_status = evacuation_controller.get_status_panel_eta()
|
||||
if(eta_status)
|
||||
stat(null, eta_status)
|
||||
|
||||
|
||||
@@ -9,9 +9,13 @@
|
||||
//Or someone snoring. So we make it where they won't hear it.
|
||||
return
|
||||
|
||||
if((language && (language.flags & KNOWONLYHEAR)) && !say_understands(speaker, language))
|
||||
return
|
||||
|
||||
//make sure the air can transmit speech - hearer's side
|
||||
var/turf/T = get_turf(src)
|
||||
if ((T) && (!(isobserver(src)))) //Ghosts can hear even in vacuum.
|
||||
var/vacuum_proof = ((language && (language.flags & PRESSUREPROOF)) || isobserver(src))
|
||||
if(T && !vacuum_proof) //Ghosts can hear even in vacuum.
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
var/pressure = (environment)? environment.return_pressure() : 0
|
||||
if(pressure < SOUND_MINIMUM_PRESSURE && get_dist(speaker, src) > 1)
|
||||
|
||||
@@ -175,6 +175,9 @@
|
||||
chosen_verb = speech_verb
|
||||
return pick(chosen_verb)
|
||||
|
||||
/datum/language/proc/handle_message_mode(var/message_mode)
|
||||
return list(src, message_mode)
|
||||
|
||||
// Language handling.
|
||||
/mob/proc/add_language(var/language)
|
||||
var/datum/language/new_language
|
||||
|
||||
@@ -68,4 +68,18 @@
|
||||
return "1em"
|
||||
|
||||
/mob/living/silicon/robot/drone/construction/matriarch/get_binary_font_size()
|
||||
return "1.2em"
|
||||
return "1.2em"
|
||||
|
||||
/datum/language/local_drone
|
||||
name = LANGUAGE_LOCAL_DRONE
|
||||
desc = "A heavily encoded damage coordination transmission, only supplied to drones within sight."
|
||||
speech_verb = list("transmits")
|
||||
ask_verb = list("transmits")
|
||||
exclaim_verb = list("transmits")
|
||||
key = "do"
|
||||
flags = RESTRICTED | KNOWONLYHEAR | PRESSUREPROOF | PASSLISTENOBJ
|
||||
|
||||
/datum/language/local_drone/handle_message_mode(var/message_mode)
|
||||
if(message_mode == "headset")
|
||||
return list(all_languages[LANGUAGE_DRONE], null)
|
||||
return list(src, null)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user