mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-13 03:33:21 +00:00
Merge branch 'master' into shep-dev-aurora-cooking
This commit is contained in:
19
.travis.yml
19
.travis.yml
@@ -4,13 +4,10 @@ language: c
|
|||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- BASENAME="vorestation" # $BASENAME.dmb, $BASENAME.dme, etc.
|
- BASENAME="vorestation" # $BASENAME.dmb, $BASENAME.dme, etc.
|
||||||
- BYOND_MAJOR="513"
|
|
||||||
- BYOND_MINOR="1520"
|
|
||||||
- MACRO_COUNT=4
|
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
directories:
|
directories:
|
||||||
- $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}
|
- $HOME/BYOND
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
@@ -37,13 +34,17 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- stage: "File Tests" #This is the odd man out, with specific installs and stuff.
|
- stage: "File Tests" #This is the odd man out, with specific installs and stuff.
|
||||||
name: "Validate Files"
|
name: "Validate Files"
|
||||||
install: #Need python for some of the tag matching stuff
|
|
||||||
- pip install --user PyYaml -q
|
|
||||||
- pip install --user beautifulsoup4 -q
|
|
||||||
script: ./tools/travis/validate_files.sh
|
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages: ~ # Don't need any packages for this
|
packages:
|
||||||
|
- python3
|
||||||
|
- python3-pip
|
||||||
|
- python3-setuptools
|
||||||
|
install: #Need python for some of the tag matching stuff
|
||||||
|
- tools/travis/install_build_deps.sh
|
||||||
|
script:
|
||||||
|
- tools/travis/validate_files.sh
|
||||||
|
- tools/travis/build_tgui.sh
|
||||||
- stage: "Unit Tests"
|
- stage: "Unit Tests"
|
||||||
env: TEST_DEFINE="UNIT_TEST" TEST_FILE="code/_unit_tests.dm" RUN="1"
|
env: TEST_DEFINE="UNIT_TEST" TEST_FILE="code/_unit_tests.dm" RUN="1"
|
||||||
name: "Compile normally (unit tests)"
|
name: "Compile normally (unit tests)"
|
||||||
|
|||||||
13
_build_dependencies.sh
Normal file
13
_build_dependencies.sh
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# This file has all the information on what versions of libraries are thrown into the code
|
||||||
|
# For dreamchecker
|
||||||
|
export SPACEMANDMM_TAG=suite-1.4
|
||||||
|
# For NanoUI + TGUI
|
||||||
|
export NODE_VERSION=12
|
||||||
|
# For the scripts in tools
|
||||||
|
export PHP_VERSION=5.6
|
||||||
|
# Byond Major
|
||||||
|
export BYOND_MAJOR=513
|
||||||
|
# Byond Minor
|
||||||
|
export BYOND_MINOR=1526
|
||||||
|
# Macro Count
|
||||||
|
export MACRO_COUNT=4
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#define SPECIES_WHITELIST_SELECTABLE 0x20 // Can select and customize, but not join as
|
#define SPECIES_WHITELIST_SELECTABLE 0x20 // Can select and customize, but not join as
|
||||||
|
|
||||||
|
#define LANGUAGE_DRUDAKAR "D'Rudak'Ar"
|
||||||
#define LANGUAGE_SLAVIC "Pan-Slavic"
|
#define LANGUAGE_SLAVIC "Pan-Slavic"
|
||||||
#define LANGUAGE_BIRDSONG "Birdsong"
|
#define LANGUAGE_BIRDSONG "Birdsong"
|
||||||
#define LANGUAGE_SAGARU "Sagaru"
|
#define LANGUAGE_SAGARU "Sagaru"
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G
|
|||||||
#define FIRE_PRIORITY_TICKER 60
|
#define FIRE_PRIORITY_TICKER 60
|
||||||
#define FIRE_PRIORITY_PLANETS 75
|
#define FIRE_PRIORITY_PLANETS 75
|
||||||
#define FIRE_PRIORITY_MACHINES 100
|
#define FIRE_PRIORITY_MACHINES 100
|
||||||
|
#define FIRE_PRIORITY_TGUI 110
|
||||||
#define FIRE_PRIORITY_PROJECTILES 150
|
#define FIRE_PRIORITY_PROJECTILES 150
|
||||||
#define FIRE_PRIORITY_CHAT 400
|
#define FIRE_PRIORITY_CHAT 400
|
||||||
#define FIRE_PRIORITY_OVERLAYS 500
|
#define FIRE_PRIORITY_OVERLAYS 500
|
||||||
|
|||||||
19
code/__defines/tgui.dm
Normal file
19
code/__defines/tgui.dm
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/// Maximum number of windows that can be suspended/reused
|
||||||
|
#define TGUI_WINDOW_SOFT_LIMIT 5
|
||||||
|
/// Maximum number of open windows
|
||||||
|
#define TGUI_WINDOW_HARD_LIMIT 9
|
||||||
|
|
||||||
|
/// Maximum ping timeout allowed to detect zombie windows
|
||||||
|
#define TGUI_PING_TIMEOUT 4 SECONDS
|
||||||
|
|
||||||
|
/// Window does not exist
|
||||||
|
#define TGUI_WINDOW_CLOSED 0
|
||||||
|
/// Window was just opened, but is still not ready to be sent data
|
||||||
|
#define TGUI_WINDOW_LOADING 1
|
||||||
|
/// Window is free and ready to receive data
|
||||||
|
#define TGUI_WINDOW_READY 2
|
||||||
|
|
||||||
|
/// Get a window id based on the provided pool index
|
||||||
|
#define TGUI_WINDOW_ID(index) "tgui-window-[index]"
|
||||||
|
/// Get a pool index of the provided window id
|
||||||
|
#define TGUI_WINDOW_INDEX(window_id) text2num(copytext(window_id, 13))
|
||||||
@@ -615,4 +615,25 @@ datum/projectile_data
|
|||||||
/proc/window_flash(var/client_or_usr)
|
/proc/window_flash(var/client_or_usr)
|
||||||
if (!client_or_usr)
|
if (!client_or_usr)
|
||||||
return
|
return
|
||||||
winset(client_or_usr, "mainwindow", "flash=5")
|
winset(client_or_usr, "mainwindow", "flash=5")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a bounding box of a list of atoms.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* - atoms - List of atoms. Can accept output of view() and range() procs.
|
||||||
|
*
|
||||||
|
* Returns: list(x1, y1, x2, y2)
|
||||||
|
*/
|
||||||
|
/proc/get_bbox_of_atoms(list/atoms)
|
||||||
|
var/list/list_x = list()
|
||||||
|
var/list/list_y = list()
|
||||||
|
for(var/_a in atoms)
|
||||||
|
var/atom/a = _a
|
||||||
|
list_x += a.x
|
||||||
|
list_y += a.y
|
||||||
|
return list(
|
||||||
|
min(list_x),
|
||||||
|
min(list_y),
|
||||||
|
max(list_x),
|
||||||
|
max(list_y))
|
||||||
@@ -176,6 +176,22 @@
|
|||||||
/proc/log_unit_test(text)
|
/proc/log_unit_test(text)
|
||||||
to_world_log("## UNIT_TEST: [text]")
|
to_world_log("## UNIT_TEST: [text]")
|
||||||
|
|
||||||
|
/proc/log_tgui(user_or_client, text)
|
||||||
|
var/entry = ""
|
||||||
|
if(!user_or_client)
|
||||||
|
entry += "no user"
|
||||||
|
else if(istype(user_or_client, /mob))
|
||||||
|
var/mob/user = user_or_client
|
||||||
|
entry += "[user.ckey] (as [user])"
|
||||||
|
else if(istype(user_or_client, /client))
|
||||||
|
var/client/client = user_or_client
|
||||||
|
entry += "[client.ckey]"
|
||||||
|
entry += ":\n[text]"
|
||||||
|
WRITE_LOG(diary, entry)
|
||||||
|
|
||||||
|
/proc/log_asset(text)
|
||||||
|
WRITE_LOG(diary, "ASSET: [text]")
|
||||||
|
|
||||||
/proc/report_progress(var/progress_message)
|
/proc/report_progress(var/progress_message)
|
||||||
admin_notice("<span class='boldannounce'>[progress_message]</span>", R_DEBUG)
|
admin_notice("<span class='boldannounce'>[progress_message]</span>", R_DEBUG)
|
||||||
to_world_log(progress_message)
|
to_world_log(progress_message)
|
||||||
|
|||||||
@@ -138,6 +138,19 @@
|
|||||||
/proc/sanitize_old(var/t,var/list/repl_chars = list("\n"="#","\t"="#"))
|
/proc/sanitize_old(var/t,var/list/repl_chars = list("\n"="#","\t"="#"))
|
||||||
return html_encode(replace_characters(t,repl_chars))
|
return html_encode(replace_characters(t,repl_chars))
|
||||||
|
|
||||||
|
|
||||||
|
//Removes a few problematic characters
|
||||||
|
/proc/sanitize_simple(t,list/repl_chars = list("\n"="#","\t"="#"))
|
||||||
|
for(var/char in repl_chars)
|
||||||
|
var/index = findtext(t, char)
|
||||||
|
while(index)
|
||||||
|
t = copytext(t, 1, index) + repl_chars[char] + copytext(t, index + length(char))
|
||||||
|
index = findtext(t, char, index + length(char))
|
||||||
|
return t
|
||||||
|
|
||||||
|
/proc/sanitize_filename(t)
|
||||||
|
return sanitize_simple(t, list("\n"="", "\t"="", "/"="", "\\"="", "?"="", "%"="", "*"="", ":"="", "|"="", "\""="", "<"="", ">"=""))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Text searches
|
* Text searches
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1571,6 +1571,14 @@ var/mob/dview/dview_mob = new
|
|||||||
/datum/proc/stack_trace(msg)
|
/datum/proc/stack_trace(msg)
|
||||||
CRASH(msg)
|
CRASH(msg)
|
||||||
|
|
||||||
|
GLOBAL_REAL_VAR(list/stack_trace_storage)
|
||||||
|
/proc/gib_stack_trace()
|
||||||
|
stack_trace_storage = list()
|
||||||
|
stack_trace()
|
||||||
|
stack_trace_storage.Cut(1, min(3,stack_trace_storage.len))
|
||||||
|
. = stack_trace_storage
|
||||||
|
stack_trace_storage = null
|
||||||
|
|
||||||
// \ref behaviour got changed in 512 so this is necesary to replicate old behaviour.
|
// \ref behaviour got changed in 512 so this is necesary to replicate old behaviour.
|
||||||
// If it ever becomes necesary to get a more performant REF(), this lies here in wait
|
// If it ever becomes necesary to get a more performant REF(), this lies here in wait
|
||||||
// #define REF(thing) (thing && istype(thing, /datum) && (thing:datum_flags & DF_USE_TAG) && thing:tag ? "[thing:tag]" : "\ref[thing]")
|
// #define REF(thing) (thing && istype(thing, /datum) && (thing:datum_flags & DF_USE_TAG) && thing:tag ? "[thing:tag]" : "\ref[thing]")
|
||||||
|
|||||||
@@ -123,8 +123,3 @@
|
|||||||
|
|
||||||
/obj/screen/fullscreen/fishbed
|
/obj/screen/fullscreen/fishbed
|
||||||
icon_state = "fishbed"
|
icon_state = "fishbed"
|
||||||
|
|
||||||
#undef FULLSCREEN_LAYER
|
|
||||||
#undef BLIND_LAYER
|
|
||||||
#undef DAMAGE_LAYER
|
|
||||||
#undef CRIT_LAYER
|
|
||||||
171
code/_onclick/hud/map_popups.dm
Normal file
171
code/_onclick/hud/map_popups.dm
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
/client
|
||||||
|
/**
|
||||||
|
* Assoc list with all the active maps - when a screen obj is added to
|
||||||
|
* a map, it's put in here as well.
|
||||||
|
*
|
||||||
|
* Format: list(<mapname> = list(/obj/screen))
|
||||||
|
*/
|
||||||
|
var/list/screen_maps = list()
|
||||||
|
|
||||||
|
/obj/screen
|
||||||
|
/**
|
||||||
|
* Map name assigned to this object.
|
||||||
|
* Automatically set by /client/proc/register_map_obj.
|
||||||
|
*/
|
||||||
|
var/assigned_map
|
||||||
|
/**
|
||||||
|
* Mark this object as garbage-collectible after you clean the map
|
||||||
|
* it was registered on.
|
||||||
|
*
|
||||||
|
* This could probably be changed to be a proc, for conditional removal.
|
||||||
|
* But for now, this works.
|
||||||
|
*/
|
||||||
|
var/del_on_map_removal = TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A screen object, which acts as a container for turfs and other things
|
||||||
|
* you want to show on the map, which you usually attach to "vis_contents".
|
||||||
|
*/
|
||||||
|
/obj/screen/map_view
|
||||||
|
icon_state = "blank"
|
||||||
|
// Map view has to be on the lowest plane to enable proper lighting
|
||||||
|
layer = SPACE_PLANE
|
||||||
|
plane = SPACE_PLANE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A generic background object.
|
||||||
|
* It is also implicitly used to allocate a rectangle on the map, which will
|
||||||
|
* be used for auto-scaling the map.
|
||||||
|
*/
|
||||||
|
/obj/screen/background
|
||||||
|
name = "background"
|
||||||
|
icon = 'icons/mob/map_backgrounds.dmi'
|
||||||
|
icon_state = "clear"
|
||||||
|
layer = SPACE_PLANE
|
||||||
|
plane = SPACE_PLANE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets screen_loc of this screen object, in form of point coordinates,
|
||||||
|
* with optional pixel offset (px, py).
|
||||||
|
*
|
||||||
|
* If applicable, "assigned_map" has to be assigned before this proc call.
|
||||||
|
*/
|
||||||
|
/obj/screen/proc/set_position(x, y, px = 0, py = 0)
|
||||||
|
if(assigned_map)
|
||||||
|
screen_loc = "[assigned_map]:[x]:[px],[y]:[py]"
|
||||||
|
else
|
||||||
|
screen_loc = "[x]:[px],[y]:[py]"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets screen_loc to fill a rectangular area of the map.
|
||||||
|
*
|
||||||
|
* If applicable, "assigned_map" has to be assigned before this proc call.
|
||||||
|
*/
|
||||||
|
/obj/screen/proc/fill_rect(x1, y1, x2, y2)
|
||||||
|
if(assigned_map)
|
||||||
|
screen_loc = "[assigned_map]:[x1],[y1] to [x2],[y2]"
|
||||||
|
else
|
||||||
|
screen_loc = "[x1],[y1] to [x2],[y2]"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers screen obj with the client, which makes it visible on the
|
||||||
|
* assigned map, and becomes a part of the assigned map's lifecycle.
|
||||||
|
*/
|
||||||
|
/client/proc/register_map_obj(obj/screen/screen_obj)
|
||||||
|
if(!screen_obj.assigned_map)
|
||||||
|
CRASH("Can't register [screen_obj] without 'assigned_map' property.")
|
||||||
|
if(!screen_maps[screen_obj.assigned_map])
|
||||||
|
screen_maps[screen_obj.assigned_map] = list()
|
||||||
|
// NOTE: Possibly an expensive operation
|
||||||
|
var/list/screen_map = screen_maps[screen_obj.assigned_map]
|
||||||
|
if(!screen_map.Find(screen_obj))
|
||||||
|
screen_map += screen_obj
|
||||||
|
if(!screen.Find(screen_obj))
|
||||||
|
screen += screen_obj
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the map of registered screen objects.
|
||||||
|
*
|
||||||
|
* Not really needed most of the time, as the client's screen list gets reset
|
||||||
|
* on relog. any of the buttons are going to get caught by garbage collection
|
||||||
|
* anyway. they're effectively qdel'd.
|
||||||
|
*/
|
||||||
|
/client/proc/clear_map(map_name)
|
||||||
|
if(!map_name || !(map_name in screen_maps))
|
||||||
|
return FALSE
|
||||||
|
for(var/obj/screen/screen_obj in screen_maps[map_name])
|
||||||
|
screen_maps[map_name] -= screen_obj
|
||||||
|
if(screen_obj.del_on_map_removal)
|
||||||
|
qdel(screen_obj)
|
||||||
|
screen_maps -= map_name
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears all the maps of registered screen objects.
|
||||||
|
*/
|
||||||
|
/client/proc/clear_all_maps()
|
||||||
|
for(var/map_name in screen_maps)
|
||||||
|
clear_map(map_name)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a popup window with a basic map element in it, without any
|
||||||
|
* further initialization.
|
||||||
|
*
|
||||||
|
* Ratio is how many pixels by how many pixels (keep it simple).
|
||||||
|
*
|
||||||
|
* Returns a map name.
|
||||||
|
*/
|
||||||
|
/client/proc/create_popup(name, ratiox = 100, ratioy = 100)
|
||||||
|
winclone(src, "popupwindow", name)
|
||||||
|
var/list/winparams = list()
|
||||||
|
winparams["size"] = "[ratiox]x[ratioy]"
|
||||||
|
winparams["on-close"] = "handle-popup-close [name]"
|
||||||
|
winset(src, "[name]", list2params(winparams))
|
||||||
|
winshow(src, "[name]", 1)
|
||||||
|
|
||||||
|
var/list/params = list()
|
||||||
|
params["parent"] = "[name]"
|
||||||
|
params["type"] = "map"
|
||||||
|
params["size"] = "[ratiox]x[ratioy]"
|
||||||
|
params["anchor1"] = "0,0"
|
||||||
|
params["anchor2"] = "[ratiox],[ratioy]"
|
||||||
|
winset(src, "[name]_map", list2params(params))
|
||||||
|
|
||||||
|
return "[name]_map"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the popup, and get it ready for generic use by giving
|
||||||
|
* it a background.
|
||||||
|
*
|
||||||
|
* Width and height are multiplied by 64 by default.
|
||||||
|
*/
|
||||||
|
/client/proc/setup_popup(popup_name, width = 9, height = 9, \
|
||||||
|
tilesize = 2, bg_icon)
|
||||||
|
if(!popup_name)
|
||||||
|
return
|
||||||
|
clear_map("[popup_name]_map")
|
||||||
|
var/x_value = world.icon_size * tilesize * width
|
||||||
|
var/y_value = world.icon_size * tilesize * height
|
||||||
|
var/map_name = create_popup(popup_name, x_value, y_value)
|
||||||
|
|
||||||
|
var/obj/screen/background/background = new
|
||||||
|
background.assigned_map = map_name
|
||||||
|
background.fill_rect(1, 1, width, height)
|
||||||
|
if(bg_icon)
|
||||||
|
background.icon_state = bg_icon
|
||||||
|
register_map_obj(background)
|
||||||
|
|
||||||
|
return map_name
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes a popup.
|
||||||
|
*/
|
||||||
|
/client/proc/close_popup(popup)
|
||||||
|
winshow(src, popup, 0)
|
||||||
|
handle_popup_close(popup)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the popup closes in any way (player or proc call) it calls this.
|
||||||
|
*/
|
||||||
|
/client/verb/handle_popup_close(window_id as text)
|
||||||
|
set hidden = TRUE
|
||||||
|
clear_map("[window_id]_map")
|
||||||
@@ -3,17 +3,20 @@
|
|||||||
#define SKYBOX_TURFS (SKYBOX_PIXELS/WORLD_ICON_SIZE)
|
#define SKYBOX_TURFS (SKYBOX_PIXELS/WORLD_ICON_SIZE)
|
||||||
|
|
||||||
// Skybox screen object.
|
// Skybox screen object.
|
||||||
/obj/skybox
|
/obj/screen/skybox
|
||||||
name = "skybox"
|
name = "skybox"
|
||||||
|
icon = null
|
||||||
|
appearance_flags = TILE_BOUND|PIXEL_SCALE
|
||||||
mouse_opacity = 0
|
mouse_opacity = 0
|
||||||
anchored = TRUE
|
anchored = TRUE
|
||||||
simulated = FALSE
|
simulated = FALSE
|
||||||
screen_loc = "CENTER,CENTER"
|
screen_loc = "CENTER,CENTER"
|
||||||
|
layer = OBJ_LAYER
|
||||||
plane = SKYBOX_PLANE
|
plane = SKYBOX_PLANE
|
||||||
blend_mode = BLEND_MULTIPLY // You actually need to do it this way or you see it in occlusion.
|
blend_mode = BLEND_MULTIPLY // You actually need to do it this way or you see it in occlusion.
|
||||||
|
|
||||||
// Adjust transform property to scale for client's view var. We assume the skybox is 736x736 px
|
// Adjust transform property to scale for client's view var. We assume the skybox is 736x736 px
|
||||||
/obj/skybox/proc/scale_to_view(var/view)
|
/obj/screen/skybox/proc/scale_to_view(var/view)
|
||||||
var/matrix/M = matrix()
|
var/matrix/M = matrix()
|
||||||
// Translate to center the icon over us!
|
// Translate to center the icon over us!
|
||||||
M.Translate(-(SKYBOX_PIXELS - WORLD_ICON_SIZE) / 2)
|
M.Translate(-(SKYBOX_PIXELS - WORLD_ICON_SIZE) / 2)
|
||||||
@@ -23,7 +26,7 @@
|
|||||||
src.transform = M
|
src.transform = M
|
||||||
|
|
||||||
/client
|
/client
|
||||||
var/obj/skybox/skybox
|
var/obj/screen/skybox/skybox
|
||||||
|
|
||||||
/client/proc/update_skybox(rebuild)
|
/client/proc/update_skybox(rebuild)
|
||||||
if(!skybox)
|
if(!skybox)
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ SUBSYSTEM_DEF(ai)
|
|||||||
while(currentrun.len)
|
while(currentrun.len)
|
||||||
var/datum/ai_holder/A = currentrun[currentrun.len]
|
var/datum/ai_holder/A = currentrun[currentrun.len]
|
||||||
--currentrun.len
|
--currentrun.len
|
||||||
if(!A || QDELETED(A) || A.busy) // Doesn't exist or won't exist soon or not doing it this tick
|
if(!A || QDELETED(A) || !A.holder?.loc || A.busy) // Doesn't exist or won't exist soon or not doing it this tick
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if(process_z[get_z(A.holder)])
|
if(process_z[get_z(A.holder)])
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ SUBSYSTEM_DEF(mobs)
|
|||||||
if(!M || QDELETED(M))
|
if(!M || QDELETED(M))
|
||||||
mob_list -= M
|
mob_list -= M
|
||||||
continue
|
continue
|
||||||
else if(M.low_priority && !(process_z[get_z(M)]))
|
else if(M.low_priority && !(M.loc && process_z[get_z(M)]))
|
||||||
slept_mobs++
|
slept_mobs++
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ SUBSYSTEM_DEF(skybox)
|
|||||||
for(var/z in zlevels)
|
for(var/z in zlevels)
|
||||||
skybox_cache["[z]"] = generate_skybox(z)
|
skybox_cache["[z]"] = generate_skybox(z)
|
||||||
|
|
||||||
for(var/client/C)
|
for(var/client/C in GLOB.clients)
|
||||||
var/their_z = get_z(C.mob)
|
var/their_z = get_z(C.mob)
|
||||||
if(!their_z) //Nullspace
|
if(!their_z) //Nullspace
|
||||||
continue
|
continue
|
||||||
|
|||||||
343
code/controllers/subsystems/tgui.dm
Normal file
343
code/controllers/subsystems/tgui.dm
Normal file
@@ -0,0 +1,343 @@
|
|||||||
|
/**
|
||||||
|
* tgui subsystem
|
||||||
|
*
|
||||||
|
* Contains all tgui state and subsystem code.
|
||||||
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
SUBSYSTEM_DEF(tgui)
|
||||||
|
name = "TGUI"
|
||||||
|
wait = 9
|
||||||
|
flags = SS_NO_INIT
|
||||||
|
priority = FIRE_PRIORITY_TGUI
|
||||||
|
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||||
|
|
||||||
|
/// A list of UIs scheduled to process
|
||||||
|
var/list/current_run = list()
|
||||||
|
/// A list of open UIs
|
||||||
|
var/list/open_uis = list()
|
||||||
|
/// A list of open UIs, grouped by src_object and ui_key.
|
||||||
|
var/list/open_uis_by_src = list()
|
||||||
|
/// The HTML base used for all UIs.
|
||||||
|
var/basehtml
|
||||||
|
|
||||||
|
/datum/controller/subsystem/tgui/PreInit()
|
||||||
|
basehtml = file2text('tgui/packages/tgui/public/tgui.html')
|
||||||
|
|
||||||
|
/datum/controller/subsystem/tgui/Shutdown()
|
||||||
|
close_all_uis()
|
||||||
|
|
||||||
|
/datum/controller/subsystem/tgui/stat_entry()
|
||||||
|
..("P:[open_uis.len]")
|
||||||
|
|
||||||
|
/datum/controller/subsystem/tgui/fire(resumed = 0)
|
||||||
|
if(!resumed)
|
||||||
|
src.current_run = open_uis.Copy()
|
||||||
|
// Cache for sanic speed (lists are references anyways)
|
||||||
|
var/list/current_run = src.current_run
|
||||||
|
while(current_run.len)
|
||||||
|
var/datum/tgui/ui = current_run[current_run.len]
|
||||||
|
current_run.len--
|
||||||
|
// TODO: Move user/src_object check to process()
|
||||||
|
if(ui && ui.user && ui.src_object)
|
||||||
|
ui.process()
|
||||||
|
else
|
||||||
|
open_uis.Remove(ui)
|
||||||
|
if(MC_TICK_CHECK)
|
||||||
|
return
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public
|
||||||
|
*
|
||||||
|
* Requests a usable tgui window from the pool.
|
||||||
|
* Returns null if pool was exhausted.
|
||||||
|
*
|
||||||
|
* required user mob
|
||||||
|
* return datum/tgui
|
||||||
|
*/
|
||||||
|
/datum/controller/subsystem/tgui/proc/request_pooled_window(mob/user)
|
||||||
|
if(!user.client)
|
||||||
|
return null
|
||||||
|
var/list/windows = user.client.tgui_windows
|
||||||
|
var/window_id
|
||||||
|
var/datum/tgui_window/window
|
||||||
|
var/window_found = FALSE
|
||||||
|
// Find a usable window
|
||||||
|
for(var/i in 1 to TGUI_WINDOW_HARD_LIMIT)
|
||||||
|
window_id = TGUI_WINDOW_ID(i)
|
||||||
|
window = windows[window_id]
|
||||||
|
// As we are looping, create missing window datums
|
||||||
|
if(!window)
|
||||||
|
window = new(user.client, window_id, pooled = TRUE)
|
||||||
|
// Skip windows with acquired locks
|
||||||
|
if(window.locked)
|
||||||
|
continue
|
||||||
|
if(window.status == TGUI_WINDOW_READY)
|
||||||
|
return window
|
||||||
|
if(window.status == TGUI_WINDOW_CLOSED)
|
||||||
|
window.status = TGUI_WINDOW_LOADING
|
||||||
|
window_found = TRUE
|
||||||
|
break
|
||||||
|
if(!window_found)
|
||||||
|
return null
|
||||||
|
return window
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public
|
||||||
|
*
|
||||||
|
* Force closes all tgui windows.
|
||||||
|
*
|
||||||
|
* required user mob
|
||||||
|
*/
|
||||||
|
/datum/controller/subsystem/tgui/proc/force_close_all_windows(mob/user)
|
||||||
|
if(user.client)
|
||||||
|
user.client.tgui_windows = list()
|
||||||
|
for(var/i in 1 to TGUI_WINDOW_HARD_LIMIT)
|
||||||
|
var/window_id = TGUI_WINDOW_ID(i)
|
||||||
|
user << browse(null, "window=[window_id]")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public
|
||||||
|
*
|
||||||
|
* Force closes the tgui window by window_id.
|
||||||
|
*
|
||||||
|
* required user mob
|
||||||
|
* required window_id string
|
||||||
|
*/
|
||||||
|
/datum/controller/subsystem/tgui/proc/force_close_window(mob/user, window_id)
|
||||||
|
// Close all tgui datums based on window_id.
|
||||||
|
for(var/datum/tgui/ui in user.tgui_open_uis)
|
||||||
|
if(ui.window && ui.window.id == window_id)
|
||||||
|
ui.close(can_be_suspended = FALSE)
|
||||||
|
// Unset machine just to be sure.
|
||||||
|
user.unset_machine()
|
||||||
|
// Close window directly just to be sure.
|
||||||
|
user << browse(null, "window=[window_id]")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public
|
||||||
|
*
|
||||||
|
* Get a open UI given a user, src_object, and ui_key and try to update it with data.
|
||||||
|
*
|
||||||
|
* required user mob The mob who opened/is using the UI.
|
||||||
|
* required src_object datum The object/datum which owns the UI.
|
||||||
|
* required ui_key string The ui_key of the UI.
|
||||||
|
*
|
||||||
|
* return datum/tgui The found UI.
|
||||||
|
**/
|
||||||
|
/datum/controller/subsystem/tgui/proc/try_update_ui(
|
||||||
|
mob/user,
|
||||||
|
datum/src_object,
|
||||||
|
datum/tgui/ui)
|
||||||
|
// Look up a UI if it wasn't passed.
|
||||||
|
if(isnull(ui))
|
||||||
|
ui = get_open_ui(user, src_object)
|
||||||
|
// Couldn't find a UI.
|
||||||
|
if(isnull(ui))
|
||||||
|
return null
|
||||||
|
ui.process_status()
|
||||||
|
// UI ended up with the closed status
|
||||||
|
// or is actively trying to close itself.
|
||||||
|
// FIXME: Doesn't actually fix the paper bug.
|
||||||
|
if(ui.status <= STATUS_CLOSE)
|
||||||
|
ui.close()
|
||||||
|
return null
|
||||||
|
ui.send_update()
|
||||||
|
return ui
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private
|
||||||
|
*
|
||||||
|
* Get a open UI given a user, src_object, and ui_key.
|
||||||
|
*
|
||||||
|
* required user mob The mob who opened/is using the UI.
|
||||||
|
* required src_object datum The object/datum which owns the UI.
|
||||||
|
* required ui_key string The ui_key of the UI.
|
||||||
|
*
|
||||||
|
* return datum/tgui The found UI.
|
||||||
|
**/
|
||||||
|
/datum/controller/subsystem/tgui/proc/get_open_ui(mob/user, datum/src_object)
|
||||||
|
var/key = "[REF(src_object)]"
|
||||||
|
// No UIs opened for this src_object
|
||||||
|
if(isnull(open_uis_by_src[key]) || !istype(open_uis_by_src[key], /list))
|
||||||
|
return null // No UIs open.
|
||||||
|
for(var/datum/tgui/ui in open_uis_by_src[key]) // Find UIs for this object.
|
||||||
|
// Make sure we have the right user
|
||||||
|
if(ui.user == user)
|
||||||
|
return ui
|
||||||
|
return null // Couldn't find a UI!
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private
|
||||||
|
*
|
||||||
|
* Update all UIs attached to src_object.
|
||||||
|
*
|
||||||
|
* required src_object datum The object/datum which owns the UIs.
|
||||||
|
*
|
||||||
|
* return int The number of UIs updated.
|
||||||
|
**/
|
||||||
|
/datum/controller/subsystem/tgui/proc/update_uis(datum/src_object)
|
||||||
|
var/count = 0
|
||||||
|
var/key = "[REF(src_object)]"
|
||||||
|
if(isnull(open_uis_by_src[key]) || !istype(open_uis_by_src[key], /list))
|
||||||
|
return count // Couldn't find any UIs for this object.
|
||||||
|
for(var/datum/tgui/ui in open_uis_by_src[key])
|
||||||
|
// Check the UI is valid.
|
||||||
|
if(ui && ui.src_object && ui.user && ui.src_object.tgui_host(ui.user))
|
||||||
|
ui.process(force = 1) // Update the UI.
|
||||||
|
count++ // Count each UI we update.
|
||||||
|
return count
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private
|
||||||
|
*
|
||||||
|
* Close all UIs attached to src_object.
|
||||||
|
*
|
||||||
|
* required src_object datum The object/datum which owns the UIs.
|
||||||
|
*
|
||||||
|
* return int The number of UIs closed.
|
||||||
|
**/
|
||||||
|
/datum/controller/subsystem/tgui/proc/close_uis(datum/src_object)
|
||||||
|
var/count = 0
|
||||||
|
var/key = "[REF(src_object)]"
|
||||||
|
// No UIs opened for this src_object
|
||||||
|
if(isnull(open_uis_by_src[key]) || !istype(open_uis_by_src[key], /list))
|
||||||
|
return count
|
||||||
|
for(var/datum/tgui/ui in open_uis_by_src[key])
|
||||||
|
if(ui && ui.src_object && ui.user && ui.src_object.tgui_host(ui.user)) // Check the UI is valid.
|
||||||
|
ui.close() // Close the UI.
|
||||||
|
count++ // Count each UI we close.
|
||||||
|
return count
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private
|
||||||
|
*
|
||||||
|
* Close all UIs regardless of their attachment to src_object.
|
||||||
|
*
|
||||||
|
* return int The number of UIs closed.
|
||||||
|
**/
|
||||||
|
/datum/controller/subsystem/tgui/proc/close_all_uis()
|
||||||
|
var/count = 0
|
||||||
|
for(var/key in open_uis_by_src)
|
||||||
|
for(var/datum/tgui/ui in open_uis_by_src[key])
|
||||||
|
if(ui && ui.src_object && ui.user && ui.src_object.tgui_host(ui.user)) // Check the UI is valid.
|
||||||
|
ui.close() // Close the UI.
|
||||||
|
count++ // Count each UI we close.
|
||||||
|
return count
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private
|
||||||
|
*
|
||||||
|
* Update all UIs belonging to a user.
|
||||||
|
*
|
||||||
|
* required user mob The mob who opened/is using the UI.
|
||||||
|
* optional src_object datum If provided, only update UIs belonging this src_object.
|
||||||
|
*
|
||||||
|
* return int The number of UIs updated.
|
||||||
|
**/
|
||||||
|
/datum/controller/subsystem/tgui/proc/update_user_uis(mob/user, datum/src_object)
|
||||||
|
var/count = 0
|
||||||
|
if(length(user?.tgui_open_uis) == 0)
|
||||||
|
return count
|
||||||
|
for(var/datum/tgui/ui in user.tgui_open_uis)
|
||||||
|
if(isnull(src_object) || ui.src_object == src_object)
|
||||||
|
ui.process(force = 1)
|
||||||
|
count++
|
||||||
|
return count
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private
|
||||||
|
*
|
||||||
|
* Close all UIs belonging to a user.
|
||||||
|
*
|
||||||
|
* required user mob The mob who opened/is using the UI.
|
||||||
|
* optional src_object datum If provided, only close UIs belonging this src_object.
|
||||||
|
*
|
||||||
|
* return int The number of UIs closed.
|
||||||
|
**/
|
||||||
|
/datum/controller/subsystem/tgui/proc/close_user_uis(mob/user, datum/src_object)
|
||||||
|
var/count = 0
|
||||||
|
if(length(user?.tgui_open_uis) == 0)
|
||||||
|
return count
|
||||||
|
for(var/datum/tgui/ui in user.tgui_open_uis)
|
||||||
|
if(isnull(src_object) || ui.src_object == src_object)
|
||||||
|
ui.close()
|
||||||
|
count++
|
||||||
|
return count
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private
|
||||||
|
*
|
||||||
|
* Add a UI to the list of open UIs.
|
||||||
|
*
|
||||||
|
* required ui datum/tgui The UI to be added.
|
||||||
|
**/
|
||||||
|
/datum/controller/subsystem/tgui/proc/on_open(datum/tgui/ui)
|
||||||
|
var/key = "[REF(ui.src_object)]"
|
||||||
|
if(isnull(open_uis_by_src[key]) || !istype(open_uis_by_src[key], /list))
|
||||||
|
open_uis_by_src[key] = list()
|
||||||
|
ui.user.tgui_open_uis |= ui
|
||||||
|
var/list/uis = open_uis_by_src[key]
|
||||||
|
uis |= ui
|
||||||
|
open_uis |= ui
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private
|
||||||
|
*
|
||||||
|
* Remove a UI from the list of open UIs.
|
||||||
|
*
|
||||||
|
* required ui datum/tgui The UI to be removed.
|
||||||
|
*
|
||||||
|
* return bool If the UI was removed or not.
|
||||||
|
**/
|
||||||
|
/datum/controller/subsystem/tgui/proc/on_close(datum/tgui/ui)
|
||||||
|
var/key = "[REF(ui.src_object)]"
|
||||||
|
if(isnull(open_uis_by_src[key]) || !istype(open_uis_by_src[key], /list))
|
||||||
|
return FALSE
|
||||||
|
// Remove it from the list of processing UIs.
|
||||||
|
open_uis.Remove(ui)
|
||||||
|
// If the user exists, remove it from them too.
|
||||||
|
if(ui.user)
|
||||||
|
ui.user.tgui_open_uis.Remove(ui)
|
||||||
|
var/list/uis = open_uis_by_src[key]
|
||||||
|
uis.Remove(ui)
|
||||||
|
if(length(uis) == 0)
|
||||||
|
open_uis_by_src.Remove(key)
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private
|
||||||
|
*
|
||||||
|
* Handle client logout, by closing all their UIs.
|
||||||
|
*
|
||||||
|
* required user mob The mob which logged out.
|
||||||
|
*
|
||||||
|
* return int The number of UIs closed.
|
||||||
|
**/
|
||||||
|
/datum/controller/subsystem/tgui/proc/on_logout(mob/user)
|
||||||
|
return close_user_uis(user)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private
|
||||||
|
*
|
||||||
|
* Handle clients switching mobs, by transferring their UIs.
|
||||||
|
*
|
||||||
|
* required user source The client's original mob.
|
||||||
|
* required user target The client's new mob.
|
||||||
|
*
|
||||||
|
* return bool If the UIs were transferred.
|
||||||
|
**/
|
||||||
|
/datum/controller/subsystem/tgui/proc/on_transfer(mob/source, mob/target)
|
||||||
|
// The old mob had no open UIs.
|
||||||
|
if(length(source?.tgui_open_uis) == 0)
|
||||||
|
return FALSE
|
||||||
|
if(isnull(target.tgui_open_uis) || !istype(target.tgui_open_uis, /list))
|
||||||
|
target.tgui_open_uis = list()
|
||||||
|
// Transfer all the UIs.
|
||||||
|
for(var/datum/tgui/ui in source.tgui_open_uis)
|
||||||
|
// Inform the UIs of their new owner.
|
||||||
|
ui.user = target
|
||||||
|
target.tgui_open_uis.Add(ui)
|
||||||
|
// Clear the old list.
|
||||||
|
source.tgui_open_uis.Cut()
|
||||||
|
return TRUE
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
var/global/datum/repository/cameras/camera_repository = new()
|
|
||||||
|
|
||||||
/proc/invalidateCameraCache()
|
|
||||||
camera_repository.networks.Cut()
|
|
||||||
camera_repository.invalidated = 1
|
|
||||||
camera_repository.camera_cache_id = (++camera_repository.camera_cache_id % 999999)
|
|
||||||
|
|
||||||
/datum/repository/cameras
|
|
||||||
var/list/networks
|
|
||||||
var/invalidated = 1
|
|
||||||
var/camera_cache_id = 1
|
|
||||||
|
|
||||||
/datum/repository/cameras/New()
|
|
||||||
networks = list()
|
|
||||||
..()
|
|
||||||
|
|
||||||
/datum/repository/cameras/proc/cameras_in_network(var/network, var/list/zlevels)
|
|
||||||
setup_cache()
|
|
||||||
var/list/network_list = networks[network]
|
|
||||||
if(LAZYLEN(zlevels))
|
|
||||||
var/list/filtered_cameras = list()
|
|
||||||
for(var/list/C in network_list)
|
|
||||||
//Camera is marked as always-visible
|
|
||||||
if(C["omni"])
|
|
||||||
filtered_cameras[++filtered_cameras.len] = C
|
|
||||||
continue
|
|
||||||
//Camera might be in an adjacent zlevel
|
|
||||||
var/camz = C["z"]
|
|
||||||
if(!camz) //It's inside something (helmet, communicator, etc) or nullspace or who knows
|
|
||||||
camz = get_z(locate(C["camera"]) in cameranet.cameras)
|
|
||||||
if(camz in zlevels)
|
|
||||||
filtered_cameras[++filtered_cameras.len] = C //Can't add lists to lists with +=
|
|
||||||
return filtered_cameras
|
|
||||||
else
|
|
||||||
return network_list
|
|
||||||
|
|
||||||
/datum/repository/cameras/proc/setup_cache()
|
|
||||||
if(!invalidated)
|
|
||||||
return
|
|
||||||
invalidated = 0
|
|
||||||
|
|
||||||
cameranet.process_sort()
|
|
||||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
|
||||||
var/cam = C.nano_structure()
|
|
||||||
for(var/network in C.network)
|
|
||||||
if(!networks[network])
|
|
||||||
networks[network] = list()
|
|
||||||
var/list/netlist = networks[network]
|
|
||||||
netlist[++netlist.len] = cam
|
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ var/global/datum/repository/crew/crew_repository = new()
|
|||||||
crewmemberData["area"] = sanitize(A.get_name())
|
crewmemberData["area"] = sanitize(A.get_name())
|
||||||
crewmemberData["x"] = pos.x
|
crewmemberData["x"] = pos.x
|
||||||
crewmemberData["y"] = pos.y
|
crewmemberData["y"] = pos.y
|
||||||
|
crewmemberData["realZ"] = pos.z
|
||||||
crewmemberData["z"] = using_map.get_zlevel_name(pos.z)
|
crewmemberData["z"] = using_map.get_zlevel_name(pos.z)
|
||||||
|
|
||||||
crewmembers[++crewmembers.len] = crewmemberData
|
crewmembers[++crewmembers.len] = crewmemberData
|
||||||
|
|||||||
@@ -11,42 +11,42 @@
|
|||||||
name = "Inflatable barriers"
|
name = "Inflatable barriers"
|
||||||
contains = list(/obj/item/weapon/storage/briefcase/inflatable = 3)
|
contains = list(/obj/item/weapon/storage/briefcase/inflatable = 3)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/engineering
|
containertype = /obj/structure/closet/crate/aether
|
||||||
containername = "Inflatable Barrier Crate"
|
containername = "Inflatable Barrier Crate"
|
||||||
|
|
||||||
/datum/supply_pack/atmos/canister_empty
|
/datum/supply_pack/atmos/canister_empty
|
||||||
name = "Empty gas canister"
|
name = "Empty gas canister"
|
||||||
cost = 7
|
cost = 7
|
||||||
containername = "Empty gas canister crate"
|
containername = "Empty gas canister crate"
|
||||||
containertype = /obj/structure/largecrate
|
containertype = /obj/structure/closet/crate/large/aether
|
||||||
contains = list(/obj/machinery/portable_atmospherics/canister)
|
contains = list(/obj/machinery/portable_atmospherics/canister)
|
||||||
|
|
||||||
/datum/supply_pack/atmos/canister_air
|
/datum/supply_pack/atmos/canister_air
|
||||||
name = "Air canister"
|
name = "Air canister"
|
||||||
cost = 10
|
cost = 10
|
||||||
containername = "Air canister crate"
|
containername = "Air canister crate"
|
||||||
containertype = /obj/structure/largecrate
|
containertype = /obj/structure/closet/crate/large/aether
|
||||||
contains = list(/obj/machinery/portable_atmospherics/canister/air)
|
contains = list(/obj/machinery/portable_atmospherics/canister/air)
|
||||||
|
|
||||||
/datum/supply_pack/atmos/canister_oxygen
|
/datum/supply_pack/atmos/canister_oxygen
|
||||||
name = "Oxygen canister"
|
name = "Oxygen canister"
|
||||||
cost = 15
|
cost = 15
|
||||||
containername = "Oxygen canister crate"
|
containername = "Oxygen canister crate"
|
||||||
containertype = /obj/structure/largecrate
|
containertype = /obj/structure/closet/crate/large/aether
|
||||||
contains = list(/obj/machinery/portable_atmospherics/canister/oxygen)
|
contains = list(/obj/machinery/portable_atmospherics/canister/oxygen)
|
||||||
|
|
||||||
/datum/supply_pack/atmos/canister_nitrogen
|
/datum/supply_pack/atmos/canister_nitrogen
|
||||||
name = "Nitrogen canister"
|
name = "Nitrogen canister"
|
||||||
cost = 10
|
cost = 10
|
||||||
containername = "Nitrogen canister crate"
|
containername = "Nitrogen canister crate"
|
||||||
containertype = /obj/structure/largecrate
|
containertype = /obj/structure/closet/crate/large/aether
|
||||||
contains = list(/obj/machinery/portable_atmospherics/canister/nitrogen)
|
contains = list(/obj/machinery/portable_atmospherics/canister/nitrogen)
|
||||||
|
|
||||||
/datum/supply_pack/atmos/canister_phoron
|
/datum/supply_pack/atmos/canister_phoron
|
||||||
name = "Phoron gas canister"
|
name = "Phoron gas canister"
|
||||||
cost = 60
|
cost = 60
|
||||||
containername = "Phoron gas canister crate"
|
containername = "Phoron gas canister crate"
|
||||||
containertype = /obj/structure/closet/crate/secure/large
|
containertype = /obj/structure/closet/crate/secure/large/aether
|
||||||
access = access_atmospherics
|
access = access_atmospherics
|
||||||
contains = list(/obj/machinery/portable_atmospherics/canister/phoron)
|
contains = list(/obj/machinery/portable_atmospherics/canister/phoron)
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
name = "N2O gas canister"
|
name = "N2O gas canister"
|
||||||
cost = 15
|
cost = 15
|
||||||
containername = "N2O gas canister crate"
|
containername = "N2O gas canister crate"
|
||||||
containertype = /obj/structure/closet/crate/secure/large
|
containertype = /obj/structure/closet/crate/secure/large/aether
|
||||||
access = access_atmospherics
|
access = access_atmospherics
|
||||||
contains = list(/obj/machinery/portable_atmospherics/canister/sleeping_agent)
|
contains = list(/obj/machinery/portable_atmospherics/canister/sleeping_agent)
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
name = "Carbon dioxide gas canister"
|
name = "Carbon dioxide gas canister"
|
||||||
cost = 15
|
cost = 15
|
||||||
containername = "CO2 canister crate"
|
containername = "CO2 canister crate"
|
||||||
containertype = /obj/structure/closet/crate/secure/large
|
containertype = /obj/structure/closet/crate/secure/large/aether
|
||||||
access = access_atmospherics
|
access = access_atmospherics
|
||||||
contains = list(/obj/machinery/portable_atmospherics/canister/carbon_dioxide)
|
contains = list(/obj/machinery/portable_atmospherics/canister/carbon_dioxide)
|
||||||
|
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
contains = list(/obj/machinery/pipedispenser/orderable)
|
contains = list(/obj/machinery/pipedispenser/orderable)
|
||||||
name = "Pipe Dispenser"
|
name = "Pipe Dispenser"
|
||||||
cost = 25
|
cost = 25
|
||||||
containertype = /obj/structure/closet/crate/secure/large
|
containertype = /obj/structure/closet/crate/secure/large/aether
|
||||||
containername = "Pipe Dispenser Crate"
|
containername = "Pipe Dispenser Crate"
|
||||||
access = access_atmospherics
|
access = access_atmospherics
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
contains = list(/obj/machinery/pipedispenser/disposal/orderable)
|
contains = list(/obj/machinery/pipedispenser/disposal/orderable)
|
||||||
name = "Disposals Pipe Dispenser"
|
name = "Disposals Pipe Dispenser"
|
||||||
cost = 25
|
cost = 25
|
||||||
containertype = /obj/structure/closet/crate/secure/large
|
containertype = /obj/structure/closet/crate/secure/large/aether
|
||||||
containername = "Disposal Dispenser Crate"
|
containername = "Disposal Dispenser Crate"
|
||||||
access = access_atmospherics
|
access = access_atmospherics
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
/obj/item/weapon/tank/air = 3
|
/obj/item/weapon/tank/air = 3
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/internals
|
containertype = /obj/structure/closet/crate/aether
|
||||||
containername = "Internals crate"
|
containername = "Internals crate"
|
||||||
|
|
||||||
/datum/supply_pack/atmos/evacuation
|
/datum/supply_pack/atmos/evacuation
|
||||||
@@ -104,5 +104,5 @@
|
|||||||
/obj/item/clothing/mask/gas = 4
|
/obj/item/clothing/mask/gas = 4
|
||||||
)
|
)
|
||||||
cost = 35
|
cost = 35
|
||||||
containertype = /obj/structure/closet/crate/internals
|
containertype = /obj/structure/closet/crate/aether
|
||||||
containername = "Emergency crate"
|
containername = "Emergency crate"
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
/obj/item/weapon/grenade/chem_grenade/incendiary
|
/obj/item/weapon/grenade/chem_grenade/incendiary
|
||||||
)
|
)
|
||||||
cost = 25
|
cost = 25
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/weapon
|
||||||
containername = "Special Ops crate"
|
containername = "Special Ops crate"
|
||||||
contraband = 1
|
contraband = 1
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
/obj/item/weapon/reagent_containers/food/snacks/unajerky = 4
|
/obj/item/weapon/reagent_containers/food/snacks/unajerky = 4
|
||||||
)
|
)
|
||||||
cost = 25
|
cost = 25
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/unathi
|
||||||
containername = "Moghes imports crate"
|
containername = "Moghes imports crate"
|
||||||
contraband = 1
|
contraband = 1
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
)
|
)
|
||||||
cost = 50
|
cost = 50
|
||||||
contraband = 1
|
contraband = 1
|
||||||
containertype = /obj/structure/closet/crate/secure/weapon
|
containertype = /obj/structure/closet/crate/hedberg
|
||||||
containername = "Ballistic weapons crate"
|
containername = "Ballistic weapons crate"
|
||||||
|
|
||||||
/datum/supply_pack/randomised/misc/telecrate //you get something awesome, a couple of decent things, and a few weak/filler things
|
/datum/supply_pack/randomised/misc/telecrate //you get something awesome, a couple of decent things, and a few weak/filler things
|
||||||
@@ -103,5 +103,5 @@
|
|||||||
)
|
)
|
||||||
cost = 250 //more than a hat crate!,
|
cost = 250 //more than a hat crate!,
|
||||||
contraband = 1
|
contraband = 1
|
||||||
containertype = /obj/structure/largecrate
|
containertype = /obj/structure/closet/crate/large
|
||||||
containername = "Suspicious crate"
|
containername = "Suspicious crate"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Here is where any supply packs
|
* Here is where any supply packs
|
||||||
* related to weapons live.
|
* related to costumes live.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
/obj/item/clothing/head/wizard/fake
|
/obj/item/clothing/head/wizard/fake
|
||||||
)
|
)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/nanothreads
|
||||||
containername = "Wizard costume crate"
|
containername = "Wizard costume crate"
|
||||||
|
|
||||||
/datum/supply_pack/randomised/costumes/hats
|
/datum/supply_pack/randomised/costumes/hats
|
||||||
@@ -48,8 +48,8 @@
|
|||||||
)
|
)
|
||||||
name = "Collectable hat crate!"
|
name = "Collectable hat crate!"
|
||||||
cost = 200
|
cost = 200
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/nanothreads
|
||||||
containername = "Collectable hats crate! Brought to you by Bass.inc!"
|
containername = "Collectable hats crate"
|
||||||
|
|
||||||
/datum/supply_pack/randomised/costumes/costume
|
/datum/supply_pack/randomised/costumes/costume
|
||||||
num_contained = 3
|
num_contained = 3
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
)
|
)
|
||||||
name = "Costumes crate"
|
name = "Costumes crate"
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/nanothreads
|
||||||
containername = "Actor Costumes"
|
containername = "Actor Costumes"
|
||||||
|
|
||||||
/datum/supply_pack/costumes/formal_wear
|
/datum/supply_pack/costumes/formal_wear
|
||||||
@@ -104,15 +104,15 @@
|
|||||||
/obj/item/clothing/shoes/leather,
|
/obj/item/clothing/shoes/leather,
|
||||||
/obj/item/clothing/accessory/wcoat
|
/obj/item/clothing/accessory/wcoat
|
||||||
)
|
)
|
||||||
name = "Formalwear closet"
|
name = "Formalwear (Suits)"
|
||||||
cost = 30
|
cost = 30
|
||||||
containertype = /obj/structure/closet
|
containertype = /obj/structure/closet/crate/gilthari
|
||||||
containername = "Formalwear for the best occasions."
|
containername = "Formal suit crate"
|
||||||
|
|
||||||
datum/supply_pack/costumes/witch
|
datum/supply_pack/costumes/witch
|
||||||
name = "Witch costume"
|
name = "Witch costume"
|
||||||
containername = "Witch costume"
|
containername = "Witch costume"
|
||||||
containertype = /obj/structure/closet
|
containertype = /obj/structure/closet/crate/nanothreads
|
||||||
cost = 20
|
cost = 20
|
||||||
contains = list(
|
contains = list(
|
||||||
/obj/item/clothing/suit/wizrobe/marisa/fake,
|
/obj/item/clothing/suit/wizrobe/marisa/fake,
|
||||||
@@ -124,7 +124,7 @@ datum/supply_pack/costumes/witch
|
|||||||
/datum/supply_pack/randomised/costumes/costume_hats
|
/datum/supply_pack/randomised/costumes/costume_hats
|
||||||
name = "Costume hats"
|
name = "Costume hats"
|
||||||
containername = "Actor hats crate"
|
containername = "Actor hats crate"
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/nanothreads
|
||||||
cost = 10
|
cost = 10
|
||||||
num_contained = 3
|
num_contained = 3
|
||||||
contains = list(
|
contains = list(
|
||||||
@@ -147,9 +147,9 @@ datum/supply_pack/costumes/witch
|
|||||||
)
|
)
|
||||||
|
|
||||||
/datum/supply_pack/randomised/costumes/dresses
|
/datum/supply_pack/randomised/costumes/dresses
|
||||||
name = "Womens formal dress locker"
|
name = "Formalwear (Dresses)"
|
||||||
containername = "Pretty dress locker"
|
containername = "Formal dress crate"
|
||||||
containertype = /obj/structure/closet
|
containertype = /obj/structure/closet/crate/gilthari
|
||||||
cost = 15
|
cost = 15
|
||||||
num_contained = 3
|
num_contained = 3
|
||||||
contains = list(
|
contains = list(
|
||||||
|
|||||||
@@ -11,30 +11,72 @@
|
|||||||
name = "Replacement lights"
|
name = "Replacement lights"
|
||||||
contains = list(/obj/item/weapon/storage/box/lights/mixed = 3)
|
contains = list(/obj/item/weapon/storage/box/lights/mixed = 3)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/galaksi
|
||||||
containername = "Replacement lights"
|
containername = "Replacement lights"
|
||||||
|
|
||||||
/datum/supply_pack/eng/smescoil
|
/datum/supply_pack/eng/smescoil
|
||||||
name = "Superconducting Magnetic Coil"
|
name = "Superconducting Magnetic Coil"
|
||||||
contains = list(/obj/item/weapon/smes_coil)
|
contains = list(/obj/item/weapon/smes_coil)
|
||||||
cost = 75
|
cost = 75
|
||||||
containertype = /obj/structure/closet/crate/engineering
|
containertype = /obj/structure/closet/crate/focalpoint
|
||||||
containername = "Superconducting Magnetic Coil crate"
|
containername = "Superconducting Magnetic Coil crate"
|
||||||
|
|
||||||
/datum/supply_pack/eng/smescoil/super_capacity
|
/datum/supply_pack/eng/smescoil/super_capacity
|
||||||
name = "Superconducting Capacitance Coil"
|
name = "Superconducting Capacitance Coil"
|
||||||
contains = list(/obj/item/weapon/smes_coil/super_capacity)
|
contains = list(/obj/item/weapon/smes_coil/super_capacity)
|
||||||
cost = 90
|
cost = 90
|
||||||
containertype = /obj/structure/closet/crate/engineering
|
containertype = /obj/structure/closet/crate/focalpoint
|
||||||
containername = "Superconducting Capacitance Coil crate"
|
containername = "Superconducting Capacitance Coil crate"
|
||||||
|
|
||||||
/datum/supply_pack/eng/smescoil/super_io
|
/datum/supply_pack/eng/smescoil/super_io
|
||||||
name = "Superconducting Transmission Coil"
|
name = "Superconducting Transmission Coil"
|
||||||
contains = list(/obj/item/weapon/smes_coil/super_io)
|
contains = list(/obj/item/weapon/smes_coil/super_io)
|
||||||
cost = 90
|
cost = 90
|
||||||
containertype = /obj/structure/closet/crate/engineering
|
containertype = /obj/structure/closet/crate/focalpoint
|
||||||
containername = "Superconducting Transmission Coil crate"
|
containername = "Superconducting Transmission Coil crate"
|
||||||
|
|
||||||
|
/datum/supply_pack/eng/shield_capacitor
|
||||||
|
name = "Shield Capacitor"
|
||||||
|
contains = list(/obj/machinery/shield_capacitor)
|
||||||
|
cost = 20
|
||||||
|
containertype = /obj/structure/closet/crate/focalpoint
|
||||||
|
containername = "shield capacitor crate"
|
||||||
|
|
||||||
|
/datum/supply_pack/eng/shield_capacitor/advanced
|
||||||
|
name = "Advanced Shield Capacitor"
|
||||||
|
contains = list(/obj/machinery/shield_capacitor/advanced)
|
||||||
|
cost = 30
|
||||||
|
containertype = /obj/structure/closet/crate/focalpoint
|
||||||
|
containername = "advanced shield capacitor crate"
|
||||||
|
|
||||||
|
/datum/supply_pack/eng/bubble_shield
|
||||||
|
name = "Bubble Shield Generator"
|
||||||
|
contains = list(/obj/machinery/shield_gen)
|
||||||
|
cost = 40
|
||||||
|
containertype =/obj/structure/closet/crate/focalpoint
|
||||||
|
containername = "shield bubble generator crate"
|
||||||
|
|
||||||
|
/datum/supply_pack/eng/bubble_shield/advanced
|
||||||
|
name = "Advanced Bubble Shield Generator"
|
||||||
|
contains = list(/obj/machinery/shield_gen/advanced)
|
||||||
|
cost = 60
|
||||||
|
containertype = /obj/structure/closet/crate/focalpoint
|
||||||
|
containername = "advanced bubble shield generator crate"
|
||||||
|
|
||||||
|
/datum/supply_pack/eng/hull_shield
|
||||||
|
name = "Hull Shield Generator"
|
||||||
|
contains = list(/obj/machinery/shield_gen/external)
|
||||||
|
cost = 80
|
||||||
|
containertype = /obj/structure/closet/crate/focalpoint
|
||||||
|
containername = "shield hull generator crate"
|
||||||
|
|
||||||
|
/datum/supply_pack/eng/hull_shield/advanced
|
||||||
|
name = "Advanced Hull Shield Generator"
|
||||||
|
contains = list(/obj/machinery/shield_gen/external/advanced)
|
||||||
|
cost = 120
|
||||||
|
containertype = /obj/structure/closet/crate/focalpoint
|
||||||
|
containername = "advanced hull shield generator crate"
|
||||||
|
|
||||||
/datum/supply_pack/eng/electrical
|
/datum/supply_pack/eng/electrical
|
||||||
name = "Electrical maintenance crate"
|
name = "Electrical maintenance crate"
|
||||||
contains = list(
|
contains = list(
|
||||||
@@ -44,7 +86,7 @@
|
|||||||
/obj/item/weapon/cell/high = 2
|
/obj/item/weapon/cell/high = 2
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/engineering/electrical
|
containertype = /obj/structure/closet/crate/ward
|
||||||
containername = "Electrical maintenance crate"
|
containername = "Electrical maintenance crate"
|
||||||
|
|
||||||
/datum/supply_pack/eng/e_welders
|
/datum/supply_pack/eng/e_welders
|
||||||
@@ -53,7 +95,7 @@
|
|||||||
/obj/item/weapon/weldingtool/electric = 3
|
/obj/item/weapon/weldingtool/electric = 3
|
||||||
)
|
)
|
||||||
cost = 15
|
cost = 15
|
||||||
containertype = /obj/structure/closet/crate/engineering/electrical
|
containertype = /obj/structure/closet/crate/ward
|
||||||
containername = "Electric welder crate"
|
containername = "Electric welder crate"
|
||||||
|
|
||||||
/datum/supply_pack/eng/mechanical
|
/datum/supply_pack/eng/mechanical
|
||||||
@@ -65,14 +107,14 @@
|
|||||||
/obj/item/clothing/head/hardhat
|
/obj/item/clothing/head/hardhat
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/engineering
|
containertype = /obj/structure/closet/crate/xion
|
||||||
containername = "Mechanical maintenance crate"
|
containername = "Mechanical maintenance crate"
|
||||||
|
|
||||||
/datum/supply_pack/eng/fueltank
|
/datum/supply_pack/eng/fueltank
|
||||||
name = "Fuel tank crate"
|
name = "Fuel tank crate"
|
||||||
contains = list(/obj/structure/reagent_dispensers/fueltank)
|
contains = list(/obj/structure/reagent_dispensers/fueltank)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/largecrate
|
containertype = /obj/structure/closet/crate/large/nanotrasen
|
||||||
containername = "fuel tank crate"
|
containername = "fuel tank crate"
|
||||||
|
|
||||||
/datum/supply_pack/eng/solar
|
/datum/supply_pack/eng/solar
|
||||||
@@ -84,35 +126,35 @@
|
|||||||
/obj/item/weapon/paper/solar
|
/obj/item/weapon/paper/solar
|
||||||
)
|
)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/engineering
|
containertype = /obj/structure/closet/crate/einstein
|
||||||
containername = "Solar pack crate"
|
containername = "Solar pack crate"
|
||||||
|
|
||||||
/datum/supply_pack/eng/engine
|
/datum/supply_pack/eng/engine
|
||||||
name = "Emitter crate"
|
name = "Emitter crate"
|
||||||
contains = list(/obj/machinery/power/emitter = 2)
|
contains = list(/obj/machinery/power/emitter = 2)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/secure/engineering
|
containertype = /obj/structure/closet/crate/secure/einstein
|
||||||
containername = "Emitter crate"
|
containername = "Emitter crate"
|
||||||
access = access_ce
|
access = access_ce
|
||||||
|
|
||||||
/datum/supply_pack/eng/engine/field_gen
|
/datum/supply_pack/eng/engine/field_gen
|
||||||
name = "Field Generator crate"
|
name = "Field Generator crate"
|
||||||
contains = list(/obj/machinery/field_generator = 2)
|
contains = list(/obj/machinery/field_generator = 2)
|
||||||
containertype = /obj/structure/closet/crate/secure/engineering
|
containertype = /obj/structure/closet/crate/secure/xion
|
||||||
containername = "Field Generator crate"
|
containername = "Field Generator crate"
|
||||||
access = access_ce
|
access = access_ce
|
||||||
|
|
||||||
/datum/supply_pack/eng/engine/sing_gen
|
/datum/supply_pack/eng/engine/sing_gen
|
||||||
name = "Singularity Generator crate"
|
name = "Singularity Generator crate"
|
||||||
contains = list(/obj/machinery/the_singularitygen)
|
contains = list(/obj/machinery/the_singularitygen)
|
||||||
containertype = /obj/structure/closet/crate/secure/engineering
|
containertype = /obj/structure/closet/crate/secure/einstein
|
||||||
containername = "Singularity Generator crate"
|
containername = "Singularity Generator crate"
|
||||||
access = access_ce
|
access = access_ce
|
||||||
|
|
||||||
/datum/supply_pack/eng/engine/collector
|
/datum/supply_pack/eng/engine/collector
|
||||||
name = "Collector crate"
|
name = "Collector crate"
|
||||||
contains = list(/obj/machinery/power/rad_collector = 3)
|
contains = list(/obj/machinery/power/rad_collector = 3)
|
||||||
containertype = /obj/structure/closet/crate/secure/engineering
|
containertype = /obj/structure/closet/crate/secure/einstein
|
||||||
containername = "Collector crate"
|
containername = "Collector crate"
|
||||||
|
|
||||||
/datum/supply_pack/eng/engine/PA
|
/datum/supply_pack/eng/engine/PA
|
||||||
@@ -127,23 +169,33 @@
|
|||||||
/obj/structure/particle_accelerator/power_box,
|
/obj/structure/particle_accelerator/power_box,
|
||||||
/obj/structure/particle_accelerator/end_cap
|
/obj/structure/particle_accelerator/end_cap
|
||||||
)
|
)
|
||||||
containertype = /obj/structure/closet/crate/secure/engineering
|
containertype = /obj/structure/closet/crate/secure/einstein
|
||||||
containername = "Particle Accelerator crate"
|
containername = "Particle Accelerator crate"
|
||||||
access = access_ce
|
access = access_ce
|
||||||
|
|
||||||
/datum/supply_pack/eng/shield_generator
|
/datum/supply_pack/eng/shield_gen
|
||||||
name = "Shield Generator Construction Kit"
|
contains = list(/obj/item/weapon/circuitboard/shield_gen)
|
||||||
contains = list(
|
name = "Bubble shield generator circuitry"
|
||||||
/obj/item/weapon/circuitboard/shield_generator,
|
cost = 30
|
||||||
/obj/item/weapon/stock_parts/capacitor,
|
containertype = /obj/structure/closet/crate/secure/focalpoint
|
||||||
/obj/item/weapon/stock_parts/micro_laser,
|
containername = "bubble shield generator circuitry crate"
|
||||||
/obj/item/weapon/smes_coil,
|
access = access_ce
|
||||||
/obj/item/weapon/stock_parts/console_screen,
|
|
||||||
/obj/item/weapon/stock_parts/subspace/amplifier
|
/datum/supply_pack/eng/shield_gen_ex
|
||||||
)
|
contains = list(/obj/item/weapon/circuitboard/shield_gen_ex)
|
||||||
cost = 80
|
name = "Hull shield generator circuitry"
|
||||||
containertype = /obj/structure/closet/crate/engineering
|
cost = 30
|
||||||
containername = "shield generator construction kit crate"
|
containertype = /obj/structure/closet/crate/secure/focalpoint
|
||||||
|
containername = "hull shield generator circuitry crate"
|
||||||
|
access = access_ce
|
||||||
|
|
||||||
|
/datum/supply_pack/eng/shield_cap
|
||||||
|
contains = list(/obj/item/weapon/circuitboard/shield_cap)
|
||||||
|
name = "Bubble shield capacitor circuitry"
|
||||||
|
cost = 30
|
||||||
|
containertype = /obj/structure/closet/crate/secure/focalpoint
|
||||||
|
containername = "shield capacitor circuitry crate"
|
||||||
|
access = access_ce
|
||||||
|
|
||||||
/datum/supply_pack/eng/smbig
|
/datum/supply_pack/eng/smbig
|
||||||
name = "Supermatter Core"
|
name = "Supermatter Core"
|
||||||
@@ -157,7 +209,7 @@
|
|||||||
contains = list(/obj/machinery/power/generator)
|
contains = list(/obj/machinery/power/generator)
|
||||||
name = "Mark I Thermoelectric Generator"
|
name = "Mark I Thermoelectric Generator"
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/secure/large
|
containertype = /obj/structure/closet/crate/secure/large/einstein
|
||||||
containername = "Mk1 TEG crate"
|
containername = "Mk1 TEG crate"
|
||||||
access = access_engine
|
access = access_engine
|
||||||
|
|
||||||
@@ -165,7 +217,7 @@
|
|||||||
contains = list(/obj/machinery/atmospherics/binary/circulator)
|
contains = list(/obj/machinery/atmospherics/binary/circulator)
|
||||||
name = "Binary atmospheric circulator"
|
name = "Binary atmospheric circulator"
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/secure/large
|
containertype = /obj/structure/closet/crate/secure/large/einstein
|
||||||
containername = "Atmospheric circulator crate"
|
containername = "Atmospheric circulator crate"
|
||||||
access = access_engine
|
access = access_engine
|
||||||
|
|
||||||
@@ -183,7 +235,7 @@
|
|||||||
name = "P.A.C.M.A.N. portable generator parts"
|
name = "P.A.C.M.A.N. portable generator parts"
|
||||||
cost = 25
|
cost = 25
|
||||||
containername = "P.A.C.M.A.N. Portable Generator Construction Kit"
|
containername = "P.A.C.M.A.N. Portable Generator Construction Kit"
|
||||||
containertype = /obj/structure/closet/crate/secure/engineering
|
containertype = /obj/structure/closet/crate/secure/focalpoint
|
||||||
access = access_tech_storage
|
access = access_tech_storage
|
||||||
contains = list(
|
contains = list(
|
||||||
/obj/item/weapon/stock_parts/micro_laser,
|
/obj/item/weapon/stock_parts/micro_laser,
|
||||||
@@ -196,7 +248,7 @@
|
|||||||
name = "Super P.A.C.M.A.N. portable generator parts"
|
name = "Super P.A.C.M.A.N. portable generator parts"
|
||||||
cost = 35
|
cost = 35
|
||||||
containername = "Super P.A.C.M.A.N. portable generator construction kit"
|
containername = "Super P.A.C.M.A.N. portable generator construction kit"
|
||||||
containertype = /obj/structure/closet/crate/secure/engineering
|
containertype = /obj/structure/closet/crate/secure/focalpoint
|
||||||
access = access_tech_storage
|
access = access_tech_storage
|
||||||
contains = list(
|
contains = list(
|
||||||
/obj/item/weapon/stock_parts/micro_laser,
|
/obj/item/weapon/stock_parts/micro_laser,
|
||||||
@@ -209,7 +261,7 @@
|
|||||||
name = "R-UST Mk. 8 Tokamak fusion core crate"
|
name = "R-UST Mk. 8 Tokamak fusion core crate"
|
||||||
cost = 50
|
cost = 50
|
||||||
containername = "R-UST Mk. 8 Tokamak Fusion Core crate"
|
containername = "R-UST Mk. 8 Tokamak Fusion Core crate"
|
||||||
containertype = /obj/structure/closet/crate/secure/engineering
|
containertype = /obj/structure/closet/crate/secure/einstein
|
||||||
access = access_engine
|
access = access_engine
|
||||||
contains = list(
|
contains = list(
|
||||||
/obj/item/weapon/book/manual/rust_engine,
|
/obj/item/weapon/book/manual/rust_engine,
|
||||||
@@ -221,7 +273,7 @@
|
|||||||
name = "R-UST Mk. 8 fuel injector crate"
|
name = "R-UST Mk. 8 fuel injector crate"
|
||||||
cost = 30
|
cost = 30
|
||||||
containername = "R-UST Mk. 8 fuel injector crate"
|
containername = "R-UST Mk. 8 fuel injector crate"
|
||||||
containertype = /obj/structure/closet/crate/secure/engineering
|
containertype = /obj/structure/closet/crate/secure/einstein
|
||||||
access = access_engine
|
access = access_engine
|
||||||
contains = list(
|
contains = list(
|
||||||
/obj/machinery/fusion_fuel_injector,
|
/obj/machinery/fusion_fuel_injector,
|
||||||
@@ -233,7 +285,7 @@
|
|||||||
name = "Gyrotron crate"
|
name = "Gyrotron crate"
|
||||||
cost = 15
|
cost = 15
|
||||||
containername = "Gyrotron Crate"
|
containername = "Gyrotron Crate"
|
||||||
containertype = /obj/structure/closet/crate/secure/engineering
|
containertype = /obj/structure/closet/crate/secure/einstein
|
||||||
access = access_engine
|
access = access_engine
|
||||||
contains = list(
|
contains = list(
|
||||||
/obj/machinery/power/emitter/gyrotron,
|
/obj/machinery/power/emitter/gyrotron,
|
||||||
@@ -244,12 +296,12 @@
|
|||||||
name = "Fusion Fuel Compressor circuitry crate"
|
name = "Fusion Fuel Compressor circuitry crate"
|
||||||
cost = 10
|
cost = 10
|
||||||
containername = "Fusion Fuel Compressor circuitry crate"
|
containername = "Fusion Fuel Compressor circuitry crate"
|
||||||
containertype = /obj/structure/closet/crate/engineering
|
containertype = /obj/structure/closet/crate/einstein
|
||||||
contains = list(/obj/item/weapon/circuitboard/fusion_fuel_compressor)
|
contains = list(/obj/item/weapon/circuitboard/fusion_fuel_compressor)
|
||||||
|
|
||||||
/datum/supply_pack/eng/tritium
|
/datum/supply_pack/eng/tritium
|
||||||
name = "Tritium crate"
|
name = "Tritium crate"
|
||||||
cost = 75
|
cost = 75
|
||||||
containername = "Tritium crate"
|
containername = "Tritium crate"
|
||||||
containertype = /obj/structure/closet/crate/engineering
|
containertype = /obj/structure/closet/crate/einstein
|
||||||
contains = list(/obj/fiftyspawner/tritium)
|
contains = list(/obj/fiftyspawner/tritium)
|
||||||
|
|||||||
@@ -1,3 +1,17 @@
|
|||||||
|
/datum/supply_pack/eng/modern_shield
|
||||||
|
name = "Modern Shield Construction Kit"
|
||||||
|
contains = list(
|
||||||
|
/obj/item/weapon/circuitboard/shield_generator,
|
||||||
|
/obj/item/weapon/stock_parts/capacitor,
|
||||||
|
/obj/item/weapon/stock_parts/micro_laser,
|
||||||
|
/obj/item/weapon/smes_coil,
|
||||||
|
/obj/item/weapon/stock_parts/console_screen,
|
||||||
|
/obj/item/weapon/stock_parts/subspace/amplifier
|
||||||
|
)
|
||||||
|
cost = 80
|
||||||
|
containertype = /obj/structure/closet/crate/focalpoint
|
||||||
|
containername = "shield generator construction kit crate"
|
||||||
|
|
||||||
/datum/supply_pack/eng/thermoregulator
|
/datum/supply_pack/eng/thermoregulator
|
||||||
contains = list(/obj/machinery/power/thermoregulator)
|
contains = list(/obj/machinery/power/thermoregulator)
|
||||||
name = "Thermal Regulator"
|
name = "Thermal Regulator"
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer = 4,
|
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer = 4,
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/gilthari
|
||||||
containername = "Party equipment"
|
containername = "Party equipment"
|
||||||
|
|
||||||
/datum/supply_pack/hospitality/barsupplies
|
/datum/supply_pack/hospitality/barsupplies
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
/obj/item/weapon/storage/box/glass_extras/sticks
|
/obj/item/weapon/storage/box/glass_extras/sticks
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/gilthari
|
||||||
containername = "crate of bar supplies"
|
containername = "crate of bar supplies"
|
||||||
|
|
||||||
/datum/supply_pack/hospitality/cookingoil
|
/datum/supply_pack/hospitality/cookingoil
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
)
|
)
|
||||||
name = "Surprise pack of five pizzas"
|
name = "Surprise pack of five pizzas"
|
||||||
cost = 15
|
cost = 15
|
||||||
containertype = /obj/structure/closet/crate/freezer
|
containertype = /obj/structure/closet/crate/freezer/centauri
|
||||||
containername = "Pizza crate"
|
containername = "Pizza crate"
|
||||||
|
|
||||||
/datum/supply_pack/hospitality/gifts
|
/datum/supply_pack/hospitality/gifts
|
||||||
@@ -81,5 +81,5 @@
|
|||||||
/obj/item/weapon/paper/card/flower
|
/obj/item/weapon/paper/card/flower
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/allico
|
||||||
containername = "crate of gifts"
|
containername = "crate of gifts"
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
name = "Monkey crate"
|
name = "Monkey crate"
|
||||||
contains = list (/obj/item/weapon/storage/box/monkeycubes)
|
contains = list (/obj/item/weapon/storage/box/monkeycubes)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/freezer
|
containertype = /obj/structure/closet/crate/freezer/nanotrasen
|
||||||
containername = "Monkey crate"
|
containername = "Monkey crate"
|
||||||
|
|
||||||
/datum/supply_pack/hydro/farwa
|
/datum/supply_pack/hydro/farwa
|
||||||
@@ -110,7 +110,7 @@
|
|||||||
/obj/item/seeds/sugarcaneseed
|
/obj/item/seeds/sugarcaneseed
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/hydroponics
|
containertype = /obj/structure/closet/crate/carp
|
||||||
containername = "Seeds crate"
|
containername = "Seeds crate"
|
||||||
access = access_hydroponics
|
access = access_hydroponics
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@
|
|||||||
/obj/item/weapon/material/twohanded/fireaxe/scythe
|
/obj/item/weapon/material/twohanded/fireaxe/scythe
|
||||||
)
|
)
|
||||||
cost = 45
|
cost = 45
|
||||||
containertype = /obj/structure/closet/crate/hydroponics
|
containertype = /obj/structure/closet/crate/grayson
|
||||||
containername = "Weed control crate"
|
containername = "Weed control crate"
|
||||||
access = access_hydroponics
|
access = access_hydroponics
|
||||||
|
|
||||||
@@ -132,7 +132,7 @@
|
|||||||
name = "Water tank crate"
|
name = "Water tank crate"
|
||||||
contains = list(/obj/structure/reagent_dispensers/watertank)
|
contains = list(/obj/structure/reagent_dispensers/watertank)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/largecrate
|
containertype = /obj/structure/closet/crate/large/aether
|
||||||
containername = "water tank crate"
|
containername = "water tank crate"
|
||||||
|
|
||||||
/datum/supply_pack/hydro/bee_keeper
|
/datum/supply_pack/hydro/bee_keeper
|
||||||
@@ -144,14 +144,14 @@
|
|||||||
/obj/item/bee_pack
|
/obj/item/bee_pack
|
||||||
)
|
)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/hydroponics
|
containertype = /obj/structure/closet/crate/carp
|
||||||
containername = "Beekeeping crate"
|
containername = "Beekeeping crate"
|
||||||
access = access_hydroponics
|
access = access_hydroponics
|
||||||
|
|
||||||
/datum/supply_pack/hydro/tray
|
/datum/supply_pack/hydro/tray
|
||||||
name = "Empty hydroponics trays"
|
name = "Empty hydroponics trays"
|
||||||
cost = 50
|
cost = 50
|
||||||
containertype = /obj/structure/closet/crate/hydroponics
|
containertype = /obj/structure/closet/crate/aether
|
||||||
containername = "Hydroponics tray crate"
|
containername = "Hydroponics tray crate"
|
||||||
contains = list(/obj/machinery/portable_atmospherics/hydroponics{anchored = 0} = 3)
|
contains = list(/obj/machinery/portable_atmospherics/hydroponics{anchored = 0} = 3)
|
||||||
access = access_hydroponics
|
access = access_hydroponics
|
||||||
|
|||||||
@@ -11,40 +11,40 @@
|
|||||||
name = "50 metal sheets"
|
name = "50 metal sheets"
|
||||||
contains = list(/obj/fiftyspawner/steel)
|
contains = list(/obj/fiftyspawner/steel)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/grayson
|
||||||
containername = "Metal sheets crate"
|
containername = "Metal sheets crate"
|
||||||
|
|
||||||
/datum/supply_pack/materials/glass50
|
/datum/supply_pack/materials/glass50
|
||||||
name = "50 glass sheets"
|
name = "50 glass sheets"
|
||||||
contains = list(/obj/fiftyspawner/glass)
|
contains = list(/obj/fiftyspawner/glass)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/grayson
|
||||||
containername = "Glass sheets crate"
|
containername = "Glass sheets crate"
|
||||||
|
|
||||||
/datum/supply_pack/materials/wood50
|
/datum/supply_pack/materials/wood50
|
||||||
name = "50 wooden planks"
|
name = "50 wooden planks"
|
||||||
contains = list(/obj/fiftyspawner/wood)
|
contains = list(/obj/fiftyspawner/wood)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/grayson
|
||||||
containername = "Wooden planks crate"
|
containername = "Wooden planks crate"
|
||||||
|
|
||||||
/datum/supply_pack/materials/plastic50
|
/datum/supply_pack/materials/plastic50
|
||||||
name = "50 plastic sheets"
|
name = "50 plastic sheets"
|
||||||
contains = list(/obj/fiftyspawner/plastic)
|
contains = list(/obj/fiftyspawner/plastic)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/grayson
|
||||||
containername = "Plastic sheets crate"
|
containername = "Plastic sheets crate"
|
||||||
|
|
||||||
/datum/supply_pack/materials/cardboard_sheets
|
/datum/supply_pack/materials/cardboard_sheets
|
||||||
contains = list(/obj/fiftyspawner/cardboard)
|
contains = list(/obj/fiftyspawner/cardboard)
|
||||||
name = "50 cardboard sheets"
|
name = "50 cardboard sheets"
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/grayson
|
||||||
containername = "Cardboard sheets crate"
|
containername = "Cardboard sheets crate"
|
||||||
|
|
||||||
/datum/supply_pack/materials/carpet
|
/datum/supply_pack/materials/carpet
|
||||||
name = "Imported carpet"
|
name = "Imported carpet"
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/grayson
|
||||||
containername = "Imported carpet crate"
|
containername = "Imported carpet crate"
|
||||||
cost = 15
|
cost = 15
|
||||||
contains = list(
|
contains = list(
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
|
|
||||||
/datum/supply_pack/misc/linoleum
|
/datum/supply_pack/misc/linoleum
|
||||||
name = "Linoleum"
|
name = "Linoleum"
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/grayson
|
||||||
containername = "Linoleum crate"
|
containername = "Linoleum crate"
|
||||||
cost = 15
|
cost = 15
|
||||||
contains = list(/obj/fiftyspawner/linoleum)
|
contains = list(/obj/fiftyspawner/linoleum)
|
||||||
@@ -22,28 +22,28 @@
|
|||||||
/obj/item/weapon/storage/box/autoinjectors
|
/obj/item/weapon/storage/box/autoinjectors
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/medical
|
containertype = /obj/structure/closet/crate/zenghu
|
||||||
containername = "Medical crate"
|
containername = "Medical crate"
|
||||||
|
|
||||||
/datum/supply_pack/med/bloodpack
|
/datum/supply_pack/med/bloodpack
|
||||||
name = "BloodPack crate"
|
name = "BloodPack crate"
|
||||||
contains = list(/obj/item/weapon/storage/box/bloodpacks = 3)
|
contains = list(/obj/item/weapon/storage/box/bloodpacks = 3)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/medical
|
containertype = /obj/structure/closet/crate/nanocare
|
||||||
containername = "BloodPack crate"
|
containername = "BloodPack crate"
|
||||||
|
|
||||||
/datum/supply_pack/med/bodybag
|
/datum/supply_pack/med/bodybag
|
||||||
name = "Body bag crate"
|
name = "Body bag crate"
|
||||||
contains = list(/obj/item/weapon/storage/box/bodybags = 3)
|
contains = list(/obj/item/weapon/storage/box/bodybags = 3)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/medical
|
containertype = /obj/structure/closet/crate/nanocare
|
||||||
containername = "Body bag crate"
|
containername = "Body bag crate"
|
||||||
|
|
||||||
/datum/supply_pack/med/cryobag
|
/datum/supply_pack/med/cryobag
|
||||||
name = "Stasis bag crate"
|
name = "Stasis bag crate"
|
||||||
contains = list(/obj/item/bodybag/cryobag = 3)
|
contains = list(/obj/item/bodybag/cryobag = 3)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/medical
|
containertype = /obj/structure/closet/crate/nanocare
|
||||||
containername = "Stasis bag crate"
|
containername = "Stasis bag crate"
|
||||||
|
|
||||||
/datum/supply_pack/med/surgery
|
/datum/supply_pack/med/surgery
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
/obj/item/weapon/surgical/circular_saw
|
/obj/item/weapon/surgical/circular_saw
|
||||||
)
|
)
|
||||||
cost = 25
|
cost = 25
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/veymed
|
||||||
containername = "Surgery crate"
|
containername = "Surgery crate"
|
||||||
access = access_medical
|
access = access_medical
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
/obj/item/weapon/storage/box/cdeathalarm_kit
|
/obj/item/weapon/storage/box/cdeathalarm_kit
|
||||||
)
|
)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/ward
|
||||||
containername = "Death Alarm crate"
|
containername = "Death Alarm crate"
|
||||||
access = access_medical
|
access = access_medical
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
/obj/item/weapon/storage/firstaid/clotting
|
/obj/item/weapon/storage/firstaid/clotting
|
||||||
)
|
)
|
||||||
cost = 100
|
cost = 100
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/zenghu
|
||||||
containername = "Clotting Medicine crate"
|
containername = "Clotting Medicine crate"
|
||||||
access = access_medical
|
access = access_medical
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@
|
|||||||
/obj/item/weapon/storage/belt/medical = 3
|
/obj/item/weapon/storage/belt/medical = 3
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/veymed
|
||||||
containername = "Sterile equipment crate"
|
containername = "Sterile equipment crate"
|
||||||
|
|
||||||
/datum/supply_pack/med/extragear
|
/datum/supply_pack/med/extragear
|
||||||
@@ -109,7 +109,7 @@
|
|||||||
/obj/item/clothing/suit/storage/hooded/wintercoat/medical = 3
|
/obj/item/clothing/suit/storage/hooded/wintercoat/medical = 3
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanocare
|
||||||
containername = "Medical surplus equipment"
|
containername = "Medical surplus equipment"
|
||||||
access = access_medical
|
access = access_medical
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
/obj/item/weapon/reagent_containers/syringe
|
/obj/item/weapon/reagent_containers/syringe
|
||||||
)
|
)
|
||||||
cost = 50
|
cost = 50
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanocare
|
||||||
containername = "Chief medical officer equipment"
|
containername = "Chief medical officer equipment"
|
||||||
access = access_cmo
|
access = access_cmo
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@
|
|||||||
/obj/item/weapon/reagent_containers/syringe
|
/obj/item/weapon/reagent_containers/syringe
|
||||||
)
|
)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanocare
|
||||||
containername = "Medical Doctor equipment"
|
containername = "Medical Doctor equipment"
|
||||||
access = access_medical_equip
|
access = access_medical_equip
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@
|
|||||||
/obj/item/weapon/reagent_containers/syringe
|
/obj/item/weapon/reagent_containers/syringe
|
||||||
)
|
)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanocare
|
||||||
containername = "Chemist equipment"
|
containername = "Chemist equipment"
|
||||||
access = access_chemistry
|
access = access_chemistry
|
||||||
|
|
||||||
@@ -207,7 +207,7 @@
|
|||||||
/obj/item/clothing/accessory/storage/white_vest
|
/obj/item/clothing/accessory/storage/white_vest
|
||||||
)
|
)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanocare
|
||||||
containername = "Paramedic equipment"
|
containername = "Paramedic equipment"
|
||||||
access = access_medical_equip
|
access = access_medical_equip
|
||||||
|
|
||||||
@@ -226,7 +226,7 @@
|
|||||||
/obj/item/weapon/cartridge/medical
|
/obj/item/weapon/cartridge/medical
|
||||||
)
|
)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanocare
|
||||||
containername = "Psychiatrist equipment"
|
containername = "Psychiatrist equipment"
|
||||||
access = access_psychiatrist
|
access = access_psychiatrist
|
||||||
|
|
||||||
@@ -247,7 +247,7 @@
|
|||||||
/obj/item/weapon/storage/box/gloves
|
/obj/item/weapon/storage/box/gloves
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanocare
|
||||||
containername = "Medical scrubs crate"
|
containername = "Medical scrubs crate"
|
||||||
access = access_medical_equip
|
access = access_medical_equip
|
||||||
|
|
||||||
@@ -264,7 +264,7 @@
|
|||||||
/obj/item/weapon/pen
|
/obj/item/weapon/pen
|
||||||
)
|
)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/veymed
|
||||||
containername = "Autopsy equipment crate"
|
containername = "Autopsy equipment crate"
|
||||||
access = access_morgue
|
access = access_morgue
|
||||||
|
|
||||||
@@ -291,7 +291,7 @@
|
|||||||
/obj/item/weapon/storage/box/gloves
|
/obj/item/weapon/storage/box/gloves
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanocare
|
||||||
containername = "Medical uniform crate"
|
containername = "Medical uniform crate"
|
||||||
access = access_medical_equip
|
access = access_medical_equip
|
||||||
|
|
||||||
@@ -309,7 +309,7 @@
|
|||||||
/obj/item/weapon/storage/box/gloves
|
/obj/item/weapon/storage/box/gloves
|
||||||
)
|
)
|
||||||
cost = 50
|
cost = 50
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanocare
|
||||||
containername = "Medical biohazard equipment"
|
containername = "Medical biohazard equipment"
|
||||||
access = access_medical_equip
|
access = access_medical_equip
|
||||||
|
|
||||||
@@ -317,7 +317,7 @@
|
|||||||
name = "Portable freezers crate"
|
name = "Portable freezers crate"
|
||||||
contains = list(/obj/item/weapon/storage/box/freezer = 7)
|
contains = list(/obj/item/weapon/storage/box/freezer = 7)
|
||||||
cost = 25
|
cost = 25
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/veymed
|
||||||
containername = "Portable freezers"
|
containername = "Portable freezers"
|
||||||
access = access_medical_equip
|
access = access_medical_equip
|
||||||
|
|
||||||
@@ -325,7 +325,7 @@
|
|||||||
name = "Virus sample crate"
|
name = "Virus sample crate"
|
||||||
contains = list(/obj/item/weapon/virusdish/random = 4)
|
contains = list(/obj/item/weapon/virusdish/random = 4)
|
||||||
cost = 25
|
cost = 25
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/zenghu
|
||||||
containername = "Virus sample crate"
|
containername = "Virus sample crate"
|
||||||
access = access_cmo
|
access = access_cmo
|
||||||
|
|
||||||
@@ -333,40 +333,40 @@
|
|||||||
name = "Defibrillator crate"
|
name = "Defibrillator crate"
|
||||||
contains = list(/obj/item/device/defib_kit = 2)
|
contains = list(/obj/item/device/defib_kit = 2)
|
||||||
cost = 30
|
cost = 30
|
||||||
containertype = /obj/structure/closet/crate/medical
|
containertype = /obj/structure/closet/crate/veymed
|
||||||
containername = "Defibrillator crate"
|
containername = "Defibrillator crate"
|
||||||
|
|
||||||
/datum/supply_pack/med/distillery
|
/datum/supply_pack/med/distillery
|
||||||
name = "Chemical distiller crate"
|
name = "Chemical distiller crate"
|
||||||
contains = list(/obj/machinery/portable_atmospherics/powered/reagent_distillery = 1)
|
contains = list(/obj/machinery/portable_atmospherics/powered/reagent_distillery = 1)
|
||||||
cost = 50
|
cost = 50
|
||||||
containertype = /obj/structure/largecrate
|
containertype = /obj/structure/closet/crate/large/nanotrasen
|
||||||
containername = "Chemical distiller crate"
|
containername = "Chemical distiller crate"
|
||||||
|
|
||||||
/datum/supply_pack/med/advdistillery
|
/datum/supply_pack/med/advdistillery
|
||||||
name = "Industrial Chemical distiller crate"
|
name = "Industrial Chemical distiller crate"
|
||||||
contains = list(/obj/machinery/portable_atmospherics/powered/reagent_distillery/industrial = 1)
|
contains = list(/obj/machinery/portable_atmospherics/powered/reagent_distillery/industrial = 1)
|
||||||
cost = 150
|
cost = 150
|
||||||
containertype = /obj/structure/largecrate
|
containertype = /obj/structure/closet/crate/large/xion
|
||||||
containername = "Industrial Chemical distiller crate"
|
containername = "Industrial Chemical distiller crate"
|
||||||
|
|
||||||
/datum/supply_pack/med/oxypump
|
/datum/supply_pack/med/oxypump
|
||||||
name = "Oxygen pump crate"
|
name = "Oxygen pump crate"
|
||||||
contains = list(/obj/machinery/oxygen_pump/mobile = 1)
|
contains = list(/obj/machinery/oxygen_pump/mobile = 1)
|
||||||
cost = 125
|
cost = 125
|
||||||
containertype = /obj/structure/largecrate
|
containertype = /obj/structure/closet/crate/large/xion
|
||||||
containername = "Oxygen pump crate"
|
containername = "Oxygen pump crate"
|
||||||
|
|
||||||
/datum/supply_pack/med/anestheticpump
|
/datum/supply_pack/med/anestheticpump
|
||||||
name = "Anesthetic pump crate"
|
name = "Anesthetic pump crate"
|
||||||
contains = list(/obj/machinery/oxygen_pump/mobile/anesthetic = 1)
|
contains = list(/obj/machinery/oxygen_pump/mobile/anesthetic = 1)
|
||||||
cost = 130
|
cost = 130
|
||||||
containertype = /obj/structure/largecrate
|
containertype = /obj/structure/closet/crate/large/nanotrasen
|
||||||
containername = "Anesthetic pump crate"
|
containername = "Anesthetic pump crate"
|
||||||
|
|
||||||
/datum/supply_pack/med/stablepump
|
/datum/supply_pack/med/stablepump
|
||||||
name = "Portable stabilizer crate"
|
name = "Portable stabilizer crate"
|
||||||
contains = list(/obj/machinery/oxygen_pump/mobile/stabilizer = 1)
|
contains = list(/obj/machinery/oxygen_pump/mobile/stabilizer = 1)
|
||||||
cost = 175
|
cost = 175
|
||||||
containertype = /obj/structure/largecrate
|
containertype = /obj/structure/closet/crate/large/nanotrasen
|
||||||
containername = "Portable stabilizer crate"
|
containername = "Portable stabilizer crate"
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
)
|
)
|
||||||
name = "Trading Card Crate"
|
name = "Trading Card Crate"
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/oculum
|
||||||
containername = "cards crate"
|
containername = "cards crate"
|
||||||
|
|
||||||
/datum/supply_pack/randomised/misc/dnd
|
/datum/supply_pack/randomised/misc/dnd
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
)
|
)
|
||||||
name = "Miniatures Crate"
|
name = "Miniatures Crate"
|
||||||
cost = 200
|
cost = 200
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/oculum
|
||||||
containername = "Miniature Crate"
|
containername = "Miniature Crate"
|
||||||
|
|
||||||
/datum/supply_pack/randomised/misc/plushies
|
/datum/supply_pack/randomised/misc/plushies
|
||||||
@@ -88,14 +88,14 @@
|
|||||||
//VOREStation Add End
|
//VOREStation Add End
|
||||||
name = "Plushies Crate"
|
name = "Plushies Crate"
|
||||||
cost = 15
|
cost = 15
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/allico
|
||||||
containername = "Plushies Crate"
|
containername = "Plushies Crate"
|
||||||
|
|
||||||
/datum/supply_pack/misc/eftpos
|
/datum/supply_pack/misc/eftpos
|
||||||
contains = list(/obj/item/device/eftpos)
|
contains = list(/obj/item/device/eftpos)
|
||||||
name = "EFTPOS scanner"
|
name = "EFTPOS scanner"
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/nanotrasen
|
||||||
containername = "EFTPOS crate"
|
containername = "EFTPOS crate"
|
||||||
|
|
||||||
/datum/supply_pack/misc/chaplaingear
|
/datum/supply_pack/misc/chaplaingear
|
||||||
@@ -113,7 +113,7 @@
|
|||||||
/obj/item/weapon/storage/fancy/candle_box = 3
|
/obj/item/weapon/storage/fancy/candle_box = 3
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/gilthari
|
||||||
containername = "Chaplain equipment crate"
|
containername = "Chaplain equipment crate"
|
||||||
|
|
||||||
/datum/supply_pack/misc/hoverpod
|
/datum/supply_pack/misc/hoverpod
|
||||||
@@ -136,14 +136,14 @@
|
|||||||
/obj/item/clothing/accessory/storage/webbing
|
/obj/item/clothing/accessory/storage/webbing
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/nanothreads
|
||||||
containername = "Webbing crate"
|
containername = "Webbing crate"
|
||||||
|
|
||||||
/datum/supply_pack/misc/holoplant
|
/datum/supply_pack/misc/holoplant
|
||||||
name = "Holoplant Pot"
|
name = "Holoplant Pot"
|
||||||
contains = list(/obj/machinery/holoplant/shipped)
|
contains = list(/obj/machinery/holoplant/shipped)
|
||||||
cost = 15
|
cost = 15
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/thinktronic
|
||||||
containername = "Holoplant crate"
|
containername = "Holoplant crate"
|
||||||
|
|
||||||
/datum/supply_pack/misc/glucose_hypos
|
/datum/supply_pack/misc/glucose_hypos
|
||||||
@@ -152,7 +152,7 @@
|
|||||||
/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose = 5
|
/obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose = 5
|
||||||
)
|
)
|
||||||
cost = 25
|
cost = 25
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/zenghu
|
||||||
containername = "Glucose Hypo Crate"
|
containername = "Glucose Hypo Crate"
|
||||||
|
|
||||||
/datum/supply_pack/misc/mre_rations
|
/datum/supply_pack/misc/mre_rations
|
||||||
@@ -169,7 +169,7 @@
|
|||||||
/obj/item/weapon/storage/mre/menu9,
|
/obj/item/weapon/storage/mre/menu9,
|
||||||
/obj/item/weapon/storage/mre/menu10)
|
/obj/item/weapon/storage/mre/menu10)
|
||||||
cost = 50
|
cost = 50
|
||||||
containertype = /obj/structure/closet/crate/freezer
|
containertype = /obj/structure/closet/crate/centauri
|
||||||
containername = "ready to eat rations"
|
containername = "ready to eat rations"
|
||||||
|
|
||||||
/datum/supply_pack/misc/paste_rations
|
/datum/supply_pack/misc/paste_rations
|
||||||
@@ -178,7 +178,7 @@
|
|||||||
/obj/item/weapon/storage/mre/menu11 = 2
|
/obj/item/weapon/storage/mre/menu11 = 2
|
||||||
)
|
)
|
||||||
cost = 25
|
cost = 25
|
||||||
containertype = /obj/structure/closet/crate/freezer
|
containertype = /obj/structure/closet/crate/freezer/centauri
|
||||||
containername = "emergency rations"
|
containername = "emergency rations"
|
||||||
|
|
||||||
/datum/supply_pack/misc/medical_rations
|
/datum/supply_pack/misc/medical_rations
|
||||||
@@ -187,5 +187,5 @@
|
|||||||
/obj/item/weapon/storage/mre/menu13 = 2
|
/obj/item/weapon/storage/mre/menu13 = 2
|
||||||
)
|
)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/freezer
|
containertype = /obj/structure/closet/crate/zenghu
|
||||||
containername = "emergency rations"
|
containername = "emergency rations"
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
/obj/item/weapon/material/twohanded/fireaxe/foam = 2
|
/obj/item/weapon/material/twohanded/fireaxe/foam = 2
|
||||||
)
|
)
|
||||||
cost = 50
|
cost = 50
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/allico
|
||||||
containername = "foam weapon crate"
|
containername = "foam weapon crate"
|
||||||
|
|
||||||
/datum/supply_pack/recreation/lasertag
|
/datum/supply_pack/recreation/lasertag
|
||||||
@@ -31,8 +31,8 @@
|
|||||||
/obj/item/weapon/gun/energy/lasertag/blue,
|
/obj/item/weapon/gun/energy/lasertag/blue,
|
||||||
/obj/item/clothing/suit/bluetag
|
/obj/item/clothing/suit/bluetag
|
||||||
)
|
)
|
||||||
containertype = /obj/structure/closet
|
containertype = /obj/structure/closet/crate/ward
|
||||||
containername = "Lasertag Closet"
|
containername = "Lasertag Supplies"
|
||||||
cost = 10
|
cost = 10
|
||||||
|
|
||||||
/datum/supply_pack/recreation/artscrafts
|
/datum/supply_pack/recreation/artscrafts
|
||||||
@@ -55,14 +55,14 @@
|
|||||||
/obj/item/weapon/wrapping_paper = 3
|
/obj/item/weapon/wrapping_paper = 3
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/allico
|
||||||
containername = "Arts and Crafts crate"
|
containername = "Arts and Crafts crate"
|
||||||
|
|
||||||
/datum/supply_pack/recreation/painters
|
/datum/supply_pack/recreation/painters
|
||||||
name = "Station Painting Supplies"
|
name = "Station Painting Supplies"
|
||||||
cost = 10
|
cost = 10
|
||||||
containername = "station painting supplies crate"
|
containername = "station painting supplies crate"
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/grayson
|
||||||
contains = list(
|
contains = list(
|
||||||
/obj/item/device/pipe_painter = 2,
|
/obj/item/device/pipe_painter = 2,
|
||||||
/obj/item/device/floor_painter = 2,
|
/obj/item/device/floor_painter = 2,
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
name = "Deluxe Fishing Bait"
|
name = "Deluxe Fishing Bait"
|
||||||
cost = 40
|
cost = 40
|
||||||
containername = "deluxe bait crate"
|
containername = "deluxe bait crate"
|
||||||
containertype = /obj/structure/closet/crate/freezer
|
containertype = /obj/structure/closet/crate/carp
|
||||||
num_contained = 8
|
num_contained = 8
|
||||||
contains = list(
|
contains = list(
|
||||||
/obj/item/weapon/storage/box/wormcan,
|
/obj/item/weapon/storage/box/wormcan,
|
||||||
@@ -93,7 +93,7 @@
|
|||||||
name = "Laser Tag Turrets"
|
name = "Laser Tag Turrets"
|
||||||
cost = 40
|
cost = 40
|
||||||
containername = "laser tag turret crate"
|
containername = "laser tag turret crate"
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/ward
|
||||||
contains = list(
|
contains = list(
|
||||||
/obj/machinery/porta_turret/lasertag/blue,
|
/obj/machinery/porta_turret/lasertag/blue,
|
||||||
/obj/machinery/porta_turret/lasertag/red
|
/obj/machinery/porta_turret/lasertag/red
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
/obj/item/weapon/cell/high = 2
|
/obj/item/weapon/cell/high = 2
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/secure/science
|
containertype = /obj/structure/closet/crate/secure/nanotrasen
|
||||||
containername = "Robotics assembly"
|
containername = "Robotics assembly"
|
||||||
access = access_robotics
|
access = access_robotics
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
name = "Morpheus robolimb blueprints"
|
name = "Morpheus robolimb blueprints"
|
||||||
contains = list(/obj/item/weapon/disk/limb/morpheus)
|
contains = list(/obj/item/weapon/disk/limb/morpheus)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/secure/science
|
containertype = /obj/structure/closet/crate/secure/morpheus
|
||||||
containername = "Robolimb blueprints (Morpheus)"
|
containername = "Robolimb blueprints (Morpheus)"
|
||||||
access = access_robotics
|
access = access_robotics
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
name = "Cyber Solutions robolimb blueprints"
|
name = "Cyber Solutions robolimb blueprints"
|
||||||
contains = list(/obj/item/weapon/disk/limb/cybersolutions)
|
contains = list(/obj/item/weapon/disk/limb/cybersolutions)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/secure/science
|
containertype = /obj/structure/closet/crate/secure/cybersolutions
|
||||||
containername = "Robolimb blueprints (Cyber Solutions)"
|
containername = "Robolimb blueprints (Cyber Solutions)"
|
||||||
access = access_robotics
|
access = access_robotics
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
name = "Xion robolimb blueprints"
|
name = "Xion robolimb blueprints"
|
||||||
contains = list(/obj/item/weapon/disk/limb/xion)
|
contains = list(/obj/item/weapon/disk/limb/xion)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/secure/science
|
containertype = /obj/structure/closet/crate/secure/xion
|
||||||
containername = "Robolimb blueprints (Xion)"
|
containername = "Robolimb blueprints (Xion)"
|
||||||
access = access_robotics
|
access = access_robotics
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
name = "Grayson robolimb blueprints"
|
name = "Grayson robolimb blueprints"
|
||||||
contains = list(/obj/item/weapon/disk/limb/grayson)
|
contains = list(/obj/item/weapon/disk/limb/grayson)
|
||||||
cost = 30
|
cost = 30
|
||||||
containertype = /obj/structure/closet/crate/secure/science
|
containertype = /obj/structure/closet/crate/secure/grayson
|
||||||
containername = "Robolimb blueprints (Grayson)"
|
containername = "Robolimb blueprints (Grayson)"
|
||||||
access = access_robotics
|
access = access_robotics
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@
|
|||||||
name = "Hephaestus robolimb blueprints"
|
name = "Hephaestus robolimb blueprints"
|
||||||
contains = list(/obj/item/weapon/disk/limb/hephaestus)
|
contains = list(/obj/item/weapon/disk/limb/hephaestus)
|
||||||
cost = 35
|
cost = 35
|
||||||
containertype = /obj/structure/closet/crate/secure/science
|
containertype = /obj/structure/closet/crate/secure/heph
|
||||||
containername = "Robolimb blueprints (Hephaestus)"
|
containername = "Robolimb blueprints (Hephaestus)"
|
||||||
access = access_robotics
|
access = access_robotics
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
name = "Ward-Takahashi robolimb blueprints"
|
name = "Ward-Takahashi robolimb blueprints"
|
||||||
contains = list(/obj/item/weapon/disk/limb/wardtakahashi)
|
contains = list(/obj/item/weapon/disk/limb/wardtakahashi)
|
||||||
cost = 35
|
cost = 35
|
||||||
containertype = /obj/structure/closet/crate/secure/science
|
containertype = /obj/structure/closet/crate/secure/ward
|
||||||
containername = "Robolimb blueprints (Ward-Takahashi)"
|
containername = "Robolimb blueprints (Ward-Takahashi)"
|
||||||
access = access_robotics
|
access = access_robotics
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@
|
|||||||
name = "Zeng Hu robolimb blueprints"
|
name = "Zeng Hu robolimb blueprints"
|
||||||
contains = list(/obj/item/weapon/disk/limb/zenghu)
|
contains = list(/obj/item/weapon/disk/limb/zenghu)
|
||||||
cost = 35
|
cost = 35
|
||||||
containertype = /obj/structure/closet/crate/secure/science
|
containertype = /obj/structure/closet/crate/secure/zenghu
|
||||||
containername = "Robolimb blueprints (Zeng Hu)"
|
containername = "Robolimb blueprints (Zeng Hu)"
|
||||||
access = access_robotics
|
access = access_robotics
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
name = "Bishop robolimb blueprints"
|
name = "Bishop robolimb blueprints"
|
||||||
contains = list(/obj/item/weapon/disk/limb/bishop)
|
contains = list(/obj/item/weapon/disk/limb/bishop)
|
||||||
cost = 70
|
cost = 70
|
||||||
containertype = /obj/structure/closet/crate/secure/science
|
containertype = /obj/structure/closet/crate/secure/bishop
|
||||||
containername = "Robolimb blueprints (Bishop)"
|
containername = "Robolimb blueprints (Bishop)"
|
||||||
access = access_robotics
|
access = access_robotics
|
||||||
|
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
/obj/item/weapon/circuitboard/mecha/ripley/peripherals
|
/obj/item/weapon/circuitboard/mecha/ripley/peripherals
|
||||||
)
|
)
|
||||||
cost = 25
|
cost = 25
|
||||||
containertype = /obj/structure/closet/crate/secure/science
|
containertype = /obj/structure/closet/crate/secure/xion
|
||||||
containername = "APLU \"Ripley\" Circuit Crate"
|
containername = "APLU \"Ripley\" Circuit Crate"
|
||||||
access = access_robotics
|
access = access_robotics
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@
|
|||||||
/obj/item/weapon/circuitboard/mecha/odysseus/main
|
/obj/item/weapon/circuitboard/mecha/odysseus/main
|
||||||
)
|
)
|
||||||
cost = 25
|
cost = 25
|
||||||
containertype = /obj/structure/closet/crate/secure/science
|
containertype = /obj/structure/closet/crate/secure/veymed
|
||||||
containername = "\"Odysseus\" Circuit Crate"
|
containername = "\"Odysseus\" Circuit Crate"
|
||||||
access = access_robotics
|
access = access_robotics
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@
|
|||||||
)
|
)
|
||||||
name = "Random APLU modkit"
|
name = "Random APLU modkit"
|
||||||
cost = 200
|
cost = 200
|
||||||
containertype = /obj/structure/closet/crate/science
|
containertype = /obj/structure/closet/crate/xion
|
||||||
containername = "heavy crate"
|
containername = "heavy crate"
|
||||||
|
|
||||||
/datum/supply_pack/randomised/robotics/exosuit_mod/durand
|
/datum/supply_pack/randomised/robotics/exosuit_mod/durand
|
||||||
@@ -168,6 +168,7 @@
|
|||||||
/obj/item/device/kit/paint/durand/phazon
|
/obj/item/device/kit/paint/durand/phazon
|
||||||
)
|
)
|
||||||
name = "Random Durand exosuit modkit"
|
name = "Random Durand exosuit modkit"
|
||||||
|
containertype = /obj/structure/closet/crate/heph
|
||||||
|
|
||||||
/datum/supply_pack/randomised/robotics/exosuit_mod/gygax
|
/datum/supply_pack/randomised/robotics/exosuit_mod/gygax
|
||||||
contains = list(
|
contains = list(
|
||||||
@@ -176,6 +177,7 @@
|
|||||||
/obj/item/device/kit/paint/gygax/recitence
|
/obj/item/device/kit/paint/gygax/recitence
|
||||||
)
|
)
|
||||||
name = "Random Gygax exosuit modkit"
|
name = "Random Gygax exosuit modkit"
|
||||||
|
containertype = /obj/structure/closet/crate/heph
|
||||||
|
|
||||||
/datum/supply_pack/robotics/jumper_cables
|
/datum/supply_pack/robotics/jumper_cables
|
||||||
name = "Jumper kit crate"
|
name = "Jumper kit crate"
|
||||||
@@ -183,7 +185,7 @@
|
|||||||
/obj/item/device/defib_kit/jumper_kit = 2
|
/obj/item/device/defib_kit/jumper_kit = 2
|
||||||
)
|
)
|
||||||
cost = 30
|
cost = 30
|
||||||
containertype = /obj/structure/closet/crate/secure/science
|
containertype = /obj/structure/closet/crate/secure/einstein
|
||||||
containername = "Jumper kit crate"
|
containername = "Jumper kit crate"
|
||||||
access = access_robotics
|
access = access_robotics
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
name = "Coolant tank crate"
|
name = "Coolant tank crate"
|
||||||
contains = list(/obj/structure/reagent_dispensers/coolanttank)
|
contains = list(/obj/structure/reagent_dispensers/coolanttank)
|
||||||
cost = 15
|
cost = 15
|
||||||
containertype = /obj/structure/largecrate
|
containertype = /obj/structure/closet/crate/large/aether
|
||||||
containername = "coolant tank crate"
|
containername = "coolant tank crate"
|
||||||
|
|
||||||
/datum/supply_pack/sci/phoron
|
/datum/supply_pack/sci/phoron
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
/obj/item/seeds/kudzuseed
|
/obj/item/seeds/kudzuseed
|
||||||
)
|
)
|
||||||
cost = 15
|
cost = 15
|
||||||
containertype = /obj/structure/closet/crate/hydroponics
|
containertype = /obj/structure/closet/crate/carp
|
||||||
containername = "Exotic Seeds crate"
|
containername = "Exotic Seeds crate"
|
||||||
access = access_hydroponics
|
access = access_hydroponics
|
||||||
|
|
||||||
@@ -47,14 +47,14 @@
|
|||||||
name = "Integrated circuit printer"
|
name = "Integrated circuit printer"
|
||||||
contains = list(/obj/item/device/integrated_circuit_printer = 2)
|
contains = list(/obj/item/device/integrated_circuit_printer = 2)
|
||||||
cost = 15
|
cost = 15
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/ward
|
||||||
containername = "Integrated circuit crate"
|
containername = "Integrated circuit crate"
|
||||||
|
|
||||||
/datum/supply_pack/sci/integrated_circuit_printer_upgrade
|
/datum/supply_pack/sci/integrated_circuit_printer_upgrade
|
||||||
name = "Integrated circuit printer upgrade - advanced designs"
|
name = "Integrated circuit printer upgrade - advanced designs"
|
||||||
contains = list(/obj/item/weapon/disk/integrated_circuit/upgrade/advanced)
|
contains = list(/obj/item/weapon/disk/integrated_circuit/upgrade/advanced)
|
||||||
cost = 30
|
cost = 30
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/ward
|
||||||
containername = "Integrated circuit crate"
|
containername = "Integrated circuit crate"
|
||||||
|
|
||||||
/datum/supply_pack/sci/xenoarch
|
/datum/supply_pack/sci/xenoarch
|
||||||
@@ -75,6 +75,6 @@
|
|||||||
/obj/item/weapon/storage/bag/fossils,
|
/obj/item/weapon/storage/bag/fossils,
|
||||||
/obj/item/weapon/hand_labeler)
|
/obj/item/weapon/hand_labeler)
|
||||||
cost = 100
|
cost = 100
|
||||||
containertype = /obj/structure/closet/crate/secure/science
|
containertype = /obj/structure/closet/crate/secure/xion
|
||||||
containername = "Xenoarchaeology Tech crate"
|
containername = "Xenoarchaeology Tech crate"
|
||||||
access = access_research
|
access = access_research
|
||||||
@@ -53,11 +53,11 @@
|
|||||||
/obj/item/clothing/accessory/storage/pouches/blue,
|
/obj/item/clothing/accessory/storage/pouches/blue,
|
||||||
)
|
)
|
||||||
cost = 30
|
cost = 30
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/heph
|
||||||
containername = "Plate Carrier crate"
|
containername = "Plate Carrier crate"
|
||||||
|
|
||||||
/datum/supply_pack/security/carriersgreen
|
/datum/supply_pack/security/carriersgreen
|
||||||
name = "Armor - Blue modular armor"
|
name = "Armor - Green modular armor"
|
||||||
contains = list(
|
contains = list(
|
||||||
/obj/item/clothing/suit/armor/pcarrier/green,
|
/obj/item/clothing/suit/armor/pcarrier/green,
|
||||||
/obj/item/clothing/accessory/armor/armguards/green,
|
/obj/item/clothing/accessory/armor/armguards/green,
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
/obj/item/clothing/accessory/storage/pouches/green,
|
/obj/item/clothing/accessory/storage/pouches/green,
|
||||||
)
|
)
|
||||||
cost = 30
|
cost = 30
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/heph
|
||||||
containername = "Plate Carrier crate"
|
containername = "Plate Carrier crate"
|
||||||
|
|
||||||
/datum/supply_pack/security/carriersnavy
|
/datum/supply_pack/security/carriersnavy
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
/obj/item/clothing/accessory/storage/pouches/navy,
|
/obj/item/clothing/accessory/storage/pouches/navy,
|
||||||
)
|
)
|
||||||
cost = 30
|
cost = 30
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/heph
|
||||||
containername = "Plate Carrier crate"
|
containername = "Plate Carrier crate"
|
||||||
|
|
||||||
/datum/supply_pack/security/carrierstan
|
/datum/supply_pack/security/carrierstan
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
/obj/item/clothing/accessory/storage/pouches/tan,
|
/obj/item/clothing/accessory/storage/pouches/tan,
|
||||||
)
|
)
|
||||||
cost = 30
|
cost = 30
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/heph
|
||||||
containername = "Plate Carrier crate"
|
containername = "Plate Carrier crate"
|
||||||
|
|
||||||
/datum/supply_pack/security/armorplate
|
/datum/supply_pack/security/armorplate
|
||||||
@@ -98,7 +98,7 @@
|
|||||||
/obj/item/clothing/accessory/armor/armorplate,
|
/obj/item/clothing/accessory/armor/armorplate,
|
||||||
)
|
)
|
||||||
cost = 5
|
cost = 5
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/lawson
|
||||||
containername = "Armor plate crate"
|
containername = "Armor plate crate"
|
||||||
|
|
||||||
/datum/supply_pack/security/armorplatestab
|
/datum/supply_pack/security/armorplatestab
|
||||||
@@ -107,7 +107,7 @@
|
|||||||
/obj/item/clothing/accessory/armor/armorplate/stab,
|
/obj/item/clothing/accessory/armor/armorplate/stab,
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/lawson
|
||||||
containername = "Armor plate crate"
|
containername = "Armor plate crate"
|
||||||
|
|
||||||
/datum/supply_pack/security/armorplatemedium
|
/datum/supply_pack/security/armorplatemedium
|
||||||
@@ -116,7 +116,7 @@
|
|||||||
/obj/item/clothing/accessory/armor/armorplate/medium,
|
/obj/item/clothing/accessory/armor/armorplate/medium,
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/lawson
|
||||||
containername = "Armor plate crate"
|
containername = "Armor plate crate"
|
||||||
|
|
||||||
/datum/supply_pack/security/armorplatetac
|
/datum/supply_pack/security/armorplatetac
|
||||||
@@ -125,7 +125,7 @@
|
|||||||
/obj/item/clothing/accessory/armor/armorplate/tactical,
|
/obj/item/clothing/accessory/armor/armorplate/tactical,
|
||||||
)
|
)
|
||||||
cost = 15
|
cost = 15
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/heph
|
||||||
containername = "Armor plate crate"
|
containername = "Armor plate crate"
|
||||||
|
|
||||||
/datum/supply_pack/randomised/security/carriers
|
/datum/supply_pack/randomised/security/carriers
|
||||||
@@ -140,7 +140,7 @@
|
|||||||
/obj/item/clothing/suit/armor/pcarrier/press
|
/obj/item/clothing/suit/armor/pcarrier/press
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/scg
|
||||||
containername = "Plate Carrier crate"
|
containername = "Plate Carrier crate"
|
||||||
|
|
||||||
/datum/supply_pack/security/carriertags
|
/datum/supply_pack/security/carriertags
|
||||||
@@ -158,7 +158,7 @@
|
|||||||
/obj/item/clothing/accessory/armor/tag/abneg
|
/obj/item/clothing/accessory/armor/tag/abneg
|
||||||
)
|
)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/scg
|
||||||
containername = "Plate Carrier crate"
|
containername = "Plate Carrier crate"
|
||||||
|
|
||||||
/datum/supply_pack/security/helmcovers
|
/datum/supply_pack/security/helmcovers
|
||||||
@@ -174,7 +174,7 @@
|
|||||||
/obj/item/clothing/accessory/armor/helmcover/tan
|
/obj/item/clothing/accessory/armor/helmcover/tan
|
||||||
)
|
)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/scg
|
||||||
containername = "Helmet Covers crate"
|
containername = "Helmet Covers crate"
|
||||||
|
|
||||||
/datum/supply_pack/randomised/security/armorplates
|
/datum/supply_pack/randomised/security/armorplates
|
||||||
@@ -193,7 +193,7 @@
|
|||||||
/obj/item/clothing/accessory/armor/armorplate/bulletproof
|
/obj/item/clothing/accessory/armor/armorplate/bulletproof
|
||||||
)
|
)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/scg
|
||||||
containername = "Armor plate crate"
|
containername = "Armor plate crate"
|
||||||
|
|
||||||
/datum/supply_pack/randomised/security/carrierarms
|
/datum/supply_pack/randomised/security/carrierarms
|
||||||
@@ -210,7 +210,7 @@
|
|||||||
/obj/item/clothing/accessory/armor/armguards/bulletproof
|
/obj/item/clothing/accessory/armor/armguards/bulletproof
|
||||||
)
|
)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/scg
|
||||||
containername = "Armor plate crate"
|
containername = "Armor plate crate"
|
||||||
|
|
||||||
/datum/supply_pack/randomised/security/carrierlegs
|
/datum/supply_pack/randomised/security/carrierlegs
|
||||||
@@ -227,7 +227,7 @@
|
|||||||
/obj/item/clothing/accessory/armor/legguards/bulletproof
|
/obj/item/clothing/accessory/armor/legguards/bulletproof
|
||||||
)
|
)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/scg
|
||||||
containername = "Armor plate crate"
|
containername = "Armor plate crate"
|
||||||
|
|
||||||
/datum/supply_pack/randomised/security/carrierbags
|
/datum/supply_pack/randomised/security/carrierbags
|
||||||
@@ -246,7 +246,7 @@
|
|||||||
/obj/item/clothing/accessory/storage/pouches/large/tan
|
/obj/item/clothing/accessory/storage/pouches/large/tan
|
||||||
)
|
)
|
||||||
cost = 50
|
cost = 50
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/scg
|
||||||
containername = "Armor plate crate"
|
containername = "Armor plate crate"
|
||||||
|
|
||||||
/datum/supply_pack/security/riot_gear
|
/datum/supply_pack/security/riot_gear
|
||||||
@@ -260,7 +260,7 @@
|
|||||||
/obj/item/weapon/storage/box/handcuffs
|
/obj/item/weapon/storage/box/handcuffs
|
||||||
)
|
)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/lawson
|
||||||
containername = "Riot gear crate"
|
containername = "Riot gear crate"
|
||||||
access = access_armory
|
access = access_armory
|
||||||
|
|
||||||
@@ -273,7 +273,7 @@
|
|||||||
/obj/item/clothing/shoes/leg_guard/riot
|
/obj/item/clothing/shoes/leg_guard/riot
|
||||||
)
|
)
|
||||||
cost = 30
|
cost = 30
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/lawson
|
||||||
containername = "Riot armor crate"
|
containername = "Riot armor crate"
|
||||||
access = access_armory
|
access = access_armory
|
||||||
|
|
||||||
@@ -287,7 +287,7 @@
|
|||||||
/obj/item/clothing/accessory/armor/legguards/riot
|
/obj/item/clothing/accessory/armor/legguards/riot
|
||||||
)
|
)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/lawson
|
||||||
containername = "Riot armor crate"
|
containername = "Riot armor crate"
|
||||||
access = access_armory
|
access = access_armory
|
||||||
|
|
||||||
@@ -300,7 +300,7 @@
|
|||||||
/obj/item/clothing/shoes/leg_guard/laserproof
|
/obj/item/clothing/shoes/leg_guard/laserproof
|
||||||
)
|
)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/lawson
|
||||||
containername = "Ablative armor crate"
|
containername = "Ablative armor crate"
|
||||||
access = access_armory
|
access = access_armory
|
||||||
|
|
||||||
@@ -314,7 +314,7 @@
|
|||||||
/obj/item/clothing/accessory/armor/legguards/laserproof
|
/obj/item/clothing/accessory/armor/legguards/laserproof
|
||||||
)
|
)
|
||||||
cost = 50
|
cost = 50
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/lawson
|
||||||
containername = "Ablative armor crate"
|
containername = "Ablative armor crate"
|
||||||
access = access_armory
|
access = access_armory
|
||||||
|
|
||||||
@@ -327,7 +327,7 @@
|
|||||||
/obj/item/clothing/shoes/leg_guard/bulletproof
|
/obj/item/clothing/shoes/leg_guard/bulletproof
|
||||||
)
|
)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/heph
|
||||||
containername = "Ballistic armor crate"
|
containername = "Ballistic armor crate"
|
||||||
access = access_armory
|
access = access_armory
|
||||||
/* VOREStation Removal - Howabout no ERT armor being orderable?
|
/* VOREStation Removal - Howabout no ERT armor being orderable?
|
||||||
@@ -342,7 +342,7 @@
|
|||||||
/obj/item/clothing/accessory/armor/legguards/bulletproof
|
/obj/item/clothing/accessory/armor/legguards/bulletproof
|
||||||
)
|
)
|
||||||
cost = 50
|
cost = 50
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/heph
|
||||||
containername = "Ballistic armor crate"
|
containername = "Ballistic armor crate"
|
||||||
access = access_armory
|
access = access_armory
|
||||||
|
|
||||||
@@ -355,13 +355,13 @@
|
|||||||
/obj/item/clothing/shoes/leg_guard/combat
|
/obj/item/clothing/shoes/leg_guard/combat
|
||||||
)
|
)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/saare
|
||||||
containername = "Combat armor crate"
|
containername = "Combat armor crate"
|
||||||
access = access_armory
|
access = access_armory
|
||||||
|
|
||||||
/datum/supply_pack/security/tactical
|
/datum/supply_pack/security/tactical
|
||||||
name = "Armor - Tactical"
|
name = "Armor - Tactical"
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/saare
|
||||||
containername = "Tactical armor crate"
|
containername = "Tactical armor crate"
|
||||||
cost = 40
|
cost = 40
|
||||||
access = access_armory
|
access = access_armory
|
||||||
@@ -387,7 +387,7 @@
|
|||||||
|
|
||||||
/datum/supply_pack/security/flexitac
|
/datum/supply_pack/security/flexitac
|
||||||
name = "Armor - Tactical Light"
|
name = "Armor - Tactical Light"
|
||||||
containertype = /obj/structure/closet/crate/secure/gear
|
containertype = /obj/structure/closet/crate/secure/saare
|
||||||
containername = "Tactical Light armor crate"
|
containername = "Tactical Light armor crate"
|
||||||
cost = 75
|
cost = 75
|
||||||
access = access_armory
|
access = access_armory
|
||||||
@@ -412,15 +412,14 @@
|
|||||||
name = "Misc - Security Barriers"
|
name = "Misc - Security Barriers"
|
||||||
contains = list(/obj/machinery/deployable/barrier = 4)
|
contains = list(/obj/machinery/deployable/barrier = 4)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/largecrate
|
containertype = /obj/structure/closet/crate/large/secure/heph
|
||||||
containername = "Security barrier crate"
|
containername = "Security barrier crate"
|
||||||
access = null
|
|
||||||
|
|
||||||
/datum/supply_pack/security/securityshieldgen
|
/datum/supply_pack/security/securityshieldgen
|
||||||
name = "Misc - Wall shield generators"
|
name = "Misc - Wall shield generators"
|
||||||
contains = list(/obj/machinery/shieldwallgen = 4)
|
contains = list(/obj/machinery/shieldwallgen = 4)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/heph
|
||||||
containername = "Wall shield generators crate"
|
containername = "Wall shield generators crate"
|
||||||
access = access_teleporter
|
access = access_teleporter
|
||||||
|
|
||||||
@@ -434,7 +433,7 @@
|
|||||||
/obj/item/clothing/accessory/holster/hip
|
/obj/item/clothing/accessory/holster/hip
|
||||||
)
|
)
|
||||||
cost = 15
|
cost = 15
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/hedberg
|
||||||
containername = "Holster crate"
|
containername = "Holster crate"
|
||||||
|
|
||||||
/datum/supply_pack/security/extragear
|
/datum/supply_pack/security/extragear
|
||||||
@@ -446,7 +445,7 @@
|
|||||||
/obj/item/clothing/suit/storage/hooded/wintercoat/security = 3
|
/obj/item/clothing/suit/storage/hooded/wintercoat/security = 3
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/nanothreads
|
||||||
containername = "Security surplus equipment"
|
containername = "Security surplus equipment"
|
||||||
|
|
||||||
/datum/supply_pack/security/detectivegear
|
/datum/supply_pack/security/detectivegear
|
||||||
@@ -473,7 +472,7 @@
|
|||||||
/obj/item/weapon/storage/bag/detective
|
/obj/item/weapon/storage/bag/detective
|
||||||
)
|
)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanotrasen
|
||||||
containername = "Forensic equipment"
|
containername = "Forensic equipment"
|
||||||
access = access_forensics_lockers
|
access = access_forensics_lockers
|
||||||
|
|
||||||
@@ -486,7 +485,7 @@
|
|||||||
/obj/item/device/detective_scanner
|
/obj/item/device/detective_scanner
|
||||||
)
|
)
|
||||||
cost = 60
|
cost = 60
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/ward
|
||||||
containername = "Forensic equipment"
|
containername = "Forensic equipment"
|
||||||
access = access_forensics_lockers
|
access = access_forensics_lockers
|
||||||
|
|
||||||
@@ -508,7 +507,7 @@
|
|||||||
/obj/item/clothing/gloves/black = 2
|
/obj/item/clothing/gloves/black = 2
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanotrasen
|
||||||
containername = "Investigation clothing"
|
containername = "Investigation clothing"
|
||||||
access = access_forensics_lockers
|
access = access_forensics_lockers
|
||||||
|
|
||||||
@@ -538,7 +537,7 @@
|
|||||||
/obj/item/device/flashlight/maglight
|
/obj/item/device/flashlight/maglight
|
||||||
)
|
)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanotrasen
|
||||||
containername = "Officer equipment"
|
containername = "Officer equipment"
|
||||||
access = access_brig
|
access = access_brig
|
||||||
|
|
||||||
@@ -567,7 +566,7 @@
|
|||||||
/obj/item/device/flashlight/maglight
|
/obj/item/device/flashlight/maglight
|
||||||
)
|
)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanotrasen
|
||||||
containername = "Warden equipment"
|
containername = "Warden equipment"
|
||||||
access = access_armory
|
access = access_armory
|
||||||
|
|
||||||
@@ -594,7 +593,7 @@
|
|||||||
/obj/item/device/flashlight/maglight
|
/obj/item/device/flashlight/maglight
|
||||||
)
|
)
|
||||||
cost = 50
|
cost = 50
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanotrasen
|
||||||
containername = "Head of security equipment"
|
containername = "Head of security equipment"
|
||||||
access = access_hos
|
access = access_hos
|
||||||
|
|
||||||
@@ -613,7 +612,7 @@
|
|||||||
/obj/item/weapon/storage/box/holobadge
|
/obj/item/weapon/storage/box/holobadge
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanotrasen
|
||||||
containername = "Security uniform crate"
|
containername = "Security uniform crate"
|
||||||
|
|
||||||
/datum/supply_pack/security/navybluesecurityclothing
|
/datum/supply_pack/security/navybluesecurityclothing
|
||||||
@@ -634,7 +633,7 @@
|
|||||||
/obj/item/weapon/storage/box/holobadge
|
/obj/item/weapon/storage/box/holobadge
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanotrasen
|
||||||
containername = "Navy blue security uniform crate"
|
containername = "Navy blue security uniform crate"
|
||||||
|
|
||||||
/datum/supply_pack/security/corporatesecurityclothing
|
/datum/supply_pack/security/corporatesecurityclothing
|
||||||
@@ -654,7 +653,7 @@
|
|||||||
/obj/item/weapon/storage/box/holobadge
|
/obj/item/weapon/storage/box/holobadge
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanotrasen
|
||||||
containername = "Corporate security uniform crate"
|
containername = "Corporate security uniform crate"
|
||||||
|
|
||||||
/datum/supply_pack/security/biosuit
|
/datum/supply_pack/security/biosuit
|
||||||
@@ -670,7 +669,7 @@
|
|||||||
/obj/item/weapon/storage/box/gloves
|
/obj/item/weapon/storage/box/gloves
|
||||||
)
|
)
|
||||||
cost = 25
|
cost = 25
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanotrasen
|
||||||
containername = "Security biohazard gear"
|
containername = "Security biohazard gear"
|
||||||
access = access_security
|
access = access_security
|
||||||
|
|
||||||
@@ -680,6 +679,6 @@
|
|||||||
/obj/item/weapon/contraband/poster/nanotrasen = 6
|
/obj/item/weapon/contraband/poster/nanotrasen = 6
|
||||||
)
|
)
|
||||||
cost = 20
|
cost = 20
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanotrasen
|
||||||
containername = "Morale Posters"
|
containername = "Morale Posters"
|
||||||
access = access_maint_tunnels
|
access = access_maint_tunnels
|
||||||
|
|||||||
@@ -18,14 +18,14 @@
|
|||||||
/obj/item/weapon/reagent_containers/food/condiment/yeast = 3
|
/obj/item/weapon/reagent_containers/food/condiment/yeast = 3
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/freezer
|
containertype = /obj/structure/closet/crate/freezer/centauri
|
||||||
containername = "Food crate"
|
containername = "Food crate"
|
||||||
|
|
||||||
/datum/supply_pack/supply/toner
|
/datum/supply_pack/supply/toner
|
||||||
name = "Toner cartridges"
|
name = "Toner cartridges"
|
||||||
contains = list(/obj/item/device/toner = 6)
|
contains = list(/obj/item/device/toner = 6)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/ummarcar
|
||||||
containername = "Toner cartridges"
|
containername = "Toner cartridges"
|
||||||
|
|
||||||
/datum/supply_pack/supply/janitor
|
/datum/supply_pack/supply/janitor
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
/obj/structure/mopbucket
|
/obj/structure/mopbucket
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/galaksi
|
||||||
containername = "Janitorial supplies"
|
containername = "Janitorial supplies"
|
||||||
|
|
||||||
/datum/supply_pack/supply/shipping
|
/datum/supply_pack/supply/shipping
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
/obj/item/weapon/tool/wirecutters,
|
/obj/item/weapon/tool/wirecutters,
|
||||||
/obj/item/weapon/tape_roll = 2)
|
/obj/item/weapon/tape_roll = 2)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/ummarcar
|
||||||
containername = "Shipping supplies crate"
|
containername = "Shipping supplies crate"
|
||||||
|
|
||||||
/datum/supply_pack/supply/bureaucracy
|
/datum/supply_pack/supply/bureaucracy
|
||||||
@@ -82,13 +82,13 @@
|
|||||||
)
|
)
|
||||||
name = "Office supplies"
|
name = "Office supplies"
|
||||||
cost = 15
|
cost = 15
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/ummarcar
|
||||||
containername = "Office supplies crate"
|
containername = "Office supplies crate"
|
||||||
|
|
||||||
/datum/supply_pack/supply/spare_pda
|
/datum/supply_pack/supply/spare_pda
|
||||||
name = "Spare PDAs"
|
name = "Spare PDAs"
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/thinktronic
|
||||||
containername = "Spare PDA crate"
|
containername = "Spare PDA crate"
|
||||||
contains = list(/obj/item/device/pda = 3)
|
contains = list(/obj/item/device/pda = 3)
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
/obj/item/clothing/glasses/meson
|
/obj/item/clothing/glasses/meson
|
||||||
)
|
)
|
||||||
cost = 10
|
cost = 10
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/xion
|
||||||
containername = "Shaft miner equipment"
|
containername = "Shaft miner equipment"
|
||||||
access = access_mining
|
access = access_mining
|
||||||
/* //VOREStation Edit - Pointless on Tether.
|
/* //VOREStation Edit - Pointless on Tether.
|
||||||
@@ -127,12 +127,12 @@
|
|||||||
name = "Cargo Train Tug"
|
name = "Cargo Train Tug"
|
||||||
contains = list(/obj/vehicle/train/engine)
|
contains = list(/obj/vehicle/train/engine)
|
||||||
cost = 35
|
cost = 35
|
||||||
containertype = /obj/structure/largecrate
|
containertype = /obj/structure/closet/crate/large/xion
|
||||||
containername = "Cargo Train Tug Crate"
|
containername = "Cargo Train Tug Crate"
|
||||||
|
|
||||||
/datum/supply_pack/supply/cargotrailer
|
/datum/supply_pack/supply/cargotrailer
|
||||||
name = "Cargo Train Trolley"
|
name = "Cargo Train Trolley"
|
||||||
contains = list(/obj/vehicle/train/trolley)
|
contains = list(/obj/vehicle/train/trolley)
|
||||||
cost = 15
|
cost = 15
|
||||||
containertype = /obj/structure/largecrate
|
containertype = /obj/structure/closet/crate/large/xion
|
||||||
containername = "Cargo Train Trolley Crate"
|
containername = "Cargo Train Trolley Crate"
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
/obj/item/weapon/tank/oxygen = 2,
|
/obj/item/weapon/tank/oxygen = 2,
|
||||||
)
|
)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/aether
|
||||||
containername = "Atmospheric voidsuit crate"
|
containername = "Atmospheric voidsuit crate"
|
||||||
access = access_atmospherics
|
access = access_atmospherics
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
/obj/item/weapon/tank/oxygen = 2,
|
/obj/item/weapon/tank/oxygen = 2,
|
||||||
)
|
)
|
||||||
cost = 50
|
cost = 50
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/aether
|
||||||
containername = "Heavy Duty Atmospheric voidsuit crate"
|
containername = "Heavy Duty Atmospheric voidsuit crate"
|
||||||
access = access_atmospherics
|
access = access_atmospherics
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
/obj/item/weapon/tank/oxygen = 2
|
/obj/item/weapon/tank/oxygen = 2
|
||||||
)
|
)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/xion
|
||||||
containername = "Engineering voidsuit crate"
|
containername = "Engineering voidsuit crate"
|
||||||
access = access_engine_equip
|
access = access_engine_equip
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
/obj/item/weapon/tank/oxygen = 2
|
/obj/item/weapon/tank/oxygen = 2
|
||||||
)
|
)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/xion
|
||||||
containername = "Engineering Construction voidsuit crate"
|
containername = "Engineering Construction voidsuit crate"
|
||||||
access = access_engine_equip
|
access = access_engine_equip
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@
|
|||||||
/obj/item/weapon/tank/oxygen = 2
|
/obj/item/weapon/tank/oxygen = 2
|
||||||
)
|
)
|
||||||
cost = 45
|
cost = 45
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/xion
|
||||||
containername = "Engineering Hazmat voidsuit crate"
|
containername = "Engineering Hazmat voidsuit crate"
|
||||||
access = access_engine_equip
|
access = access_engine_equip
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@
|
|||||||
/obj/item/weapon/tank/oxygen = 2
|
/obj/item/weapon/tank/oxygen = 2
|
||||||
)
|
)
|
||||||
cost = 50
|
cost = 50
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/xion
|
||||||
containername = "Reinforced Engineering voidsuit crate"
|
containername = "Reinforced Engineering voidsuit crate"
|
||||||
access = access_engine_equip
|
access = access_engine_equip
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@
|
|||||||
/obj/item/weapon/tank/oxygen = 2
|
/obj/item/weapon/tank/oxygen = 2
|
||||||
)
|
)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/veymed
|
||||||
containername = "Medical voidsuit crate"
|
containername = "Medical voidsuit crate"
|
||||||
access = access_medical_equip
|
access = access_medical_equip
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@
|
|||||||
/obj/item/weapon/tank/oxygen = 2
|
/obj/item/weapon/tank/oxygen = 2
|
||||||
)
|
)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/veymed
|
||||||
containername = "Medical EMT voidsuit crate"
|
containername = "Medical EMT voidsuit crate"
|
||||||
access = access_medical_equip
|
access = access_medical_equip
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@
|
|||||||
/obj/item/weapon/tank/oxygen = 2
|
/obj/item/weapon/tank/oxygen = 2
|
||||||
)
|
)
|
||||||
cost = 45
|
cost = 45
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/nanocare
|
||||||
containername = "Medical Biohazard voidsuit crate"
|
containername = "Medical Biohazard voidsuit crate"
|
||||||
access = access_medical_equip
|
access = access_medical_equip
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@
|
|||||||
/obj/item/weapon/tank/oxygen = 2
|
/obj/item/weapon/tank/oxygen = 2
|
||||||
)
|
)
|
||||||
cost = 60
|
cost = 60
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/veymed
|
||||||
containername = "Vey-Med Autoadaptive voidsuit (humanoid) crate"
|
containername = "Vey-Med Autoadaptive voidsuit (humanoid) crate"
|
||||||
access = access_medical_equip
|
access = access_medical_equip
|
||||||
|
|
||||||
@@ -168,7 +168,7 @@
|
|||||||
/obj/item/weapon/tank/oxygen = 2
|
/obj/item/weapon/tank/oxygen = 2
|
||||||
)
|
)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/heph
|
||||||
containername = "Security voidsuit crate"
|
containername = "Security voidsuit crate"
|
||||||
|
|
||||||
/datum/supply_pack/voidsuits/security/crowd
|
/datum/supply_pack/voidsuits/security/crowd
|
||||||
@@ -181,7 +181,7 @@
|
|||||||
/obj/item/weapon/tank/oxygen = 2
|
/obj/item/weapon/tank/oxygen = 2
|
||||||
)
|
)
|
||||||
cost = 60
|
cost = 60
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/heph
|
||||||
containername = "Security Crowd Control voidsuit crate"
|
containername = "Security Crowd Control voidsuit crate"
|
||||||
access = access_armory
|
access = access_armory
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@
|
|||||||
/obj/item/weapon/tank/oxygen = 2
|
/obj/item/weapon/tank/oxygen = 2
|
||||||
)
|
)
|
||||||
cost = 60
|
cost = 60
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/heph
|
||||||
containername = "Security EVA voidsuit crate"
|
containername = "Security EVA voidsuit crate"
|
||||||
access = access_armory
|
access = access_armory
|
||||||
|
|
||||||
@@ -208,7 +208,7 @@
|
|||||||
/obj/item/weapon/tank/oxygen = 2
|
/obj/item/weapon/tank/oxygen = 2
|
||||||
)
|
)
|
||||||
cost = 40
|
cost = 40
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/xion
|
||||||
containername = "Mining voidsuit crate"
|
containername = "Mining voidsuit crate"
|
||||||
access = access_mining
|
access = access_mining
|
||||||
|
|
||||||
@@ -221,7 +221,7 @@
|
|||||||
/obj/item/weapon/tank/oxygen = 2
|
/obj/item/weapon/tank/oxygen = 2
|
||||||
)
|
)
|
||||||
cost = 50
|
cost = 50
|
||||||
containertype = /obj/structure/closet/crate/secure
|
containertype = /obj/structure/closet/crate/secure/grayson
|
||||||
containername = "Frontier Mining voidsuit crate"
|
containername = "Frontier Mining voidsuit crate"
|
||||||
access = access_mining
|
access = access_mining
|
||||||
|
|
||||||
@@ -232,6 +232,6 @@
|
|||||||
/obj/item/clothing/mask/gas/zaddat = 1
|
/obj/item/clothing/mask/gas/zaddat = 1
|
||||||
)
|
)
|
||||||
cost = 30
|
cost = 30
|
||||||
containertype = /obj/structure/closet/crate
|
containertype = /obj/structure/closet/crate/nanotrasen
|
||||||
containername = "Zaddat Shroud crate"
|
containername = "Zaddat Shroud crate"
|
||||||
access = null
|
access = null
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/atom/movable
|
/atom/movable
|
||||||
layer = OBJ_LAYER
|
layer = OBJ_LAYER
|
||||||
appearance_flags = TILE_BOUND|PIXEL_SCALE
|
appearance_flags = TILE_BOUND|PIXEL_SCALE|KEEP_TOGETHER
|
||||||
glide_size = 8
|
glide_size = 8
|
||||||
var/last_move = null //The direction the atom last moved
|
var/last_move = null //The direction the atom last moved
|
||||||
var/anchored = 0
|
var/anchored = 0
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
var/datum/riding/riding_datum = null
|
var/datum/riding/riding_datum = null
|
||||||
var/does_spin = TRUE // Does the atom spin when thrown (of course it does :P)
|
var/does_spin = TRUE // Does the atom spin when thrown (of course it does :P)
|
||||||
var/movement_type = NONE
|
var/movement_type = NONE
|
||||||
|
|
||||||
var/cloaked = FALSE //If we're cloaked or not
|
var/cloaked = FALSE //If we're cloaked or not
|
||||||
var/image/cloaked_selfimage //The image we use for our client to let them see where we are
|
var/image/cloaked_selfimage //The image we use for our client to let them see where we are
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@
|
|||||||
glide_for(movetime)
|
glide_for(movetime)
|
||||||
loc = newloc
|
loc = newloc
|
||||||
. = TRUE
|
. = TRUE
|
||||||
|
|
||||||
// So objects can be informed of z-level changes
|
// So objects can be informed of z-level changes
|
||||||
if (old_z != dest_z)
|
if (old_z != dest_z)
|
||||||
onTransitZ(old_z, dest_z)
|
onTransitZ(old_z, dest_z)
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
var/atom/movable/thing = i
|
var/atom/movable/thing = i
|
||||||
// We don't call parent so we are calling this for byond
|
// We don't call parent so we are calling this for byond
|
||||||
thing.Crossed(src)
|
thing.Crossed(src)
|
||||||
|
|
||||||
// We're a multi-tile object (multiple locs)
|
// We're a multi-tile object (multiple locs)
|
||||||
else if(. && newloc)
|
else if(. && newloc)
|
||||||
. = doMove(newloc)
|
. = doMove(newloc)
|
||||||
@@ -282,7 +282,7 @@
|
|||||||
glide_for(movetime)
|
glide_for(movetime)
|
||||||
last_move = isnull(direction) ? 0 : direction
|
last_move = isnull(direction) ? 0 : direction
|
||||||
loc = destination
|
loc = destination
|
||||||
|
|
||||||
// Unset this in case it was set in some other proc. We're no longer moving diagonally for sure.
|
// Unset this in case it was set in some other proc. We're no longer moving diagonally for sure.
|
||||||
moving_diagonally = 0
|
moving_diagonally = 0
|
||||||
|
|
||||||
@@ -294,27 +294,27 @@
|
|||||||
// If it's not the same area, Exited() it
|
// If it's not the same area, Exited() it
|
||||||
if(old_area && old_area != destarea)
|
if(old_area && old_area != destarea)
|
||||||
old_area.Exited(src, destination)
|
old_area.Exited(src, destination)
|
||||||
|
|
||||||
// Uncross everything where we left
|
// Uncross everything where we left
|
||||||
for(var/i in oldloc)
|
for(var/i in oldloc)
|
||||||
var/atom/movable/AM = i
|
var/atom/movable/AM = i
|
||||||
if(AM == src)
|
if(AM == src)
|
||||||
continue
|
continue
|
||||||
AM.Uncrossed(src)
|
AM.Uncrossed(src)
|
||||||
|
|
||||||
// Information about turf and z-levels for source and dest collected
|
// Information about turf and z-levels for source and dest collected
|
||||||
var/turf/oldturf = get_turf(oldloc)
|
var/turf/oldturf = get_turf(oldloc)
|
||||||
var/turf/destturf = get_turf(destination)
|
var/turf/destturf = get_turf(destination)
|
||||||
var/old_z = (oldturf ? oldturf.z : null)
|
var/old_z = (oldturf ? oldturf.z : null)
|
||||||
var/dest_z = (destturf ? destturf.z : null)
|
var/dest_z = (destturf ? destturf.z : null)
|
||||||
|
|
||||||
// So objects can be informed of z-level changes
|
// So objects can be informed of z-level changes
|
||||||
if (old_z != dest_z)
|
if (old_z != dest_z)
|
||||||
onTransitZ(old_z, dest_z)
|
onTransitZ(old_z, dest_z)
|
||||||
|
|
||||||
// Destination atom Entered
|
// Destination atom Entered
|
||||||
destination.Entered(src, oldloc)
|
destination.Entered(src, oldloc)
|
||||||
|
|
||||||
// Entered() the new area if it's not the same area
|
// Entered() the new area if it's not the same area
|
||||||
if(destarea && old_area != destarea)
|
if(destarea && old_area != destarea)
|
||||||
destarea.Entered(src, oldloc)
|
destarea.Entered(src, oldloc)
|
||||||
@@ -366,7 +366,7 @@
|
|||||||
glide_size = initial(glide_size)
|
glide_size = initial(glide_size)
|
||||||
else
|
else
|
||||||
glide_size = initial(glide_size)
|
glide_size = initial(glide_size)
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
//called when src is thrown into hit_atom
|
//called when src is thrown into hit_atom
|
||||||
@@ -623,7 +623,7 @@
|
|||||||
/atom/movable/proc/cloak_animation(var/length = 1 SECOND)
|
/atom/movable/proc/cloak_animation(var/length = 1 SECOND)
|
||||||
//Save these
|
//Save these
|
||||||
var/initial_alpha = alpha
|
var/initial_alpha = alpha
|
||||||
|
|
||||||
//Animate alpha fade
|
//Animate alpha fade
|
||||||
animate(src, alpha = 0, time = length)
|
animate(src, alpha = 0, time = length)
|
||||||
|
|
||||||
|
|||||||
@@ -232,12 +232,6 @@
|
|||||||
else
|
else
|
||||||
to_chat(O, "<b><a href='byond://?src=\ref[O];track2=\ref[O];track=\ref[U];trackname=[U.name]'>[U]</a></b> holds \a [itemname] up to one of your cameras ...")
|
to_chat(O, "<b><a href='byond://?src=\ref[O];track2=\ref[O];track=\ref[U];trackname=[U.name]'>[U]</a></b> holds \a [itemname] up to one of your cameras ...")
|
||||||
O << browse(text("<HTML><HEAD><TITLE>[]</TITLE></HEAD><BODY><TT>[]</TT></BODY></HTML>", itemname, info), text("window=[]", itemname))
|
O << browse(text("<HTML><HEAD><TITLE>[]</TITLE></HEAD><BODY><TT>[]</TT></BODY></HTML>", itemname, info), text("window=[]", itemname))
|
||||||
for(var/mob/O in player_list)
|
|
||||||
if (istype(O.machine, /obj/machinery/computer/security))
|
|
||||||
var/obj/machinery/computer/security/S = O.machine
|
|
||||||
if (S.current_camera == src)
|
|
||||||
to_chat(O, "[U] holds \a [itemname] up to one of the cameras ...")
|
|
||||||
O << browse(text("<HTML><HEAD><TITLE>[]</TITLE></HEAD><BODY><TT>[]</TT></BODY></HTML>", itemname, info), text("window=[]", itemname))
|
|
||||||
|
|
||||||
else if (istype(W, /obj/item/weapon/camera_bug))
|
else if (istype(W, /obj/item/weapon/camera_bug))
|
||||||
if (!src.can_use())
|
if (!src.can_use())
|
||||||
@@ -494,8 +488,6 @@
|
|||||||
else
|
else
|
||||||
cameranet.updateVisibility(src, 0)
|
cameranet.updateVisibility(src, 0)
|
||||||
|
|
||||||
invalidateCameraCache()
|
|
||||||
|
|
||||||
// Resets the camera's wires to fully operational state. Used by one of Malfunction abilities.
|
// Resets the camera's wires to fully operational state. Used by one of Malfunction abilities.
|
||||||
/obj/machinery/camera/proc/reset_wires()
|
/obj/machinery/camera/proc/reset_wires()
|
||||||
if(!wires)
|
if(!wires)
|
||||||
|
|||||||
@@ -173,7 +173,6 @@ var/global/list/engineering_networks = list(
|
|||||||
var/number = my_area.len
|
var/number = my_area.len
|
||||||
|
|
||||||
c_tag = "[A.name] #[number]"
|
c_tag = "[A.name] #[number]"
|
||||||
invalidateCameraCache()
|
|
||||||
|
|
||||||
/obj/machinery/camera/autoname/Destroy()
|
/obj/machinery/camera/autoname/Destroy()
|
||||||
var/area/A = get_area(src)
|
var/area/A = get_area(src)
|
||||||
|
|||||||
@@ -1,142 +1,132 @@
|
|||||||
/obj/machinery/computer/aifixer
|
/obj/machinery/computer/aifixer
|
||||||
name = "\improper AI system integrity restorer"
|
name = "\improper AI system integrity restorer"
|
||||||
desc = "Restores AI units to working condition, assuming you have one inside!"
|
desc = "Used with intelliCards containing nonfunctional AIs to restore them to working order."
|
||||||
icon_keyboard = "rd_key"
|
|
||||||
icon_screen = "ai-fixer"
|
|
||||||
light_color = "#a97faa"
|
|
||||||
circuit = /obj/item/weapon/circuitboard/aifixer
|
|
||||||
req_one_access = list(access_robotics, access_heads)
|
req_one_access = list(access_robotics, access_heads)
|
||||||
var/mob/living/silicon/ai/occupant = null
|
circuit = /obj/item/weapon/circuitboard/aifixer
|
||||||
var/active = 0
|
icon_keyboard = "tech_key"
|
||||||
|
icon_screen = "ai-fixer"
|
||||||
|
light_color = LIGHT_COLOR_PINK
|
||||||
|
|
||||||
|
active_power_usage = 1000
|
||||||
|
|
||||||
/obj/machinery/computer/aifixer/New()
|
/// Variable containing transferred AI
|
||||||
..()
|
var/mob/living/silicon/ai/occupier
|
||||||
update_icon()
|
/// Variable dictating if we are in the process of restoring the occupier AI
|
||||||
|
var/restoring = FALSE
|
||||||
/obj/machinery/computer/aifixer/proc/load_ai(var/mob/living/silicon/ai/transfer, var/obj/item/device/aicard/card, var/mob/user)
|
|
||||||
|
|
||||||
if(!transfer)
|
|
||||||
return
|
|
||||||
|
|
||||||
// Transfer over the AI.
|
|
||||||
to_chat(transfer, "You have been transferred into a stationary terminal. Sadly, there is no remote access from here.")
|
|
||||||
to_chat(user, "<span class='notice'>Transfer successful:</span> [transfer.name] placed within stationary terminal.")
|
|
||||||
|
|
||||||
transfer.loc = src
|
|
||||||
transfer.cancel_camera()
|
|
||||||
transfer.control_disabled = 1
|
|
||||||
occupant = transfer
|
|
||||||
|
|
||||||
if(card)
|
|
||||||
card.clear()
|
|
||||||
|
|
||||||
update_icon()
|
|
||||||
|
|
||||||
/obj/machinery/computer/aifixer/attackby(I as obj, user as mob)
|
|
||||||
|
|
||||||
|
/obj/machinery/computer/aifixer/attackby(obj/item/I, mob/living/user)
|
||||||
|
if(I.is_screwdriver())
|
||||||
|
if(occupier)
|
||||||
|
if(stat & (NOPOWER|BROKEN))
|
||||||
|
to_chat(user, "<span class='warning'>The screws on [name]'s screen won't budge.</span>")
|
||||||
|
else
|
||||||
|
to_chat(user, "<span class='warning'>The screws on [name]'s screen won't budge and it emits a warning beep.</span>")
|
||||||
|
return
|
||||||
if(istype(I, /obj/item/device/aicard))
|
if(istype(I, /obj/item/device/aicard))
|
||||||
|
|
||||||
if(stat & (NOPOWER|BROKEN))
|
if(stat & (NOPOWER|BROKEN))
|
||||||
to_chat(user, "This terminal isn't functioning right now.")
|
to_chat(user, "<span class='warning'>This terminal isn't functioning right now.</span>")
|
||||||
|
return
|
||||||
|
if(restoring)
|
||||||
|
to_chat(user, "<span class='danger'>Terminal is busy restoring [occupier] right now.</span>")
|
||||||
return
|
return
|
||||||
|
|
||||||
var/obj/item/device/aicard/card = I
|
var/obj/item/device/aicard/card = I
|
||||||
var/mob/living/silicon/ai/comp_ai = locate() in src
|
if(occupier)
|
||||||
var/mob/living/silicon/ai/card_ai = locate() in card
|
if(card.grab_ai(occupier, user))
|
||||||
|
occupier = null
|
||||||
|
else if(card.carded_ai)
|
||||||
|
var/mob/living/silicon/ai/new_occupant = card.carded_ai
|
||||||
|
to_chat(new_occupant, "<span class='notice'>You have been transferred into a stationary terminal. Sadly there is no remote access from here.</span>")
|
||||||
|
to_chat(user, "<span class='notice'>Transfer Successful:</span> [new_occupant] placed within stationary terminal.")
|
||||||
|
new_occupant.forceMove(src)
|
||||||
|
new_occupant.cancel_camera()
|
||||||
|
new_occupant.control_disabled = TRUE
|
||||||
|
occupier = new_occupant
|
||||||
|
card.clear()
|
||||||
|
update_icon()
|
||||||
|
else
|
||||||
|
to_chat(user, "<span class='notice'>There is no AI loaded onto this computer, and no AI loaded onto [I]. What exactly are you trying to do here?</span>")
|
||||||
|
return ..()
|
||||||
|
|
||||||
if(istype(comp_ai))
|
/obj/machinery/computer/aifixer/attack_hand(mob/user)
|
||||||
if(active)
|
if(stat & (NOPOWER|BROKEN))
|
||||||
to_chat(user, "<span class='danger'>ERROR:</span> Reconstruction in progress.")
|
|
||||||
return
|
|
||||||
card.grab_ai(comp_ai, user)
|
|
||||||
if(!(locate(/mob/living/silicon/ai) in src)) occupant = null
|
|
||||||
else if(istype(card_ai))
|
|
||||||
load_ai(card_ai,card,user)
|
|
||||||
occupant = locate(/mob/living/silicon/ai) in src
|
|
||||||
|
|
||||||
update_icon()
|
|
||||||
return
|
return
|
||||||
..()
|
tgui_interact(user)
|
||||||
return
|
|
||||||
|
|
||||||
/obj/machinery/computer/aifixer/attack_ai(var/mob/user as mob)
|
/obj/machinery/computer/aifixer/tgui_interact(mob/user, datum/tgui/ui)
|
||||||
return attack_hand(user)
|
ui = SStgui.try_update_ui(user, src, ui)
|
||||||
|
if(!ui)
|
||||||
|
ui = new(user, src, "AiRestorer", name)
|
||||||
|
ui.open()
|
||||||
|
|
||||||
/obj/machinery/computer/aifixer/attack_hand(var/mob/user as mob)
|
/obj/machinery/computer/aifixer/tgui_data(mob/user)
|
||||||
|
var/list/data = list()
|
||||||
|
|
||||||
|
data["ejectable"] = FALSE
|
||||||
|
data["AI_present"] = FALSE
|
||||||
|
data["error"] = null
|
||||||
|
if(!occupier)
|
||||||
|
data["error"] = "Please transfer an AI unit."
|
||||||
|
else
|
||||||
|
data["AI_present"] = TRUE
|
||||||
|
data["name"] = occupier.name
|
||||||
|
data["restoring"] = restoring
|
||||||
|
data["health"] = (occupier.health + 100) / 2
|
||||||
|
data["isDead"] = occupier.stat == DEAD
|
||||||
|
var/list/laws = list()
|
||||||
|
for(var/datum/ai_law/law in occupier.laws.all_laws())
|
||||||
|
laws += "[law.get_index()]: [law.law]"
|
||||||
|
data["laws"] = laws
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
/obj/machinery/computer/aifixer/tgui_act(action, params)
|
||||||
if(..())
|
if(..())
|
||||||
return
|
return
|
||||||
|
if(!occupier)
|
||||||
|
restoring = FALSE
|
||||||
|
|
||||||
user.set_machine(src)
|
switch(action)
|
||||||
var/dat = "<h3>AI System Integrity Restorer</h3><br><br>"
|
if("PRG_beginReconstruction")
|
||||||
|
if(occupier?.health < 100)
|
||||||
|
to_chat(usr, "<span class='notice'>Reconstruction in progress. This will take several minutes.</span>")
|
||||||
|
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, FALSE)
|
||||||
|
restoring = TRUE
|
||||||
|
var/mob/observer/dead/ghost = occupier.get_ghost()
|
||||||
|
if(ghost)
|
||||||
|
ghost.notify_revive("Your core files are being restored!", source = src)
|
||||||
|
. = TRUE
|
||||||
|
|
||||||
if (src.occupant)
|
/obj/machinery/computer/aifixer/proc/Fix()
|
||||||
var/laws
|
use_power(active_power_usage)
|
||||||
dat += "Stored AI: [src.occupant.name]<br>System integrity: [src.occupant.hardware_integrity()]%<br>Backup Capacitor: [src.occupant.backup_capacitor()]%<br>"
|
occupier.adjustOxyLoss(-5, 0, FALSE)
|
||||||
|
occupier.adjustFireLoss(-5, 0, FALSE)
|
||||||
|
occupier.adjustBruteLoss(-5, 0)
|
||||||
|
if(occupier.health >= 0 && occupier.stat == DEAD)
|
||||||
|
occupier.revive()
|
||||||
|
|
||||||
for (var/datum/ai_law/law in occupant.laws.all_laws())
|
return occupier.health < 100
|
||||||
laws += "[law.get_index()]: [law.law]<BR>"
|
|
||||||
|
|
||||||
dat += "Laws:<br>[laws]<br>"
|
|
||||||
|
|
||||||
if (src.occupant.stat == 2)
|
|
||||||
dat += "<b>AI nonfunctional</b>"
|
|
||||||
else
|
|
||||||
dat += "<b>AI functional</b>"
|
|
||||||
if (!src.active)
|
|
||||||
dat += {"<br><br><A href='byond://?src=\ref[src];fix=1'>Begin Reconstruction</A>"}
|
|
||||||
else
|
|
||||||
dat += "<br><br>Reconstruction in process, please wait.<br>"
|
|
||||||
dat += {" <A href='?src=\ref[user];mach_close=computer'>Close</A>"}
|
|
||||||
|
|
||||||
user << browse(dat, "window=computer;size=400x500")
|
|
||||||
onclose(user, "computer")
|
|
||||||
return
|
|
||||||
|
|
||||||
/obj/machinery/computer/aifixer/process()
|
/obj/machinery/computer/aifixer/process()
|
||||||
if(..())
|
if(..())
|
||||||
src.updateDialog()
|
if(restoring)
|
||||||
return
|
var/oldstat = occupier.stat
|
||||||
|
restoring = Fix()
|
||||||
/obj/machinery/computer/aifixer/Topic(href, href_list)
|
if(oldstat != occupier.stat)
|
||||||
if(..())
|
update_icon()
|
||||||
return 1
|
|
||||||
if (href_list["fix"])
|
|
||||||
src.active = 1
|
|
||||||
src.overlays += image(icon, "ai-fixer-on")
|
|
||||||
while (src.occupant.getOxyLoss() > 0 || src.occupant.getFireLoss() > 0 || src.occupant.getToxLoss() > 0 || src.occupant.getBruteLoss() > 0)
|
|
||||||
src.occupant.adjustOxyLoss(-1)
|
|
||||||
src.occupant.adjustFireLoss(-1)
|
|
||||||
src.occupant.adjustToxLoss(-1)
|
|
||||||
src.occupant.adjustBruteLoss(-1)
|
|
||||||
src.occupant.updatehealth()
|
|
||||||
if (src.occupant.health >= 0 && src.occupant.stat == DEAD)
|
|
||||||
src.occupant.set_stat(CONSCIOUS)
|
|
||||||
src.occupant.lying = 0
|
|
||||||
dead_mob_list -= src.occupant
|
|
||||||
living_mob_list += src.occupant
|
|
||||||
src.overlays -= image(icon, "ai-fixer-404")
|
|
||||||
src.overlays += image(icon, "ai-fixer-full")
|
|
||||||
src.occupant.add_ai_verbs()
|
|
||||||
src.updateUsrDialog()
|
|
||||||
sleep(10)
|
|
||||||
src.active = 0
|
|
||||||
src.overlays -= image(icon, "ai-fixer-on")
|
|
||||||
|
|
||||||
|
|
||||||
src.add_fingerprint(usr)
|
|
||||||
src.updateUsrDialog()
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
/obj/machinery/computer/aifixer/update_icon()
|
/obj/machinery/computer/aifixer/update_icon()
|
||||||
..()
|
. = ..()
|
||||||
if((stat & BROKEN) || (stat & NOPOWER))
|
if(stat & (NOPOWER|BROKEN))
|
||||||
return
|
return
|
||||||
|
|
||||||
if(occupant)
|
if(restoring)
|
||||||
if(occupant.stat)
|
. += "ai-fixer-on"
|
||||||
add_overlay("ai-fixer-404")
|
if (occupier)
|
||||||
else
|
switch (occupier.stat)
|
||||||
add_overlay("ai-fixer-full")
|
if (CONSCIOUS)
|
||||||
|
. += "ai-fixer-full"
|
||||||
|
if (UNCONSCIOUS)
|
||||||
|
. += "ai-fixer-404"
|
||||||
else
|
else
|
||||||
add_overlay("ai-fixer-empty")
|
. += "ai-fixer-empty"
|
||||||
@@ -3,201 +3,44 @@
|
|||||||
/obj/machinery/computer/security
|
/obj/machinery/computer/security
|
||||||
name = "security camera monitor"
|
name = "security camera monitor"
|
||||||
desc = "Used to access the various cameras on the station."
|
desc = "Used to access the various cameras on the station."
|
||||||
|
|
||||||
icon_keyboard = "security_key"
|
icon_keyboard = "security_key"
|
||||||
icon_screen = "cameras"
|
icon_screen = "cameras"
|
||||||
light_color = "#a91515"
|
light_color = "#a91515"
|
||||||
var/current_network = null
|
|
||||||
var/obj/machinery/camera/current_camera = null
|
|
||||||
var/last_pic = 1.0
|
|
||||||
var/list/network
|
|
||||||
var/mapping = 0//For the overview file, interesting bit of code.
|
|
||||||
var/cache_id = 0
|
|
||||||
circuit = /obj/item/weapon/circuitboard/security
|
circuit = /obj/item/weapon/circuitboard/security
|
||||||
|
|
||||||
/obj/machinery/computer/security/New()
|
var/mapping = 0//For the overview file, interesting bit of code.
|
||||||
if(!network)
|
var/list/network = list()
|
||||||
|
|
||||||
|
var/datum/tgui_module/camera/camera
|
||||||
|
|
||||||
|
/obj/machinery/computer/security/Initialize()
|
||||||
|
. = ..()
|
||||||
|
if(!LAZYLEN(network))
|
||||||
network = using_map.station_networks.Copy()
|
network = using_map.station_networks.Copy()
|
||||||
..()
|
camera = new(src, network)
|
||||||
if(network.len)
|
|
||||||
current_network = network[1]
|
|
||||||
|
|
||||||
/obj/machinery/computer/security/attack_ai(var/mob/user as mob)
|
/obj/machinery/computer/security/Destroy()
|
||||||
return attack_hand(user)
|
QDEL_NULL(camera)
|
||||||
|
return ..()
|
||||||
|
|
||||||
/obj/machinery/computer/security/check_eye(var/mob/user as mob)
|
/obj/machinery/computer/security/tgui_interact(mob/user, datum/tgui/ui = null)
|
||||||
if (user.stat || ((get_dist(user, src) > 1 || !( user.canmove ) || user.blinded) && !istype(user, /mob/living/silicon))) //user can't see - not sure why canmove is here.
|
camera.tgui_interact(user, ui)
|
||||||
return -1
|
|
||||||
if(!current_camera)
|
|
||||||
return 0
|
|
||||||
var/viewflag = current_camera.check_eye(user)
|
|
||||||
if ( viewflag < 0 ) //camera doesn't work
|
|
||||||
reset_current()
|
|
||||||
return viewflag
|
|
||||||
|
|
||||||
/obj/machinery/computer/security/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1)
|
/obj/machinery/computer/security/attack_hand(mob/user)
|
||||||
if(stat & (NOPOWER|BROKEN)) return
|
add_fingerprint(user)
|
||||||
if(user.stat) return
|
if(stat & (BROKEN|NOPOWER))
|
||||||
|
|
||||||
var/data[0]
|
|
||||||
|
|
||||||
data["current_camera"] = current_camera ? current_camera.nano_structure() : null
|
|
||||||
data["current_network"] = current_network
|
|
||||||
data["networks"] = network ? network : list()
|
|
||||||
|
|
||||||
var/map_levels = using_map.get_map_levels(src.z, TRUE, om_range = DEFAULT_OVERMAP_RANGE)
|
|
||||||
data["map_levels"] = map_levels
|
|
||||||
|
|
||||||
if(current_network)
|
|
||||||
data["cameras"] = camera_repository.cameras_in_network(current_network, map_levels)
|
|
||||||
if(current_camera)
|
|
||||||
switch_to_camera(user, current_camera)
|
|
||||||
|
|
||||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
|
||||||
if (!ui)
|
|
||||||
ui = new(user, src, ui_key, "sec_camera.tmpl", "Camera Console", 900, 800)
|
|
||||||
|
|
||||||
// adding a template with the key "mapContent" enables the map ui functionality
|
|
||||||
ui.add_template("mapContent", "sec_camera_map_content.tmpl")
|
|
||||||
// adding a template with the key "mapHeader" replaces the map header content
|
|
||||||
ui.add_template("mapHeader", "sec_camera_map_header.tmpl")
|
|
||||||
|
|
||||||
ui.set_initial_data(data)
|
|
||||||
ui.open()
|
|
||||||
|
|
||||||
/obj/machinery/computer/security/Topic(href, href_list)
|
|
||||||
if(..())
|
|
||||||
return 1
|
|
||||||
if(href_list["switch_camera"])
|
|
||||||
if(stat&(NOPOWER|BROKEN)) return //VOREStation Edit - Removed zlevel check
|
|
||||||
if(usr.stat || ((get_dist(usr, src) > 1 || !( usr.canmove ) || usr.blinded) && !istype(usr, /mob/living/silicon))) return
|
|
||||||
var/obj/machinery/camera/C = locate(href_list["switch_camera"]) in cameranet.cameras
|
|
||||||
if(!C)
|
|
||||||
return
|
|
||||||
if(!(current_network in C.network))
|
|
||||||
return
|
|
||||||
|
|
||||||
switch_to_camera(usr, C)
|
|
||||||
return 1
|
|
||||||
else if(href_list["switch_network"])
|
|
||||||
if(stat&(NOPOWER|BROKEN)) return //VOREStation Edit - Removed zlevel check
|
|
||||||
if(usr.stat || ((get_dist(usr, src) > 1 || !( usr.canmove ) || usr.blinded) && !istype(usr, /mob/living/silicon))) return
|
|
||||||
if(href_list["switch_network"] in network)
|
|
||||||
current_network = href_list["switch_network"]
|
|
||||||
return 1
|
|
||||||
else if(href_list["reset"])
|
|
||||||
if(stat&(NOPOWER|BROKEN)) return //VOREStation Edit - Removed zlevel check
|
|
||||||
if(usr.stat || ((get_dist(usr, src) > 1 || !( usr.canmove ) || usr.blinded) && !istype(usr, /mob/living/silicon))) return
|
|
||||||
reset_current()
|
|
||||||
usr.reset_view(current_camera)
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
. = ..()
|
|
||||||
|
|
||||||
/obj/machinery/computer/security/attack_hand(var/mob/user as mob)
|
|
||||||
if(stat & (NOPOWER|BROKEN)) return
|
|
||||||
|
|
||||||
if(!isAI(user))
|
|
||||||
user.set_machine(src)
|
|
||||||
ui_interact(user)
|
|
||||||
|
|
||||||
/obj/machinery/computer/security/proc/switch_to_camera(var/mob/user, var/obj/machinery/camera/C)
|
|
||||||
//don't need to check if the camera works for AI because the AI jumps to the camera location and doesn't actually look through cameras.
|
|
||||||
if(isAI(user))
|
|
||||||
var/mob/living/silicon/ai/A = user
|
|
||||||
// Only allow non-carded AIs to view because the interaction with the eye gets all wonky otherwise.
|
|
||||||
if(!A.is_in_chassis())
|
|
||||||
return 0
|
|
||||||
|
|
||||||
A.eyeobj.setLoc(get_turf(C))
|
|
||||||
A.client.eye = A.eyeobj
|
|
||||||
return 1
|
|
||||||
|
|
||||||
if (!C.can_use() || user.stat || (get_dist(user, src) > 1 || user.machine != src || user.blinded || !( user.canmove ) && !istype(user, /mob/living/silicon)))
|
|
||||||
return 0
|
|
||||||
set_current(C)
|
|
||||||
user.reset_view(current_camera)
|
|
||||||
check_eye(user)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
/obj/machinery/computer/security/relaymove(mob/user,direct)
|
|
||||||
var/turf/T = get_turf(current_camera)
|
|
||||||
for(var/i; i < 10; i++)
|
|
||||||
T = get_step(T, direct)
|
|
||||||
jump_on_click(user, T)
|
|
||||||
|
|
||||||
//Camera control: moving.
|
|
||||||
/obj/machinery/computer/security/proc/jump_on_click(var/mob/user,var/A)
|
|
||||||
if(user.machine != src)
|
|
||||||
return
|
return
|
||||||
var/obj/machinery/camera/jump_to
|
tgui_interact(user)
|
||||||
if(istype(A,/obj/machinery/camera))
|
|
||||||
jump_to = A
|
|
||||||
else if(ismob(A))
|
|
||||||
if(ishuman(A))
|
|
||||||
jump_to = locate() in A:head
|
|
||||||
else if(isrobot(A))
|
|
||||||
jump_to = A:camera
|
|
||||||
else if(isobj(A))
|
|
||||||
jump_to = locate() in A
|
|
||||||
else if(isturf(A))
|
|
||||||
var/best_dist = INFINITY
|
|
||||||
for(var/obj/machinery/camera/camera in get_area(A))
|
|
||||||
if(!camera.can_use())
|
|
||||||
continue
|
|
||||||
if(!can_access_camera(camera))
|
|
||||||
continue
|
|
||||||
var/dist = get_dist(camera,A)
|
|
||||||
if(dist < best_dist)
|
|
||||||
best_dist = dist
|
|
||||||
jump_to = camera
|
|
||||||
if(isnull(jump_to))
|
|
||||||
return
|
|
||||||
if(can_access_camera(jump_to))
|
|
||||||
switch_to_camera(user,jump_to)
|
|
||||||
|
|
||||||
/obj/machinery/computer/security/process()
|
/obj/machinery/computer/security/attack_ai(mob/user)
|
||||||
if(cache_id != camera_repository.camera_cache_id)
|
to_chat(user, "<span class='notice'>You realise its kind of stupid to access a camera console when you have the entire camera network at your metaphorical fingertips</span>")
|
||||||
cache_id = camera_repository.camera_cache_id
|
return
|
||||||
SSnanoui.update_uis(src)
|
|
||||||
|
|
||||||
/obj/machinery/computer/security/proc/can_access_camera(var/obj/machinery/camera/C)
|
/obj/machinery/computer/security/proc/set_network(list/new_network)
|
||||||
var/list/shared_networks = src.network & C.network
|
network = new_network
|
||||||
if(shared_networks.len)
|
camera.network = network
|
||||||
return 1
|
camera.access_based = FALSE
|
||||||
return 0
|
|
||||||
|
|
||||||
/obj/machinery/computer/security/proc/set_current(var/obj/machinery/camera/C)
|
|
||||||
if(current_camera == C)
|
|
||||||
return
|
|
||||||
|
|
||||||
if(current_camera)
|
|
||||||
reset_current()
|
|
||||||
|
|
||||||
src.current_camera = C
|
|
||||||
if(current_camera)
|
|
||||||
current_camera.camera_computers_using_this.Add(src)
|
|
||||||
update_use_power(USE_POWER_ACTIVE)
|
|
||||||
var/mob/living/L = current_camera.loc
|
|
||||||
if(istype(L))
|
|
||||||
L.tracking_initiated()
|
|
||||||
|
|
||||||
/obj/machinery/computer/security/proc/reset_current()
|
|
||||||
if(current_camera)
|
|
||||||
current_camera.camera_computers_using_this.Remove(src)
|
|
||||||
var/mob/living/L = current_camera.loc
|
|
||||||
if(istype(L))
|
|
||||||
L.tracking_cancelled()
|
|
||||||
current_camera = null
|
|
||||||
update_use_power(USE_POWER_IDLE)
|
|
||||||
|
|
||||||
//Camera control: mouse.
|
|
||||||
/* Oh my god
|
|
||||||
/atom/DblClick()
|
|
||||||
..()
|
|
||||||
if(istype(usr.machine,/obj/machinery/computer/security))
|
|
||||||
var/obj/machinery/computer/security/console = usr.machine
|
|
||||||
console.jump_on_click(usr,src)
|
|
||||||
*/
|
|
||||||
|
|
||||||
//Camera control: arrow keys.
|
//Camera control: arrow keys.
|
||||||
/obj/machinery/computer/security/telescreen
|
/obj/machinery/computer/security/telescreen
|
||||||
|
|||||||
@@ -1,116 +0,0 @@
|
|||||||
|
|
||||||
//the researchable camera circuit that can connect to any camera network
|
|
||||||
|
|
||||||
/obj/item/weapon/circuitboard/camera
|
|
||||||
//name = "Circuit board (Camera)"
|
|
||||||
var/secured = 1
|
|
||||||
var/authorised = 0
|
|
||||||
var/possibleNets[0]
|
|
||||||
var/network = ""
|
|
||||||
build_path = null
|
|
||||||
|
|
||||||
//when adding a new camera network, you should only need to update these two procs
|
|
||||||
New()
|
|
||||||
possibleNets["Engineering"] = access_ce
|
|
||||||
possibleNets["SS13"] = access_hos
|
|
||||||
possibleNets["Mining"] = access_mining
|
|
||||||
possibleNets["Cargo"] = access_qm
|
|
||||||
possibleNets["Research"] = access_rd
|
|
||||||
possibleNets["Medbay"] = access_cmo
|
|
||||||
..()
|
|
||||||
|
|
||||||
proc/updateBuildPath()
|
|
||||||
build_path = null
|
|
||||||
if(authorised && secured)
|
|
||||||
switch(network)
|
|
||||||
if("SS13")
|
|
||||||
build_path = /obj/machinery/computer/security
|
|
||||||
if("Engineering")
|
|
||||||
build_path = /obj/machinery/computer/security/engineering
|
|
||||||
if("Mining")
|
|
||||||
build_path = /obj/machinery/computer/security/mining
|
|
||||||
if("Research")
|
|
||||||
build_path = /obj/machinery/computer/security/research
|
|
||||||
if("Medbay")
|
|
||||||
build_path = /obj/machinery/computer/security/medbay
|
|
||||||
if("Cargo")
|
|
||||||
build_path = /obj/machinery/computer/security/cargo
|
|
||||||
|
|
||||||
attackby(var/obj/item/I, var/mob/user)//if(health > 50)
|
|
||||||
..()
|
|
||||||
else if(I.is_screwdriver())
|
|
||||||
secured = !secured
|
|
||||||
user.visible_message("<span class='notice'>The [src] can [secured ? "no longer" : "now"] be modified.</span>")
|
|
||||||
playsound(src, I.usesound, 50, 1)
|
|
||||||
updateBuildPath()
|
|
||||||
return
|
|
||||||
|
|
||||||
attack_self(var/mob/user)
|
|
||||||
if(!secured && ishuman(user))
|
|
||||||
user.machine = src
|
|
||||||
interact(user, 0)
|
|
||||||
|
|
||||||
proc/interact(var/mob/user, var/ai=0)
|
|
||||||
if(secured)
|
|
||||||
return
|
|
||||||
if (!ishuman(user))
|
|
||||||
return ..(user)
|
|
||||||
var/t = "<B>Circuitboard Console - Camera Monitoring Computer</B><BR>"
|
|
||||||
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
|
|
||||||
t += "<hr> Please select a camera network:<br>"
|
|
||||||
|
|
||||||
for(var/curNet in possibleNets)
|
|
||||||
if(network == curNet)
|
|
||||||
t += "- [curNet]<br>"
|
|
||||||
else
|
|
||||||
t += "- <A href='?src=\ref[src];net=[curNet]'>[curNet]</A><BR>"
|
|
||||||
t += "<hr>"
|
|
||||||
if(network)
|
|
||||||
if(authorised)
|
|
||||||
t += "Authenticated <A href='?src=\ref[src];removeauth=1'>(Clear Auth)</A><BR>"
|
|
||||||
else
|
|
||||||
t += "<A href='?src=\ref[src];auth=1'><b>*Authenticate*</b></A> (Requires an appropriate access ID)<br>"
|
|
||||||
else
|
|
||||||
t += "<A href='?src=\ref[src];auth=1'>*Authenticate*</A> (Requires an appropriate access ID)<BR>"
|
|
||||||
t += "<A href='?src=\ref[src];close=1'>Close</A><BR>"
|
|
||||||
user << browse(t, "window=camcircuit;size=500x400")
|
|
||||||
onclose(user, "camcircuit")
|
|
||||||
|
|
||||||
Topic(href, href_list)
|
|
||||||
..()
|
|
||||||
if( href_list["close"] )
|
|
||||||
usr << browse(null, "window=camcircuit")
|
|
||||||
usr.machine = null
|
|
||||||
return
|
|
||||||
else if(href_list["net"])
|
|
||||||
network = href_list["net"]
|
|
||||||
authorised = 0
|
|
||||||
else if( href_list["auth"] )
|
|
||||||
var/mob/M = usr
|
|
||||||
var/obj/item/weapon/card/id/I = M.equipped()
|
|
||||||
if (istype(I, /obj/item/device/pda))
|
|
||||||
var/obj/item/device/pda/pda = I
|
|
||||||
I = pda.id
|
|
||||||
if (I && istype(I))
|
|
||||||
if(access_captain in I.access)
|
|
||||||
authorised = 1
|
|
||||||
else if (possibleNets[network] in I.access)
|
|
||||||
authorised = 1
|
|
||||||
if(istype(I,/obj/item/weapon/card/emag))
|
|
||||||
I.resolve_attackby(src, usr)
|
|
||||||
else if( href_list["removeauth"] )
|
|
||||||
authorised = 0
|
|
||||||
updateDialog()
|
|
||||||
|
|
||||||
updateDialog()
|
|
||||||
if(istype(src.loc,/mob))
|
|
||||||
attack_self(src.loc)
|
|
||||||
|
|
||||||
/obj/item/weapon/circuitboard/camera/emag_act(var/remaining_charges, var/mob/user)
|
|
||||||
if(network)
|
|
||||||
authorised = 1
|
|
||||||
to_chat(user, "<span class='notice'>You authorised the circuit network!</span>")
|
|
||||||
updateDialog()
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
to_chat(user, "<span class='warning'>You must select a camera network circuit!</span>")
|
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
idle_power_usage = 250
|
idle_power_usage = 250
|
||||||
active_power_usage = 500
|
active_power_usage = 500
|
||||||
circuit = /obj/item/weapon/circuitboard/crew
|
circuit = /obj/item/weapon/circuitboard/crew
|
||||||
var/datum/nano_module/program/crew_monitor/crew_monitor
|
var/datum/tgui_module/crew_monitor/crew_monitor
|
||||||
|
|
||||||
/obj/machinery/computer/crew/New()
|
/obj/machinery/computer/crew/New()
|
||||||
crew_monitor = new(src)
|
crew_monitor = new(src)
|
||||||
@@ -20,16 +20,16 @@
|
|||||||
..()
|
..()
|
||||||
|
|
||||||
/obj/machinery/computer/crew/attack_ai(mob/user)
|
/obj/machinery/computer/crew/attack_ai(mob/user)
|
||||||
ui_interact(user)
|
attack_hand(user)
|
||||||
|
|
||||||
/obj/machinery/computer/crew/attack_hand(mob/user)
|
/obj/machinery/computer/crew/attack_hand(mob/user)
|
||||||
add_fingerprint(user)
|
add_fingerprint(user)
|
||||||
if(stat & (BROKEN|NOPOWER))
|
if(stat & (BROKEN|NOPOWER))
|
||||||
return
|
return
|
||||||
ui_interact(user)
|
tgui_interact(user)
|
||||||
|
|
||||||
/obj/machinery/computer/crew/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
/obj/machinery/computer/crew/tgui_interact(mob/user, datum/tgui/ui = null)
|
||||||
crew_monitor.ui_interact(user, ui_key, ui, force_open)
|
crew_monitor.tgui_interact(user, ui)
|
||||||
|
|
||||||
/obj/machinery/computer/crew/interact(mob/user)
|
/obj/machinery/computer/crew/interact(mob/user)
|
||||||
crew_monitor.ui_interact(user)
|
crew_monitor.tgui_interact(user)
|
||||||
|
|||||||
@@ -522,7 +522,7 @@
|
|||||||
|
|
||||||
announce.autosay("[to_despawn.real_name], [to_despawn.mind.role_alt_title], [on_store_message]", "[on_store_name]", announce_channel, using_map.get_map_levels(z, TRUE, om_range = DEFAULT_OVERMAP_RANGE))
|
announce.autosay("[to_despawn.real_name], [to_despawn.mind.role_alt_title], [on_store_message]", "[on_store_name]", announce_channel, using_map.get_map_levels(z, TRUE, om_range = DEFAULT_OVERMAP_RANGE))
|
||||||
//visible_message("<span class='notice'>\The [initial(name)] hums and hisses as it moves [to_despawn.real_name] into storage.</span>", 3)
|
//visible_message("<span class='notice'>\The [initial(name)] hums and hisses as it moves [to_despawn.real_name] into storage.</span>", 3)
|
||||||
visible_message("<span class='notice'>\The [initial(name)] [on_store_visible_message_1] [to_despawn.real_name] [on_store_visible_message_2].</span>", 3)
|
visible_message("<span class='notice'>\The [initial(name)] [on_store_visible_message_1] [to_despawn.real_name] [on_store_visible_message_2]</span>", 3)
|
||||||
|
|
||||||
//VOREStation Edit begin: Dont delete mobs-in-mobs
|
//VOREStation Edit begin: Dont delete mobs-in-mobs
|
||||||
if(to_despawn.client && to_despawn.stat<2)
|
if(to_despawn.client && to_despawn.stat<2)
|
||||||
|
|||||||
@@ -164,6 +164,8 @@
|
|||||||
var/datum/action/innate/mecha/mech_switch_damtype/switch_damtype_action = new
|
var/datum/action/innate/mecha/mech_switch_damtype/switch_damtype_action = new
|
||||||
var/datum/action/innate/mecha/mech_toggle_phasing/phasing_action = new
|
var/datum/action/innate/mecha/mech_toggle_phasing/phasing_action = new
|
||||||
|
|
||||||
|
var/weapons_only_cycle = FALSE //So combat mechs don't switch to their equipment at times.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/obj/mecha/drain_power(var/drain_check)
|
/obj/mecha/drain_power(var/drain_check)
|
||||||
|
|||||||
@@ -185,12 +185,15 @@
|
|||||||
var/list/available_equipment = list()
|
var/list/available_equipment = list()
|
||||||
available_equipment = chassis.equipment
|
available_equipment = chassis.equipment
|
||||||
|
|
||||||
|
if(chassis.weapons_only_cycle)
|
||||||
|
available_equipment = chassis.weapon_equipment
|
||||||
|
|
||||||
if(available_equipment.len == 0)
|
if(available_equipment.len == 0)
|
||||||
chassis.occupant_message("No equipment available.")
|
chassis.occupant_message("No equipment available.")
|
||||||
return
|
return
|
||||||
if(!chassis.selected)
|
if(!chassis.selected)
|
||||||
chassis.selected = available_equipment[1]
|
chassis.selected = available_equipment[1]
|
||||||
chassis.occupant_message("You select [chassis.selected]")
|
chassis.occupant_message("You select [chassis.selected]")
|
||||||
send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list())
|
send_byjax(chassis.occupant,"exosuit.browser","eq_list",chassis.get_equipment_list())
|
||||||
button_icon_state = "mech_cycle_equip_on"
|
button_icon_state = "mech_cycle_equip_on"
|
||||||
button.UpdateIcon()
|
button.UpdateIcon()
|
||||||
@@ -419,3 +422,17 @@
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
/obj/mecha/verb/toggle_weapons_only_cycle()
|
||||||
|
set category = "Exosuit Interface"
|
||||||
|
set name = "Toggle weapons only cycling"
|
||||||
|
set src = usr.loc
|
||||||
|
set popup_menu = 0
|
||||||
|
set_weapons_only_cycle()
|
||||||
|
|
||||||
|
/obj/mecha/proc/set_weapons_only_cycle()
|
||||||
|
if(usr!=src.occupant)
|
||||||
|
return
|
||||||
|
weapons_only_cycle = !weapons_only_cycle
|
||||||
|
src.occupant_message("<font color=\"[weapons_only_cycle?"#00f\">En":"#f00\">Dis"]abled weapons only cycling.</font>")
|
||||||
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
R.add_language(LANGUAGE_ECUREUILIAN, 1)
|
R.add_language(LANGUAGE_ECUREUILIAN, 1)
|
||||||
R.add_language(LANGUAGE_DAEMON, 1)
|
R.add_language(LANGUAGE_DAEMON, 1)
|
||||||
R.add_language(LANGUAGE_ENOCHIAN, 1)
|
R.add_language(LANGUAGE_ENOCHIAN, 1)
|
||||||
R.add_language(LANGUAGE_SLAVIC, 1)
|
R.add_language(LANGUAGE_SLAVIC, 1)
|
||||||
|
R.add_language(LANGUAGE_DRUDAKAR, 1)
|
||||||
return 1
|
return 1
|
||||||
else
|
else
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
var/datum/pipe_recipe/recipe // pipe recipie selected for display/construction
|
var/datum/pipe_recipe/recipe // pipe recipie selected for display/construction
|
||||||
var/static/datum/pipe_recipe/first_atmos
|
var/static/datum/pipe_recipe/first_atmos
|
||||||
var/static/datum/pipe_recipe/first_disposal
|
var/static/datum/pipe_recipe/first_disposal
|
||||||
var/static/datum/asset/iconsheet/pipes/icon_assets
|
var/static/datum/asset/spritesheet/pipes/icon_assets
|
||||||
var/static/list/pipe_layers = list(
|
var/static/list/pipe_layers = list(
|
||||||
"Regular" = PIPING_LAYER_REGULAR,
|
"Regular" = PIPING_LAYER_REGULAR,
|
||||||
"Supply" = PIPING_LAYER_SUPPLY,
|
"Supply" = PIPING_LAYER_SUPPLY,
|
||||||
@@ -75,7 +75,7 @@
|
|||||||
/obj/item/weapon/pipe_dispenser/interact(mob/user)
|
/obj/item/weapon/pipe_dispenser/interact(mob/user)
|
||||||
SetupPipes()
|
SetupPipes()
|
||||||
if(!icon_assets)
|
if(!icon_assets)
|
||||||
icon_assets = get_asset_datum(/datum/asset/iconsheet/pipes)
|
icon_assets = get_asset_datum(/datum/asset/spritesheet/pipes)
|
||||||
icon_assets.send(user)
|
icon_assets.send(user)
|
||||||
|
|
||||||
var/list/lines = list()
|
var/list/lines = list()
|
||||||
@@ -365,7 +365,7 @@
|
|||||||
if(_dir == p_dir && flipped == p_flipped)
|
if(_dir == p_dir && flipped == p_flipped)
|
||||||
attrs += " class=\"linkOn\""
|
attrs += " class=\"linkOn\""
|
||||||
if(icon_state)
|
if(icon_state)
|
||||||
var/img_tag = icon_assets.icon_tag(icon_state, _dir)
|
var/img_tag = icon_assets.icon_tag("[dirtext]-[icon_state]")
|
||||||
return "<a href=\"?src=\ref[src];dir=[dirtext];flipped=[flipped]\" title=\"[title]\"[attrs]>[img_tag]</a>"
|
return "<a href=\"?src=\ref[src];dir=[dirtext];flipped=[flipped]\" title=\"[title]\"[attrs]>[img_tag]</a>"
|
||||||
else
|
else
|
||||||
return "<a href=\"?src=\ref[src];dir=[dirtext];flipped=[flipped]\" title=\"[title]\"[attrs]>[noimg]</a>"
|
return "<a href=\"?src=\ref[src];dir=[dirtext];flipped=[flipped]\" title=\"[title]\"[attrs]>[noimg]</a>"
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
/obj/item/weapon/circuitboard/security/New()
|
/obj/item/weapon/circuitboard/security/New()
|
||||||
..()
|
..()
|
||||||
network = using_map.station_networks
|
|
||||||
|
|
||||||
/obj/item/weapon/circuitboard/security/tv
|
/obj/item/weapon/circuitboard/security/tv
|
||||||
name = T_BOARD("security camera monitor - television")
|
name = T_BOARD("security camera monitor - television")
|
||||||
@@ -45,7 +44,7 @@
|
|||||||
|
|
||||||
/obj/item/weapon/circuitboard/security/construct(var/obj/machinery/computer/security/C)
|
/obj/item/weapon/circuitboard/security/construct(var/obj/machinery/computer/security/C)
|
||||||
if (..(C))
|
if (..(C))
|
||||||
C.network = network.Copy()
|
C.set_network(network.Copy())
|
||||||
|
|
||||||
/obj/item/weapon/circuitboard/security/deconstruct(var/obj/machinery/computer/security/C)
|
/obj/item/weapon/circuitboard/security/deconstruct(var/obj/machinery/computer/security/C)
|
||||||
if (..(C))
|
if (..(C))
|
||||||
|
|||||||
@@ -34,6 +34,36 @@
|
|||||||
/obj/effect/decal/cleanable/dirt,
|
/obj/effect/decal/cleanable/dirt,
|
||||||
/obj/effect/decal/remains/robot)
|
/obj/effect/decal/remains/robot)
|
||||||
|
|
||||||
|
/obj/random/crate //Random 'standard' crates for variety in maintenance spawns.
|
||||||
|
name = "random crate"
|
||||||
|
desc = "This is a random crate"
|
||||||
|
icon = 'icons/obj/closets/bases/crate.dmi'
|
||||||
|
icon_state = "base"
|
||||||
|
|
||||||
|
/obj/random/crate/item_to_spawn() //General crates, excludes some more high-grade and medical brands
|
||||||
|
return pick (/obj/structure/closet/crate/plastic,
|
||||||
|
/obj/structure/closet/crate/aether,
|
||||||
|
/obj/structure/closet/crate/centauri,
|
||||||
|
/obj/structure/closet/crate/einstein,
|
||||||
|
/obj/structure/closet/crate/focalpoint,
|
||||||
|
/obj/structure/closet/crate/gilthari,
|
||||||
|
/obj/structure/closet/crate/grayson,
|
||||||
|
/obj/structure/closet/crate/nanotrasen,
|
||||||
|
/obj/structure/closet/crate/nanothreads,
|
||||||
|
/obj/structure/closet/crate/oculum,
|
||||||
|
/obj/structure/closet/crate/ward,
|
||||||
|
/obj/structure/closet/crate/xion,
|
||||||
|
/obj/structure/closet/crate/zenghu,
|
||||||
|
/obj/structure/closet/crate/allico,
|
||||||
|
/obj/structure/closet/crate/carp,
|
||||||
|
/obj/structure/closet/crate/galaksi,
|
||||||
|
/obj/structure/closet/crate/thinktronic,
|
||||||
|
/obj/structure/closet/crate/ummarcar,
|
||||||
|
/obj/structure/closet/crate/unathi,
|
||||||
|
/obj/structure/closet/crate/hydroponics,
|
||||||
|
/obj/structure/closet/crate/engineering,
|
||||||
|
/obj/structure/closet/crate)
|
||||||
|
|
||||||
/obj/random/obstruction //Large objects to block things off in maintenance
|
/obj/random/obstruction //Large objects to block things off in maintenance
|
||||||
name = "random obstruction"
|
name = "random obstruction"
|
||||||
desc = "This is a random obstruction."
|
desc = "This is a random obstruction."
|
||||||
|
|||||||
@@ -761,8 +761,210 @@
|
|||||||
"lid_stripes" = COLOR_NT_RED
|
"lid_stripes" = COLOR_NT_RED
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Freezers
|
||||||
|
|
||||||
/decl/closet_appearance/crate/freezer
|
/decl/closet_appearance/crate/freezer
|
||||||
|
color = COLOR_OFF_WHITE
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/freezer/centauri
|
||||||
color = COLOR_BABY_BLUE
|
color = COLOR_BABY_BLUE
|
||||||
|
extra_decals = list(
|
||||||
|
"centauri" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/freezer/nanotrasen
|
||||||
|
color = COLOR_BABY_BLUE
|
||||||
|
extra_decals = list(
|
||||||
|
"nano" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
// Corporate Branding
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/aether
|
||||||
|
color = COLOR_YELLOW_GRAY
|
||||||
|
decals = list(
|
||||||
|
"crate_stripes" = COLOR_BLUE_LIGHT,
|
||||||
|
"aether" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/allico
|
||||||
|
color = COLOR_LIGHT_VIOLET
|
||||||
|
decals = list(
|
||||||
|
"crate_stripe" = COLOR_AMBER
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/carp
|
||||||
|
color = COLOR_PURPLE
|
||||||
|
decals = list(
|
||||||
|
"toptext" = COLOR_OFF_WHITE,
|
||||||
|
"crate_reticle" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/centauri
|
||||||
|
color = COLOR_BABY_BLUE
|
||||||
|
decals = list(
|
||||||
|
"crate_stripe" = COLOR_LUMINOL
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"centauri" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/cybersolutions
|
||||||
|
color = COLOR_ALUMINIUM
|
||||||
|
extra_decals = list(
|
||||||
|
"hazard" = COLOR_DARK_GOLD,
|
||||||
|
"toptext" = COLOR_DARK_GOLD
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/einstein
|
||||||
|
color = COLOR_DARK_BLUE_GRAY
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripe_left" = COLOR_BEIGE,
|
||||||
|
"crate_stripe_right" = COLOR_BEIGE,
|
||||||
|
"einstein" = COLOR_OFF_WHITE,
|
||||||
|
"hazard" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/focalpoint
|
||||||
|
color = COLOR_GOLD
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripe_left" = COLOR_NAVY_BLUE,
|
||||||
|
"crate_stripe_right" = COLOR_NAVY_BLUE,
|
||||||
|
"focal" = COLOR_OFF_WHITE,
|
||||||
|
"hazard" = COLOR_NAVY_BLUE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/galaksi
|
||||||
|
color = COLOR_OFF_WHITE
|
||||||
|
decals = list(
|
||||||
|
"lid_stripes" = COLOR_HULL,
|
||||||
|
"galaksi" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/gilthari
|
||||||
|
color = COLOR_GRAY20
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripe_left" = COLOR_GOLD,
|
||||||
|
"crate_stripe_right" = COLOR_GOLD,
|
||||||
|
"gilthari" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/grayson
|
||||||
|
color = COLOR_STEEL
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripe_left" = COLOR_MAROON,
|
||||||
|
"crate_stripe_right" = COLOR_MAROON,
|
||||||
|
"grayson" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/heph
|
||||||
|
color = COLOR_GRAY20
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripe_left" = COLOR_NT_RED,
|
||||||
|
"crate_stripe_right" = COLOR_NT_RED,
|
||||||
|
"heph" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/morpheus
|
||||||
|
color = COLOR_ALUMINIUM
|
||||||
|
extra_decals = list(
|
||||||
|
"hazard" = COLOR_GUNMETAL,
|
||||||
|
"toptext" = COLOR_GUNMETAL
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/nanotrasen
|
||||||
|
color = COLOR_NT_RED
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripe_left" = COLOR_OFF_WHITE,
|
||||||
|
"crate_stripe_right" = COLOR_OFF_WHITE,
|
||||||
|
"nano" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/nanotrasenclothing
|
||||||
|
color = COLOR_NT_RED
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripe_left" = COLOR_SEDONA,
|
||||||
|
"crate_stripe_right" = COLOR_SEDONA,
|
||||||
|
"nano" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/nanotrasenmedical
|
||||||
|
color = COLOR_OFF_WHITE
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripe" = COLOR_NT_RED,
|
||||||
|
"nano" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/oculum
|
||||||
|
color = COLOR_SURGERY_BLUE
|
||||||
|
decals = list(
|
||||||
|
"crate_stripe_left" = COLOR_OFF_WHITE,
|
||||||
|
"crate_stripe_right" = COLOR_OFF_WHITE,
|
||||||
|
"oculum" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/secure/saare
|
||||||
|
color = COLOR_ALUMINIUM
|
||||||
|
extra_decals = list(
|
||||||
|
"hazard" = COLOR_RED,
|
||||||
|
"xion" = COLOR_GRAY40
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/thinktronic
|
||||||
|
color = COLOR_PALE_PURPLE_GRAY
|
||||||
|
decals = list(
|
||||||
|
"toptext" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/ummarcar
|
||||||
|
color = COLOR_BEIGE
|
||||||
|
decals = list(
|
||||||
|
"crate_stripes" = COLOR_OFF_WHITE,
|
||||||
|
"toptext" = COLOR_GRAY20
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/unathiimport
|
||||||
|
color = COLOR_SILVER
|
||||||
|
decals = list(
|
||||||
|
"crate_stripe" = COLOR_RED,
|
||||||
|
"crate_reticle" = COLOR_RED_GRAY
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/veymed
|
||||||
|
color = COLOR_OFF_WHITE
|
||||||
|
decals = list(
|
||||||
|
"crate_stripe" = COLOR_PALE_BTL_GREEN
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"lid_stripes" = COLOR_RED,
|
||||||
|
"crate_cross" = COLOR_GREEN
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/ward
|
||||||
|
color = COLOR_OFF_WHITE
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripe_left" = COLOR_COMMAND_BLUE,
|
||||||
|
"crate_stripe_right" = COLOR_COMMAND_BLUE,
|
||||||
|
"hazard" = COLOR_OFF_WHITE,
|
||||||
|
"wt" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/xion
|
||||||
|
color = COLOR_ORANGE
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripes" = COLOR_OFF_WHITE,
|
||||||
|
"xion" = COLOR_OFF_WHITE,
|
||||||
|
"hazard" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/zenghu
|
||||||
|
color = COLOR_OFF_WHITE
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripes" = COLOR_RED,
|
||||||
|
"zenghu" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
// Secure Crates
|
||||||
|
|
||||||
/decl/closet_appearance/crate/secure
|
/decl/closet_appearance/crate/secure
|
||||||
can_lock = TRUE
|
can_lock = TRUE
|
||||||
@@ -775,7 +977,8 @@
|
|||||||
extra_decals = list(
|
extra_decals = list(
|
||||||
"crate_stripe_left" = COLOR_OFF_WHITE,
|
"crate_stripe_left" = COLOR_OFF_WHITE,
|
||||||
"crate_stripe_right" = COLOR_OFF_WHITE,
|
"crate_stripe_right" = COLOR_OFF_WHITE,
|
||||||
"toxin" = COLOR_OFF_WHITE
|
"toxin" = COLOR_OFF_WHITE,
|
||||||
|
"nano" = COLOR_OFF_WHITE
|
||||||
)
|
)
|
||||||
|
|
||||||
/decl/closet_appearance/crate/secure/weapon
|
/decl/closet_appearance/crate/secure/weapon
|
||||||
@@ -789,16 +992,61 @@
|
|||||||
"hazard" = COLOR_OFF_WHITE
|
"hazard" = COLOR_OFF_WHITE
|
||||||
)
|
)
|
||||||
|
|
||||||
/decl/closet_appearance/crate/secure/heph
|
// Secure corporate branding
|
||||||
color = COLOR_GRAY20
|
|
||||||
|
/decl/closet_appearance/crate/secure/aether
|
||||||
|
color = COLOR_YELLOW_GRAY
|
||||||
decals = list(
|
decals = list(
|
||||||
"crate_bracing"
|
"crate_bracing"
|
||||||
)
|
)
|
||||||
extra_decals = list(
|
extra_decals = list(
|
||||||
"crate_stripe_left" = COLOR_NT_RED,
|
"crate_stripes" = COLOR_BLUE_LIGHT,
|
||||||
"crate_stripe_right" = COLOR_NT_RED,
|
"aether" = COLOR_OFF_WHITE
|
||||||
"hazard" = COLOR_OFF_WHITE,
|
)
|
||||||
"heph" = COLOR_OFF_WHITE
|
|
||||||
|
/decl/closet_appearance/crate/secure/bishop
|
||||||
|
color = COLOR_OFF_WHITE
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripe_left" = COLOR_SKY_BLUE,
|
||||||
|
"crate_stripe_right" = COLOR_SKY_BLUE,
|
||||||
|
"bishop" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/secure/cybersolutions
|
||||||
|
color = COLOR_ALUMINIUM
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"hazard" = COLOR_DARK_GOLD,
|
||||||
|
"toptext" = COLOR_DARK_GOLD
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/secure/einstein
|
||||||
|
color = COLOR_DARK_BLUE_GRAY
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripe_left" = COLOR_BEIGE,
|
||||||
|
"crate_stripe_right" = COLOR_BEIGE,
|
||||||
|
"einstein" = COLOR_OFF_WHITE,
|
||||||
|
"hazard" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/secure/focalpoint
|
||||||
|
color = COLOR_GOLD
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripe_left" = COLOR_NAVY_BLUE,
|
||||||
|
"crate_stripe_right" = COLOR_NAVY_BLUE,
|
||||||
|
"focal" = COLOR_OFF_WHITE,
|
||||||
|
"hazard" = COLOR_NAVY_BLUE
|
||||||
)
|
)
|
||||||
|
|
||||||
/decl/closet_appearance/crate/secure/gilthari
|
/decl/closet_appearance/crate/secure/gilthari
|
||||||
@@ -813,16 +1061,15 @@
|
|||||||
"gilthari" = COLOR_OFF_WHITE
|
"gilthari" = COLOR_OFF_WHITE
|
||||||
)
|
)
|
||||||
|
|
||||||
/decl/closet_appearance/crate/secure/ward
|
/decl/closet_appearance/crate/secure/grayson
|
||||||
color = COLOR_OFF_WHITE
|
color = COLOR_STEEL
|
||||||
decals = list(
|
decals = list(
|
||||||
"crate_bracing"
|
"crate_bracing"
|
||||||
)
|
)
|
||||||
extra_decals = list(
|
extra_decals = list(
|
||||||
"crate_stripe_left" = COLOR_COMMAND_BLUE,
|
"crate_stripe_left" = COLOR_MAROON,
|
||||||
"crate_stripe_right" = COLOR_COMMAND_BLUE,
|
"crate_stripe_right" = COLOR_MAROON,
|
||||||
"hazard" = COLOR_OFF_WHITE,
|
"grayson" = COLOR_OFF_WHITE
|
||||||
"wt" = COLOR_OFF_WHITE
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/decl/closet_appearance/crate/secure/hedberg
|
/decl/closet_appearance/crate/secure/hedberg
|
||||||
@@ -837,6 +1084,18 @@
|
|||||||
"hedberg" = COLOR_OFF_WHITE
|
"hedberg" = COLOR_OFF_WHITE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/secure/heph
|
||||||
|
color = COLOR_GRAY20
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripe_left" = COLOR_NT_RED,
|
||||||
|
"crate_stripe_right" = COLOR_NT_RED,
|
||||||
|
"hazard" = COLOR_OFF_WHITE,
|
||||||
|
"heph" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
/decl/closet_appearance/crate/secure/lawson
|
/decl/closet_appearance/crate/secure/lawson
|
||||||
color = COLOR_SAN_MARINO_BLUE
|
color = COLOR_SAN_MARINO_BLUE
|
||||||
decals = list(
|
decals = list(
|
||||||
@@ -849,6 +1108,103 @@
|
|||||||
"lawson" = COLOR_OFF_WHITE
|
"lawson" = COLOR_OFF_WHITE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/secure/morpheus
|
||||||
|
color = COLOR_ALUMINIUM
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"hazard" = COLOR_GUNMETAL,
|
||||||
|
"toptext" = COLOR_GUNMETAL
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/secure/nanotrasen
|
||||||
|
color = COLOR_NT_RED
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripe_left" = COLOR_OFF_WHITE,
|
||||||
|
"crate_stripe_right" = COLOR_OFF_WHITE,
|
||||||
|
"nano" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/secure/nanotrasenmedical
|
||||||
|
color = COLOR_OFF_WHITE
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripe" = COLOR_NT_RED,
|
||||||
|
"nano" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/secure/saare
|
||||||
|
color = COLOR_ALUMINIUM
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"hazard" = COLOR_RED,
|
||||||
|
"xion" = COLOR_GRAY40
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/secure/solgov
|
||||||
|
color = COLOR_SAN_MARINO_BLUE
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripe_left" = COLOR_OFF_WHITE,
|
||||||
|
"crate_stripes" = COLOR_OFF_WHITE,
|
||||||
|
"hazard" = COLOR_OFF_WHITE,
|
||||||
|
"scg" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/secure/veymed
|
||||||
|
color = COLOR_OFF_WHITE
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing",
|
||||||
|
"crate_stripe" = COLOR_PALE_BTL_GREEN
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"lid_stripes" = COLOR_RED,
|
||||||
|
"crate_cross" = COLOR_GREEN
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/secure/ward
|
||||||
|
color = COLOR_OFF_WHITE
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripe_left" = COLOR_COMMAND_BLUE,
|
||||||
|
"crate_stripe_right" = COLOR_COMMAND_BLUE,
|
||||||
|
"hazard" = COLOR_OFF_WHITE,
|
||||||
|
"wt" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/secure/xion
|
||||||
|
color = COLOR_ORANGE
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripes" = COLOR_OFF_WHITE,
|
||||||
|
"xion" = COLOR_OFF_WHITE,
|
||||||
|
"hazard" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/crate/secure/zenghu
|
||||||
|
color = COLOR_OFF_WHITE
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"crate_stripes" = COLOR_RED,
|
||||||
|
"zenghu" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
/decl/closet_appearance/crate/secure/hydroponics
|
/decl/closet_appearance/crate/secure/hydroponics
|
||||||
extra_decals = list(
|
extra_decals = list(
|
||||||
"crate_stripe_left" = COLOR_GREEN_GRAY,
|
"crate_stripe_left" = COLOR_GREEN_GRAY,
|
||||||
@@ -869,6 +1225,7 @@
|
|||||||
extra_decals = null
|
extra_decals = null
|
||||||
|
|
||||||
/decl/closet_appearance/large_crate/critter
|
/decl/closet_appearance/large_crate/critter
|
||||||
|
color = COLOR_BEIGE
|
||||||
decals = list(
|
decals = list(
|
||||||
"airholes"
|
"airholes"
|
||||||
)
|
)
|
||||||
@@ -882,6 +1239,42 @@
|
|||||||
"text" = COLOR_GREEN_GRAY
|
"text" = COLOR_GREEN_GRAY
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/large_crate/aether
|
||||||
|
color = COLOR_YELLOW_GRAY
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"text" = COLOR_BLUE_LIGHT
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/large_crate/einstein
|
||||||
|
color = COLOR_DARK_BLUE_GRAY
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"text" = COLOR_BEIGE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/large_crate/nanotrasen
|
||||||
|
color = COLOR_NT_RED
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"text" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/large_crate/xion
|
||||||
|
color = COLOR_ORANGE
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"text" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
/decl/closet_appearance/large_crate/secure
|
/decl/closet_appearance/large_crate/secure
|
||||||
can_lock = TRUE
|
can_lock = TRUE
|
||||||
|
|
||||||
@@ -895,6 +1288,46 @@
|
|||||||
"text_upper" = COLOR_OFF_WHITE
|
"text_upper" = COLOR_OFF_WHITE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/large_crate/secure/aether
|
||||||
|
color = COLOR_YELLOW_GRAY
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"marking" = COLOR_OFF_WHITE,
|
||||||
|
"text_upper" = COLOR_BLUE_LIGHT
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/large_crate/secure/einstein
|
||||||
|
color = COLOR_DARK_BLUE_GRAY
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"marking" = COLOR_OFF_WHITE,
|
||||||
|
"text_upper" = COLOR_BEIGE
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/large_crate/secure/heph
|
||||||
|
color = COLOR_GRAY20
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"marking" = COLOR_NT_RED,
|
||||||
|
"text_upper" = COLOR_NT_RED
|
||||||
|
)
|
||||||
|
|
||||||
|
/decl/closet_appearance/large_crate/secure/xion
|
||||||
|
color = COLOR_ORANGE
|
||||||
|
decals = list(
|
||||||
|
"crate_bracing"
|
||||||
|
)
|
||||||
|
extra_decals = list(
|
||||||
|
"marking" = COLOR_OFF_WHITE,
|
||||||
|
"text_upper" = COLOR_OFF_WHITE
|
||||||
|
)
|
||||||
|
|
||||||
// Cabinets.
|
// Cabinets.
|
||||||
/decl/closet_appearance/cabinet
|
/decl/closet_appearance/cabinet
|
||||||
base_icon = 'icons/obj/closets/bases/cabinet.dmi'
|
base_icon = 'icons/obj/closets/bases/cabinet.dmi'
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
icon = 'icons/obj/closets/bases/crate.dmi'
|
icon = 'icons/obj/closets/bases/crate.dmi'
|
||||||
closet_appearance = /decl/closet_appearance/crate
|
closet_appearance = /decl/closet_appearance/crate
|
||||||
climbable = 1
|
climbable = 1
|
||||||
|
dir = 4 //Spawn facing 'forward' by default.
|
||||||
var/points_per_crate = 5
|
var/points_per_crate = 5
|
||||||
var/rigged = 0
|
var/rigged = 0
|
||||||
|
|
||||||
@@ -65,6 +66,26 @@
|
|||||||
update_icon()
|
update_icon()
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/verb/rotate_clockwise()
|
||||||
|
set name = "Rotate Crate Clockwise"
|
||||||
|
set category = "Object"
|
||||||
|
set src in oview(1)
|
||||||
|
|
||||||
|
if (usr.stat || usr.restrained() || anchored)
|
||||||
|
return
|
||||||
|
|
||||||
|
src.set_dir(turn(src.dir, 270))
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/verb/rotate_counterclockwise()
|
||||||
|
set category = "Object"
|
||||||
|
set name = "Rotate Crate Counterclockwise"
|
||||||
|
set src in view(1)
|
||||||
|
|
||||||
|
if (usr.stat || usr.restrained() || anchored)
|
||||||
|
return
|
||||||
|
|
||||||
|
src.set_dir(turn(src.dir, 90))
|
||||||
|
|
||||||
/obj/structure/closet/crate/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
/obj/structure/closet/crate/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||||
if(opened)
|
if(opened)
|
||||||
if(isrobot(user))
|
if(isrobot(user))
|
||||||
@@ -274,6 +295,14 @@
|
|||||||
var/target_temp = T0C - 40
|
var/target_temp = T0C - 40
|
||||||
var/cooling_power = 40
|
var/cooling_power = 40
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/freezer/centauri
|
||||||
|
desc = "A freezer stamped with the logo of Centauri Provisions."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/freezer/centauri
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/freezer/nanotrasen
|
||||||
|
desc = "A freezer stamped with the logo of NanoTrasen."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/freezer/nanotrasen
|
||||||
|
|
||||||
/obj/structure/closet/crate/freezer/return_air()
|
/obj/structure/closet/crate/freezer/return_air()
|
||||||
var/datum/gas_mixture/gas = (..())
|
var/datum/gas_mixture/gas = (..())
|
||||||
if(!gas) return null
|
if(!gas) return null
|
||||||
@@ -303,6 +332,11 @@
|
|||||||
organ.preserved = 0
|
organ.preserved = 0
|
||||||
..()
|
..()
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/weapon
|
||||||
|
name = "weapons crate"
|
||||||
|
desc = "A barely secured weapons crate."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/secure/weapon
|
||||||
|
|
||||||
/obj/structure/closet/crate/freezer/rations //Fpr use in the escape shuttle
|
/obj/structure/closet/crate/freezer/rations //Fpr use in the escape shuttle
|
||||||
name = "emergency rations"
|
name = "emergency rations"
|
||||||
desc = "A crate of emergency rations."
|
desc = "A crate of emergency rations."
|
||||||
@@ -310,14 +344,12 @@
|
|||||||
starts_with = list(
|
starts_with = list(
|
||||||
/obj/random/mre = 6)
|
/obj/random/mre = 6)
|
||||||
|
|
||||||
|
|
||||||
/obj/structure/closet/crate/bin
|
/obj/structure/closet/crate/bin
|
||||||
name = "large bin"
|
name = "large bin"
|
||||||
desc = "A large bin."
|
desc = "A large bin."
|
||||||
closet_appearance = null
|
closet_appearance = null
|
||||||
icon = 'icons/obj/closets/largebin.dmi'
|
icon = 'icons/obj/closets/largebin.dmi'
|
||||||
|
|
||||||
|
|
||||||
/obj/structure/closet/crate/radiation
|
/obj/structure/closet/crate/radiation
|
||||||
name = "radioactive gear crate"
|
name = "radioactive gear crate"
|
||||||
desc = "A crate with a radiation sign on it."
|
desc = "A crate with a radiation sign on it."
|
||||||
@@ -327,27 +359,145 @@
|
|||||||
/obj/item/clothing/suit/radiation = 4,
|
/obj/item/clothing/suit/radiation = 4,
|
||||||
/obj/item/clothing/head/radiation = 4)
|
/obj/item/clothing/head/radiation = 4)
|
||||||
|
|
||||||
|
//TSCs
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/aether
|
||||||
|
desc = "A crate painted in the colours of Aether Atmospherics and Recycling."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/aether
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/centauri
|
||||||
|
desc = "A crate decorated with the logo of Centauri Provisions."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/centauri
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/einstein
|
||||||
|
desc = "A crate labelled with an Einstein Engines sticker."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/einstein
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/focalpoint
|
||||||
|
desc = "A crate marked with the decal of Focal Point Energistics."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/focalpoint
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/gilthari
|
||||||
|
desc = "A crate embossed with the logo of Gilthari Exports."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/gilthari
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/grayson
|
||||||
|
desc = "A bare metal crate spraypainted with Grayson Manufactories decals."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/grayson
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/heph
|
||||||
|
desc = "A sturdy crate marked with the logo of Hephaestus Industries."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/heph
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/morpheus
|
||||||
|
desc = "A crate crudely imprinted with 'MORPHEUS CYBERKINETICS'."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/morpheus
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/nanotrasen
|
||||||
|
desc = "A crate emblazoned with the standard NanoTrasen livery."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/nanotrasen
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/nanothreads
|
||||||
|
desc = "A crate emblazoned with the NanoThreads Garments livery, a subsidary of the NanoTrasen Corporation."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/nanotrasenclothing
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/nanocare
|
||||||
|
desc = "A crate emblazoned with the NanoCare Medical livery, a subsidary of the NanoTrasen Corporation."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/nanotrasenmedical
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/oculum
|
||||||
|
desc = "A crate minimally decorated with the logo of media giant Oculum Broadcast."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/oculum
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/veymed
|
||||||
|
desc = "A sterile crate extensively detailed in Veymed colours."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/veymed
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/ward
|
||||||
|
desc = "A crate decaled with the logo of Ward-Takahashi."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/ward
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/xion
|
||||||
|
desc = "A crate painted in Xion Manufacturing Group orange."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/xion
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/zenghu
|
||||||
|
desc = "A sterile crate marked with the logo of Zeng-Hu Pharmaceuticals."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/zenghu
|
||||||
|
|
||||||
|
// Brands/subsidiaries
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/allico
|
||||||
|
desc = "A crate painted in the distinctive cheerful colours of AlliCo. Ltd."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/allico
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/carp
|
||||||
|
desc = "A crate painted with the garish livery of Consolidated Agricultural Resources Plc."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/carp
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/hedberg
|
||||||
|
name = "weapons crate"
|
||||||
|
desc = "A weapons crate stamped with the logo of Hedberg-Hammarstrom and the lock conspicuously absent."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/secure/hedberg
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/galaksi
|
||||||
|
desc = "A crate printed with the markings of Ward-Takahashi's Galaksi Appliance branding."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/galaksi
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/thinktronic
|
||||||
|
desc = "A crate printed with the markings of Thinktronic Systems."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/thinktronic
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/ummarcar
|
||||||
|
desc = "A flimsy crate marked labelled 'UmMarcar Office Supply'."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/ummarcar
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/unathi
|
||||||
|
name = "import crate"
|
||||||
|
desc = "A crate painted with the markings of Moghes Imported Sissalik Jerky."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/unathiimport
|
||||||
|
|
||||||
|
|
||||||
|
// Secure Crates
|
||||||
|
|
||||||
/obj/structure/closet/crate/secure/weapon
|
/obj/structure/closet/crate/secure/weapon
|
||||||
name = "weapons crate"
|
name = "weapons crate"
|
||||||
desc = "A secure weapons crate."
|
desc = "A secure weapons crate."
|
||||||
closet_appearance = /decl/closet_appearance/crate/secure/weapon
|
closet_appearance = /decl/closet_appearance/crate/secure/weapon
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/aether
|
||||||
|
desc = "A secure crate painted in the colours of Aether Atmospherics and Recycling."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/secure/aether
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/bishop
|
||||||
|
desc = "A secure crate finely decorated with the emblem of Bishop Cybernetics."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/secure/bishop
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/cybersolutions
|
||||||
|
desc = "An unadorned secure metal crate labelled 'Cyber Solutions'."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/secure/cybersolutions
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/einstein
|
||||||
|
desc = "A secure crate labelled with an Einstein Engines sticker."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/secure/einstein
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/focalpoint
|
||||||
|
desc = "A secure crate marked with the decal of Focal Point Energistics."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/secure/focalpoint
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/gilthari
|
||||||
|
desc = "A secure crate embossed with the logo of Gilthari Exports."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/secure/gilthari
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/grayson
|
||||||
|
desc = "A secure bare metal crate spraypainted with Grayson Manufactories decals."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/secure/grayson
|
||||||
|
|
||||||
/obj/structure/closet/crate/secure/hedberg
|
/obj/structure/closet/crate/secure/hedberg
|
||||||
name = "weapons crate"
|
name = "weapons crate"
|
||||||
desc = "A secure weapons crate stamped with the logo of Hedberg-Hammarstrom."
|
desc = "A secure weapons crate stamped with the logo of Hedberg-Hammarstrom."
|
||||||
closet_appearance = /decl/closet_appearance/crate/secure/hedberg
|
closet_appearance = /decl/closet_appearance/crate/secure/hedberg
|
||||||
|
|
||||||
/obj/structure/closet/crate/secure/gilthari
|
|
||||||
name = "weapons crate"
|
|
||||||
desc = "A secure weapons crate embossed with the logo of Gilthari Exports."
|
|
||||||
closet_appearance = /decl/closet_appearance/crate/secure/gilthari
|
|
||||||
|
|
||||||
/obj/structure/closet/crate/secure/ward
|
|
||||||
name = "weapons crate"
|
|
||||||
desc = "A secure weapons crate decaled with the logo of Ward-Takahashi."
|
|
||||||
closet_appearance = /decl/closet_appearance/crate/secure/ward
|
|
||||||
|
|
||||||
/obj/structure/closet/crate/secure/heph
|
/obj/structure/closet/crate/secure/heph
|
||||||
name = "weapons crate"
|
name = "weapons crate"
|
||||||
desc = "A secure weapons crate marked with the logo of Hephaestus Industries."
|
desc = "A secure weapons crate marked with the logo of Hephaestus Industries."
|
||||||
@@ -358,9 +508,47 @@
|
|||||||
desc = "A secure weapons crate marked with the logo of Lawson Arms."
|
desc = "A secure weapons crate marked with the logo of Lawson Arms."
|
||||||
closet_appearance = /decl/closet_appearance/crate/secure/lawson
|
closet_appearance = /decl/closet_appearance/crate/secure/lawson
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/morpheus
|
||||||
|
desc = "A secure crate crudely imprinted with 'MORPHEUS CYBERKINETICS'."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/secure/morpheus
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/nanotrasen
|
||||||
|
desc = "A secure crate emblazoned with the standard NanoTrasen livery."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/secure/nanotrasen
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/nanocare
|
||||||
|
desc = "A secure crate emblazoned with the NanoCare Medical livery, a subsidary of the NanoTrasen Corporation."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/secure/nanotrasenmedical
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/scg
|
||||||
|
name = "weapons crate"
|
||||||
|
desc = "A secure crate in the official colours of the Solar Confederate Government."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/secure/solgov
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/saare
|
||||||
|
name = "weapons crate"
|
||||||
|
desc = "A secure weapons crate plainly stamped with the logo of Stealth Assault Enterprises."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/secure/saare
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/veymed
|
||||||
|
desc = "A secure sterile crate extensively detailed in Veymed colours."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/secure/veymed
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/ward
|
||||||
|
desc = "A secure crate decaled with the logo of Ward-Takahashi."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/secure/ward
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/xion
|
||||||
|
desc = "A secure crate painted in Xion Manufacturing Group orange."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/secure/xion
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/zenghu
|
||||||
|
desc = "A secure sterile crate marked with the logo of Zeng-Hu Pharmaceuticals."
|
||||||
|
closet_appearance = /decl/closet_appearance/crate/secure/zenghu
|
||||||
|
|
||||||
/obj/structure/closet/crate/secure/phoron
|
/obj/structure/closet/crate/secure/phoron
|
||||||
name = "phoron crate"
|
name = "phoron crate"
|
||||||
desc = "A secure phoron crate."
|
desc = "A secure phoron crate painted in standard NanoTrasen livery."
|
||||||
closet_appearance = /decl/closet_appearance/crate/secure/hazard
|
closet_appearance = /decl/closet_appearance/crate/secure/hazard
|
||||||
|
|
||||||
/obj/structure/closet/crate/secure/gear
|
/obj/structure/closet/crate/secure/gear
|
||||||
@@ -368,27 +556,24 @@
|
|||||||
desc = "A secure gear crate."
|
desc = "A secure gear crate."
|
||||||
closet_appearance = /decl/closet_appearance/crate/secure/weapon
|
closet_appearance = /decl/closet_appearance/crate/secure/weapon
|
||||||
|
|
||||||
|
|
||||||
/obj/structure/closet/crate/secure/hydrosec
|
/obj/structure/closet/crate/secure/hydrosec
|
||||||
name = "secure hydroponics crate"
|
name = "secure hydroponics crate"
|
||||||
desc = "A crate with a lock on it, painted in the scheme of the station's botanists."
|
desc = "A crate with a lock on it, painted in the scheme of the station's botanists."
|
||||||
closet_appearance = /decl/closet_appearance/crate/secure/hydroponics
|
closet_appearance = /decl/closet_appearance/crate/secure/hydroponics
|
||||||
|
|
||||||
|
|
||||||
/obj/structure/closet/crate/secure/engineering
|
/obj/structure/closet/crate/secure/engineering
|
||||||
desc = "A crate with a lock on it, painted in the scheme of the station's engineers."
|
desc = "A crate with a lock on it, painted in the scheme of the station's engineers."
|
||||||
name = "secure engineering crate"
|
name = "secure engineering crate"
|
||||||
|
|
||||||
|
|
||||||
/obj/structure/closet/crate/secure/science
|
/obj/structure/closet/crate/secure/science
|
||||||
name = "secure science crate"
|
name = "secure science crate"
|
||||||
desc = "A crate with a lock on it, painted in the scheme of the station's scientists."
|
desc = "A crate with a lock on it, painted in the scheme of the station's scientists."
|
||||||
|
|
||||||
|
|
||||||
/obj/structure/closet/crate/secure/bin
|
/obj/structure/closet/crate/secure/bin
|
||||||
name = "secure bin"
|
name = "secure bin"
|
||||||
desc = "A secure bin."
|
desc = "A secure bin."
|
||||||
|
|
||||||
|
// Large crates
|
||||||
|
|
||||||
/obj/structure/closet/crate/large
|
/obj/structure/closet/crate/large
|
||||||
name = "large crate"
|
name = "large crate"
|
||||||
@@ -414,6 +599,30 @@
|
|||||||
break
|
break
|
||||||
return
|
return
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/large/critter
|
||||||
|
name = "animal crate"
|
||||||
|
desc = "A hefty crate for hauling animals."
|
||||||
|
closet_appearance = /decl/closet_appearance/large_crate/critter
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/large/aether
|
||||||
|
name = "large atmospherics crate"
|
||||||
|
desc = "A hefty metal crate, painted in Aether Atmospherics and Recycling colours."
|
||||||
|
closet_appearance = /decl/closet_appearance/large_crate/aether
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/large/einstein
|
||||||
|
name = "large crate"
|
||||||
|
desc = "A hefty metal crate, painted in Einstein Engines colours."
|
||||||
|
closet_appearance = /decl/closet_appearance/large_crate/einstein
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/large/nanotrasen
|
||||||
|
name = "large crate"
|
||||||
|
desc = "A hefty metal crate, painted in standard NanoTrasen livery."
|
||||||
|
closet_appearance = /decl/closet_appearance/large_crate/nanotrasen
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/large/xion
|
||||||
|
name = "large crate"
|
||||||
|
desc = "A hefty metal crate, painted in Xion Manufacturing Group orange."
|
||||||
|
closet_appearance = /decl/closet_appearance/large_crate/xion
|
||||||
|
|
||||||
/obj/structure/closet/crate/secure/large
|
/obj/structure/closet/crate/secure/large
|
||||||
name = "large crate"
|
name = "large crate"
|
||||||
@@ -441,10 +650,30 @@
|
|||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
//fluff variant
|
|
||||||
/obj/structure/closet/crate/secure/large/reinforced
|
/obj/structure/closet/crate/secure/large/reinforced
|
||||||
desc = "A hefty, reinforced metal crate with an electronic locking system."
|
desc = "A hefty, reinforced metal crate with an electronic locking system."
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/large/aether
|
||||||
|
name = "secure atmospherics crate"
|
||||||
|
desc = "A hefty metal crate with an electronic locking system, painted in Aether Atmospherics and Recycling colours."
|
||||||
|
closet_appearance = /decl/closet_appearance/large_crate/secure/aether
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/large/einstein
|
||||||
|
desc = "A hefty metal crate with an electronic locking system, painted in Einstein Engines colours."
|
||||||
|
closet_appearance = /decl/closet_appearance/large_crate/secure/einstein
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/large/secure/heph
|
||||||
|
desc = "A hefty metal crate with an electronic locking system, marked with Hephaestus Industries colours."
|
||||||
|
closet_appearance = /decl/closet_appearance/large_crate/secure/heph
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/secure/large/nanotrasen
|
||||||
|
desc = "A hefty metal crate with an electronic locking system, painted in standard NanoTrasen livery."
|
||||||
|
closet_appearance = /decl/closet_appearance/large_crate/secure/hazard
|
||||||
|
|
||||||
|
/obj/structure/closet/crate/large/secure/xion
|
||||||
|
desc = "A hefty metal crate with an electronic locking system, painted in Xion Manufacturing Group orange."
|
||||||
|
closet_appearance = /decl/closet_appearance/large_crate/secure/xion
|
||||||
|
|
||||||
/obj/structure/closet/crate/engineering
|
/obj/structure/closet/crate/engineering
|
||||||
name = "engineering crate"
|
name = "engineering crate"
|
||||||
|
|
||||||
|
|||||||
@@ -44,8 +44,8 @@
|
|||||||
|
|
||||||
/obj/structure/largecrate/hoverpod
|
/obj/structure/largecrate/hoverpod
|
||||||
name = "\improper Hoverpod assembly crate"
|
name = "\improper Hoverpod assembly crate"
|
||||||
desc = "It comes in a box for the fabricator's sake. Where does the wood come from? ... And why is it lighter?"
|
desc = "You aren't sure how this crate is so light, but the Wulf Aeronautics logo might be a hint."
|
||||||
icon_state = "mulecrate"
|
icon_state = "vehiclecrate"
|
||||||
|
|
||||||
/obj/structure/largecrate/hoverpod/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
/obj/structure/largecrate/hoverpod/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||||
if(W.is_crowbar())
|
if(W.is_crowbar())
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
|
|
||||||
/obj/structure/largecrate/vehicle
|
/obj/structure/largecrate/vehicle
|
||||||
name = "vehicle crate"
|
name = "vehicle crate"
|
||||||
desc = "It comes in a box for the consumer's sake. ..How is this lighter?"
|
desc = "Wulf Aeronautics says it comes in a box for the consumer's sake... How is this so light?"
|
||||||
icon_state = "vehiclecrate"
|
icon_state = "vehiclecrate"
|
||||||
|
|
||||||
/obj/structure/largecrate/vehicle/Initialize()
|
/obj/structure/largecrate/vehicle/Initialize()
|
||||||
@@ -74,18 +74,22 @@
|
|||||||
|
|
||||||
/obj/structure/largecrate/vehicle/quadbike
|
/obj/structure/largecrate/vehicle/quadbike
|
||||||
name = "\improper ATV crate"
|
name = "\improper ATV crate"
|
||||||
|
desc = "A hefty wooden crate proudly displaying the logo of Ward-Takahashi's automotive division."
|
||||||
starts_with = list(/obj/structure/vehiclecage/quadbike)
|
starts_with = list(/obj/structure/vehiclecage/quadbike)
|
||||||
|
|
||||||
/obj/structure/largecrate/vehicle/quadtrailer
|
/obj/structure/largecrate/vehicle/quadtrailer
|
||||||
name = "\improper ATV trailer crate"
|
name = "\improper ATV trailer crate"
|
||||||
|
desc = "A hefty wooden crate proudly displaying the logo of Ward-Takahashi's automotive division."
|
||||||
starts_with = list(/obj/structure/vehiclecage/quadtrailer)
|
starts_with = list(/obj/structure/vehiclecage/quadtrailer)
|
||||||
|
|
||||||
/obj/structure/largecrate/animal
|
/obj/structure/largecrate/animal
|
||||||
icon_state = "lisacrate" //VOREStation Edit
|
icon_state = "crittercrate"
|
||||||
|
desc = "A hefty wooden crate with air holes. It is marked with the logo of NanoTrasen Pastures and the slogan, '90% less cloning defects* than competing brands**, or your money back***!'"
|
||||||
|
|
||||||
/obj/structure/largecrate/animal/mulebot
|
/obj/structure/largecrate/animal/mulebot
|
||||||
name = "Mulebot crate"
|
name = "Mulebot crate"
|
||||||
icon_state = "mulecrate" //VOREStation Edit
|
desc = "A hefty wooden crate labelled 'Proud Product of the Xion Manufacturing Group'"
|
||||||
|
icon_state = "mulecrate"
|
||||||
starts_with = list(/mob/living/bot/mulebot)
|
starts_with = list(/mob/living/bot/mulebot)
|
||||||
|
|
||||||
/obj/structure/largecrate/animal/corgi
|
/obj/structure/largecrate/animal/corgi
|
||||||
|
|||||||
@@ -253,6 +253,10 @@
|
|||||||
'sound/vore/sunesound/prey/death_07.ogg','sound/vore/sunesound/prey/death_08.ogg','sound/vore/sunesound/prey/death_09.ogg',
|
'sound/vore/sunesound/prey/death_07.ogg','sound/vore/sunesound/prey/death_08.ogg','sound/vore/sunesound/prey/death_09.ogg',
|
||||||
'sound/vore/sunesound/prey/death_10.ogg')
|
'sound/vore/sunesound/prey/death_10.ogg')
|
||||||
//END VORESTATION EDIT
|
//END VORESTATION EDIT
|
||||||
|
if ("terminal_type")
|
||||||
|
soundin = pick('sound/machines/terminal_button01.ogg', 'sound/machines/terminal_button02.ogg', 'sound/machines/terminal_button03.ogg', \
|
||||||
|
'sound/machines/terminal_button04.ogg', 'sound/machines/terminal_button05.ogg', 'sound/machines/terminal_button06.ogg', \
|
||||||
|
'sound/machines/terminal_button07.ogg', 'sound/machines/terminal_button08.ogg')
|
||||||
return soundin
|
return soundin
|
||||||
|
|
||||||
//Are these even used?
|
//Are these even used?
|
||||||
|
|||||||
@@ -119,3 +119,11 @@ NOTE: It checks usr by default. Supply the "user" argument if you wish to check
|
|||||||
holder.disassociate()
|
holder.disassociate()
|
||||||
//qdel(holder)
|
//qdel(holder)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
//This proc checks whether subject has at least ONE of the rights specified in rights_required.
|
||||||
|
/proc/check_rights_for(client/subject, rights_required)
|
||||||
|
if(subject && subject.holder)
|
||||||
|
if(rights_required && !(rights_required & subject.holder.rights))
|
||||||
|
return 0
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
@@ -18,7 +18,6 @@
|
|||||||
var/list/sources = new() //List of sources triggering the alarm. Used to determine when the alarm should be cleared.
|
var/list/sources = new() //List of sources triggering the alarm. Used to determine when the alarm should be cleared.
|
||||||
var/list/sources_assoc = new() //Associative list of source triggers. Used to efficiently acquire the alarm source.
|
var/list/sources_assoc = new() //Associative list of source triggers. Used to efficiently acquire the alarm source.
|
||||||
var/list/cameras //List of cameras that can be switched to, if the player has that capability.
|
var/list/cameras //List of cameras that can be switched to, if the player has that capability.
|
||||||
var/cache_id //ID for camera cache, changed by invalidateCameraCache().
|
|
||||||
var/area/last_area //The last acquired area, used should origin be lost (for example a destroyed borg containing an alarming camera).
|
var/area/last_area //The last acquired area, used should origin be lost (for example a destroyed borg containing an alarming camera).
|
||||||
var/area/last_name //The last acquired name, used should origin be lost
|
var/area/last_name //The last acquired name, used should origin be lost
|
||||||
var/area/last_camera_area //The last area in which cameras where fetched, used to see if the camera list should be updated.
|
var/area/last_camera_area //The last area in which cameras where fetched, used to see if the camera list should be updated.
|
||||||
@@ -78,15 +77,10 @@
|
|||||||
return last_name
|
return last_name
|
||||||
|
|
||||||
/datum/alarm/proc/cameras()
|
/datum/alarm/proc/cameras()
|
||||||
// reset camera cache
|
|
||||||
if(camera_repository.camera_cache_id != cache_id)
|
|
||||||
cameras = null
|
|
||||||
cache_id = camera_repository.camera_cache_id
|
|
||||||
// If the alarm origin has changed area, for example a borg containing an alarming camera, reset the list of cameras
|
// If the alarm origin has changed area, for example a borg containing an alarming camera, reset the list of cameras
|
||||||
else if(cameras && (last_camera_area != alarm_area()))
|
if(cameras && (last_camera_area != alarm_area()))
|
||||||
cameras = null
|
cameras = null
|
||||||
|
|
||||||
// The list of cameras is also reset by /proc/invalidateCameraCache()
|
|
||||||
if(!cameras)
|
if(!cameras)
|
||||||
cameras = origin ? origin.get_alarm_cameras() : last_area.get_alarm_cameras()
|
cameras = origin ? origin.get_alarm_cameras() : last_area.get_alarm_cameras()
|
||||||
|
|
||||||
|
|||||||
110
code/modules/asset_cache/asset_cache.dm
Normal file
110
code/modules/asset_cache/asset_cache.dm
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
Asset cache quick users guide:
|
||||||
|
|
||||||
|
Make a datum in asset_list_items.dm with your assets for your thing.
|
||||||
|
Checkout asset_list.dm for the helper subclasses
|
||||||
|
The simple subclass will most like be of use for most cases.
|
||||||
|
Then call get_asset_datum() with the type of the datum you created and store the return
|
||||||
|
Then call .send(client) on that stored return value.
|
||||||
|
|
||||||
|
Note: If your code uses output() with assets you will need to call asset_flush on the client and wait for it to return before calling output(). You only need do this if .send(client) returned TRUE
|
||||||
|
*/
|
||||||
|
|
||||||
|
//When sending mutiple assets, how many before we give the client a quaint little sending resources message
|
||||||
|
#define ASSET_CACHE_TELL_CLIENT_AMOUNT 8
|
||||||
|
|
||||||
|
//This proc sends the asset to the client, but only if it needs it.
|
||||||
|
//This proc blocks(sleeps) unless verify is set to false
|
||||||
|
/proc/send_asset(client/client, asset_name)
|
||||||
|
return send_asset_list(client, list(asset_name))
|
||||||
|
|
||||||
|
/// Sends a list of assets to a client
|
||||||
|
/// This proc will no longer block, use client.asset_flush() if you to need know when the client has all assets (such as for output()). (This is not required for browse() calls as they use the same message queue as asset sends)
|
||||||
|
/// client - a client or mob
|
||||||
|
/// asset_list - A list of asset filenames to be sent to the client.
|
||||||
|
/// Returns TRUE if any assets were sent.
|
||||||
|
/proc/send_asset_list(client/client, list/asset_list)
|
||||||
|
if(!istype(client))
|
||||||
|
if(ismob(client))
|
||||||
|
var/mob/M = client
|
||||||
|
if(M.client)
|
||||||
|
client = M.client
|
||||||
|
else
|
||||||
|
return
|
||||||
|
else
|
||||||
|
return
|
||||||
|
|
||||||
|
var/list/unreceived = list()
|
||||||
|
|
||||||
|
for (var/asset_name in asset_list)
|
||||||
|
var/datum/asset_cache_item/asset = SSassets.cache[asset_name]
|
||||||
|
if (!asset)
|
||||||
|
continue
|
||||||
|
var/asset_file = asset.resource
|
||||||
|
if (!asset_file)
|
||||||
|
continue
|
||||||
|
|
||||||
|
var/asset_md5 = asset.md5
|
||||||
|
if (client.sent_assets[asset_name] == asset_md5)
|
||||||
|
continue
|
||||||
|
unreceived[asset_name] = asset_md5
|
||||||
|
|
||||||
|
if (unreceived.len)
|
||||||
|
if (unreceived.len >= ASSET_CACHE_TELL_CLIENT_AMOUNT)
|
||||||
|
to_chat(client, "Sending Resources...")
|
||||||
|
|
||||||
|
for(var/asset in unreceived)
|
||||||
|
var/datum/asset_cache_item/ACI
|
||||||
|
if ((ACI = SSassets.cache[asset]))
|
||||||
|
log_asset("Sending asset [asset] to client [client]")
|
||||||
|
client << browse_rsc(ACI.resource, asset)
|
||||||
|
|
||||||
|
client.sent_assets |= unreceived
|
||||||
|
addtimer(CALLBACK(client, /client/proc/asset_cache_update_json), 1 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE)
|
||||||
|
return TRUE
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
//This proc will download the files without clogging up the browse() queue, used for passively sending files on connection start.
|
||||||
|
//The proc calls procs that sleep for long times.
|
||||||
|
/proc/getFilesSlow(client/client, list/files, register_asset = TRUE, filerate = 3)
|
||||||
|
var/startingfilerate = filerate
|
||||||
|
for(var/file in files)
|
||||||
|
if (!client)
|
||||||
|
break
|
||||||
|
if (register_asset)
|
||||||
|
register_asset(file, files[file])
|
||||||
|
|
||||||
|
if (send_asset(client, file))
|
||||||
|
if (!(--filerate))
|
||||||
|
filerate = startingfilerate
|
||||||
|
client.asset_flush()
|
||||||
|
stoplag(0) //queuing calls like this too quickly can cause issues in some client versions
|
||||||
|
|
||||||
|
//This proc "registers" an asset, it adds it to the cache for further use, you cannot touch it from this point on or you'll fuck things up.
|
||||||
|
//icons and virtual assets get copied to the dyn rsc before use
|
||||||
|
/proc/register_asset(asset_name, asset)
|
||||||
|
var/datum/asset_cache_item/ACI = new(asset_name, asset)
|
||||||
|
|
||||||
|
//this is technically never something that was supported and i want metrics on how often it happens if at all.
|
||||||
|
if (SSassets.cache[asset_name])
|
||||||
|
var/datum/asset_cache_item/OACI = SSassets.cache[asset_name]
|
||||||
|
if (OACI.md5 != ACI.md5)
|
||||||
|
stack_trace("ERROR: new asset added to the asset cache with the same name as another asset: [asset_name] existing asset md5: [OACI.md5] new asset md5:[ACI.md5]")
|
||||||
|
else
|
||||||
|
var/list/stacktrace = gib_stack_trace()
|
||||||
|
log_asset("WARNING: dupe asset added to the asset cache: [asset_name] existing asset md5: [OACI.md5] new asset md5:[ACI.md5]\n[stacktrace.Join("\n")]")
|
||||||
|
SSassets.cache[asset_name] = ACI
|
||||||
|
return ACI
|
||||||
|
|
||||||
|
/// Returns the url of the asset, currently this is just its name, here to allow further work cdn'ing assets.
|
||||||
|
/// Can be given an asset as well, this is just a work around for buggy edge cases where two assets may have the same name, doesn't matter now, but it will when the cdn comes.
|
||||||
|
/proc/get_asset_url(asset_name, asset = null)
|
||||||
|
var/datum/asset_cache_item/ACI = SSassets.cache[asset_name]
|
||||||
|
return ACI?.url
|
||||||
|
|
||||||
|
//Generated names do not include file extention.
|
||||||
|
//Used mainly for code that deals with assets in a generic way
|
||||||
|
//The same asset will always lead to the same asset name
|
||||||
|
/proc/generate_asset_name(file)
|
||||||
|
return "asset.[md5(fcopy_rsc(file))]"
|
||||||
|
|
||||||
51
code/modules/asset_cache/asset_cache_client.dm
Normal file
51
code/modules/asset_cache/asset_cache_client.dm
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
|
||||||
|
/// Process asset cache client topic calls for "asset_cache_confirm_arrival=[INT]"
|
||||||
|
/client/proc/asset_cache_confirm_arrival(job_id)
|
||||||
|
var/asset_cache_job = round(text2num(job_id))
|
||||||
|
//because we skip the limiter, we have to make sure this is a valid arrival and not somebody tricking us into letting them append to a list without limit.
|
||||||
|
if (asset_cache_job > 0 && asset_cache_job <= last_asset_job && !(completed_asset_jobs["[asset_cache_job]"]))
|
||||||
|
completed_asset_jobs["[asset_cache_job]"] = TRUE
|
||||||
|
last_completed_asset_job = max(last_completed_asset_job, asset_cache_job)
|
||||||
|
else
|
||||||
|
return asset_cache_job || TRUE
|
||||||
|
|
||||||
|
|
||||||
|
/// Process asset cache client topic calls for "asset_cache_preload_data=[HTML+JSON_STRING]
|
||||||
|
/client/proc/asset_cache_preload_data(data)
|
||||||
|
/*var/jsonend = findtextEx(data, "{{{ENDJSONDATA}}}")
|
||||||
|
if (!jsonend)
|
||||||
|
CRASH("invalid asset_cache_preload_data, no jsonendmarker")*/
|
||||||
|
//var/json = html_decode(copytext(data, 1, jsonend))
|
||||||
|
var/json = data
|
||||||
|
var/list/preloaded_assets = json_decode(json)
|
||||||
|
|
||||||
|
for (var/preloaded_asset in preloaded_assets)
|
||||||
|
if (copytext(preloaded_asset, findlasttext(preloaded_asset, ".")+1) in list("js", "jsm", "htm", "html"))
|
||||||
|
preloaded_assets -= preloaded_asset
|
||||||
|
continue
|
||||||
|
sent_assets |= preloaded_assets
|
||||||
|
|
||||||
|
|
||||||
|
/// Updates the client side stored html/json combo file used to keep track of what assets the client has between restarts/reconnects.
|
||||||
|
/client/proc/asset_cache_update_json(verify = FALSE, list/new_assets = list())
|
||||||
|
if (world.time - connection_time < 10 SECONDS) //don't override the existing data file on a new connection
|
||||||
|
return
|
||||||
|
if (!islist(new_assets))
|
||||||
|
new_assets = list("[new_assets]" = md5(SSassets.cache[new_assets]))
|
||||||
|
|
||||||
|
src << browse(json_encode(new_assets|sent_assets), "file=asset_data.json&display=0")
|
||||||
|
|
||||||
|
/// Blocks until all currently sending browser assets have been sent.
|
||||||
|
/// Due to byond limitations, this proc will sleep for 1 client round trip even if the client has no pending asset sends.
|
||||||
|
/// This proc will return an untrue value if it had to return before confirming the send, such as timeout or the client going away.
|
||||||
|
/client/proc/asset_flush(timeout = 50)
|
||||||
|
var/job = ++last_asset_job
|
||||||
|
var/t = 0
|
||||||
|
var/timeout_time = timeout
|
||||||
|
src << browse({"<script>window.location.href="?asset_cache_confirm_arrival=[job]"</script>"}, "window=asset_cache_browser&file=asset_cache_send_verify.htm")
|
||||||
|
|
||||||
|
while(!completed_asset_jobs["[job]"] && t < timeout_time) // Reception is handled in Topic()
|
||||||
|
stoplag(1) // Lock up the caller until this is received.
|
||||||
|
t++
|
||||||
|
if (t < timeout_time)
|
||||||
|
return TRUE
|
||||||
23
code/modules/asset_cache/asset_cache_item.dm
Normal file
23
code/modules/asset_cache/asset_cache_item.dm
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* # asset_cache_item
|
||||||
|
*
|
||||||
|
* An internal datum containing info on items in the asset cache. Mainly used to cache md5 info for speed.
|
||||||
|
**/
|
||||||
|
/datum/asset_cache_item
|
||||||
|
var/name
|
||||||
|
var/url
|
||||||
|
var/md5
|
||||||
|
var/resource
|
||||||
|
|
||||||
|
/datum/asset_cache_item/New(name, file)
|
||||||
|
if (!isfile(file))
|
||||||
|
file = fcopy_rsc(file)
|
||||||
|
md5 = md5(file)
|
||||||
|
if (!md5)
|
||||||
|
md5 = md5(fcopy_rsc(file))
|
||||||
|
if (!md5)
|
||||||
|
CRASH("invalid asset sent to asset cache")
|
||||||
|
log_world("asset cache unexpected success of second fcopy_rsc")
|
||||||
|
src.name = name
|
||||||
|
url = name
|
||||||
|
resource = file
|
||||||
260
code/modules/asset_cache/asset_list.dm
Normal file
260
code/modules/asset_cache/asset_list.dm
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
|
||||||
|
//These datums are used to populate the asset cache, the proc "register()" does this.
|
||||||
|
//Place any asset datums you create in asset_list_items.dm
|
||||||
|
|
||||||
|
//all of our asset datums, used for referring to these later
|
||||||
|
GLOBAL_LIST_EMPTY(asset_datums)
|
||||||
|
|
||||||
|
//get an assetdatum or make a new one
|
||||||
|
/proc/get_asset_datum(type)
|
||||||
|
return GLOB.asset_datums[type] || new type()
|
||||||
|
|
||||||
|
/datum/asset
|
||||||
|
var/_abstract = /datum/asset
|
||||||
|
|
||||||
|
/datum/asset/New()
|
||||||
|
GLOB.asset_datums[type] = src
|
||||||
|
register()
|
||||||
|
|
||||||
|
/datum/asset/proc/get_url_mappings()
|
||||||
|
return list()
|
||||||
|
|
||||||
|
/datum/asset/proc/register()
|
||||||
|
return
|
||||||
|
|
||||||
|
/datum/asset/proc/send(client)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
//If you don't need anything complicated.
|
||||||
|
/datum/asset/simple
|
||||||
|
_abstract = /datum/asset/simple
|
||||||
|
var/assets = list()
|
||||||
|
|
||||||
|
/datum/asset/simple/register()
|
||||||
|
for(var/asset_name in assets)
|
||||||
|
assets[asset_name] = register_asset(asset_name, assets[asset_name])
|
||||||
|
|
||||||
|
/datum/asset/simple/send(client)
|
||||||
|
. = send_asset_list(client, assets)
|
||||||
|
|
||||||
|
/datum/asset/simple/get_url_mappings()
|
||||||
|
. = list()
|
||||||
|
for (var/asset_name in assets)
|
||||||
|
var/datum/asset_cache_item/ACI = assets[asset_name]
|
||||||
|
if (!ACI)
|
||||||
|
continue
|
||||||
|
.[asset_name] = ACI.url
|
||||||
|
|
||||||
|
|
||||||
|
// For registering or sending multiple others at once
|
||||||
|
/datum/asset/group
|
||||||
|
_abstract = /datum/asset/group
|
||||||
|
var/list/children
|
||||||
|
|
||||||
|
/datum/asset/group/register()
|
||||||
|
for(var/type in children)
|
||||||
|
get_asset_datum(type)
|
||||||
|
|
||||||
|
/datum/asset/group/send(client/C)
|
||||||
|
for(var/type in children)
|
||||||
|
var/datum/asset/A = get_asset_datum(type)
|
||||||
|
. = A.send(C) || .
|
||||||
|
|
||||||
|
/datum/asset/group/get_url_mappings()
|
||||||
|
. = list()
|
||||||
|
for(var/type in children)
|
||||||
|
var/datum/asset/A = get_asset_datum(type)
|
||||||
|
. += A.get_url_mappings()
|
||||||
|
|
||||||
|
// spritesheet implementation - coalesces various icons into a single .png file
|
||||||
|
// and uses CSS to select icons out of that file - saves on transferring some
|
||||||
|
// 1400-odd individual PNG files
|
||||||
|
#define SPR_SIZE 1
|
||||||
|
#define SPR_IDX 2
|
||||||
|
#define SPRSZ_COUNT 1
|
||||||
|
#define SPRSZ_ICON 2
|
||||||
|
#define SPRSZ_STRIPPED 3
|
||||||
|
|
||||||
|
/datum/asset/spritesheet
|
||||||
|
_abstract = /datum/asset/spritesheet
|
||||||
|
var/name
|
||||||
|
var/list/sizes = list() // "32x32" -> list(10, icon/normal, icon/stripped)
|
||||||
|
var/list/sprites = list() // "foo_bar" -> list("32x32", 5)
|
||||||
|
|
||||||
|
/datum/asset/spritesheet/register()
|
||||||
|
if (!name)
|
||||||
|
CRASH("spritesheet [type] cannot register without a name")
|
||||||
|
ensure_stripped()
|
||||||
|
for(var/size_id in sizes)
|
||||||
|
var/size = sizes[size_id]
|
||||||
|
register_asset("[name]_[size_id].png", size[SPRSZ_STRIPPED])
|
||||||
|
var/res_name = "spritesheet_[name].css"
|
||||||
|
var/fname = "data/spritesheets/[res_name]"
|
||||||
|
fdel(fname)
|
||||||
|
text2file(generate_css(), fname)
|
||||||
|
register_asset(res_name, fcopy_rsc(fname))
|
||||||
|
fdel(fname)
|
||||||
|
|
||||||
|
/datum/asset/spritesheet/send(client/C)
|
||||||
|
if (!name)
|
||||||
|
return
|
||||||
|
var/all = list("spritesheet_[name].css")
|
||||||
|
for(var/size_id in sizes)
|
||||||
|
all += "[name]_[size_id].png"
|
||||||
|
. = send_asset_list(C, all)
|
||||||
|
|
||||||
|
/datum/asset/spritesheet/get_url_mappings()
|
||||||
|
if (!name)
|
||||||
|
return
|
||||||
|
. = list("spritesheet_[name].css" = get_asset_url("spritesheet_[name].css"))
|
||||||
|
for(var/size_id in sizes)
|
||||||
|
.["[name]_[size_id].png"] = get_asset_url("[name]_[size_id].png")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/datum/asset/spritesheet/proc/ensure_stripped(sizes_to_strip = sizes)
|
||||||
|
for(var/size_id in sizes_to_strip)
|
||||||
|
var/size = sizes[size_id]
|
||||||
|
if (size[SPRSZ_STRIPPED])
|
||||||
|
continue
|
||||||
|
|
||||||
|
#ifdef RUST_G
|
||||||
|
// save flattened version
|
||||||
|
var/fname = "data/spritesheets/[name]_[size_id].png"
|
||||||
|
fcopy(size[SPRSZ_ICON], fname)
|
||||||
|
var/error = call(RUST_G, "dmi_strip_metadata")(fname)
|
||||||
|
if(length(error))
|
||||||
|
stack_trace("Failed to strip [name]_[size_id].png: [error]")
|
||||||
|
size[SPRSZ_STRIPPED] = icon(fname)
|
||||||
|
fdel(fname)
|
||||||
|
#else
|
||||||
|
#warn It looks like you don't have RUST_G enabled. Without RUST_G, the RPD icons will not function, so it strongly recommended you reenable it.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/datum/asset/spritesheet/proc/generate_css()
|
||||||
|
var/list/out = list()
|
||||||
|
|
||||||
|
for (var/size_id in sizes)
|
||||||
|
var/size = sizes[size_id]
|
||||||
|
var/icon/tiny = size[SPRSZ_ICON]
|
||||||
|
out += ".[name][size_id]{display:inline-block;width:[tiny.Width()]px;height:[tiny.Height()]px;background:url('[get_asset_url("[name]_[size_id].png")]') no-repeat;}"
|
||||||
|
|
||||||
|
for (var/sprite_id in sprites)
|
||||||
|
var/sprite = sprites[sprite_id]
|
||||||
|
var/size_id = sprite[SPR_SIZE]
|
||||||
|
var/idx = sprite[SPR_IDX]
|
||||||
|
var/size = sizes[size_id]
|
||||||
|
|
||||||
|
var/icon/tiny = size[SPRSZ_ICON]
|
||||||
|
var/icon/big = size[SPRSZ_STRIPPED]
|
||||||
|
var/per_line = big.Width() / tiny.Width()
|
||||||
|
var/x = (idx % per_line) * tiny.Width()
|
||||||
|
var/y = round(idx / per_line) * tiny.Height()
|
||||||
|
|
||||||
|
out += ".[name][size_id].[sprite_id]{background-position:-[x]px -[y]px;}"
|
||||||
|
|
||||||
|
return out.Join("\n")
|
||||||
|
|
||||||
|
/datum/asset/spritesheet/proc/Insert(sprite_name, icon/I, icon_state="", dir=SOUTH, frame=1, moving=FALSE)
|
||||||
|
I = icon(I, icon_state=icon_state, dir=dir, frame=frame, moving=moving)
|
||||||
|
if (!I || !length(icon_states(I))) // that direction or state doesn't exist
|
||||||
|
return
|
||||||
|
var/size_id = "[I.Width()]x[I.Height()]"
|
||||||
|
var/size = sizes[size_id]
|
||||||
|
|
||||||
|
if (sprites[sprite_name])
|
||||||
|
CRASH("duplicate sprite \"[sprite_name]\" in sheet [name] ([type])")
|
||||||
|
|
||||||
|
if (size)
|
||||||
|
var/position = size[SPRSZ_COUNT]++
|
||||||
|
var/icon/sheet = size[SPRSZ_ICON]
|
||||||
|
size[SPRSZ_STRIPPED] = null
|
||||||
|
sheet.Insert(I, icon_state=sprite_name)
|
||||||
|
sprites[sprite_name] = list(size_id, position)
|
||||||
|
else
|
||||||
|
sizes[size_id] = size = list(1, I, null)
|
||||||
|
sprites[sprite_name] = list(size_id, 0)
|
||||||
|
|
||||||
|
/datum/asset/spritesheet/proc/InsertAll(prefix, icon/I, list/directions)
|
||||||
|
if (length(prefix))
|
||||||
|
prefix = "[prefix]-"
|
||||||
|
|
||||||
|
if (!directions)
|
||||||
|
directions = list(SOUTH)
|
||||||
|
|
||||||
|
for (var/icon_state_name in icon_states(I))
|
||||||
|
for (var/direction in directions)
|
||||||
|
var/prefix2 = (directions.len > 1) ? "[dir2text(direction)]-" : ""
|
||||||
|
Insert("[prefix][prefix2][icon_state_name]", I, icon_state=icon_state_name, dir=direction)
|
||||||
|
|
||||||
|
/datum/asset/spritesheet/proc/css_tag()
|
||||||
|
return {"<link rel="stylesheet" href="[css_filename()]" />"}
|
||||||
|
|
||||||
|
/datum/asset/spritesheet/proc/css_filename()
|
||||||
|
return get_asset_url("spritesheet_[name].css")
|
||||||
|
|
||||||
|
/datum/asset/spritesheet/proc/icon_tag(sprite_name)
|
||||||
|
var/sprite = sprites[sprite_name]
|
||||||
|
if (!sprite)
|
||||||
|
return null
|
||||||
|
var/size_id = sprite[SPR_SIZE]
|
||||||
|
return {"<span class="[name][size_id] [sprite_name]"></span>"}
|
||||||
|
|
||||||
|
/datum/asset/spritesheet/proc/icon_class_name(sprite_name)
|
||||||
|
var/sprite = sprites[sprite_name]
|
||||||
|
if (!sprite)
|
||||||
|
return null
|
||||||
|
var/size_id = sprite[SPR_SIZE]
|
||||||
|
return {"[name][size_id] [sprite_name]"}
|
||||||
|
|
||||||
|
#undef SPR_SIZE
|
||||||
|
#undef SPR_IDX
|
||||||
|
#undef SPRSZ_COUNT
|
||||||
|
#undef SPRSZ_ICON
|
||||||
|
#undef SPRSZ_STRIPPED
|
||||||
|
|
||||||
|
|
||||||
|
/datum/asset/spritesheet/simple
|
||||||
|
_abstract = /datum/asset/spritesheet/simple
|
||||||
|
var/list/assets
|
||||||
|
|
||||||
|
/datum/asset/spritesheet/simple/register()
|
||||||
|
for (var/key in assets)
|
||||||
|
Insert(key, assets[key])
|
||||||
|
..()
|
||||||
|
|
||||||
|
//Generates assets based on iconstates of a single icon
|
||||||
|
/datum/asset/simple/icon_states
|
||||||
|
_abstract = /datum/asset/simple/icon_states
|
||||||
|
var/icon
|
||||||
|
var/list/directions = list(SOUTH)
|
||||||
|
var/frame = 1
|
||||||
|
var/movement_states = FALSE
|
||||||
|
|
||||||
|
var/prefix = "default" //asset_name = "[prefix].[icon_state_name].png"
|
||||||
|
var/generic_icon_names = FALSE //generate icon filenames using generate_asset_name() instead the above format
|
||||||
|
|
||||||
|
/datum/asset/simple/icon_states/register(_icon = icon)
|
||||||
|
for(var/icon_state_name in icon_states(_icon))
|
||||||
|
for(var/direction in directions)
|
||||||
|
var/asset = icon(_icon, icon_state_name, direction, frame, movement_states)
|
||||||
|
if (!asset)
|
||||||
|
continue
|
||||||
|
asset = fcopy_rsc(asset) //dedupe
|
||||||
|
var/prefix2 = (directions.len > 1) ? "[dir2text(direction)]." : ""
|
||||||
|
var/asset_name = sanitize_filename("[prefix].[prefix2][icon_state_name].png")
|
||||||
|
if (generic_icon_names)
|
||||||
|
asset_name = "[generate_asset_name(asset)].png"
|
||||||
|
|
||||||
|
register_asset(asset_name, asset)
|
||||||
|
|
||||||
|
/datum/asset/simple/icon_states/multiple_icons
|
||||||
|
_abstract = /datum/asset/simple/icon_states/multiple_icons
|
||||||
|
var/list/icons
|
||||||
|
|
||||||
|
/datum/asset/simple/icon_states/multiple_icons/register()
|
||||||
|
for(var/i in icons)
|
||||||
|
..(i)
|
||||||
|
|
||||||
|
|
||||||
445
code/modules/asset_cache/asset_list_items.dm
Normal file
445
code/modules/asset_cache/asset_list_items.dm
Normal file
@@ -0,0 +1,445 @@
|
|||||||
|
//DEFINITIONS FOR ASSET DATUMS START HERE.
|
||||||
|
|
||||||
|
/datum/asset/simple/tgui
|
||||||
|
assets = list(
|
||||||
|
"tgui.bundle.js" = 'tgui/packages/tgui/public/tgui.bundle.js',
|
||||||
|
"tgui.bundle.css" = 'tgui/packages/tgui/public/tgui.bundle.css',
|
||||||
|
)
|
||||||
|
|
||||||
|
// /datum/asset/simple/headers
|
||||||
|
// assets = list(
|
||||||
|
// "alarm_green.gif" = 'icons/program_icons/alarm_green.gif',
|
||||||
|
// "alarm_red.gif" = 'icons/program_icons/alarm_red.gif',
|
||||||
|
// "batt_5.gif" = 'icons/program_icons/batt_5.gif',
|
||||||
|
// "batt_20.gif" = 'icons/program_icons/batt_20.gif',
|
||||||
|
// "batt_40.gif" = 'icons/program_icons/batt_40.gif',
|
||||||
|
// "batt_60.gif" = 'icons/program_icons/batt_60.gif',
|
||||||
|
// "batt_80.gif" = 'icons/program_icons/batt_80.gif',
|
||||||
|
// "batt_100.gif" = 'icons/program_icons/batt_100.gif',
|
||||||
|
// "charging.gif" = 'icons/program_icons/charging.gif',
|
||||||
|
// "downloader_finished.gif" = 'icons/program_icons/downloader_finished.gif',
|
||||||
|
// "downloader_running.gif" = 'icons/program_icons/downloader_running.gif',
|
||||||
|
// "ntnrc_idle.gif" = 'icons/program_icons/ntnrc_idle.gif',
|
||||||
|
// "ntnrc_new.gif" = 'icons/program_icons/ntnrc_new.gif',
|
||||||
|
// "power_norm.gif" = 'icons/program_icons/power_norm.gif',
|
||||||
|
// "power_warn.gif" = 'icons/program_icons/power_warn.gif',
|
||||||
|
// "sig_high.gif" = 'icons/program_icons/sig_high.gif',
|
||||||
|
// "sig_low.gif" = 'icons/program_icons/sig_low.gif',
|
||||||
|
// "sig_lan.gif" = 'icons/program_icons/sig_lan.gif',
|
||||||
|
// "sig_none.gif" = 'icons/program_icons/sig_none.gif',
|
||||||
|
// "smmon_0.gif" = 'icons/program_icons/smmon_0.gif',
|
||||||
|
// "smmon_1.gif" = 'icons/program_icons/smmon_1.gif',
|
||||||
|
// "smmon_2.gif" = 'icons/program_icons/smmon_2.gif',
|
||||||
|
// "smmon_3.gif" = 'icons/program_icons/smmon_3.gif',
|
||||||
|
// "smmon_4.gif" = 'icons/program_icons/smmon_4.gif',
|
||||||
|
// "smmon_5.gif" = 'icons/program_icons/smmon_5.gif',
|
||||||
|
// "smmon_6.gif" = 'icons/program_icons/smmon_6.gif',
|
||||||
|
// "borg_mon.gif" = 'icons/program_icons/borg_mon.gif'
|
||||||
|
// )
|
||||||
|
|
||||||
|
// /datum/asset/simple/radar_assets
|
||||||
|
// assets = list(
|
||||||
|
// "ntosradarbackground.png" = 'icons/UI_Icons/tgui/ntosradar_background.png',
|
||||||
|
// "ntosradarpointer.png" = 'icons/UI_Icons/tgui/ntosradar_pointer.png',
|
||||||
|
// "ntosradarpointerS.png" = 'icons/UI_Icons/tgui/ntosradar_pointer_S.png'
|
||||||
|
// )
|
||||||
|
|
||||||
|
// /datum/asset/spritesheet/simple/pda
|
||||||
|
// name = "pda"
|
||||||
|
// assets = list(
|
||||||
|
// "atmos" = 'icons/pda_icons/pda_atmos.png',
|
||||||
|
// "back" = 'icons/pda_icons/pda_back.png',
|
||||||
|
// "bell" = 'icons/pda_icons/pda_bell.png',
|
||||||
|
// "blank" = 'icons/pda_icons/pda_blank.png',
|
||||||
|
// "boom" = 'icons/pda_icons/pda_boom.png',
|
||||||
|
// "bucket" = 'icons/pda_icons/pda_bucket.png',
|
||||||
|
// "medbot" = 'icons/pda_icons/pda_medbot.png',
|
||||||
|
// "floorbot" = 'icons/pda_icons/pda_floorbot.png',
|
||||||
|
// "cleanbot" = 'icons/pda_icons/pda_cleanbot.png',
|
||||||
|
// "crate" = 'icons/pda_icons/pda_crate.png',
|
||||||
|
// "cuffs" = 'icons/pda_icons/pda_cuffs.png',
|
||||||
|
// "eject" = 'icons/pda_icons/pda_eject.png',
|
||||||
|
// "flashlight" = 'icons/pda_icons/pda_flashlight.png',
|
||||||
|
// "honk" = 'icons/pda_icons/pda_honk.png',
|
||||||
|
// "mail" = 'icons/pda_icons/pda_mail.png',
|
||||||
|
// "medical" = 'icons/pda_icons/pda_medical.png',
|
||||||
|
// "menu" = 'icons/pda_icons/pda_menu.png',
|
||||||
|
// "mule" = 'icons/pda_icons/pda_mule.png',
|
||||||
|
// "notes" = 'icons/pda_icons/pda_notes.png',
|
||||||
|
// "power" = 'icons/pda_icons/pda_power.png',
|
||||||
|
// "rdoor" = 'icons/pda_icons/pda_rdoor.png',
|
||||||
|
// "reagent" = 'icons/pda_icons/pda_reagent.png',
|
||||||
|
// "refresh" = 'icons/pda_icons/pda_refresh.png',
|
||||||
|
// "scanner" = 'icons/pda_icons/pda_scanner.png',
|
||||||
|
// "signaler" = 'icons/pda_icons/pda_signaler.png',
|
||||||
|
// "skills" = 'icons/pda_icons/pda_skills.png',
|
||||||
|
// "status" = 'icons/pda_icons/pda_status.png',
|
||||||
|
// "dronephone" = 'icons/pda_icons/pda_dronephone.png',
|
||||||
|
// "emoji" = 'icons/pda_icons/pda_emoji.png'
|
||||||
|
// )
|
||||||
|
|
||||||
|
// /datum/asset/spritesheet/simple/paper
|
||||||
|
// name = "paper"
|
||||||
|
// assets = list(
|
||||||
|
// "stamp-clown" = 'icons/stamp_icons/large_stamp-clown.png',
|
||||||
|
// "stamp-deny" = 'icons/stamp_icons/large_stamp-deny.png',
|
||||||
|
// "stamp-ok" = 'icons/stamp_icons/large_stamp-ok.png',
|
||||||
|
// "stamp-hop" = 'icons/stamp_icons/large_stamp-hop.png',
|
||||||
|
// "stamp-cmo" = 'icons/stamp_icons/large_stamp-cmo.png',
|
||||||
|
// "stamp-ce" = 'icons/stamp_icons/large_stamp-ce.png',
|
||||||
|
// "stamp-hos" = 'icons/stamp_icons/large_stamp-hos.png',
|
||||||
|
// "stamp-rd" = 'icons/stamp_icons/large_stamp-rd.png',
|
||||||
|
// "stamp-cap" = 'icons/stamp_icons/large_stamp-cap.png',
|
||||||
|
// "stamp-qm" = 'icons/stamp_icons/large_stamp-qm.png',
|
||||||
|
// "stamp-law" = 'icons/stamp_icons/large_stamp-law.png',
|
||||||
|
// "stamp-chap" = 'icons/stamp_icons/large_stamp-chap.png',
|
||||||
|
// "stamp-mime" = 'icons/stamp_icons/large_stamp-mime.png',
|
||||||
|
// "stamp-centcom" = 'icons/stamp_icons/large_stamp-centcom.png',
|
||||||
|
// "stamp-syndicate" = 'icons/stamp_icons/large_stamp-syndicate.png'
|
||||||
|
// )
|
||||||
|
|
||||||
|
|
||||||
|
// /datum/asset/simple/irv
|
||||||
|
// assets = list(
|
||||||
|
// "jquery-ui.custom-core-widgit-mouse-sortable-min.js" = 'html/IRV/jquery-ui.custom-core-widgit-mouse-sortable-min.js',
|
||||||
|
// )
|
||||||
|
|
||||||
|
// /datum/asset/group/irv
|
||||||
|
// children = list(
|
||||||
|
// /datum/asset/simple/jquery,
|
||||||
|
// /datum/asset/simple/irv
|
||||||
|
// )
|
||||||
|
|
||||||
|
/datum/asset/simple/generic
|
||||||
|
assets = list(
|
||||||
|
"search.js" = 'html/search.js',
|
||||||
|
"panels.css" = 'html/panels.css',
|
||||||
|
"loading.gif" = 'html/images/loading.gif',
|
||||||
|
"ntlogo.png" = 'html/images/ntlogo.png',
|
||||||
|
"sglogo.png" = 'html/images/sglogo.png',
|
||||||
|
"talisman.png" = 'html/images/talisman.png',
|
||||||
|
"paper_bg.png" = 'html/images/paper_bg.png',
|
||||||
|
"no_image32.png" = 'html/images/no_image32.png',
|
||||||
|
)
|
||||||
|
|
||||||
|
/datum/asset/simple/changelog
|
||||||
|
assets = list(
|
||||||
|
"88x31.png" = 'html/88x31.png',
|
||||||
|
"bug-minus.png" = 'html/bug-minus.png',
|
||||||
|
"cross-circle.png" = 'html/cross-circle.png',
|
||||||
|
"hard-hat-exclamation.png" = 'html/hard-hat-exclamation.png',
|
||||||
|
"image-minus.png" = 'html/image-minus.png',
|
||||||
|
"image-plus.png" = 'html/image-plus.png',
|
||||||
|
"map-pencil.png" = 'html/map-pencil.png',
|
||||||
|
"music-minus.png" = 'html/music-minus.png',
|
||||||
|
"music-plus.png" = 'html/music-plus.png',
|
||||||
|
"tick-circle.png" = 'html/tick-circle.png',
|
||||||
|
"wrench-screwdriver.png" = 'html/wrench-screwdriver.png',
|
||||||
|
"spell-check.png" = 'html/spell-check.png',
|
||||||
|
"burn-exclamation.png" = 'html/burn-exclamation.png',
|
||||||
|
"chevron.png" = 'html/chevron.png',
|
||||||
|
"chevron-expand.png" = 'html/chevron-expand.png',
|
||||||
|
"changelog.css" = 'html/changelog.css',
|
||||||
|
"changelog.js" = 'html/changelog.js',
|
||||||
|
"changelog.html" = 'html/changelog.html'
|
||||||
|
)
|
||||||
|
|
||||||
|
// /datum/asset/group/goonchat
|
||||||
|
// children = list(
|
||||||
|
// /datum/asset/simple/jquery,
|
||||||
|
// /datum/asset/simple/goonchat,
|
||||||
|
// /datum/asset/spritesheet/goonchat,
|
||||||
|
// /datum/asset/simple/fontawesome
|
||||||
|
// )
|
||||||
|
|
||||||
|
// /datum/asset/simple/jquery
|
||||||
|
// assets = list(
|
||||||
|
// "jquery.min.js" = 'code/modules/goonchat/browserassets/js/jquery.min.js',
|
||||||
|
// )
|
||||||
|
|
||||||
|
// /datum/asset/simple/goonchat
|
||||||
|
// assets = list(
|
||||||
|
// "json2.min.js" = 'code/modules/goonchat/browserassets/js/json2.min.js',
|
||||||
|
// "browserOutput.js" = 'code/modules/goonchat/browserassets/js/browserOutput.js',
|
||||||
|
// "browserOutput.css" = 'code/modules/goonchat/browserassets/css/browserOutput.css',
|
||||||
|
// "browserOutput_white.css" = 'code/modules/goonchat/browserassets/css/browserOutput_white.css',
|
||||||
|
// )
|
||||||
|
|
||||||
|
/datum/asset/simple/fontawesome
|
||||||
|
assets = list(
|
||||||
|
"fa-regular-400.eot" = 'html/font-awesome/webfonts/fa-regular-400.eot',
|
||||||
|
"fa-regular-400.woff" = 'html/font-awesome/webfonts/fa-regular-400.woff',
|
||||||
|
"fa-solid-900.eot" = 'html/font-awesome/webfonts/fa-solid-900.eot',
|
||||||
|
"fa-solid-900.woff" = 'html/font-awesome/webfonts/fa-solid-900.woff',
|
||||||
|
"font-awesome.css" = 'html/font-awesome/css/all.min.css',
|
||||||
|
"v4shim.css" = 'html/font-awesome/css/v4-shims.min.css'
|
||||||
|
)
|
||||||
|
|
||||||
|
// /datum/asset/spritesheet/goonchat
|
||||||
|
// name = "chat"
|
||||||
|
|
||||||
|
// /datum/asset/spritesheet/goonchat/register()
|
||||||
|
// InsertAll("emoji", 'icons/emoji.dmi')
|
||||||
|
|
||||||
|
// // pre-loading all lanugage icons also helps to avoid meta
|
||||||
|
// InsertAll("language", 'icons/misc/language.dmi')
|
||||||
|
// // catch languages which are pulling icons from another file
|
||||||
|
// for(var/path in typesof(/datum/language))
|
||||||
|
// var/datum/language/L = path
|
||||||
|
// var/icon = initial(L.icon)
|
||||||
|
// if (icon != 'icons/misc/language.dmi')
|
||||||
|
// var/icon_state = initial(L.icon_state)
|
||||||
|
// Insert("language-[icon_state]", icon, icon_state=icon_state)
|
||||||
|
|
||||||
|
// ..()
|
||||||
|
|
||||||
|
// /datum/asset/simple/permissions
|
||||||
|
// assets = list(
|
||||||
|
// "padlock.png" = 'html/padlock.png'
|
||||||
|
// )
|
||||||
|
|
||||||
|
// /datum/asset/simple/notes
|
||||||
|
// assets = list(
|
||||||
|
// "high_button.png" = 'html/high_button.png',
|
||||||
|
// "medium_button.png" = 'html/medium_button.png',
|
||||||
|
// "minor_button.png" = 'html/minor_button.png',
|
||||||
|
// "none_button.png" = 'html/none_button.png',
|
||||||
|
// )
|
||||||
|
|
||||||
|
// /datum/asset/simple/arcade
|
||||||
|
// assets = list(
|
||||||
|
// "boss1.gif" = 'icons/UI_Icons/Arcade/boss1.gif',
|
||||||
|
// "boss2.gif" = 'icons/UI_Icons/Arcade/boss2.gif',
|
||||||
|
// "boss3.gif" = 'icons/UI_Icons/Arcade/boss3.gif',
|
||||||
|
// "boss4.gif" = 'icons/UI_Icons/Arcade/boss4.gif',
|
||||||
|
// "boss5.gif" = 'icons/UI_Icons/Arcade/boss5.gif',
|
||||||
|
// "boss6.gif" = 'icons/UI_Icons/Arcade/boss6.gif',
|
||||||
|
// )
|
||||||
|
|
||||||
|
// /datum/asset/spritesheet/simple/achievements
|
||||||
|
// name ="achievements"
|
||||||
|
// assets = list(
|
||||||
|
// "default" = 'icons/UI_Icons/Achievements/default.png',
|
||||||
|
// "basemisc" = 'icons/UI_Icons/Achievements/basemisc.png',
|
||||||
|
// "baseboss" = 'icons/UI_Icons/Achievements/baseboss.png',
|
||||||
|
// "baseskill" = 'icons/UI_Icons/Achievements/baseskill.png',
|
||||||
|
// "bbgum" = 'icons/UI_Icons/Achievements/Boss/bbgum.png',
|
||||||
|
// "colossus" = 'icons/UI_Icons/Achievements/Boss/colossus.png',
|
||||||
|
// "hierophant" = 'icons/UI_Icons/Achievements/Boss/hierophant.png',
|
||||||
|
// "legion" = 'icons/UI_Icons/Achievements/Boss/legion.png',
|
||||||
|
// "miner" = 'icons/UI_Icons/Achievements/Boss/miner.png',
|
||||||
|
// "swarmer" = 'icons/UI_Icons/Achievements/Boss/swarmer.png',
|
||||||
|
// "tendril" = 'icons/UI_Icons/Achievements/Boss/tendril.png',
|
||||||
|
// "featofstrength" = 'icons/UI_Icons/Achievements/Misc/featofstrength.png',
|
||||||
|
// "helbital" = 'icons/UI_Icons/Achievements/Misc/helbital.png',
|
||||||
|
// "jackpot" = 'icons/UI_Icons/Achievements/Misc/jackpot.png',
|
||||||
|
// "meteors" = 'icons/UI_Icons/Achievements/Misc/meteors.png',
|
||||||
|
// "timewaste" = 'icons/UI_Icons/Achievements/Misc/timewaste.png',
|
||||||
|
// "upgrade" = 'icons/UI_Icons/Achievements/Misc/upgrade.png',
|
||||||
|
// "clownking" = 'icons/UI_Icons/Achievements/Misc/clownking.png',
|
||||||
|
// "clownthanks" = 'icons/UI_Icons/Achievements/Misc/clownthanks.png',
|
||||||
|
// "rule8" = 'icons/UI_Icons/Achievements/Misc/rule8.png',
|
||||||
|
// "snail" = 'icons/UI_Icons/Achievements/Misc/snail.png',
|
||||||
|
// "mining" = 'icons/UI_Icons/Achievements/Skills/mining.png',
|
||||||
|
// )
|
||||||
|
|
||||||
|
// /datum/asset/spritesheet/simple/pills
|
||||||
|
// name ="pills"
|
||||||
|
// assets = list(
|
||||||
|
// "pill1" = 'icons/UI_Icons/Pills/pill1.png',
|
||||||
|
// "pill2" = 'icons/UI_Icons/Pills/pill2.png',
|
||||||
|
// "pill3" = 'icons/UI_Icons/Pills/pill3.png',
|
||||||
|
// "pill4" = 'icons/UI_Icons/Pills/pill4.png',
|
||||||
|
// "pill5" = 'icons/UI_Icons/Pills/pill5.png',
|
||||||
|
// "pill6" = 'icons/UI_Icons/Pills/pill6.png',
|
||||||
|
// "pill7" = 'icons/UI_Icons/Pills/pill7.png',
|
||||||
|
// "pill8" = 'icons/UI_Icons/Pills/pill8.png',
|
||||||
|
// "pill9" = 'icons/UI_Icons/Pills/pill9.png',
|
||||||
|
// "pill10" = 'icons/UI_Icons/Pills/pill10.png',
|
||||||
|
// "pill11" = 'icons/UI_Icons/Pills/pill11.png',
|
||||||
|
// "pill12" = 'icons/UI_Icons/Pills/pill12.png',
|
||||||
|
// "pill13" = 'icons/UI_Icons/Pills/pill13.png',
|
||||||
|
// "pill14" = 'icons/UI_Icons/Pills/pill14.png',
|
||||||
|
// "pill15" = 'icons/UI_Icons/Pills/pill15.png',
|
||||||
|
// "pill16" = 'icons/UI_Icons/Pills/pill16.png',
|
||||||
|
// "pill17" = 'icons/UI_Icons/Pills/pill17.png',
|
||||||
|
// "pill18" = 'icons/UI_Icons/Pills/pill18.png',
|
||||||
|
// "pill19" = 'icons/UI_Icons/Pills/pill19.png',
|
||||||
|
// "pill20" = 'icons/UI_Icons/Pills/pill20.png',
|
||||||
|
// "pill21" = 'icons/UI_Icons/Pills/pill21.png',
|
||||||
|
// "pill22" = 'icons/UI_Icons/Pills/pill22.png',
|
||||||
|
// )
|
||||||
|
|
||||||
|
// //this exists purely to avoid meta by pre-loading all language icons.
|
||||||
|
// /datum/asset/language/register()
|
||||||
|
// for(var/path in typesof(/datum/language))
|
||||||
|
// set waitfor = FALSE
|
||||||
|
// var/datum/language/L = new path ()
|
||||||
|
// L.get_icon()
|
||||||
|
|
||||||
|
/datum/asset/spritesheet/pipes
|
||||||
|
name = "pipes"
|
||||||
|
|
||||||
|
/datum/asset/spritesheet/pipes/register()
|
||||||
|
for(var/each in list('icons/obj/pipe-item.dmi', 'icons/obj/pipes/disposal.dmi'))
|
||||||
|
InsertAll("", each, global.alldirs)
|
||||||
|
..()
|
||||||
|
|
||||||
|
// // Representative icons for each research design
|
||||||
|
// /datum/asset/spritesheet/research_designs
|
||||||
|
// name = "design"
|
||||||
|
|
||||||
|
// /datum/asset/spritesheet/research_designs/register()
|
||||||
|
// for (var/path in subtypesof(/datum/design))
|
||||||
|
// var/datum/design/D = path
|
||||||
|
|
||||||
|
// var/icon_file
|
||||||
|
// var/icon_state
|
||||||
|
// var/icon/I
|
||||||
|
|
||||||
|
// if(initial(D.research_icon) && initial(D.research_icon_state)) //If the design has an icon replacement skip the rest
|
||||||
|
// icon_file = initial(D.research_icon)
|
||||||
|
// icon_state = initial(D.research_icon_state)
|
||||||
|
// if(!(icon_state in icon_states(icon_file)))
|
||||||
|
// warning("design [D] with icon '[icon_file]' missing state '[icon_state]'")
|
||||||
|
// continue
|
||||||
|
// I = icon(icon_file, icon_state, SOUTH)
|
||||||
|
|
||||||
|
// else
|
||||||
|
// // construct the icon and slap it into the resource cache
|
||||||
|
// var/atom/item = initial(D.build_path)
|
||||||
|
// if (!ispath(item, /atom))
|
||||||
|
// // biogenerator outputs to beakers by default
|
||||||
|
// if (initial(D.build_type) & BIOGENERATOR)
|
||||||
|
// item = /obj/item/reagent_containers/glass/beaker/large
|
||||||
|
// else
|
||||||
|
// continue // shouldn't happen, but just in case
|
||||||
|
|
||||||
|
// // circuit boards become their resulting machines or computers
|
||||||
|
// if (ispath(item, /obj/item/circuitboard))
|
||||||
|
// var/obj/item/circuitboard/C = item
|
||||||
|
// var/machine = initial(C.build_path)
|
||||||
|
// if (machine)
|
||||||
|
// item = machine
|
||||||
|
|
||||||
|
// icon_file = initial(item.icon)
|
||||||
|
// icon_state = initial(item.icon_state)
|
||||||
|
|
||||||
|
// if(!(icon_state in icon_states(icon_file)))
|
||||||
|
// warning("design [D] with icon '[icon_file]' missing state '[icon_state]'")
|
||||||
|
// continue
|
||||||
|
// I = icon(icon_file, icon_state, SOUTH)
|
||||||
|
|
||||||
|
// // computers (and snowflakes) get their screen and keyboard sprites
|
||||||
|
// if (ispath(item, /obj/machinery/computer) || ispath(item, /obj/machinery/power/solar_control))
|
||||||
|
// var/obj/machinery/computer/C = item
|
||||||
|
// var/screen = initial(C.icon_screen)
|
||||||
|
// var/keyboard = initial(C.icon_keyboard)
|
||||||
|
// var/all_states = icon_states(icon_file)
|
||||||
|
// if (screen && (screen in all_states))
|
||||||
|
// I.Blend(icon(icon_file, screen, SOUTH), ICON_OVERLAY)
|
||||||
|
// if (keyboard && (keyboard in all_states))
|
||||||
|
// I.Blend(icon(icon_file, keyboard, SOUTH), ICON_OVERLAY)
|
||||||
|
|
||||||
|
// Insert(initial(D.id), I)
|
||||||
|
// return ..()
|
||||||
|
|
||||||
|
// /datum/asset/spritesheet/vending
|
||||||
|
// name = "vending"
|
||||||
|
|
||||||
|
// /datum/asset/spritesheet/vending/register()
|
||||||
|
// for (var/k in GLOB.vending_products)
|
||||||
|
// var/atom/item = k
|
||||||
|
// if (!ispath(item, /atom))
|
||||||
|
// continue
|
||||||
|
|
||||||
|
// var/icon_file = initial(item.icon)
|
||||||
|
// var/icon_state = initial(item.icon_state)
|
||||||
|
// var/icon/I
|
||||||
|
|
||||||
|
// var/icon_states_list = icon_states(icon_file)
|
||||||
|
// if(icon_state in icon_states_list)
|
||||||
|
// I = icon(icon_file, icon_state, SOUTH)
|
||||||
|
// var/c = initial(item.color)
|
||||||
|
// if (!isnull(c) && c != "#FFFFFF")
|
||||||
|
// I.Blend(c, ICON_MULTIPLY)
|
||||||
|
// else
|
||||||
|
// var/icon_states_string
|
||||||
|
// for (var/an_icon_state in icon_states_list)
|
||||||
|
// if (!icon_states_string)
|
||||||
|
// icon_states_string = "[json_encode(an_icon_state)](\ref[an_icon_state])"
|
||||||
|
// else
|
||||||
|
// icon_states_string += ", [json_encode(an_icon_state)](\ref[an_icon_state])"
|
||||||
|
// stack_trace("[item] does not have a valid icon state, icon=[icon_file], icon_state=[json_encode(icon_state)](\ref[icon_state]), icon_states=[icon_states_string]")
|
||||||
|
// I = icon('icons/turf/floors.dmi', "", SOUTH)
|
||||||
|
|
||||||
|
// var/imgid = replacetext(replacetext("[item]", "/obj/item/", ""), "/", "-")
|
||||||
|
|
||||||
|
// Insert(imgid, I)
|
||||||
|
// return ..()
|
||||||
|
|
||||||
|
// /datum/asset/simple/genetics
|
||||||
|
// assets = list(
|
||||||
|
// "dna_discovered.gif" = 'html/dna_discovered.gif',
|
||||||
|
// "dna_undiscovered.gif" = 'html/dna_undiscovered.gif',
|
||||||
|
// "dna_extra.gif" = 'html/dna_extra.gif'
|
||||||
|
// )
|
||||||
|
|
||||||
|
// /datum/asset/simple/orbit
|
||||||
|
// assets = list(
|
||||||
|
// "ghost.png" = 'html/ghost.png'
|
||||||
|
// )
|
||||||
|
|
||||||
|
// /datum/asset/simple/vv
|
||||||
|
// assets = list(
|
||||||
|
// "view_variables.css" = 'html/admin/view_variables.css'
|
||||||
|
// )
|
||||||
|
|
||||||
|
// /datum/asset/spritesheet/sheetmaterials
|
||||||
|
// name = "sheetmaterials"
|
||||||
|
|
||||||
|
// /datum/asset/spritesheet/sheetmaterials/register()
|
||||||
|
// InsertAll("", 'icons/obj/stack_objects.dmi')
|
||||||
|
|
||||||
|
// // Special case to handle Bluespace Crystals
|
||||||
|
// Insert("polycrystal", 'icons/obj/telescience.dmi', "polycrystal")
|
||||||
|
// ..()
|
||||||
|
|
||||||
|
/datum/asset/nanoui
|
||||||
|
var/list/common = list()
|
||||||
|
|
||||||
|
var/list/common_dirs = list(
|
||||||
|
"nano/css/",
|
||||||
|
"nano/images/",
|
||||||
|
"nano/images/modular_computers/",
|
||||||
|
"nano/js/"
|
||||||
|
)
|
||||||
|
var/list/template_dirs = list(
|
||||||
|
"nano/templates/"
|
||||||
|
)
|
||||||
|
|
||||||
|
/datum/asset/nanoui/register()
|
||||||
|
// Crawl the directories to find files.
|
||||||
|
for(var/path in common_dirs)
|
||||||
|
var/list/filenames = flist(path)
|
||||||
|
for(var/filename in filenames)
|
||||||
|
if(copytext(filename, length(filename)) != "/") // Ignore directories.
|
||||||
|
if(fexists(path + filename))
|
||||||
|
common[filename] = fcopy_rsc(path + filename)
|
||||||
|
register_asset(filename, common[filename])
|
||||||
|
// Combine all templates into a single bundle.
|
||||||
|
var/list/template_data = list()
|
||||||
|
for(var/path in template_dirs)
|
||||||
|
var/list/filenames = flist(path)
|
||||||
|
for(var/filename in filenames)
|
||||||
|
if(copytext(filename, length(filename) - 4) == ".tmpl") // Ignore directories.
|
||||||
|
template_data[filename] = file2text(path + filename)
|
||||||
|
var/template_bundle = "function nanouiTemplateBundle(){return [json_encode(template_data)];}"
|
||||||
|
var/fname = "data/nano_templates_bundle.js"
|
||||||
|
fdel(fname)
|
||||||
|
text2file(template_bundle, fname)
|
||||||
|
register_asset("nano_templates_bundle.js", fcopy_rsc(fname))
|
||||||
|
fdel(fname)
|
||||||
|
|
||||||
|
/datum/asset/nanoui/send(client)
|
||||||
|
send_asset_list(client, common)
|
||||||
29
code/modules/asset_cache/validate_assets.html
Normal file
29
code/modules/asset_cache/validate_assets.html
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
//this is used over window.location because window.location has a character limit in IE.
|
||||||
|
function sendbyond(text) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', '?'+text, true);
|
||||||
|
xhr.send(null);
|
||||||
|
}
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', 'asset_data.json', true);
|
||||||
|
xhr.responseType = 'text';
|
||||||
|
xhr.onreadystatechange = function () {
|
||||||
|
if (xhr.readyState === 4) {
|
||||||
|
var status = xhr.status;
|
||||||
|
if (status >= 200 && status < 400) {
|
||||||
|
sendbyond('asset_cache_preload_data=' + encodeURIComponent(xhr.responseText));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send(null);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,309 +0,0 @@
|
|||||||
/*
|
|
||||||
Asset cache quick users guide:
|
|
||||||
|
|
||||||
Make a datum at the bottom of this file with your assets for your thing.
|
|
||||||
The simple subsystem will most like be of use for most cases.
|
|
||||||
Then call get_asset_datum() with the type of the datum you created and store the return
|
|
||||||
Then call .send(client) on that stored return value.
|
|
||||||
|
|
||||||
You can set verify to TRUE if you want send() to sleep until the client has the assets.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// Amount of time(ds) MAX to send per asset, if this get exceeded we cancel the sleeping.
|
|
||||||
// This is doubled for the first asset, then added per asset after
|
|
||||||
#define ASSET_CACHE_SEND_TIMEOUT 7
|
|
||||||
|
|
||||||
//When sending mutiple assets, how many before we give the client a quaint little sending resources message
|
|
||||||
#define ASSET_CACHE_TELL_CLIENT_AMOUNT 8
|
|
||||||
|
|
||||||
//When passively preloading assets, how many to send at once? Too high creates noticable lag where as too low can flood the client's cache with "verify" files
|
|
||||||
#define ASSET_CACHE_PRELOAD_CONCURRENT 3
|
|
||||||
|
|
||||||
/client
|
|
||||||
var/list/cache = list() // List of all assets sent to this client by the asset cache.
|
|
||||||
var/list/completed_asset_jobs = list() // List of all completed jobs, awaiting acknowledgement.
|
|
||||||
var/list/sending = list()
|
|
||||||
var/last_asset_job = 0 // Last job done.
|
|
||||||
|
|
||||||
//This proc sends the asset to the client, but only if it needs it.
|
|
||||||
//This proc blocks(sleeps) unless verify is set to false
|
|
||||||
/proc/send_asset(var/client/client, var/asset_name, var/verify = TRUE)
|
|
||||||
client = CLIENT_FROM_VAR(client) // Will get client from a mob, or accept a client, or return null
|
|
||||||
if(!istype(client))
|
|
||||||
return 0
|
|
||||||
|
|
||||||
if(client.cache.Find(asset_name) || client.sending.Find(asset_name))
|
|
||||||
return 0
|
|
||||||
|
|
||||||
client << browse_rsc(SSassets.cache[asset_name], asset_name)
|
|
||||||
if(!verify) // Can't access the asset cache browser, rip.
|
|
||||||
client.cache += asset_name
|
|
||||||
return 1
|
|
||||||
|
|
||||||
client.sending |= asset_name
|
|
||||||
var/job = ++client.last_asset_job
|
|
||||||
|
|
||||||
client << browse({"
|
|
||||||
<script>
|
|
||||||
window.location.href="?asset_cache_confirm_arrival=[job]"
|
|
||||||
</script>
|
|
||||||
"}, "window=asset_cache_browser")
|
|
||||||
|
|
||||||
var/t = 0
|
|
||||||
var/timeout_time = (ASSET_CACHE_SEND_TIMEOUT * client.sending.len) + ASSET_CACHE_SEND_TIMEOUT
|
|
||||||
while(client && !client.completed_asset_jobs.Find(job) && t < timeout_time) // Reception is handled in Topic()
|
|
||||||
sleep(1) // Lock up the caller until this is received.
|
|
||||||
t++
|
|
||||||
|
|
||||||
if(client)
|
|
||||||
client.sending -= asset_name
|
|
||||||
client.cache |= asset_name
|
|
||||||
client.completed_asset_jobs -= job
|
|
||||||
|
|
||||||
return 1
|
|
||||||
|
|
||||||
//This proc blocks(sleeps) unless verify is set to false
|
|
||||||
/proc/send_asset_list(var/client/client, var/list/asset_list, var/verify = TRUE)
|
|
||||||
client = CLIENT_FROM_VAR(client) // Will get client from a mob, or accept a client, or return null
|
|
||||||
if(!istype(client))
|
|
||||||
return 0
|
|
||||||
|
|
||||||
var/list/unreceived = asset_list - (client.cache + client.sending)
|
|
||||||
if(!unreceived || !unreceived.len)
|
|
||||||
return 0
|
|
||||||
if(unreceived.len >= ASSET_CACHE_TELL_CLIENT_AMOUNT)
|
|
||||||
to_chat(client, "Sending Resources...")
|
|
||||||
for(var/asset in unreceived)
|
|
||||||
if(asset in SSassets.cache)
|
|
||||||
client << browse_rsc(SSassets.cache[asset], asset)
|
|
||||||
|
|
||||||
if(!verify) // Can't access the asset cache browser, rip.
|
|
||||||
client.cache += unreceived
|
|
||||||
return 1
|
|
||||||
|
|
||||||
client.sending |= unreceived
|
|
||||||
var/job = ++client.last_asset_job
|
|
||||||
|
|
||||||
client << browse({"
|
|
||||||
<script>
|
|
||||||
window.location.href="?asset_cache_confirm_arrival=[job]"
|
|
||||||
</script>
|
|
||||||
"}, "window=asset_cache_browser")
|
|
||||||
|
|
||||||
var/t = 0
|
|
||||||
var/timeout_time = ASSET_CACHE_SEND_TIMEOUT * client.sending.len
|
|
||||||
while(client && !client.completed_asset_jobs.Find(job) && t < timeout_time) // Reception is handled in Topic()
|
|
||||||
sleep(1) // Lock up the caller until this is received.
|
|
||||||
t++
|
|
||||||
|
|
||||||
if(client)
|
|
||||||
client.sending -= unreceived
|
|
||||||
client.cache |= unreceived
|
|
||||||
client.completed_asset_jobs -= job
|
|
||||||
|
|
||||||
return 1
|
|
||||||
|
|
||||||
//This proc will download the files without clogging up the browse() queue, used for passively sending files on connection start.
|
|
||||||
//The proc calls procs that sleep for long times.
|
|
||||||
/proc/getFilesSlow(var/client/client, var/list/files, var/register_asset = TRUE)
|
|
||||||
var/concurrent_tracker = 1
|
|
||||||
for(var/file in files)
|
|
||||||
if(!client)
|
|
||||||
break
|
|
||||||
if(register_asset)
|
|
||||||
register_asset(file, files[file])
|
|
||||||
if(concurrent_tracker >= ASSET_CACHE_PRELOAD_CONCURRENT)
|
|
||||||
concurrent_tracker = 1
|
|
||||||
send_asset(client, file)
|
|
||||||
else
|
|
||||||
concurrent_tracker++
|
|
||||||
send_asset(client, file, verify = FALSE)
|
|
||||||
sleep(0) //queuing calls like this too quickly can cause issues in some client versions
|
|
||||||
|
|
||||||
//This proc "registers" an asset, it adds it to the cache for further use, you cannot touch it from this point on or you'll fuck things up.
|
|
||||||
//if it's an icon or something be careful, you'll have to copy it before further use.
|
|
||||||
/proc/register_asset(var/asset_name, var/asset)
|
|
||||||
SSassets.cache[asset_name] = asset
|
|
||||||
|
|
||||||
//These datums are used to populate the asset cache, the proc "register()" does this.
|
|
||||||
|
|
||||||
//all of our asset datums, used for referring to these later
|
|
||||||
/var/global/list/asset_datums = list()
|
|
||||||
|
|
||||||
//get a assetdatum or make a new one
|
|
||||||
/proc/get_asset_datum(var/type)
|
|
||||||
if(!(type in asset_datums))
|
|
||||||
return new type()
|
|
||||||
return asset_datums[type]
|
|
||||||
|
|
||||||
/datum/asset
|
|
||||||
var/_abstract = /datum/asset // Marker so we don't instanatiate abstract types
|
|
||||||
|
|
||||||
/datum/asset/New()
|
|
||||||
asset_datums[type] = src
|
|
||||||
register()
|
|
||||||
|
|
||||||
/datum/asset/proc/register()
|
|
||||||
return
|
|
||||||
|
|
||||||
/datum/asset/proc/send(client)
|
|
||||||
return
|
|
||||||
|
|
||||||
//If you don't need anything complicated.
|
|
||||||
/datum/asset/simple
|
|
||||||
_abstract = /datum/asset/simple
|
|
||||||
var/assets = list()
|
|
||||||
var/verify = FALSE
|
|
||||||
|
|
||||||
/datum/asset/simple/register()
|
|
||||||
for(var/asset_name in assets)
|
|
||||||
register_asset(asset_name, assets[asset_name])
|
|
||||||
/datum/asset/simple/send(client)
|
|
||||||
send_asset_list(client,assets,verify)
|
|
||||||
|
|
||||||
//
|
|
||||||
// iconsheet Assets - For making lots of icon states available at once without sending a thousand tiny files.
|
|
||||||
//
|
|
||||||
/datum/asset/iconsheet
|
|
||||||
_abstract = /datum/asset/iconsheet
|
|
||||||
var/name // Name of the iconsheet. Asset will be named after this.
|
|
||||||
var/verify = FALSE
|
|
||||||
|
|
||||||
/datum/asset/iconsheet/register(var/list/sprites)
|
|
||||||
if (!name)
|
|
||||||
CRASH("iconsheet [type] cannot register without a name")
|
|
||||||
if (!islist(sprites))
|
|
||||||
CRASH("iconsheet [type] cannot register without a sprites list")
|
|
||||||
|
|
||||||
var/res_name = "iconsheet_[name].css"
|
|
||||||
var/fname = "data/iconsheets/[res_name]"
|
|
||||||
fdel(fname)
|
|
||||||
text2file(generate_css(sprites), fname)
|
|
||||||
register_asset(res_name, fcopy_rsc(fname))
|
|
||||||
fdel(fname)
|
|
||||||
|
|
||||||
/datum/asset/iconsheet/send(client/C)
|
|
||||||
if (!name)
|
|
||||||
return
|
|
||||||
send_asset_list(C, list("iconsheet_[name].css"), verify)
|
|
||||||
|
|
||||||
/datum/asset/iconsheet/proc/generate_css(var/list/sprites)
|
|
||||||
var/list/out = list(".[name]{display:inline-block;}")
|
|
||||||
for(var/sprite_id in sprites)
|
|
||||||
var/icon/I = sprites[sprite_id]
|
|
||||||
var/data_url = "'data:image/png;base64,[icon2base64(I)]'"
|
|
||||||
out += ".[name].[sprite_id]{width:[I.Width()]px;height:[I.Height()]px;background-image:url([data_url]);}"
|
|
||||||
return out.Join("\n")
|
|
||||||
|
|
||||||
/datum/asset/iconsheet/proc/build_sprite_list(icon/I, list/directions, prefix = null)
|
|
||||||
if (length(prefix))
|
|
||||||
prefix = "[prefix]-"
|
|
||||||
|
|
||||||
if (!directions)
|
|
||||||
directions = list(SOUTH)
|
|
||||||
|
|
||||||
var/sprites = list()
|
|
||||||
for (var/icon_state_name in cached_icon_states(I))
|
|
||||||
for (var/direction in directions)
|
|
||||||
var/suffix = (directions.len > 1) ? "-[dir2text(direction)]" : ""
|
|
||||||
var/sprite_name = "[prefix][icon_state_name][suffix]"
|
|
||||||
var/icon/sprite = icon(I, icon_state=icon_state_name, dir=direction, frame=1, moving=FALSE)
|
|
||||||
if (!sprite || !length(cached_icon_states(sprite))) // that direction or state doesn't exist
|
|
||||||
continue
|
|
||||||
sprites[sprite_name] = sprite
|
|
||||||
return sprites
|
|
||||||
|
|
||||||
// Get HTML link tag for including the iconsheet css file.
|
|
||||||
/datum/asset/iconsheet/proc/css_tag()
|
|
||||||
return "<link rel='stylesheet' href='iconsheet_[name].css' />"
|
|
||||||
|
|
||||||
// get HTML tag for showing an icon
|
|
||||||
/datum/asset/iconsheet/proc/icon_tag(icon_state, dir = SOUTH)
|
|
||||||
return "<span class='[name] [icon_state]-[dir2text(dir)]'></span>"
|
|
||||||
|
|
||||||
//DEFINITIONS FOR ASSET DATUMS START HERE.
|
|
||||||
/datum/asset/simple/generic
|
|
||||||
assets = list(
|
|
||||||
"search.js" = 'html/search.js',
|
|
||||||
"panels.css" = 'html/panels.css',
|
|
||||||
"loading.gif" = 'html/images/loading.gif',
|
|
||||||
"ntlogo.png" = 'html/images/ntlogo.png',
|
|
||||||
"sglogo.png" = 'html/images/sglogo.png',
|
|
||||||
"talisman.png" = 'html/images/talisman.png',
|
|
||||||
"paper_bg.png" = 'html/images/paper_bg.png',
|
|
||||||
"no_image32.png" = 'html/images/no_image32.png',
|
|
||||||
)
|
|
||||||
|
|
||||||
/datum/asset/simple/changelog
|
|
||||||
assets = list(
|
|
||||||
"88x31.png" = 'html/88x31.png',
|
|
||||||
"bug-minus.png" = 'html/bug-minus.png',
|
|
||||||
"cross-circle.png" = 'html/cross-circle.png',
|
|
||||||
"hard-hat-exclamation.png" = 'html/hard-hat-exclamation.png',
|
|
||||||
"image-minus.png" = 'html/image-minus.png',
|
|
||||||
"image-plus.png" = 'html/image-plus.png',
|
|
||||||
"map-pencil.png" = 'html/map-pencil.png',
|
|
||||||
"music-minus.png" = 'html/music-minus.png',
|
|
||||||
"music-plus.png" = 'html/music-plus.png',
|
|
||||||
"tick-circle.png" = 'html/tick-circle.png',
|
|
||||||
"wrench-screwdriver.png" = 'html/wrench-screwdriver.png',
|
|
||||||
"spell-check.png" = 'html/spell-check.png',
|
|
||||||
"burn-exclamation.png" = 'html/burn-exclamation.png',
|
|
||||||
"chevron.png" = 'html/chevron.png',
|
|
||||||
"chevron-expand.png" = 'html/chevron-expand.png',
|
|
||||||
"changelog.css" = 'html/changelog.css',
|
|
||||||
"changelog.js" = 'html/changelog.js',
|
|
||||||
"changelog.html" = 'html/changelog.html'
|
|
||||||
)
|
|
||||||
|
|
||||||
/datum/asset/nanoui
|
|
||||||
var/list/common = list()
|
|
||||||
|
|
||||||
var/list/common_dirs = list(
|
|
||||||
"nano/css/",
|
|
||||||
"nano/images/",
|
|
||||||
"nano/images/modular_computers/",
|
|
||||||
"nano/js/"
|
|
||||||
)
|
|
||||||
var/list/template_dirs = list(
|
|
||||||
"nano/templates/"
|
|
||||||
)
|
|
||||||
|
|
||||||
/datum/asset/nanoui/register()
|
|
||||||
// Crawl the directories to find files.
|
|
||||||
for(var/path in common_dirs)
|
|
||||||
var/list/filenames = flist(path)
|
|
||||||
for(var/filename in filenames)
|
|
||||||
if(copytext(filename, length(filename)) != "/") // Ignore directories.
|
|
||||||
if(fexists(path + filename))
|
|
||||||
common[filename] = fcopy_rsc(path + filename)
|
|
||||||
register_asset(filename, common[filename])
|
|
||||||
// Combine all templates into a single bundle.
|
|
||||||
var/list/template_data = list()
|
|
||||||
for(var/path in template_dirs)
|
|
||||||
var/list/filenames = flist(path)
|
|
||||||
for(var/filename in filenames)
|
|
||||||
if(copytext(filename, length(filename) - 4) == ".tmpl") // Ignore directories.
|
|
||||||
template_data[filename] = file2text(path + filename)
|
|
||||||
var/template_bundle = "function nanouiTemplateBundle(){return [json_encode(template_data)];}"
|
|
||||||
var/fname = "data/nano_templates_bundle.js"
|
|
||||||
fdel(fname)
|
|
||||||
text2file(template_bundle, fname)
|
|
||||||
register_asset("nano_templates_bundle.js", fcopy_rsc(fname))
|
|
||||||
fdel(fname)
|
|
||||||
|
|
||||||
/datum/asset/nanoui/send(client)
|
|
||||||
send_asset_list(client, common)
|
|
||||||
|
|
||||||
|
|
||||||
// VOREStation Add Start - pipes iconsheet asset
|
|
||||||
/datum/asset/iconsheet/pipes
|
|
||||||
name = "pipes"
|
|
||||||
|
|
||||||
/datum/asset/iconsheet/pipes/register()
|
|
||||||
var/list/sprites = list()
|
|
||||||
for (var/each in list('icons/obj/pipe-item.dmi', 'icons/obj/pipes/disposal.dmi'))
|
|
||||||
sprites += build_sprite_list(each, global.alldirs)
|
|
||||||
..(sprites)
|
|
||||||
// VOREStation Add End
|
|
||||||
@@ -59,3 +59,18 @@
|
|||||||
preload_rsc = PRELOAD_RSC
|
preload_rsc = PRELOAD_RSC
|
||||||
|
|
||||||
var/global/obj/screen/click_catcher/void
|
var/global/obj/screen/click_catcher/void
|
||||||
|
|
||||||
|
// List of all asset filenames sent to this client by the asset cache, along with their assoicated md5s
|
||||||
|
var/list/sent_assets = list()
|
||||||
|
/// List of all completed blocking send jobs awaiting acknowledgement by send_asset
|
||||||
|
var/list/completed_asset_jobs = list()
|
||||||
|
/// Last asset send job id.
|
||||||
|
var/last_asset_job = 0
|
||||||
|
var/last_completed_asset_job = 0
|
||||||
|
|
||||||
|
///world.time they connected
|
||||||
|
var/connection_time
|
||||||
|
///world.realtime they connected
|
||||||
|
var/connection_realtime
|
||||||
|
///world.timeofday they connected
|
||||||
|
var/connection_timeofday
|
||||||
|
|||||||
@@ -34,10 +34,12 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// asset_cache
|
||||||
|
var/asset_cache_job
|
||||||
if(href_list["asset_cache_confirm_arrival"])
|
if(href_list["asset_cache_confirm_arrival"])
|
||||||
var/job = text2num(href_list["asset_cache_confirm_arrival"])
|
asset_cache_job = asset_cache_confirm_arrival(href_list["asset_cache_confirm_arrival"])
|
||||||
completed_asset_jobs += job
|
if (!asset_cache_job)
|
||||||
return
|
return
|
||||||
|
|
||||||
//search the href for script injection
|
//search the href for script injection
|
||||||
if( findtext(href,"<script",1,0) )
|
if( findtext(href,"<script",1,0) )
|
||||||
@@ -46,6 +48,10 @@
|
|||||||
//del(usr)
|
//del(usr)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
// Tgui Topic middleware
|
||||||
|
if(!tgui_Topic(href_list))
|
||||||
|
return
|
||||||
|
|
||||||
//Admin PM
|
//Admin PM
|
||||||
if(href_list["priv_msg"])
|
if(href_list["priv_msg"])
|
||||||
var/client/C = locate(href_list["priv_msg"])
|
var/client/C = locate(href_list["priv_msg"])
|
||||||
@@ -106,6 +112,15 @@
|
|||||||
if(config && config.log_hrefs && href_logfile)
|
if(config && config.log_hrefs && href_logfile)
|
||||||
WRITE_LOG(href_logfile, "[src] (usr:[usr])</small> || [hsrc ? "[hsrc] " : ""][href]")
|
WRITE_LOG(href_logfile, "[src] (usr:[usr])</small> || [hsrc ? "[hsrc] " : ""][href]")
|
||||||
|
|
||||||
|
//byond bug ID:2256651
|
||||||
|
if (asset_cache_job && (asset_cache_job in completed_asset_jobs))
|
||||||
|
to_chat(src, "<span class='danger'>An error has been detected in how your client is receiving resources. Attempting to correct.... (If you keep seeing these messages you might want to close byond and reconnect)</span>")
|
||||||
|
src << browse("...", "window=asset_cache_browser")
|
||||||
|
return
|
||||||
|
if (href_list["asset_cache_preload_data"])
|
||||||
|
asset_cache_preload_data(href_list["asset_cache_preload_data"])
|
||||||
|
return
|
||||||
|
|
||||||
switch(href_list["_src_"])
|
switch(href_list["_src_"])
|
||||||
if("holder") hsrc = holder
|
if("holder") hsrc = holder
|
||||||
if("usr") hsrc = mob
|
if("usr") hsrc = mob
|
||||||
@@ -181,6 +196,10 @@
|
|||||||
. = ..() //calls mob.Login()
|
. = ..() //calls mob.Login()
|
||||||
prefs.sanitize_preferences()
|
prefs.sanitize_preferences()
|
||||||
|
|
||||||
|
connection_time = world.time
|
||||||
|
connection_realtime = world.realtime
|
||||||
|
connection_timeofday = world.timeofday
|
||||||
|
|
||||||
if(custom_event_msg && custom_event_msg != "")
|
if(custom_event_msg && custom_event_msg != "")
|
||||||
to_chat(src, "<h1 class='alert'>Custom Event</h1>")
|
to_chat(src, "<h1 class='alert'>Custom Event</h1>")
|
||||||
to_chat(src, "<h2 class='alert'>A custom event is taking place. OOC Info:</h2>")
|
to_chat(src, "<h2 class='alert'>A custom event is taking place. OOC Info:</h2>")
|
||||||
@@ -408,8 +427,12 @@
|
|||||||
//send resources to the client. It's here in its own proc so we can move it around easiliy if need be
|
//send resources to the client. It's here in its own proc so we can move it around easiliy if need be
|
||||||
/client/proc/send_resources()
|
/client/proc/send_resources()
|
||||||
spawn (10) //removing this spawn causes all clients to not get verbs.
|
spawn (10) //removing this spawn causes all clients to not get verbs.
|
||||||
|
|
||||||
|
//load info on what assets the client has
|
||||||
|
src << browse('code/modules/asset_cache/validate_assets.html', "window=asset_cache_browser")
|
||||||
|
|
||||||
//Precache the client with all other assets slowly, so as to not block other browse() calls
|
//Precache the client with all other assets slowly, so as to not block other browse() calls
|
||||||
getFilesSlow(src, SSassets.preload, register_asset = FALSE)
|
addtimer(CALLBACK(GLOBAL_PROC, /proc/getFilesSlow, src, SSassets.preload, FALSE), 5 SECONDS)
|
||||||
|
|
||||||
mob/proc/MayRespawn()
|
mob/proc/MayRespawn()
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
S["ooccolor"] >> pref.ooccolor
|
S["ooccolor"] >> pref.ooccolor
|
||||||
S["tooltipstyle"] >> pref.tooltipstyle
|
S["tooltipstyle"] >> pref.tooltipstyle
|
||||||
S["client_fps"] >> pref.client_fps
|
S["client_fps"] >> pref.client_fps
|
||||||
|
S["tgui_fancy"] >> pref.tgui_fancy
|
||||||
|
S["tgui_lock"] >> pref.tgui_lock
|
||||||
|
|
||||||
/datum/category_item/player_setup_item/player_global/ui/save_preferences(var/savefile/S)
|
/datum/category_item/player_setup_item/player_global/ui/save_preferences(var/savefile/S)
|
||||||
S["UI_style"] << pref.UI_style
|
S["UI_style"] << pref.UI_style
|
||||||
@@ -17,6 +19,8 @@
|
|||||||
S["ooccolor"] << pref.ooccolor
|
S["ooccolor"] << pref.ooccolor
|
||||||
S["tooltipstyle"] << pref.tooltipstyle
|
S["tooltipstyle"] << pref.tooltipstyle
|
||||||
S["client_fps"] << pref.client_fps
|
S["client_fps"] << pref.client_fps
|
||||||
|
S["tgui_fancy"] << pref.tgui_fancy
|
||||||
|
S["tgui_lock"] << pref.tgui_lock
|
||||||
|
|
||||||
/datum/category_item/player_setup_item/player_global/ui/sanitize_preferences()
|
/datum/category_item/player_setup_item/player_global/ui/sanitize_preferences()
|
||||||
pref.UI_style = sanitize_inlist(pref.UI_style, all_ui_styles, initial(pref.UI_style))
|
pref.UI_style = sanitize_inlist(pref.UI_style, all_ui_styles, initial(pref.UI_style))
|
||||||
@@ -25,20 +29,24 @@
|
|||||||
pref.ooccolor = sanitize_hexcolor(pref.ooccolor, initial(pref.ooccolor))
|
pref.ooccolor = sanitize_hexcolor(pref.ooccolor, initial(pref.ooccolor))
|
||||||
pref.tooltipstyle = sanitize_inlist(pref.tooltipstyle, all_tooltip_styles, initial(pref.tooltipstyle))
|
pref.tooltipstyle = sanitize_inlist(pref.tooltipstyle, all_tooltip_styles, initial(pref.tooltipstyle))
|
||||||
pref.client_fps = sanitize_integer(pref.client_fps, 0, MAX_CLIENT_FPS, initial(pref.client_fps))
|
pref.client_fps = sanitize_integer(pref.client_fps, 0, MAX_CLIENT_FPS, initial(pref.client_fps))
|
||||||
|
pref.tgui_fancy = sanitize_integer(pref.tgui_fancy, 0, 1, initial(pref.tgui_fancy))
|
||||||
|
pref.tgui_lock = sanitize_integer(pref.tgui_lock, 0, 1, initial(pref.tgui_lock))
|
||||||
|
|
||||||
/datum/category_item/player_setup_item/player_global/ui/content(var/mob/user)
|
/datum/category_item/player_setup_item/player_global/ui/content(var/mob/user)
|
||||||
. = "<b>UI Style:</b> <a href='?src=\ref[src];select_style=1'><b>[pref.UI_style]</b></a><br>"
|
. = "<b>UI Style:</b> <a href='?src=\ref[src];select_style=1'><b>[pref.UI_style]</b></a><br>"
|
||||||
. += "<b>Custom UI</b> (recommended for White UI):<br>"
|
. += "<b>Custom UI</b> (recommended for White UI):<br>"
|
||||||
. += "-Color: <a href='?src=\ref[src];select_color=1'><b>[pref.UI_style_color]</b></a><3E>[color_square(hex = pref.UI_style_color)]<5D><a href='?src=\ref[src];reset=ui'>reset</a><br>"
|
. += "-Color: <a href='?src=\ref[src];select_color=1'><b>[pref.UI_style_color]</b></a><3E>[color_square(hex = pref.UI_style_color)]<5D><a href='?src=\ref[src];reset=ui'>reset</a><br>"
|
||||||
. += "-Alpha(transparency): <a href='?src=\ref[src];select_alpha=1'><b>[pref.UI_style_alpha]</b></a><3E><a href='?src=\ref[src];reset=alpha'>reset</a><br>"
|
. += "-Alpha(transparency): <a href='?src=\ref[src];select_alpha=1'><b>[pref.UI_style_alpha]</b></a><3E><a href='?src=\ref[src];reset=alpha'>reset</a><br>"
|
||||||
. += "<b>Tooltip Style:</b> <a href='?src=\ref[src];select_tooltip_style=1'><b>[pref.tooltipstyle]</b></a><br>"
|
. += "<b>Tooltip Style:</b> <a href='?src=\ref[src];select_tooltip_style=1'><b>[pref.tooltipstyle]</b></a><br>"
|
||||||
. += "<b>Client FPS:</b> <a href='?src=\ref[src];select_client_fps=1'><b>[pref.client_fps]</b></a><br>"
|
. += "<b>Client FPS:</b> <a href='?src=\ref[src];select_client_fps=1'><b>[pref.client_fps]</b></a><br>"
|
||||||
|
. += "<b>tgui Window Mode:</b> <a href='?src=\ref[src];tgui_fancy=1'><b>[(pref.tgui_fancy) ? "Fancy (default)" : "Compatible (slower)"]</b></a><br>"
|
||||||
|
. += "<b>tgui Window Placement:</b> <a href='?src=\ref[src];tgui_lock=1'><b>[(pref.tgui_lock) ? "Primary Monitor" : "Free (default)"]</b></a><br>"
|
||||||
if(can_select_ooc_color(user))
|
if(can_select_ooc_color(user))
|
||||||
. += "<b>OOC Color:</b><3E>"
|
. += "<b>OOC Color:</b><3E>"
|
||||||
if(pref.ooccolor == initial(pref.ooccolor))
|
if(pref.ooccolor == initial(pref.ooccolor))
|
||||||
. += "<a href='?src=\ref[src];select_ooc_color=1'><b>Using Default</b></a><br>"
|
. += "<a href='?src=\ref[src];select_ooc_color=1'><b>Using Default</b></a><br>"
|
||||||
else
|
else
|
||||||
. += "<a href='?src=\ref[src];select_ooc_color=1'><b>[pref.ooccolor]</b></a> [color_square(hex = pref.ooccolor)]<5D><a href='?src=\ref[src];reset=ooc'>reset</a><br>"
|
. += "<a href='?src=\ref[src];select_ooc_color=1'><b>[pref.ooccolor]</b></a> [color_square(hex = pref.ooccolor)]<5D><a href='?src=\ref[src];reset=ooc'>reset</a><br>"
|
||||||
|
|
||||||
/datum/category_item/player_setup_item/player_global/ui/OnTopic(var/href,var/list/href_list, var/mob/user)
|
/datum/category_item/player_setup_item/player_global/ui/OnTopic(var/href,var/list/href_list, var/mob/user)
|
||||||
if(href_list["select_style"])
|
if(href_list["select_style"])
|
||||||
@@ -80,6 +88,14 @@
|
|||||||
pref.client.fps = fps_new
|
pref.client.fps = fps_new
|
||||||
return TOPIC_REFRESH
|
return TOPIC_REFRESH
|
||||||
|
|
||||||
|
else if(href_list["tgui_fancy"])
|
||||||
|
pref.tgui_fancy = !pref.tgui_fancy
|
||||||
|
return TOPIC_REFRESH
|
||||||
|
|
||||||
|
else if(href_list["tgui_lock"])
|
||||||
|
pref.tgui_lock = !pref.tgui_lock
|
||||||
|
return TOPIC_REFRESH
|
||||||
|
|
||||||
else if(href_list["reset"])
|
else if(href_list["reset"])
|
||||||
switch(href_list["reset"])
|
switch(href_list["reset"])
|
||||||
if("ui")
|
if("ui")
|
||||||
|
|||||||
@@ -20,4 +20,8 @@
|
|||||||
/datum/gear/mask/sterile
|
/datum/gear/mask/sterile
|
||||||
display_name = "sterile mask"
|
display_name = "sterile mask"
|
||||||
path = /obj/item/clothing/mask/surgical
|
path = /obj/item/clothing/mask/surgical
|
||||||
cost = 2
|
cost = 2
|
||||||
|
|
||||||
|
/datum/gear/mask/veil
|
||||||
|
display_name = "black veil"
|
||||||
|
path = /obj/item/clothing/mask/veil
|
||||||
@@ -556,4 +556,28 @@
|
|||||||
|
|
||||||
/datum/gear/uniform/haltertop
|
/datum/gear/uniform/haltertop
|
||||||
display_name = "halter top"
|
display_name = "halter top"
|
||||||
path = /obj/item/clothing/under/haltertop
|
path = /obj/item/clothing/under/haltertop
|
||||||
|
|
||||||
|
/datum/gear/uniform/revealingdress
|
||||||
|
display_name = "revealing dress"
|
||||||
|
path = /obj/item/clothing/under/dress/revealingdress
|
||||||
|
|
||||||
|
/datum/gear/uniform/rippedpunk
|
||||||
|
display_name = "ripped punk jeans"
|
||||||
|
path = /obj/item/clothing/under/rippedpunk
|
||||||
|
|
||||||
|
/datum/gear/uniform/gothic
|
||||||
|
display_name = "gothic dress"
|
||||||
|
path = /obj/item/clothing/under/dress/gothic
|
||||||
|
|
||||||
|
/datum/gear/uniform/formalred
|
||||||
|
display_name = "formal red dress"
|
||||||
|
path = /obj/item/clothing/under/dress/formalred
|
||||||
|
|
||||||
|
/datum/gear/uniform/pentagram
|
||||||
|
display_name = "pentagram dress"
|
||||||
|
path = /obj/item/clothing/under/dress/pentagram
|
||||||
|
|
||||||
|
/datum/gear/uniform/yellowswoop
|
||||||
|
display_name = "yellow swooped dress"
|
||||||
|
path = /obj/item/clothing/under/dress/yellowswoop
|
||||||
@@ -24,6 +24,9 @@ datum/preferences
|
|||||||
var/tooltipstyle = "Midnight" //Style for popup tooltips
|
var/tooltipstyle = "Midnight" //Style for popup tooltips
|
||||||
var/client_fps = 0
|
var/client_fps = 0
|
||||||
|
|
||||||
|
var/tgui_fancy = TRUE
|
||||||
|
var/tgui_lock = FALSE
|
||||||
|
|
||||||
//character preferences
|
//character preferences
|
||||||
var/real_name //our character's name
|
var/real_name //our character's name
|
||||||
var/be_random_name = 0 //whether we are a random name every round
|
var/be_random_name = 0 //whether we are a random name every round
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
icon_state = "glasses"
|
icon_state = "glasses"
|
||||||
var/datum/nano_module/arscreen
|
var/datum/nano_module/arscreen
|
||||||
var/arscreen_path
|
var/arscreen_path
|
||||||
|
var/datum/tgui_module/tgarscreen
|
||||||
|
var/tgarscreen_path
|
||||||
var/flash_prot = 0 //0 for none, 1 for flash weapon protection, 2 for welder protection
|
var/flash_prot = 0 //0 for none, 1 for flash weapon protection, 2 for welder protection
|
||||||
enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_AUGMENTED)
|
enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_AUGMENTED)
|
||||||
plane_slots = list(slot_glasses)
|
plane_slots = list(slot_glasses)
|
||||||
@@ -16,21 +18,33 @@
|
|||||||
..()
|
..()
|
||||||
if(arscreen_path)
|
if(arscreen_path)
|
||||||
arscreen = new arscreen_path(src)
|
arscreen = new arscreen_path(src)
|
||||||
|
if(tgarscreen_path)
|
||||||
|
tgarscreen = new tgarscreen_path(src)
|
||||||
|
|
||||||
/obj/item/clothing/glasses/omnihud/Destroy()
|
/obj/item/clothing/glasses/omnihud/Destroy()
|
||||||
QDEL_NULL(arscreen)
|
QDEL_NULL(arscreen)
|
||||||
|
QDEL_NULL(tgarscreen)
|
||||||
. = ..()
|
. = ..()
|
||||||
|
|
||||||
/obj/item/clothing/glasses/omnihud/dropped()
|
/obj/item/clothing/glasses/omnihud/dropped()
|
||||||
if(arscreen)
|
if(arscreen)
|
||||||
SSnanoui.close_uis(src)
|
SSnanoui.close_uis(src)
|
||||||
|
if(tgarscreen)
|
||||||
|
SStgui.close_uis(src)
|
||||||
..()
|
..()
|
||||||
|
|
||||||
/obj/item/clothing/glasses/omnihud/emp_act(var/severity)
|
/obj/item/clothing/glasses/omnihud/emp_act(var/severity)
|
||||||
|
if(arscreen)
|
||||||
|
SSnanoui.close_uis(src)
|
||||||
|
if(tgarscreen)
|
||||||
|
SStgui.close_uis(src)
|
||||||
var/disconnect_ar = arscreen
|
var/disconnect_ar = arscreen
|
||||||
|
var/disconnect_tgar = tgarscreen
|
||||||
arscreen = null
|
arscreen = null
|
||||||
|
tgarscreen = null
|
||||||
spawn(20 SECONDS)
|
spawn(20 SECONDS)
|
||||||
arscreen = disconnect_ar
|
arscreen = disconnect_ar
|
||||||
|
tgarscreen = disconnect_tgar
|
||||||
..()
|
..()
|
||||||
|
|
||||||
/obj/item/clothing/glasses/omnihud/proc/flashed()
|
/obj/item/clothing/glasses/omnihud/proc/flashed()
|
||||||
@@ -71,12 +85,12 @@
|
|||||||
These have been upgraded with medical records access and virus database integration."
|
These have been upgraded with medical records access and virus database integration."
|
||||||
mode = "med"
|
mode = "med"
|
||||||
action_button_name = "AR Console (Crew Monitor)"
|
action_button_name = "AR Console (Crew Monitor)"
|
||||||
arscreen_path = /datum/nano_module/program/crew_monitor
|
tgarscreen_path = /datum/tgui_module/crew_monitor/glasses
|
||||||
enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_CH_STATUS_R,VIS_CH_BACKUP,VIS_AUGMENTED)
|
enables_planes = list(VIS_CH_ID,VIS_CH_HEALTH_VR,VIS_CH_STATUS_R,VIS_CH_BACKUP,VIS_AUGMENTED)
|
||||||
|
|
||||||
ar_interact(var/mob/living/carbon/human/user)
|
ar_interact(var/mob/living/carbon/human/user)
|
||||||
if(arscreen)
|
if(tgarscreen)
|
||||||
arscreen.ui_interact(user,"main",null,1,glasses_state)
|
tgarscreen.tgui_interact(user)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
/obj/item/clothing/glasses/omnihud/sec
|
/obj/item/clothing/glasses/omnihud/sec
|
||||||
|
|||||||
@@ -288,3 +288,10 @@
|
|||||||
desc = "A fine black bandana with nanotech lining and a skull emblem. Can be worn on the head or face."
|
desc = "A fine black bandana with nanotech lining and a skull emblem. Can be worn on the head or face."
|
||||||
icon_state = "bandskull"
|
icon_state = "bandskull"
|
||||||
item_state_slots = list(slot_r_hand_str = "bandskull", slot_l_hand_str = "bandskull")
|
item_state_slots = list(slot_r_hand_str = "bandskull", slot_l_hand_str = "bandskull")
|
||||||
|
|
||||||
|
/obj/item/clothing/mask/veil
|
||||||
|
name = "black veil"
|
||||||
|
desc = "A black veil, typically worn at funerals or by goths."
|
||||||
|
w_class = ITEMSIZE_TINY
|
||||||
|
body_parts_covered = FACE
|
||||||
|
icon_state = "veil"
|
||||||
@@ -535,6 +535,37 @@
|
|||||||
desc = "A red and white dress themed after some winter holidays. Tastefully festive!"
|
desc = "A red and white dress themed after some winter holidays. Tastefully festive!"
|
||||||
icon_state = "festivedress"
|
icon_state = "festivedress"
|
||||||
|
|
||||||
|
/obj/item/clothing/under/dress/revealingdress
|
||||||
|
name = "revealing dress"
|
||||||
|
desc = "A very revealing black and blue dress. Is this work appropriate?"
|
||||||
|
icon_state = "revealingdress"
|
||||||
|
index = 1
|
||||||
|
|
||||||
|
/obj/item/clothing/under/dress/gothic
|
||||||
|
name = "gothic dress"
|
||||||
|
desc = "A black dress with a sheer mesh over it, tastefully old school goth."
|
||||||
|
icon_state = "gothic"
|
||||||
|
index = 1
|
||||||
|
|
||||||
|
/obj/item/clothing/under/dress/formalred
|
||||||
|
name = "formal red dress"
|
||||||
|
desc = "A very formal red dress, for those fancy galas."
|
||||||
|
icon_state = "formalred"
|
||||||
|
flags_inv = HIDESHOES
|
||||||
|
index = 1
|
||||||
|
|
||||||
|
/obj/item/clothing/under/dress/pentagram
|
||||||
|
name = "pentagram dress"
|
||||||
|
desc = "A black dress with straps over the chest in the shape of a pentagram."
|
||||||
|
icon_state = "pentagram"
|
||||||
|
index = 1
|
||||||
|
|
||||||
|
obj/item/clothing/under/dress/yellowswoop
|
||||||
|
name = "yellow swooped dress"
|
||||||
|
desc = "A yellow dress that swoops to the side."
|
||||||
|
icon_state = "yellowswoop"
|
||||||
|
index = 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* wedding stuff
|
* wedding stuff
|
||||||
*/
|
*/
|
||||||
@@ -767,6 +798,12 @@ Uniforms and such
|
|||||||
desc = "Jean shorts and a black halter top. Perfect for casual Fridays!"
|
desc = "Jean shorts and a black halter top. Perfect for casual Fridays!"
|
||||||
icon_state = "haltertop"
|
icon_state = "haltertop"
|
||||||
|
|
||||||
|
/obj/item/clothing/under/rippedpunk
|
||||||
|
name = "ripped punk jeans"
|
||||||
|
desc = "Black ripped jeans and a fishnet top. How punk."
|
||||||
|
icon_state = "rippedpunk"
|
||||||
|
index = 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* swimsuit
|
* swimsuit
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -77,7 +77,7 @@
|
|||||||
// This will actually protect it from further damage.
|
// This will actually protect it from further damage.
|
||||||
if(prob(25))
|
if(prob(25))
|
||||||
A.energy_fail(rand(60, 120))
|
A.energy_fail(rand(60, 120))
|
||||||
log_debug("ELECTRICAL EVENT: Disabled \the [A]'s power for a temporary amount of time.")
|
// log_debug("ELECTRICAL EVENT: Disabled \the [A]'s power for a temporary amount of time.")
|
||||||
playsound(A, 'sound/machines/defib_success.ogg', 50, 1)
|
playsound(A, 'sound/machines/defib_success.ogg', 50, 1)
|
||||||
apcs_disabled++
|
apcs_disabled++
|
||||||
return
|
return
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
// Decent chance to overload lighting circuit.
|
// Decent chance to overload lighting circuit.
|
||||||
if(prob(30))
|
if(prob(30))
|
||||||
A.overload_lighting()
|
A.overload_lighting()
|
||||||
log_debug("ELECTRICAL EVENT: Overloaded \the [A]'s lighting.")
|
// log_debug("ELECTRICAL EVENT: Overloaded \the [A]'s lighting.")
|
||||||
playsound(A, 'sound/effects/lightningshock.ogg', 50, 1)
|
playsound(A, 'sound/effects/lightningshock.ogg', 50, 1)
|
||||||
apcs_overloaded++
|
apcs_overloaded++
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@
|
|||||||
if(prob(5))
|
if(prob(5))
|
||||||
A.emagged = TRUE
|
A.emagged = TRUE
|
||||||
A.update_icon()
|
A.update_icon()
|
||||||
log_debug("ELECTRICAL EVENT: Emagged \the [A].")
|
// log_debug("ELECTRICAL EVENT: Emagged \the [A].")
|
||||||
playsound(A, 'sound/machines/chime.ogg', 50, 1)
|
playsound(A, 'sound/machines/chime.ogg', 50, 1)
|
||||||
apcs_emagged++
|
apcs_emagged++
|
||||||
|
|
||||||
|
|||||||
@@ -40,13 +40,13 @@
|
|||||||
var/list/activity = list()
|
var/list/activity = list()
|
||||||
for(var/department in departments)
|
for(var/department in departments)
|
||||||
activity[department] = assess_department(department)
|
activity[department] = assess_department(department)
|
||||||
log_debug("Assessing department [department]. They have activity of [activity[department]].")
|
// log_debug("Assessing department [department]. They have activity of [activity[department]].")
|
||||||
|
|
||||||
var/list/most_active_departments = list() // List of winners.
|
var/list/most_active_departments = list() // List of winners.
|
||||||
var/highest_activity = null // Department who is leading in activity, if one exists.
|
var/highest_activity = null // Department who is leading in activity, if one exists.
|
||||||
var/highest_number = 0 // Activity score needed to beat to be the most active department.
|
var/highest_number = 0 // Activity score needed to beat to be the most active department.
|
||||||
for(var/i = 1, i <= cutoff_number, i++)
|
for(var/i = 1, i <= cutoff_number, i++)
|
||||||
log_debug("Doing [i]\th round of counting.")
|
// log_debug("Doing [i]\th round of counting.")
|
||||||
for(var/department in activity)
|
for(var/department in activity)
|
||||||
if(department in department_blacklist) // Blacklisted?
|
if(department in department_blacklist) // Blacklisted?
|
||||||
continue
|
continue
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
if(highest_activity) // Someone's a winner.
|
if(highest_activity) // Someone's a winner.
|
||||||
most_active_departments.Add(highest_activity) // Add to the list of most active.
|
most_active_departments.Add(highest_activity) // Add to the list of most active.
|
||||||
activity.Remove(highest_activity) // Remove them from the other list so they don't win more than once.
|
activity.Remove(highest_activity) // Remove them from the other list so they don't win more than once.
|
||||||
log_debug("[highest_activity] has won the [i]\th round of activity counting.")
|
// log_debug("[highest_activity] has won the [i]\th round of activity counting.")
|
||||||
highest_activity = null // Now reset for the next round.
|
highest_activity = null // Now reset for the next round.
|
||||||
highest_number = 0
|
highest_number = 0
|
||||||
//todo: finish
|
//todo: finish
|
||||||
|
|||||||
@@ -37,7 +37,6 @@
|
|||||||
|
|
||||||
/obj/machinery/camera/deactivate(user as mob, var/choice = 1)
|
/obj/machinery/camera/deactivate(user as mob, var/choice = 1)
|
||||||
..(user, choice)
|
..(user, choice)
|
||||||
invalidateCameraCache()
|
|
||||||
if(src.can_use())
|
if(src.can_use())
|
||||||
cameranet.addCamera(src)
|
cameranet.addCamera(src)
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -110,6 +110,21 @@
|
|||||||
"ver", "stv", "pro", "ski"
|
"ver", "stv", "pro", "ski"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/datum/language/drudakar
|
||||||
|
name = LANGUAGE_DRUDAKAR
|
||||||
|
desc = "The native language of the D'Rudak'Ar, a loosely tied together community of dragons and demi-dragons based in the Diul system. Features include many hard consonants and rolling 'r's."
|
||||||
|
speech_verb = "gaos"
|
||||||
|
ask_verb = "gaos"
|
||||||
|
exclaim_verb = "GAOS"
|
||||||
|
whisper_verb = "gaos"
|
||||||
|
colour = "drudakar"
|
||||||
|
key = "K"
|
||||||
|
syllables = list(
|
||||||
|
"gok", "rha", "rou", "gao", "do", "ra", "bo", "lah", "draz", "khi", "zah", "lah", "ora", "ille",
|
||||||
|
"ghlas", "ghlai", "tyur", "vah", "bao", "raag", "drag", "zhi", "dahl", "tiyr", "vahl", "nyem",
|
||||||
|
"roar", "hyaa", "ma", "ha", "ya", "shi", "yo", "go"
|
||||||
|
)
|
||||||
|
|
||||||
/datum/language/unathi
|
/datum/language/unathi
|
||||||
flags = 0
|
flags = 0
|
||||||
/datum/language/tajaran
|
/datum/language/tajaran
|
||||||
|
|||||||
@@ -1,3 +1,13 @@
|
|||||||
|
// Medbot Info
|
||||||
|
|
||||||
|
#define MEDBOT_PANIC_NONE 0
|
||||||
|
#define MEDBOT_PANIC_LOW 15
|
||||||
|
#define MEDBOT_PANIC_MED 35
|
||||||
|
#define MEDBOT_PANIC_HIGH 55
|
||||||
|
#define MEDBOT_PANIC_FUCK 70
|
||||||
|
#define MEDBOT_PANIC_ENDING 90
|
||||||
|
#define MEDBOT_PANIC_END 100
|
||||||
|
|
||||||
/mob/living/bot/medbot
|
/mob/living/bot/medbot
|
||||||
name = "Medibot"
|
name = "Medibot"
|
||||||
desc = "A little medical robot. He looks somewhat underwhelmed."
|
desc = "A little medical robot. He looks somewhat underwhelmed."
|
||||||
@@ -23,6 +33,15 @@
|
|||||||
var/treatment_virus = "spaceacillin"
|
var/treatment_virus = "spaceacillin"
|
||||||
var/treatment_emag = "toxin"
|
var/treatment_emag = "toxin"
|
||||||
var/declare_treatment = 0 //When attempting to treat a patient, should it notify everyone wearing medhuds?
|
var/declare_treatment = 0 //When attempting to treat a patient, should it notify everyone wearing medhuds?
|
||||||
|
|
||||||
|
// Are we tipped over?
|
||||||
|
var/is_tipped = FALSE
|
||||||
|
//How panicked we are about being tipped over (why would you do this?)
|
||||||
|
var/tipped_status = MEDBOT_PANIC_NONE
|
||||||
|
//The name we got when we were tipped
|
||||||
|
var/tipper_name
|
||||||
|
//The last time we were tipped/righted and said a voice line, to avoid spam
|
||||||
|
var/last_tipping_action_voice = 0
|
||||||
|
|
||||||
/mob/living/bot/medbot/mysterious
|
/mob/living/bot/medbot/mysterious
|
||||||
name = "\improper Mysterious Medibot"
|
name = "\improper Mysterious Medibot"
|
||||||
@@ -34,6 +53,9 @@
|
|||||||
treatment_tox = "anti_toxin"
|
treatment_tox = "anti_toxin"
|
||||||
|
|
||||||
/mob/living/bot/medbot/handleIdle()
|
/mob/living/bot/medbot/handleIdle()
|
||||||
|
if(is_tipped) // Don't handle idle things if we're incapacitated!
|
||||||
|
return
|
||||||
|
|
||||||
if(vocal && prob(1))
|
if(vocal && prob(1))
|
||||||
var/message_options = list(
|
var/message_options = list(
|
||||||
"Radar, put a mask on!" = 'sound/voice/medbot/mradar.ogg',
|
"Radar, put a mask on!" = 'sound/voice/medbot/mradar.ogg',
|
||||||
@@ -47,6 +69,9 @@
|
|||||||
playsound(src, message_options[message], 50, 0)
|
playsound(src, message_options[message], 50, 0)
|
||||||
|
|
||||||
/mob/living/bot/medbot/handleAdjacentTarget()
|
/mob/living/bot/medbot/handleAdjacentTarget()
|
||||||
|
if(is_tipped) // Don't handle targets if we're incapacitated!
|
||||||
|
return
|
||||||
|
|
||||||
UnarmedAttack(target)
|
UnarmedAttack(target)
|
||||||
|
|
||||||
/mob/living/bot/medbot/handlePanic() // Speed modification based on alert level.
|
/mob/living/bot/medbot/handlePanic() // Speed modification based on alert level.
|
||||||
@@ -76,6 +101,9 @@
|
|||||||
return .
|
return .
|
||||||
|
|
||||||
/mob/living/bot/medbot/lookForTargets()
|
/mob/living/bot/medbot/lookForTargets()
|
||||||
|
if(is_tipped) // Don't look for targets if we're incapacitated!
|
||||||
|
return
|
||||||
|
|
||||||
for(var/mob/living/carbon/human/H in view(7, src)) // Time to find a patient!
|
for(var/mob/living/carbon/human/H in view(7, src)) // Time to find a patient!
|
||||||
if(confirmTarget(H))
|
if(confirmTarget(H))
|
||||||
target = H
|
target = H
|
||||||
@@ -162,7 +190,28 @@
|
|||||||
else
|
else
|
||||||
icon_state = "medibot[on]"
|
icon_state = "medibot[on]"
|
||||||
|
|
||||||
/mob/living/bot/medbot/attack_hand(var/mob/user)
|
/mob/living/bot/medbot/attack_hand(mob/living/carbon/human/H)
|
||||||
|
if(H.a_intent == I_DISARM && !is_tipped)
|
||||||
|
H.visible_message("<span class='danger'>[H] begins tipping over [src].</span>", "<span class='warning'>You begin tipping over [src]...</span>")
|
||||||
|
|
||||||
|
if(world.time > last_tipping_action_voice + 15 SECONDS)
|
||||||
|
last_tipping_action_voice = world.time // message for tipping happens when we start interacting, message for righting comes after finishing
|
||||||
|
var/list/messagevoice = list("Hey, wait..." = 'sound/voice/medbot/hey_wait.ogg',"Please don't..." = 'sound/voice/medbot/please_dont.ogg',"I trusted you..." = 'sound/voice/medbot/i_trusted_you.ogg', "Nooo..." = 'sound/voice/medbot/nooo.ogg', "Oh fuck-" = 'sound/voice/medbot/oh_fuck.ogg')
|
||||||
|
var/message = pick(messagevoice)
|
||||||
|
say(message)
|
||||||
|
playsound(src, messagevoice[message], 70, FALSE)
|
||||||
|
|
||||||
|
if(do_after(H, 3 SECONDS, target=src))
|
||||||
|
tip_over(H)
|
||||||
|
|
||||||
|
else if(H.a_intent == I_HELP && is_tipped)
|
||||||
|
H.visible_message("<span class='notice'>[H] begins righting [src].</span>", "<span class='notice'>You begin righting [src]...</span>")
|
||||||
|
if(do_after(H, 3 SECONDS, target=src))
|
||||||
|
set_right(H)
|
||||||
|
else
|
||||||
|
interact()
|
||||||
|
|
||||||
|
/mob/living/bot/medbot/proc/interact(mob/user)
|
||||||
var/dat
|
var/dat
|
||||||
dat += "<TT><B>Automatic Medical Unit v1.0</B></TT><BR><BR>"
|
dat += "<TT><B>Automatic Medical Unit v1.0</B></TT><BR><BR>"
|
||||||
dat += "Status: <A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A><BR>"
|
dat += "Status: <A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A><BR>"
|
||||||
@@ -300,6 +349,89 @@
|
|||||||
s.start()
|
s.start()
|
||||||
qdel(src)
|
qdel(src)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
/mob/living/bot/medbot/handleRegular()
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
if(is_tipped)
|
||||||
|
handle_panic()
|
||||||
|
return
|
||||||
|
|
||||||
|
/mob/living/bot/medbot/proc/tip_over(mob/user)
|
||||||
|
playsound(src, 'sound/machines/warning-buzzer.ogg', 50)
|
||||||
|
user.visible_message("<span class='danger'>[user] tips over [src]!</span>", "<span class='danger'>You tip [src] over!</span>")
|
||||||
|
is_tipped = TRUE
|
||||||
|
tipper_name = user.name
|
||||||
|
var/matrix/mat = transform
|
||||||
|
transform = mat.Turn(180)
|
||||||
|
|
||||||
|
/mob/living/bot/medbot/proc/set_right(mob/user)
|
||||||
|
var/list/messagevoice
|
||||||
|
if(user)
|
||||||
|
user.visible_message("<span class='notice'>[user] sets [src] right-side up!</span>", "<span class='green'>You set [src] right-side up!</span>")
|
||||||
|
if(user.name == tipper_name)
|
||||||
|
messagevoice = list("I forgive you." = 'sound/voice/medbot/forgive.ogg')
|
||||||
|
else
|
||||||
|
messagevoice = list("Thank you!" = 'sound/voice/medbot/thank_you.ogg', "You are a good person." = 'sound/voice/medbot/youre_good.ogg')
|
||||||
|
else
|
||||||
|
visible_message("<span class='notice'>[src] manages to [pick("writhe", "wriggle", "wiggle")] enough to right itself.</span>")
|
||||||
|
messagevoice = list("Fuck you." = 'sound/voice/medbot/fuck_you.ogg', "Your behavior has been reported, have a nice day." = 'sound/voice/medbot/reported.ogg')
|
||||||
|
|
||||||
|
tipper_name = null
|
||||||
|
if(world.time > last_tipping_action_voice + 15 SECONDS)
|
||||||
|
last_tipping_action_voice = world.time
|
||||||
|
var/message = pick(messagevoice)
|
||||||
|
say(message)
|
||||||
|
playsound(src, messagevoice[message], 70)
|
||||||
|
tipped_status = MEDBOT_PANIC_NONE
|
||||||
|
is_tipped = FALSE
|
||||||
|
transform = matrix()
|
||||||
|
|
||||||
|
// if someone tipped us over, check whether we should ask for help or just right ourselves eventually
|
||||||
|
/mob/living/bot/medbot/proc/handle_panic()
|
||||||
|
tipped_status++
|
||||||
|
var/list/messagevoice
|
||||||
|
switch(tipped_status)
|
||||||
|
if(MEDBOT_PANIC_LOW)
|
||||||
|
messagevoice = list("I require assistance." = 'sound/voice/medbot/i_require_asst.ogg')
|
||||||
|
if(MEDBOT_PANIC_MED)
|
||||||
|
messagevoice = list("Please put me back." = 'sound/voice/medbot/please_put_me_back.ogg')
|
||||||
|
if(MEDBOT_PANIC_HIGH)
|
||||||
|
messagevoice = list("Please, I am scared!" = 'sound/voice/medbot/please_im_scared.ogg')
|
||||||
|
if(MEDBOT_PANIC_FUCK)
|
||||||
|
messagevoice = list("I don't like this, I need help!" = 'sound/voice/medbot/dont_like.ogg', "This hurts, my pain is real!" = 'sound/voice/medbot/pain_is_real.ogg')
|
||||||
|
if(MEDBOT_PANIC_ENDING)
|
||||||
|
messagevoice = list("Is this the end?" = 'sound/voice/medbot/is_this_the_end.ogg', "Nooo!" = 'sound/voice/medbot/nooo.ogg')
|
||||||
|
if(MEDBOT_PANIC_END)
|
||||||
|
global_announcer.autosay("PSYCH ALERT: Crewmember [tipper_name] recorded displaying antisocial tendencies torturing bots in [get_area(src)]. Please schedule psych evaluation.", "[src]", "Medical")
|
||||||
|
set_right() // strong independent medbot
|
||||||
|
|
||||||
|
// if(prob(tipped_status)) // Commented out pending introduction of jitter stuff from /tg/
|
||||||
|
// do_jitter_animation(tipped_status * 0.1)
|
||||||
|
|
||||||
|
if(messagevoice)
|
||||||
|
var/message = pick(messagevoice)
|
||||||
|
say(message)
|
||||||
|
playsound(src, messagevoice[message], 70)
|
||||||
|
else if(prob(tipped_status * 0.2))
|
||||||
|
playsound(src, 'sound/machines/warning-buzzer.ogg', 30, extrarange=-2)
|
||||||
|
|
||||||
|
/mob/living/bot/medbot/examine(mob/user)
|
||||||
|
. = ..()
|
||||||
|
if(tipped_status == MEDBOT_PANIC_NONE)
|
||||||
|
return
|
||||||
|
|
||||||
|
switch(tipped_status)
|
||||||
|
if(MEDBOT_PANIC_NONE to MEDBOT_PANIC_LOW)
|
||||||
|
. += "It appears to be tipped over, and is quietly waiting for someone to set it right."
|
||||||
|
if(MEDBOT_PANIC_LOW to MEDBOT_PANIC_MED)
|
||||||
|
. += "It is tipped over and requesting help."
|
||||||
|
if(MEDBOT_PANIC_MED to MEDBOT_PANIC_HIGH)
|
||||||
|
. += "They are tipped over and appear visibly distressed." // now we humanize the medbot as a they, not an it
|
||||||
|
if(MEDBOT_PANIC_HIGH to MEDBOT_PANIC_FUCK)
|
||||||
|
. += "<span class='warning'>They are tipped over and visibly panicking!</span>"
|
||||||
|
if(MEDBOT_PANIC_FUCK to INFINITY)
|
||||||
|
. += "<span class='warning'><b>They are freaking out from being tipped over!</b></span>"
|
||||||
|
|
||||||
/mob/living/bot/medbot/confirmTarget(var/mob/living/carbon/human/H)
|
/mob/living/bot/medbot/confirmTarget(var/mob/living/carbon/human/H)
|
||||||
if(!..())
|
if(!..())
|
||||||
@@ -430,3 +562,12 @@
|
|||||||
S.name = created_name
|
S.name = created_name
|
||||||
user.drop_from_inventory(src)
|
user.drop_from_inventory(src)
|
||||||
qdel(src)
|
qdel(src)
|
||||||
|
|
||||||
|
// Undefine these.
|
||||||
|
#undef MEDBOT_PANIC_NONE
|
||||||
|
#undef MEDBOT_PANIC_LOW
|
||||||
|
#undef MEDBOT_PANIC_MED
|
||||||
|
#undef MEDBOT_PANIC_HIGH
|
||||||
|
#undef MEDBOT_PANIC_FUCK
|
||||||
|
#undef MEDBOT_PANIC_ENDING
|
||||||
|
#undef MEDBOT_PANIC_END
|
||||||
|
|||||||
@@ -48,6 +48,21 @@
|
|||||||
|
|
||||||
update_hair()
|
update_hair()
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
/mob/living/carbon/human/proc/change_hair_gradient(var/hair_gradient)
|
||||||
|
if(!hair_gradient)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(grad_style == hair_gradient)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!(hair_gradient in GLOB.hair_gradients))
|
||||||
|
return
|
||||||
|
|
||||||
|
grad_style = hair_gradient
|
||||||
|
|
||||||
|
update_hair()
|
||||||
|
return 1
|
||||||
|
|
||||||
/mob/living/carbon/human/proc/change_facial_hair(var/facial_hair_style)
|
/mob/living/carbon/human/proc/change_facial_hair(var/facial_hair_style)
|
||||||
if(!facial_hair_style)
|
if(!facial_hair_style)
|
||||||
@@ -104,6 +119,17 @@
|
|||||||
|
|
||||||
update_hair()
|
update_hair()
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
/mob/living/carbon/human/proc/change_grad_color(var/red, var/green, var/blue)
|
||||||
|
if(red == r_grad && green == g_grad && blue == b_grad)
|
||||||
|
return
|
||||||
|
|
||||||
|
r_grad = red
|
||||||
|
g_grad = green
|
||||||
|
b_grad = blue
|
||||||
|
|
||||||
|
update_hair()
|
||||||
|
return 1
|
||||||
|
|
||||||
/mob/living/carbon/human/proc/change_facial_hair_color(var/red, var/green, var/blue)
|
/mob/living/carbon/human/proc/change_facial_hair_color(var/red, var/green, var/blue)
|
||||||
if(red == r_facial && green == g_facial && blue == b_facial)
|
if(red == r_facial && green == g_facial && blue == b_facial)
|
||||||
|
|||||||
@@ -146,6 +146,10 @@
|
|||||||
message = "rumbles their throat, puffs their cheeks and croaks."
|
message = "rumbles their throat, puffs their cheeks and croaks."
|
||||||
m_type = 2
|
m_type = 2
|
||||||
playsound(src, 'sound/voice/Croak.ogg', 50, 0, preference = /datum/client_preference/emote_noises)
|
playsound(src, 'sound/voice/Croak.ogg', 50, 0, preference = /datum/client_preference/emote_noises)
|
||||||
|
if("gao")
|
||||||
|
message = "lets out a gao."
|
||||||
|
m_type = 2
|
||||||
|
playsound(src, 'sound/voice/gao.ogg', 50, 0, preference = /datum/client_preference/emote_noises)
|
||||||
if("nsay")
|
if("nsay")
|
||||||
nsay()
|
nsay()
|
||||||
return TRUE
|
return TRUE
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ var/list/wrapped_species_by_ref = list()
|
|||||||
|
|
||||||
var/list/valid_hairstyles = list()
|
var/list/valid_hairstyles = list()
|
||||||
var/list/valid_facialhairstyles = list()
|
var/list/valid_facialhairstyles = list()
|
||||||
|
var/list/valid_gradstyles = GLOB.hair_gradients
|
||||||
for(var/hairstyle in hair_styles_list)
|
for(var/hairstyle in hair_styles_list)
|
||||||
var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
|
var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
|
||||||
if(gender == MALE && S.gender == FEMALE)
|
if(gender == MALE && S.gender == FEMALE)
|
||||||
@@ -112,6 +113,9 @@ var/list/wrapped_species_by_ref = list()
|
|||||||
if(valid_hairstyles.len)
|
if(valid_hairstyles.len)
|
||||||
var/new_hair = input("Select a hairstyle.", "Shapeshifter Hair") as null|anything in valid_hairstyles
|
var/new_hair = input("Select a hairstyle.", "Shapeshifter Hair") as null|anything in valid_hairstyles
|
||||||
change_hair(new_hair ? new_hair : "Bald")
|
change_hair(new_hair ? new_hair : "Bald")
|
||||||
|
if(valid_gradstyles.len)
|
||||||
|
var/new_hair = input("Select a hair gradient style.", "Shapeshifter Hair") as null|anything in valid_gradstyles
|
||||||
|
change_hair_gradient(new_hair ? new_hair : "None")
|
||||||
if(valid_facialhairstyles.len)
|
if(valid_facialhairstyles.len)
|
||||||
var/new_hair = input("Select a facial hair style.", "Shapeshifter Hair") as null|anything in valid_facialhairstyles
|
var/new_hair = input("Select a facial hair style.", "Shapeshifter Hair") as null|anything in valid_facialhairstyles
|
||||||
change_facial_hair(new_hair ? new_hair : "Shaved")
|
change_facial_hair(new_hair ? new_hair : "Shaved")
|
||||||
@@ -216,6 +220,10 @@ var/list/wrapped_species_by_ref = list()
|
|||||||
if(!new_hair)
|
if(!new_hair)
|
||||||
return
|
return
|
||||||
shapeshifter_set_hair_color(new_hair)
|
shapeshifter_set_hair_color(new_hair)
|
||||||
|
var/new_grad = input("Please select a new hair gradient color.", "Hair Gradient Colour") as color
|
||||||
|
if(!new_grad)
|
||||||
|
return
|
||||||
|
shapeshifter_set_grad_color(new_grad)
|
||||||
var/new_fhair = input("Please select a new facial hair color.", "Facial Hair Color") as color
|
var/new_fhair = input("Please select a new facial hair color.", "Facial Hair Color") as color
|
||||||
if(!new_fhair)
|
if(!new_fhair)
|
||||||
return
|
return
|
||||||
@@ -225,6 +233,10 @@ var/list/wrapped_species_by_ref = list()
|
|||||||
|
|
||||||
change_hair_color(hex2num(copytext(new_hair, 2, 4)), hex2num(copytext(new_hair, 4, 6)), hex2num(copytext(new_hair, 6, 8)))
|
change_hair_color(hex2num(copytext(new_hair, 2, 4)), hex2num(copytext(new_hair, 4, 6)), hex2num(copytext(new_hair, 6, 8)))
|
||||||
|
|
||||||
|
/mob/living/carbon/human/proc/shapeshifter_set_grad_color(var/new_grad)
|
||||||
|
|
||||||
|
change_grad_color(hex2num(copytext(new_grad, 2, 4)), hex2num(copytext(new_grad, 4, 6)), hex2num(copytext(new_grad, 6, 8)))
|
||||||
|
|
||||||
/mob/living/carbon/human/proc/shapeshifter_set_facial_color(var/new_fhair)
|
/mob/living/carbon/human/proc/shapeshifter_set_facial_color(var/new_fhair)
|
||||||
|
|
||||||
change_facial_hair_color(hex2num(copytext(new_fhair, 2, 4)), hex2num(copytext(new_fhair, 4, 6)), hex2num(copytext(new_fhair, 6, 8)))
|
change_facial_hair_color(hex2num(copytext(new_fhair, 2, 4)), hex2num(copytext(new_fhair, 4, 6)), hex2num(copytext(new_fhair, 6, 8)))
|
||||||
|
|||||||
@@ -133,3 +133,4 @@
|
|||||||
/datum/trait/colorblind/para_taj/apply(var/datum/species/S,var/mob/living/carbon/human/H)
|
/datum/trait/colorblind/para_taj/apply(var/datum/species/S,var/mob/living/carbon/human/H)
|
||||||
..(S,H)
|
..(S,H)
|
||||||
H.add_modifier(/datum/modifier/trait/colorblind_taj)
|
H.add_modifier(/datum/modifier/trait/colorblind_taj)
|
||||||
|
|
||||||
@@ -19,19 +19,19 @@
|
|||||||
var_changes = list("metabolic_rate" = 1.4, "hunger_factor" = 0.4, "metabolism" = 0.012) // +40% rate and 8x hunger (Double Teshari)
|
var_changes = list("metabolic_rate" = 1.4, "hunger_factor" = 0.4, "metabolism" = 0.012) // +40% rate and 8x hunger (Double Teshari)
|
||||||
excludes = list(/datum/trait/metabolism_up, /datum/trait/metabolism_down)
|
excludes = list(/datum/trait/metabolism_up, /datum/trait/metabolism_down)
|
||||||
|
|
||||||
/datum/trait/cold_discomfort
|
/datum/trait/coldadapt
|
||||||
name = "Hot-Blooded"
|
name = "Cold-Adapted"
|
||||||
desc = "You are too hot at the standard 20C. 18C is more suitable. Rolling down your jumpsuit or being unclothed helps."
|
desc = "You are able to withstand much colder temperatures than other species, and can even be comfortable in extremely cold environments. You are also more vulnerable to hot environments as a consequence of these adaptations."
|
||||||
cost = 0
|
cost = 0
|
||||||
var_changes = list("heat_discomfort_level" = T0C+19)
|
var_changes = list("cold_level_1" = 200, "cold_level_2" = 150, "cold_level_3" = 90, "breath_cold_level_1" = 180, "breath_cold_level_2" = 100, "breath_cold_level_3" = 60, "cold_discomfort_level" = 210, "heat_level_1" = 305, "heat_level_2" = 360, "heat_level_3" = 700, "breath_heat_level_1" = 345, "breath_heat_level_2" = 380, "breath_heat_level_3" = 780, "heat_discomfort_level" = 295)
|
||||||
excludes = list(/datum/trait/hot_discomfort)
|
excludes = list(/datum/trait/hotadapt)
|
||||||
|
|
||||||
/datum/trait/hot_discomfort
|
/datum/trait/hotadapt
|
||||||
name = "Cold-Blooded"
|
name = "Heat-Adapted"
|
||||||
desc = "You are too cold at the standard 20C. 22C is more suitable. Wearing clothing that covers your legs and torso helps."
|
desc = "You are able to withstand much hotter temperatures than other species, and can even be comfortable in extremely hot environments. You are also more vulnerable to cold environments as a consequence of these adaptations."
|
||||||
cost = 0
|
cost = 0
|
||||||
var_changes = list("cold_discomfort_level" = T0C+21)
|
var_changes = list("heat_level_1" = 420, "heat_level_2" = 460, "heat_level_3" = 1100, "breath_heat_level_1" = 440, "breath_heat_level_2" = 510, "breath_heat_level_3" = 1500, "heat_discomfort_level" = 390, "cold_level_1" = 280, "cold_level_2" = 220, "cold_level_3" = 140, "breath_cold_level_1" = 260, "breath_cold_level_2" = 240, "breath_cold_level_3" = 120, "cold_discomfort_level" = 280)
|
||||||
excludes = list(/datum/trait/cold_discomfort)
|
excludes = list(/datum/trait/coldadapt)
|
||||||
|
|
||||||
/datum/trait/autohiss_unathi
|
/datum/trait/autohiss_unathi
|
||||||
name = "Autohiss (Unathi)"
|
name = "Autohiss (Unathi)"
|
||||||
|
|||||||
@@ -123,4 +123,10 @@
|
|||||||
name = "Traceur"
|
name = "Traceur"
|
||||||
desc = "You're capable of parkour and can *flip over low objects (most of the time)."
|
desc = "You're capable of parkour and can *flip over low objects (most of the time)."
|
||||||
cost = 2
|
cost = 2
|
||||||
var_changes = list("agility" = 90)
|
var_changes = list("agility" = 90)
|
||||||
|
|
||||||
|
/datum/trait/snowwalker
|
||||||
|
name = "Snow Walker"
|
||||||
|
desc = "You are able to move unhindered on snow."
|
||||||
|
cost = 1
|
||||||
|
var_changes = list("snow_movement" = -2)
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
add_language(LANGUAGE_ECUREUILIAN, 1)
|
add_language(LANGUAGE_ECUREUILIAN, 1)
|
||||||
add_language(LANGUAGE_DAEMON, 1)
|
add_language(LANGUAGE_DAEMON, 1)
|
||||||
add_language(LANGUAGE_ENOCHIAN, 1)
|
add_language(LANGUAGE_ENOCHIAN, 1)
|
||||||
|
add_language(LANGUAGE_DRUDAKAR, 1)
|
||||||
|
|
||||||
/mob/AIize(var/move = TRUE)
|
/mob/AIize(var/move = TRUE)
|
||||||
. = ..()
|
. = ..()
|
||||||
@@ -14,4 +15,5 @@
|
|||||||
add_language(LANGUAGE_CANILUNZT, 1)
|
add_language(LANGUAGE_CANILUNZT, 1)
|
||||||
add_language(LANGUAGE_ECUREUILIAN, 1)
|
add_language(LANGUAGE_ECUREUILIAN, 1)
|
||||||
add_language(LANGUAGE_DAEMON, 1)
|
add_language(LANGUAGE_DAEMON, 1)
|
||||||
add_language(LANGUAGE_ENOCHIAN, 1)
|
add_language(LANGUAGE_ENOCHIAN, 1)
|
||||||
|
add_language(LANGUAGE_DRUDAKAR, 1)
|
||||||
@@ -673,7 +673,7 @@
|
|||||||
name = "Digestive Analyzer"
|
name = "Digestive Analyzer"
|
||||||
desc = "A mounted destructive analyzer unit with fuel processor."
|
desc = "A mounted destructive analyzer unit with fuel processor."
|
||||||
icon_state = "analyzer"
|
icon_state = "analyzer"
|
||||||
max_item_count = 1
|
max_item_count = 10
|
||||||
startdrain = 100
|
startdrain = 100
|
||||||
analyzer = TRUE
|
analyzer = TRUE
|
||||||
|
|
||||||
@@ -691,7 +691,7 @@
|
|||||||
icon_state = "decompiler"
|
icon_state = "decompiler"
|
||||||
max_item_count = 20
|
max_item_count = 20
|
||||||
delivery = TRUE
|
delivery = TRUE
|
||||||
|
|
||||||
/obj/item/device/dogborg/sleeper/compactor/supply //Miner borg belly
|
/obj/item/device/dogborg/sleeper/compactor/supply //Miner borg belly
|
||||||
name = "Supply Satchel"
|
name = "Supply Satchel"
|
||||||
desc = "A mounted survival unit with fuel processor."
|
desc = "A mounted survival unit with fuel processor."
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
LANGUAGE_CANILUNZT = 0,
|
LANGUAGE_CANILUNZT = 0,
|
||||||
LANGUAGE_ECUREUILIAN= 0,
|
LANGUAGE_ECUREUILIAN= 0,
|
||||||
LANGUAGE_DAEMON = 0,
|
LANGUAGE_DAEMON = 0,
|
||||||
LANGUAGE_ENOCHIAN = 0
|
LANGUAGE_ENOCHIAN = 0,
|
||||||
|
LANGUAGE_DRUDAKAR = 0
|
||||||
)
|
)
|
||||||
var/vr_sprites = list()
|
var/vr_sprites = list()
|
||||||
var/pto_type = null
|
var/pto_type = null
|
||||||
@@ -34,7 +35,8 @@
|
|||||||
LANGUAGE_CANILUNZT = 1,
|
LANGUAGE_CANILUNZT = 1,
|
||||||
LANGUAGE_ECUREUILIAN= 1,
|
LANGUAGE_ECUREUILIAN= 1,
|
||||||
LANGUAGE_DAEMON = 1,
|
LANGUAGE_DAEMON = 1,
|
||||||
LANGUAGE_ENOCHIAN = 1
|
LANGUAGE_ENOCHIAN = 1,
|
||||||
|
LANGUAGE_DRUDAKAR = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
/hook/startup/proc/robot_modules_vr()
|
/hook/startup/proc/robot_modules_vr()
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
var/register_alarms = 1
|
var/register_alarms = 1
|
||||||
var/datum/nano_module/alarm_monitor/all/alarm_monitor
|
var/datum/nano_module/alarm_monitor/all/alarm_monitor
|
||||||
var/datum/nano_module/atmos_control/atmos_control
|
var/datum/nano_module/atmos_control/atmos_control
|
||||||
var/datum/nano_module/program/crew_monitor/crew_monitor
|
var/datum/tgui_module/crew_monitor/robot/crew_monitor
|
||||||
var/datum/nano_module/law_manager/law_manager
|
var/datum/nano_module/law_manager/law_manager
|
||||||
var/datum/nano_module/power_monitor/power_monitor
|
var/datum/nano_module/power_monitor/power_monitor
|
||||||
var/datum/nano_module/rcon/rcon
|
var/datum/nano_module/rcon/rcon
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
set category = "Subystems"
|
set category = "Subystems"
|
||||||
set name = "Crew Monitor"
|
set name = "Crew Monitor"
|
||||||
|
|
||||||
crew_monitor.ui_interact(usr, state = self_state)
|
crew_monitor.tgui_interact(usr)
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Law Manager *
|
* Law Manager *
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
maxHealth = 5
|
maxHealth = 5
|
||||||
health = 5
|
health = 5
|
||||||
|
|
||||||
|
movement_cooldown = 1.5
|
||||||
|
|
||||||
mob_size = MOB_MINISCULE
|
mob_size = MOB_MINISCULE
|
||||||
pass_flags = PASSTABLE
|
pass_flags = PASSTABLE
|
||||||
// can_pull_size = ITEMSIZE_TINY
|
// can_pull_size = ITEMSIZE_TINY
|
||||||
@@ -101,15 +103,13 @@
|
|||||||
|
|
||||||
/mob/living/simple_mob/animal/passive/mouse/rat
|
/mob/living/simple_mob/animal/passive/mouse/rat
|
||||||
name = "rat"
|
name = "rat"
|
||||||
|
body_color = "rat"
|
||||||
|
icon_state = "mouse_rat"
|
||||||
maxHealth = 20
|
maxHealth = 20
|
||||||
health = 20
|
health = 20
|
||||||
|
|
||||||
ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive
|
ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive
|
||||||
|
|
||||||
/mob/living/simple_mob/animal/passive/mouse/rat/Initialize()
|
|
||||||
..()
|
|
||||||
adjust_scale(1.2)
|
|
||||||
|
|
||||||
//TOM IS ALIVE! SQUEEEEEEEE~K :)
|
//TOM IS ALIVE! SQUEEEEEEEE~K :)
|
||||||
/mob/living/simple_mob/animal/passive/mouse/brown/Tom
|
/mob/living/simple_mob/animal/passive/mouse/brown/Tom
|
||||||
name = "Tom"
|
name = "Tom"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
icon_state = "panther"
|
icon_state = "panther"
|
||||||
icon_living = "panther"
|
icon_living = "panther"
|
||||||
|
icon_rest = "panther-rest"
|
||||||
icon_dead = "panther-dead"
|
icon_dead = "panther-dead"
|
||||||
icon = 'icons/mob/vore64x64.dmi'
|
icon = 'icons/mob/vore64x64.dmi'
|
||||||
vis_height = 64
|
vis_height = 64
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/mob/Logout()
|
/mob/Logout()
|
||||||
SSnanoui.user_logout(src) // this is used to clean up (remove) this user's Nano UIs
|
SSnanoui.user_logout(src) // this is used to clean up (remove) this user's Nano UIs
|
||||||
|
SStgui.on_logout(src) // Cleanup any TGUIs the user has open
|
||||||
player_list -= src
|
player_list -= src
|
||||||
disconnect_time = world.realtime //VOREStation Addition: logging when we disappear.
|
disconnect_time = world.realtime //VOREStation Addition: logging when we disappear.
|
||||||
update_client_z(null)
|
update_client_z(null)
|
||||||
|
|||||||
@@ -163,6 +163,7 @@
|
|||||||
idle_threads.Add(active_program)
|
idle_threads.Add(active_program)
|
||||||
active_program.program_state = PROGRAM_STATE_BACKGROUND // Should close any existing UIs
|
active_program.program_state = PROGRAM_STATE_BACKGROUND // Should close any existing UIs
|
||||||
SSnanoui.close_uis(active_program.NM ? active_program.NM : active_program)
|
SSnanoui.close_uis(active_program.NM ? active_program.NM : active_program)
|
||||||
|
SStgui.close_uis(active_program.TM ? active_program.TM : active_program)
|
||||||
active_program = null
|
active_program = null
|
||||||
update_icon()
|
update_icon()
|
||||||
if(istype(user))
|
if(istype(user))
|
||||||
@@ -202,7 +203,6 @@
|
|||||||
minimize_program(user)
|
minimize_program(user)
|
||||||
|
|
||||||
if(P.run_program(user))
|
if(P.run_program(user))
|
||||||
active_program = P
|
|
||||||
update_icon()
|
update_icon()
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,13 @@
|
|||||||
var/required_access = null // List of required accesses to run/download the program.
|
var/required_access = null // List of required accesses to run/download the program.
|
||||||
var/requires_access_to_run = 1 // Whether the program checks for required_access when run.
|
var/requires_access_to_run = 1 // Whether the program checks for required_access when run.
|
||||||
var/requires_access_to_download = 1 // Whether the program checks for required_access when downloading.
|
var/requires_access_to_download = 1 // Whether the program checks for required_access when downloading.
|
||||||
|
// NanoModule
|
||||||
var/datum/nano_module/NM = null // If the program uses NanoModule, put it here and it will be automagically opened. Otherwise implement ui_interact.
|
var/datum/nano_module/NM = null // If the program uses NanoModule, put it here and it will be automagically opened. Otherwise implement ui_interact.
|
||||||
var/nanomodule_path = null // Path to nanomodule, make sure to set this if implementing new program.
|
var/nanomodule_path = null // Path to nanomodule, make sure to set this if implementing new program.
|
||||||
|
// TGUIModule
|
||||||
|
var/datum/tgui_module/TM = null // If the program uses TGUIModule, put it here and it will be automagically opened. Otherwise implement tgui_interact.
|
||||||
|
var/tguimodule_path = null // Path to tguimodule, make sure to set this if implementing new program.
|
||||||
|
// Etc Program stuff
|
||||||
var/program_state = PROGRAM_STATE_KILLED// PROGRAM_STATE_KILLED or PROGRAM_STATE_BACKGROUND or PROGRAM_STATE_ACTIVE - specifies whether this program is running.
|
var/program_state = PROGRAM_STATE_KILLED// PROGRAM_STATE_KILLED or PROGRAM_STATE_BACKGROUND or PROGRAM_STATE_ACTIVE - specifies whether this program is running.
|
||||||
var/obj/item/modular_computer/computer // Device that runs this program.
|
var/obj/item/modular_computer/computer // Device that runs this program.
|
||||||
var/filedesc = "Unknown Program" // User-friendly name of this program.
|
var/filedesc = "Unknown Program" // User-friendly name of this program.
|
||||||
@@ -125,9 +130,14 @@
|
|||||||
// When implementing new program based device, use this to run the program.
|
// When implementing new program based device, use this to run the program.
|
||||||
/datum/computer_file/program/proc/run_program(var/mob/living/user)
|
/datum/computer_file/program/proc/run_program(var/mob/living/user)
|
||||||
if(can_run(user, 1) || !requires_access_to_run)
|
if(can_run(user, 1) || !requires_access_to_run)
|
||||||
|
computer.active_program = src
|
||||||
if(nanomodule_path)
|
if(nanomodule_path)
|
||||||
NM = new nanomodule_path(src, new /datum/topic_manager/program(src), src)
|
NM = new nanomodule_path(src, new /datum/topic_manager/program(src), src)
|
||||||
NM.using_access = user.GetAccess()
|
NM.using_access = user.GetAccess()
|
||||||
|
if(tguimodule_path)
|
||||||
|
TM = new tguimodule_path(src)
|
||||||
|
TM.using_access = user.GetAccess()
|
||||||
|
TM.tgui_interact(user)
|
||||||
if(requires_ntnet && network_destination)
|
if(requires_ntnet && network_destination)
|
||||||
generate_network_log("Connection opened to [network_destination].")
|
generate_network_log("Connection opened to [network_destination].")
|
||||||
program_state = PROGRAM_STATE_ACTIVE
|
program_state = PROGRAM_STATE_ACTIVE
|
||||||
@@ -139,9 +149,11 @@
|
|||||||
program_state = PROGRAM_STATE_KILLED
|
program_state = PROGRAM_STATE_KILLED
|
||||||
if(network_destination)
|
if(network_destination)
|
||||||
generate_network_log("Connection to [network_destination] closed.")
|
generate_network_log("Connection to [network_destination] closed.")
|
||||||
if(NM)
|
QDEL_NULL(NM)
|
||||||
qdel(NM)
|
if(TM)
|
||||||
NM = null
|
SStgui.close_uis(TM)
|
||||||
|
qdel(TM)
|
||||||
|
TM = null
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
// This is called every tick when the program is enabled. Ensure you do parent call if you override it. If parent returns 1 continue with UI initialisation.
|
// This is called every tick when the program is enabled. Ensure you do parent call if you override it. If parent returns 1 continue with UI initialisation.
|
||||||
@@ -154,9 +166,11 @@
|
|||||||
if(istype(NM))
|
if(istype(NM))
|
||||||
NM.ui_interact(user, ui_key, null, force_open)
|
NM.ui_interact(user, ui_key, null, force_open)
|
||||||
return 0
|
return 0
|
||||||
|
if(istype(TM))
|
||||||
|
TM.tgui_interact(user)
|
||||||
|
return 0
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
// CONVENTIONS, READ THIS WHEN CREATING NEW PROGRAM AND OVERRIDING THIS PROC:
|
// CONVENTIONS, READ THIS WHEN CREATING NEW PROGRAM AND OVERRIDING THIS PROC:
|
||||||
// Topic calls are automagically forwarded from NanoModule this program contains.
|
// Topic calls are automagically forwarded from NanoModule this program contains.
|
||||||
// Calls beginning with "PRG_" are reserved for programs handling.
|
// Calls beginning with "PRG_" are reserved for programs handling.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/datum/computer_file/program/camera_monitor/hacked
|
/datum/computer_file/program/camera_monitor/hacked
|
||||||
filename = "camcrypt"
|
filename = "camcrypt"
|
||||||
filedesc = "Camera Decryption Tool"
|
filedesc = "Camera Decryption Tool"
|
||||||
nanomodule_path = /datum/nano_module/camera_monitor/hacked
|
tguimodule_path = /datum/tgui_module/camera/ntos/hacked
|
||||||
program_icon_state = "hostile"
|
program_icon_state = "hostile"
|
||||||
program_key_state = "security_key"
|
program_key_state = "security_key"
|
||||||
program_menu_icon = "zoomin"
|
program_menu_icon = "zoomin"
|
||||||
@@ -15,25 +15,8 @@
|
|||||||
if(program_state != PROGRAM_STATE_ACTIVE) // Background programs won't trigger alarms.
|
if(program_state != PROGRAM_STATE_ACTIVE) // Background programs won't trigger alarms.
|
||||||
return
|
return
|
||||||
|
|
||||||
var/datum/nano_module/camera_monitor/hacked/HNM = NM
|
|
||||||
|
|
||||||
// The program is active and connected to one of the station's networks. Has a very small chance to trigger IDS alarm every tick.
|
// The program is active and connected to one of the station's networks. Has a very small chance to trigger IDS alarm every tick.
|
||||||
if(HNM && HNM.current_network && (HNM.current_network in using_map.station_networks) && prob(0.1))
|
if(prob(0.1))
|
||||||
if(ntnet_global.intrusion_detection_enabled)
|
if(ntnet_global.intrusion_detection_enabled)
|
||||||
ntnet_global.add_log("IDS WARNING - Unauthorised access detected to camera network [HNM.current_network] by device with NID [computer.network_card.get_network_tag()]")
|
ntnet_global.add_log("IDS WARNING - Unauthorised access detected to camera network by device with NID [computer.network_card.get_network_tag()]")
|
||||||
ntnet_global.intrusion_detection_alarm = 1
|
ntnet_global.intrusion_detection_alarm = 1
|
||||||
|
|
||||||
|
|
||||||
/datum/nano_module/camera_monitor/hacked
|
|
||||||
name = "Hacked Camera Monitoring Program"
|
|
||||||
//available_to_ai = FALSE
|
|
||||||
|
|
||||||
/datum/nano_module/camera_monitor/hacked/can_access_network(var/mob/user, var/network_access)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
// The hacked variant has access to all commonly used networks.
|
|
||||||
/datum/nano_module/camera_monitor/hacked/modify_networks_list(var/list/networks)
|
|
||||||
networks.Add(list(list("tag" = NETWORK_MERCENARY, "has_access" = 1)))
|
|
||||||
networks.Add(list(list("tag" = NETWORK_ERT, "has_access" = 1)))
|
|
||||||
networks.Add(list(list("tag" = NETWORK_CRESCENT, "has_access" = 1)))
|
|
||||||
return networks
|
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
/datum/computer_file/program/camera_monitor
|
/datum/computer_file/program/camera_monitor
|
||||||
filename = "cammon"
|
filename = "cammon"
|
||||||
filedesc = "Camera Monitoring"
|
filedesc = "Camera Monitoring"
|
||||||
nanomodule_path = /datum/nano_module/camera_monitor
|
tguimodule_path = /datum/tgui_module/camera/ntos
|
||||||
program_icon_state = "cameras"
|
program_icon_state = "cameras"
|
||||||
program_key_state = "generic_key"
|
program_key_state = "generic_key"
|
||||||
program_menu_icon = "search"
|
program_menu_icon = "search"
|
||||||
@@ -39,163 +39,11 @@
|
|||||||
available_on_ntnet = 1
|
available_on_ntnet = 1
|
||||||
requires_ntnet = 1
|
requires_ntnet = 1
|
||||||
|
|
||||||
/datum/nano_module/camera_monitor
|
|
||||||
name = "Camera Monitoring program"
|
|
||||||
var/obj/machinery/camera/current_camera = null
|
|
||||||
var/current_network = null
|
|
||||||
|
|
||||||
/datum/nano_module/camera_monitor/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, state = default_state)
|
|
||||||
var/list/data = host.initial_data()
|
|
||||||
|
|
||||||
data["current_camera"] = current_camera ? current_camera.nano_structure() : null
|
|
||||||
data["current_network"] = current_network
|
|
||||||
|
|
||||||
var/list/all_networks[0]
|
|
||||||
for(var/network in using_map.station_networks)
|
|
||||||
if(can_access_network(user, get_camera_access(network), 1))
|
|
||||||
all_networks.Add(list(list(
|
|
||||||
"tag" = network,
|
|
||||||
"has_access" = 1
|
|
||||||
)))
|
|
||||||
for(var/network in using_map.secondary_networks)
|
|
||||||
if(can_access_network(user, get_camera_access(network), 0))
|
|
||||||
all_networks.Add(list(list(
|
|
||||||
"tag" = network,
|
|
||||||
"has_access" = 1
|
|
||||||
)))
|
|
||||||
|
|
||||||
all_networks = modify_networks_list(all_networks)
|
|
||||||
|
|
||||||
data["networks"] = all_networks
|
|
||||||
|
|
||||||
var/list/map_levels = using_map.get_map_levels(get_z(nano_host()), TRUE, om_range = DEFAULT_OVERMAP_RANGE)
|
|
||||||
|
|
||||||
if(current_network)
|
|
||||||
data["cameras"] = camera_repository.cameras_in_network(current_network, map_levels)
|
|
||||||
|
|
||||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
|
||||||
if (!ui)
|
|
||||||
ui = new(user, src, ui_key, "mod_sec_camera.tmpl", "Camera Monitoring", 900, 800)
|
|
||||||
// ui.auto_update_layout = 1 // Disabled as with suit sensors monitor - breaks the UI map. Re-enable once it's fixed somehow.
|
|
||||||
|
|
||||||
ui.add_template("mapContent", "sec_camera_map_content.tmpl")
|
|
||||||
ui.add_template("mapHeader", "mod_sec_camera_map_header.tmpl")
|
|
||||||
ui.set_initial_data(data)
|
|
||||||
ui.open()
|
|
||||||
|
|
||||||
// Intended to be overriden by subtypes to manually add non-station networks to the list.
|
|
||||||
/datum/nano_module/camera_monitor/proc/modify_networks_list(var/list/networks)
|
|
||||||
return networks
|
|
||||||
|
|
||||||
/datum/nano_module/camera_monitor/proc/can_access_network(var/mob/user, var/network_access, var/station_network = 0)
|
|
||||||
// No access passed, or 0 which is considered no access requirement. Allow it.
|
|
||||||
if(!network_access)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
if(station_network)
|
|
||||||
return check_access(user, network_access) || check_access(user, access_security) || check_access(user, access_heads)
|
|
||||||
else
|
|
||||||
return check_access(user, network_access)
|
|
||||||
|
|
||||||
/datum/nano_module/camera_monitor/Topic(href, href_list)
|
|
||||||
if(..())
|
|
||||||
return 1
|
|
||||||
|
|
||||||
if(href_list["switch_camera"])
|
|
||||||
var/obj/machinery/camera/C = locate(href_list["switch_camera"]) in cameranet.cameras
|
|
||||||
if(!C)
|
|
||||||
return
|
|
||||||
if(!(current_network in C.network))
|
|
||||||
return
|
|
||||||
|
|
||||||
switch_to_camera(usr, C)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
else if(href_list["switch_network"])
|
|
||||||
// Either security access, or access to the specific camera network's department is required in order to access the network.
|
|
||||||
if(can_access_network(usr, get_camera_access(href_list["switch_network"]), (href_list["switch_network"] in using_map.station_networks)))
|
|
||||||
current_network = href_list["switch_network"]
|
|
||||||
else
|
|
||||||
to_chat(usr, "\The [nano_host()] shows an \"Network Access Denied\" error message.")
|
|
||||||
return 1
|
|
||||||
|
|
||||||
else if(href_list["reset"])
|
|
||||||
reset_current()
|
|
||||||
usr.reset_view(current_camera)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
/datum/nano_module/camera_monitor/proc/switch_to_camera(var/mob/user, var/obj/machinery/camera/C)
|
|
||||||
//don't need to check if the camera works for AI because the AI jumps to the camera location and doesn't actually look through cameras.
|
|
||||||
if(isAI(user))
|
|
||||||
var/mob/living/silicon/ai/A = user
|
|
||||||
// Only allow non-carded AIs to view because the interaction with the eye gets all wonky otherwise.
|
|
||||||
if(!A.is_in_chassis())
|
|
||||||
return 0
|
|
||||||
|
|
||||||
A.eyeobj.setLoc(get_turf(C))
|
|
||||||
A.client.eye = A.eyeobj
|
|
||||||
return 1
|
|
||||||
|
|
||||||
set_current(C)
|
|
||||||
user.machine = nano_host()
|
|
||||||
user.reset_view(C)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
/datum/nano_module/camera_monitor/proc/set_current(var/obj/machinery/camera/C)
|
|
||||||
if(current_camera == C)
|
|
||||||
return
|
|
||||||
|
|
||||||
if(current_camera)
|
|
||||||
reset_current()
|
|
||||||
|
|
||||||
current_camera = C
|
|
||||||
if(current_camera)
|
|
||||||
var/mob/living/L = current_camera.loc
|
|
||||||
if(istype(L))
|
|
||||||
L.tracking_initiated()
|
|
||||||
|
|
||||||
/datum/nano_module/camera_monitor/proc/reset_current()
|
|
||||||
if(current_camera)
|
|
||||||
var/mob/living/L = current_camera.loc
|
|
||||||
if(istype(L))
|
|
||||||
L.tracking_cancelled()
|
|
||||||
current_camera = null
|
|
||||||
|
|
||||||
/datum/nano_module/camera_monitor/check_eye(var/mob/user as mob)
|
|
||||||
if(!current_camera)
|
|
||||||
return 0
|
|
||||||
var/viewflag = current_camera.check_eye(user)
|
|
||||||
if ( viewflag < 0 ) //camera doesn't work
|
|
||||||
reset_current()
|
|
||||||
return viewflag
|
|
||||||
|
|
||||||
|
|
||||||
// ERT Variant of the program
|
// ERT Variant of the program
|
||||||
/datum/computer_file/program/camera_monitor/ert
|
/datum/computer_file/program/camera_monitor/ert
|
||||||
filename = "ntcammon"
|
filename = "ntcammon"
|
||||||
filedesc = "Advanced Camera Monitoring"
|
filedesc = "Advanced Camera Monitoring"
|
||||||
extended_desc = "This program allows remote access to the camera system. Some camera networks may have additional access requirements. This version has an integrated database with additional encrypted keys."
|
extended_desc = "This program allows remote access to the camera system. Some camera networks may have additional access requirements. This version has an integrated database with additional encrypted keys."
|
||||||
size = 14
|
size = 14
|
||||||
nanomodule_path = /datum/nano_module/camera_monitor/ert
|
tguimodule_path = /datum/tgui_module/camera/ntos/ert
|
||||||
available_on_ntnet = 0
|
available_on_ntnet = 0
|
||||||
|
|
||||||
/datum/nano_module/camera_monitor/ert
|
|
||||||
name = "Advanced Camera Monitoring Program"
|
|
||||||
//available_to_ai = FALSE
|
|
||||||
|
|
||||||
// The ERT variant has access to ERT and crescent cams, but still checks for accesses. ERT members should be able to use it.
|
|
||||||
/datum/nano_module/camera_monitor/ert/modify_networks_list(var/list/networks)
|
|
||||||
..()
|
|
||||||
networks.Add(list(list("tag" = NETWORK_ERT, "has_access" = 1)))
|
|
||||||
networks.Add(list(list("tag" = NETWORK_CRESCENT, "has_access" = 1)))
|
|
||||||
return networks
|
|
||||||
|
|
||||||
/datum/nano_module/camera_monitor/apply_visual(mob/M)
|
|
||||||
if(current_camera)
|
|
||||||
current_camera.apply_visual(M)
|
|
||||||
else
|
|
||||||
remove_visual(M)
|
|
||||||
|
|
||||||
/datum/nano_module/camera_monitor/remove_visual(mob/M)
|
|
||||||
if(current_camera)
|
|
||||||
current_camera.remove_visual(M)
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/datum/computer_file/program/suit_sensors
|
/datum/computer_file/program/suit_sensors
|
||||||
filename = "sensormonitor"
|
filename = "sensormonitor"
|
||||||
filedesc = "Suit Sensors Monitoring"
|
filedesc = "Suit Sensors Monitoring"
|
||||||
nanomodule_path = /datum/nano_module/program/crew_monitor
|
tguimodule_path = /datum/tgui_module/crew_monitor/ntos
|
||||||
program_icon_state = "crew"
|
program_icon_state = "crew"
|
||||||
program_key_state = "med_key"
|
program_key_state = "med_key"
|
||||||
program_menu_icon = "heart"
|
program_menu_icon = "heart"
|
||||||
@@ -10,68 +10,3 @@
|
|||||||
requires_ntnet = 1
|
requires_ntnet = 1
|
||||||
network_destination = "crew lifesigns monitoring system"
|
network_destination = "crew lifesigns monitoring system"
|
||||||
size = 11
|
size = 11
|
||||||
|
|
||||||
|
|
||||||
/datum/nano_module/program/crew_monitor
|
|
||||||
name = "Crew monitor"
|
|
||||||
|
|
||||||
/datum/nano_module/program/crew_monitor/Topic(href, href_list)
|
|
||||||
if(..()) return 1
|
|
||||||
var/turf/T = get_turf(nano_host()) // TODO: Allow setting any using_map.contact_levels from the interface.
|
|
||||||
if (!T || !(T.z in using_map.player_levels))
|
|
||||||
to_chat(usr, "<span class='warning'>Unable to establish a connection</span>: You're too far away from the station!")
|
|
||||||
return 0
|
|
||||||
if(href_list["track"])
|
|
||||||
if(isAI(usr))
|
|
||||||
var/mob/living/silicon/ai/AI = usr
|
|
||||||
var/mob/living/carbon/human/H = locate(href_list["track"]) in mob_list
|
|
||||||
if(hassensorlevel(H, SUIT_SENSOR_TRACKING))
|
|
||||||
AI.ai_actual_track(H)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
/datum/nano_module/program/crew_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
|
|
||||||
var/list/data = host.initial_data()
|
|
||||||
|
|
||||||
data["isAI"] = isAI(user)
|
|
||||||
|
|
||||||
var/z = get_z(nano_host())
|
|
||||||
var/list/map_levels = using_map.get_map_levels(z, TRUE, om_range = DEFAULT_OVERMAP_RANGE)
|
|
||||||
data["map_levels"] = map_levels
|
|
||||||
|
|
||||||
data["crewmembers"] = list()
|
|
||||||
for(var/zlevel in map_levels)
|
|
||||||
data["crewmembers"] += crew_repository.health_data(zlevel)
|
|
||||||
|
|
||||||
if(!data["map_levels"].len)
|
|
||||||
to_chat(user, "<span class='warning'>The crew monitor doesn't seem like it'll work here.</span>")
|
|
||||||
if(program)
|
|
||||||
program.kill_program()
|
|
||||||
if(ui)
|
|
||||||
ui.close()
|
|
||||||
return
|
|
||||||
|
|
||||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
|
||||||
if(!ui)
|
|
||||||
ui = new(user, src, ui_key, "crew_monitor.tmpl", "Crew Monitoring Computer", 900, 800, state = state)
|
|
||||||
|
|
||||||
// adding a template with the key "mapContent" enables the map ui functionality
|
|
||||||
ui.add_template("mapContent", "crew_monitor_map_content.tmpl")
|
|
||||||
// adding a template with the key "mapHeader" replaces the map header content
|
|
||||||
ui.add_template("mapHeader", "crew_monitor_map_header.tmpl")
|
|
||||||
if(!(ui.map_z_level in data["map_levels"]))
|
|
||||||
ui.set_map_z_level(data["map_levels"][1])
|
|
||||||
|
|
||||||
ui.set_initial_data(data)
|
|
||||||
ui.open()
|
|
||||||
|
|
||||||
// should make the UI auto-update; doesn't seem to?
|
|
||||||
ui.set_auto_update(1)
|
|
||||||
|
|
||||||
/*/datum/nano_module/program/crew_monitor/proc/scan()
|
|
||||||
for(var/mob/living/carbon/human/H in mob_list)
|
|
||||||
if(istype(H.w_uniform, /obj/item/clothing/under))
|
|
||||||
var/obj/item/clothing/under/C = H.w_uniform
|
|
||||||
if (C.has_sensor)
|
|
||||||
tracked |= C
|
|
||||||
return 1
|
|
||||||
*/
|
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
access = access_medical
|
access = access_medical
|
||||||
cost = 625
|
cost = 625
|
||||||
p_drain = 0.025
|
p_drain = 0.025
|
||||||
var/datum/nano_module/program/crew_monitor/arscreen
|
var/datum/tgui_module/crew_monitor/nif/arscreen
|
||||||
|
|
||||||
New()
|
New()
|
||||||
..()
|
..()
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
activate()
|
activate()
|
||||||
if((. = ..()))
|
if((. = ..()))
|
||||||
arscreen.ui_interact(nif.human,"main",null,1,nif_state)
|
arscreen.tgui_interact(nif.human)
|
||||||
return TRUE
|
return TRUE
|
||||||
|
|
||||||
deactivate()
|
deactivate()
|
||||||
|
|||||||
@@ -212,7 +212,6 @@
|
|||||||
|
|
||||||
// leave the disposal
|
// leave the disposal
|
||||||
/obj/machinery/disposal/proc/go_out(mob/user)
|
/obj/machinery/disposal/proc/go_out(mob/user)
|
||||||
|
|
||||||
if (user.client)
|
if (user.client)
|
||||||
user.client.eye = user.client.mob
|
user.client.eye = user.client.mob
|
||||||
user.client.perspective = MOB_PERSPECTIVE
|
user.client.perspective = MOB_PERSPECTIVE
|
||||||
@@ -222,11 +221,11 @@
|
|||||||
|
|
||||||
// ai as human but can't flush
|
// ai as human but can't flush
|
||||||
/obj/machinery/disposal/attack_ai(mob/user as mob)
|
/obj/machinery/disposal/attack_ai(mob/user as mob)
|
||||||
interact(user, 1)
|
add_hiddenprint(user)
|
||||||
|
tgui_interact(user)
|
||||||
|
|
||||||
// human interact with machine
|
// human interact with machine
|
||||||
/obj/machinery/disposal/attack_hand(mob/user as mob)
|
/obj/machinery/disposal/attack_hand(mob/user as mob)
|
||||||
|
|
||||||
if(stat & BROKEN)
|
if(stat & BROKEN)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -236,91 +235,147 @@
|
|||||||
|
|
||||||
// Clumsy folks can only flush it.
|
// Clumsy folks can only flush it.
|
||||||
if(user.IsAdvancedToolUser(1))
|
if(user.IsAdvancedToolUser(1))
|
||||||
interact(user, 0)
|
tgui_interact(user)
|
||||||
else
|
else
|
||||||
flush = !flush
|
flush = !flush
|
||||||
update()
|
update()
|
||||||
return
|
return
|
||||||
|
|
||||||
// user interaction
|
// user interaction
|
||||||
/obj/machinery/disposal/interact(mob/user, var/ai=0)
|
/obj/machinery/disposal/tgui_interact(mob/user, datum/tgui/ui = null)
|
||||||
|
ui = SStgui.try_update_ui(user, src, ui)
|
||||||
|
if(!ui)
|
||||||
|
ui = new(user, src, "DisposalBin")
|
||||||
|
ui.open()
|
||||||
|
|
||||||
src.add_fingerprint(user)
|
/obj/machinery/disposal/tgui_data(mob/user)
|
||||||
if(stat & BROKEN)
|
var/list/data = list()
|
||||||
user.unset_machine()
|
|
||||||
|
data["isAI"] = isAI(user)
|
||||||
|
data["flushing"] = flush
|
||||||
|
data["mode"] = mode
|
||||||
|
data["pressure"] = round(clamp(100* air_contents.return_pressure() / (SEND_PRESSURE), 0, 100),1)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
/obj/machinery/disposal/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||||
|
if(..())
|
||||||
|
return
|
||||||
|
|
||||||
|
if(usr.loc == src)
|
||||||
|
to_chat(usr, "<span class='warning'>You cannot reach the controls from inside.</span>")
|
||||||
return
|
return
|
||||||
|
|
||||||
var/dat = "<head><title>Waste Disposal Unit</title></head><body><TT><B>Waste Disposal Unit</B><HR>"
|
if(mode==-1 && action != "eject") // If the mode is -1, only allow ejection
|
||||||
|
to_chat(usr, "<span class='warning'>The disposal units power is disabled.</span>")
|
||||||
|
return
|
||||||
|
|
||||||
|
if(stat & BROKEN)
|
||||||
|
return
|
||||||
|
|
||||||
|
add_fingerprint(usr)
|
||||||
|
|
||||||
if(!ai) // AI can't pull flush handle
|
if(flushing)
|
||||||
if(flush)
|
return
|
||||||
dat += "Disposal handle: <A href='?src=\ref[src];handle=0'>Disengage</A> <B>Engaged</B>"
|
|
||||||
else
|
if(isturf(loc))
|
||||||
dat += "Disposal handle: <B>Disengaged</B> <A href='?src=\ref[src];handle=1'>Engage</A>"
|
if(action == "pumpOn")
|
||||||
|
mode = 1
|
||||||
|
update()
|
||||||
|
if(action == "pumpOff")
|
||||||
|
mode = 0
|
||||||
|
update()
|
||||||
|
|
||||||
dat += "<BR><HR><A href='?src=\ref[src];eject=1'>Eject contents</A><HR>"
|
if(!issilicon(usr))
|
||||||
|
if(action == "engageHandle")
|
||||||
|
flush = 1
|
||||||
|
update()
|
||||||
|
if(action == "disengageHandle")
|
||||||
|
flush = 0
|
||||||
|
update()
|
||||||
|
|
||||||
if(mode <= 0)
|
if(action == "eject")
|
||||||
dat += "Pump: <B>Off</B> <A href='?src=\ref[src];pump=1'>On</A><BR>"
|
eject()
|
||||||
else if(mode == 1)
|
|
||||||
dat += "Pump: <A href='?src=\ref[src];pump=0'>Off</A> <B>On</B> (pressurizing)<BR>"
|
return TRUE
|
||||||
else
|
|
||||||
dat += "Pump: <A href='?src=\ref[src];pump=0'>Off</A> <B>On</B> (idle)<BR>"
|
|
||||||
|
|
||||||
var/per = 100* air_contents.return_pressure() / (SEND_PRESSURE)
|
// src.add_fingerprint(user)
|
||||||
|
// if(stat & BROKEN)
|
||||||
|
// user.unset_machine()
|
||||||
|
// return
|
||||||
|
|
||||||
dat += "Pressure: [round(per, 1)]%<BR></body>"
|
// var/dat = "<head><title>Waste Disposal Unit</title></head><body><TT><B>Waste Disposal Unit</B><HR>"
|
||||||
|
|
||||||
|
// if(!ai) // AI can't pull flush handle
|
||||||
|
// if(flush)
|
||||||
|
// dat += "Disposal handle: <A href='?src=\ref[src];handle=0'>Disengage</A> <B>Engaged</B>"
|
||||||
|
// else
|
||||||
|
// dat += "Disposal handle: <B>Disengaged</B> <A href='?src=\ref[src];handle=1'>Engage</A>"
|
||||||
|
|
||||||
|
// dat += "<BR><HR><A href='?src=\ref[src];eject=1'>Eject contents</A><HR>"
|
||||||
|
|
||||||
|
// if(mode <= 0)
|
||||||
|
// dat += "Pump: <B>Off</B> <A href='?src=\ref[src];pump=1'>On</A><BR>"
|
||||||
|
// else if(mode == 1)
|
||||||
|
// dat += "Pump: <A href='?src=\ref[src];pump=0'>Off</A> <B>On</B> (pressurizing)<BR>"
|
||||||
|
// else
|
||||||
|
// dat += "Pump: <A href='?src=\ref[src];pump=0'>Off</A> <B>On</B> (idle)<BR>"
|
||||||
|
|
||||||
|
// var/per = 100* air_contents.return_pressure() / (SEND_PRESSURE)
|
||||||
|
|
||||||
|
// dat += "Pressure: [round(per, 1)]%<BR></body>"
|
||||||
|
|
||||||
|
|
||||||
user.set_machine(src)
|
// user.set_machine(src)
|
||||||
user << browse(dat, "window=disposal;size=360x170")
|
// user << browse(dat, "window=disposal;size=360x170")
|
||||||
onclose(user, "disposal")
|
// onclose(user, "disposal")
|
||||||
|
|
||||||
// handle machine interaction
|
// handle machine interaction
|
||||||
|
|
||||||
/obj/machinery/disposal/Topic(href, href_list)
|
// /obj/machinery/disposal/Topic(href, href_list)
|
||||||
if(usr.loc == src)
|
// if(usr.loc == src)
|
||||||
to_chat(usr, "<font color='red'>You cannot reach the controls from inside.</font>")
|
// to_chat(usr, "<font color='red'>You cannot reach the controls from inside.</font>")
|
||||||
return
|
// return
|
||||||
|
|
||||||
if(mode==-1 && !href_list["eject"]) // only allow ejecting if mode is -1
|
// if(mode==-1 && !href_list["eject"]) // only allow ejecting if mode is -1
|
||||||
to_chat(usr, "<font color='red'>The disposal units power is disabled.</font>")
|
// to_chat(usr, "<font color='red'>The disposal units power is disabled.</font>")
|
||||||
return
|
// return
|
||||||
if(..())
|
// if(..())
|
||||||
return
|
// return
|
||||||
|
|
||||||
if(stat & BROKEN)
|
// if(stat & BROKEN)
|
||||||
return
|
// return
|
||||||
if(usr.stat || usr.restrained() || src.flushing)
|
// if(usr.stat || usr.restrained() || src.flushing)
|
||||||
return
|
// return
|
||||||
|
|
||||||
if(istype(src.loc, /turf))
|
// if(istype(src.loc, /turf))
|
||||||
usr.set_machine(src)
|
// usr.set_machine(src)
|
||||||
|
|
||||||
if(href_list["close"])
|
// if(href_list["close"])
|
||||||
usr.unset_machine()
|
// usr.unset_machine()
|
||||||
usr << browse(null, "window=disposal")
|
// usr << browse(null, "window=disposal")
|
||||||
return
|
// return
|
||||||
|
|
||||||
if(href_list["pump"])
|
// if(href_list["pump"])
|
||||||
if(text2num(href_list["pump"]))
|
// if(text2num(href_list["pump"]))
|
||||||
mode = 1
|
// mode = 1
|
||||||
else
|
// else
|
||||||
mode = 0
|
// mode = 0
|
||||||
update()
|
// update()
|
||||||
|
|
||||||
if(!isAI(usr))
|
// if(!isAI(usr))
|
||||||
if(href_list["handle"])
|
// if(href_list["handle"])
|
||||||
flush = text2num(href_list["handle"])
|
// flush = text2num(href_list["handle"])
|
||||||
update()
|
// update()
|
||||||
|
|
||||||
if(href_list["eject"])
|
// if(href_list["eject"])
|
||||||
eject()
|
// eject()
|
||||||
else
|
// else
|
||||||
usr << browse(null, "window=disposal")
|
// usr << browse(null, "window=disposal")
|
||||||
usr.unset_machine()
|
// usr.unset_machine()
|
||||||
return
|
// return
|
||||||
return
|
// return
|
||||||
|
|
||||||
// eject the contents of the disposal unit
|
// eject the contents of the disposal unit
|
||||||
/obj/machinery/disposal/proc/eject()
|
/obj/machinery/disposal/proc/eject()
|
||||||
|
|||||||
191
code/modules/tgui/external.dm
Normal file
191
code/modules/tgui/external.dm
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
/**
|
||||||
|
* tgui external
|
||||||
|
*
|
||||||
|
* Contains all external tgui declarations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public
|
||||||
|
*
|
||||||
|
* Used to open and update UIs.
|
||||||
|
* If this proc is not implemented properly, the UI will not update correctly.
|
||||||
|
*
|
||||||
|
* required user mob The mob who opened/is using the UI.
|
||||||
|
* optional ui datum/tgui The UI to be updated, if it exists.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/datum/proc/tgui_interact(mob/user, datum/tgui/ui = null)
|
||||||
|
return FALSE // Not implemented.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public
|
||||||
|
*
|
||||||
|
* Data to be sent to the UI.
|
||||||
|
* This must be implemented for a UI to work.
|
||||||
|
*
|
||||||
|
* required user mob The mob interacting with the UI.
|
||||||
|
*
|
||||||
|
* return list Data to be sent to the UI.
|
||||||
|
*/
|
||||||
|
/datum/proc/tgui_data(mob/user)
|
||||||
|
return list() // Not implemented.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public
|
||||||
|
*
|
||||||
|
* Static Data to be sent to the UI.
|
||||||
|
* Static data differs from normal data in that it's large data that should be
|
||||||
|
* sent infrequently. This is implemented optionally for heavy uis that would
|
||||||
|
* be sending a lot of redundant data frequently. Gets squished into one
|
||||||
|
* object on the frontend side, but the static part is cached.
|
||||||
|
*
|
||||||
|
* required user mob The mob interacting with the UI.
|
||||||
|
*
|
||||||
|
* return list Statuic Data to be sent to the UI.
|
||||||
|
*/
|
||||||
|
/datum/proc/tgui_static_data(mob/user)
|
||||||
|
return list()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public
|
||||||
|
*
|
||||||
|
* Forces an update on static data. Should be done manually whenever something
|
||||||
|
* happens to change static data.
|
||||||
|
*
|
||||||
|
* required user the mob currently interacting with the ui
|
||||||
|
* optional ui ui to be updated
|
||||||
|
*/
|
||||||
|
/datum/proc/update_tgui_static_data(mob/user, datum/tgui/ui)
|
||||||
|
ui = SStgui.try_update_ui(user, src, ui)
|
||||||
|
// If there was no ui to update, there's no static data to update either.
|
||||||
|
if(!ui)
|
||||||
|
ui = SStgui.get_open_ui(user, src)
|
||||||
|
if(ui)
|
||||||
|
ui.send_full_update()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public
|
||||||
|
*
|
||||||
|
* Called on a UI when the UI receieves a href.
|
||||||
|
* Think of this as Topic().
|
||||||
|
*
|
||||||
|
* required action string The action/button that has been invoked by the user.
|
||||||
|
* required params list A list of parameters attached to the button.
|
||||||
|
*
|
||||||
|
* return bool If the UI should be updated or not.
|
||||||
|
*/
|
||||||
|
/datum/proc/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||||
|
// If UI is not interactive or usr calling Topic is not the UI user, bail.
|
||||||
|
if(!ui || ui.status != STATUS_INTERACTIVE)
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public
|
||||||
|
*
|
||||||
|
* Called on an object when a tgui object is being created, allowing you to
|
||||||
|
* push various assets to tgui, for examples spritesheets.
|
||||||
|
*
|
||||||
|
* return list List of asset datums or file paths.
|
||||||
|
*/
|
||||||
|
/datum/proc/ui_assets(mob/user)
|
||||||
|
return list()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private
|
||||||
|
*
|
||||||
|
* The UI's host object (usually src_object).
|
||||||
|
* This allows modules/datums to have the UI attached to them,
|
||||||
|
* and be a part of another object.
|
||||||
|
*/
|
||||||
|
/datum/proc/tgui_host(mob/user)
|
||||||
|
return src // Default src.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private
|
||||||
|
*
|
||||||
|
* The UI's state controller to be used for created uis
|
||||||
|
* This is a proc over a var for memory reasons
|
||||||
|
*/
|
||||||
|
/datum/proc/tgui_state(mob/user)
|
||||||
|
return GLOB.tgui_default_state
|
||||||
|
|
||||||
|
/**
|
||||||
|
* global
|
||||||
|
*
|
||||||
|
* Associative list of JSON-encoded shared states that were set by
|
||||||
|
* tgui clients.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/datum/var/list/tgui_shared_states
|
||||||
|
|
||||||
|
/**
|
||||||
|
* global
|
||||||
|
*
|
||||||
|
* Tracks open UIs for a user.
|
||||||
|
*/
|
||||||
|
/mob/var/list/tgui_open_uis = list()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* global
|
||||||
|
*
|
||||||
|
* Tracks open windows for a user.
|
||||||
|
*/
|
||||||
|
/client/var/list/tgui_windows = list()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public
|
||||||
|
*
|
||||||
|
* Called on a UI's object when the UI is closed, not to be confused with
|
||||||
|
* client/verb/uiclose(), which closes the ui window
|
||||||
|
*/
|
||||||
|
/datum/proc/tgui_close(mob/user)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* verb
|
||||||
|
*
|
||||||
|
* Called by UIs when they are closed.
|
||||||
|
* Must be a verb so winset() can call it.
|
||||||
|
*
|
||||||
|
* required uiref ref The UI that was closed.
|
||||||
|
*/
|
||||||
|
/client/verb/tguiclose(window_id as text)
|
||||||
|
// Name the verb, and hide it from the user panel.
|
||||||
|
set name = "uiclose"
|
||||||
|
set hidden = TRUE
|
||||||
|
|
||||||
|
var/mob/user = src && src.mob
|
||||||
|
if(!user)
|
||||||
|
return
|
||||||
|
// Close all tgui datums based on window_id.
|
||||||
|
SStgui.force_close_window(user, window_id)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Middleware for /client/Topic.
|
||||||
|
*
|
||||||
|
* return bool Whether the topic is passed (TRUE), or cancelled (FALSE).
|
||||||
|
*/
|
||||||
|
/proc/tgui_Topic(href_list)
|
||||||
|
// Skip non-tgui topics
|
||||||
|
if(!href_list["tgui"])
|
||||||
|
return TRUE
|
||||||
|
var/type = href_list["type"]
|
||||||
|
// Unconditionally collect tgui logs
|
||||||
|
if(type == "log")
|
||||||
|
log_tgui(usr, href_list["message"])
|
||||||
|
// Locate window
|
||||||
|
var/window_id = href_list["window_id"]
|
||||||
|
var/datum/tgui_window/window
|
||||||
|
if(window_id)
|
||||||
|
window = usr.client.tgui_windows[window_id]
|
||||||
|
if(!window)
|
||||||
|
log_tgui(usr, "Error: Couldn't find the window datum, force closing.")
|
||||||
|
SStgui.force_close_window(usr, window_id)
|
||||||
|
return FALSE
|
||||||
|
// Decode payload
|
||||||
|
var/payload
|
||||||
|
if(href_list["payload"])
|
||||||
|
payload = json_decode(href_list["payload"])
|
||||||
|
// Pass message to window
|
||||||
|
if(window)
|
||||||
|
window.on_message(type, payload, href_list)
|
||||||
|
return FALSE
|
||||||
46
code/modules/tgui/modules/_base.dm
Normal file
46
code/modules/tgui/modules/_base.dm
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
TGUI MODULES
|
||||||
|
|
||||||
|
This allows for datum-based TGUIs that can be hooked into objects.
|
||||||
|
This is useful for things such as the power monitor, which needs to exist on a physical console in the world, but also as a virtual device the AI can use
|
||||||
|
|
||||||
|
Code is pretty much ripped verbatim from nano modules, but with un-needed stuff removed
|
||||||
|
*/
|
||||||
|
/datum/tgui_module
|
||||||
|
var/name
|
||||||
|
var/datum/host
|
||||||
|
var/list/using_access
|
||||||
|
|
||||||
|
var/tgui_id
|
||||||
|
|
||||||
|
/datum/tgui_module/New(var/host)
|
||||||
|
src.host = host
|
||||||
|
|
||||||
|
/datum/tgui_module/tgui_host()
|
||||||
|
return host ? host : src
|
||||||
|
|
||||||
|
/datum/tgui_module/tgui_close(mob/user)
|
||||||
|
if(host)
|
||||||
|
host.tgui_close(user)
|
||||||
|
|
||||||
|
/datum/tgui_module/proc/check_access(mob/user, access)
|
||||||
|
if(!access)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
if(using_access)
|
||||||
|
if(access in using_access)
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if(!istype(user))
|
||||||
|
return 0
|
||||||
|
|
||||||
|
var/obj/item/weapon/card/id/I = user.GetIdCard()
|
||||||
|
if(!I)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if(access in I.access)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
return 0
|
||||||
295
code/modules/tgui/modules/camera.dm
Normal file
295
code/modules/tgui/modules/camera.dm
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
/datum/tgui_module/camera
|
||||||
|
name = "Security Cameras"
|
||||||
|
tgui_id = "CameraConsole"
|
||||||
|
|
||||||
|
var/access_based = FALSE
|
||||||
|
var/list/network = list()
|
||||||
|
var/list/additional_networks = list()
|
||||||
|
|
||||||
|
var/obj/machinery/camera/active_camera
|
||||||
|
var/list/concurrent_users = list()
|
||||||
|
|
||||||
|
// Stuff needed to render the map
|
||||||
|
var/map_name
|
||||||
|
var/const/default_map_size = 15
|
||||||
|
var/obj/screen/map_view/cam_screen
|
||||||
|
/// All the plane masters that need to be applied.
|
||||||
|
var/list/cam_plane_masters
|
||||||
|
var/obj/screen/background/cam_background
|
||||||
|
var/obj/screen/background/cam_foreground
|
||||||
|
var/obj/screen/skybox/local_skybox
|
||||||
|
// Needed for moving camera support
|
||||||
|
var/camera_diff_x = -1
|
||||||
|
var/camera_diff_y = -1
|
||||||
|
var/camera_diff_z = -1
|
||||||
|
|
||||||
|
/datum/tgui_module/camera/New(host, list/network_computer)
|
||||||
|
. = ..()
|
||||||
|
if(!LAZYLEN(network_computer))
|
||||||
|
access_based = TRUE
|
||||||
|
else
|
||||||
|
network = network_computer
|
||||||
|
map_name = "camera_console_[REF(src)]_map"
|
||||||
|
// Initialize map objects
|
||||||
|
cam_screen = new
|
||||||
|
cam_screen.name = "screen"
|
||||||
|
cam_screen.assigned_map = map_name
|
||||||
|
cam_screen.del_on_map_removal = FALSE
|
||||||
|
cam_screen.screen_loc = "[map_name]:1,1"
|
||||||
|
cam_plane_masters = list()
|
||||||
|
|
||||||
|
for(var/plane in subtypesof(/obj/screen/plane_master))
|
||||||
|
var/obj/screen/instance = new plane()
|
||||||
|
instance.assigned_map = map_name
|
||||||
|
instance.del_on_map_removal = FALSE
|
||||||
|
instance.screen_loc = "[map_name]:CENTER"
|
||||||
|
cam_plane_masters += instance
|
||||||
|
|
||||||
|
local_skybox = new()
|
||||||
|
local_skybox.assigned_map = map_name
|
||||||
|
local_skybox.del_on_map_removal = FALSE
|
||||||
|
local_skybox.screen_loc = "[map_name]:CENTER,CENTER"
|
||||||
|
cam_plane_masters += local_skybox
|
||||||
|
|
||||||
|
cam_background = new
|
||||||
|
cam_background.assigned_map = map_name
|
||||||
|
cam_background.del_on_map_removal = FALSE
|
||||||
|
|
||||||
|
var/mutable_appearance/scanlines = mutable_appearance('icons/effects/static.dmi', "scanlines")
|
||||||
|
scanlines.alpha = 50
|
||||||
|
scanlines.layer = FULLSCREEN_LAYER
|
||||||
|
|
||||||
|
var/mutable_appearance/noise = mutable_appearance('icons/effects/static.dmi', "1 light")
|
||||||
|
noise.layer = FULLSCREEN_LAYER
|
||||||
|
|
||||||
|
cam_foreground = new
|
||||||
|
cam_foreground.assigned_map = map_name
|
||||||
|
cam_foreground.del_on_map_removal = FALSE
|
||||||
|
cam_foreground.plane = PLANE_FULLSCREEN
|
||||||
|
cam_foreground.add_overlay(scanlines)
|
||||||
|
cam_foreground.add_overlay(noise)
|
||||||
|
|
||||||
|
/datum/tgui_module/camera/Destroy()
|
||||||
|
qdel(cam_screen)
|
||||||
|
QDEL_LIST(cam_plane_masters)
|
||||||
|
qdel(cam_background)
|
||||||
|
qdel(cam_foreground)
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/datum/tgui_module/camera/tgui_interact(mob/user, datum/tgui/ui = null)
|
||||||
|
// Update UI
|
||||||
|
ui = SStgui.try_update_ui(user, src, ui)
|
||||||
|
// Show static if can't use the camera
|
||||||
|
if(!active_camera?.can_use())
|
||||||
|
show_camera_static()
|
||||||
|
if(!ui)
|
||||||
|
var/user_ref = REF(user)
|
||||||
|
var/is_living = isliving(user)
|
||||||
|
// Ghosts shouldn't count towards concurrent users, which produces
|
||||||
|
// an audible terminal_on click.
|
||||||
|
if(is_living)
|
||||||
|
concurrent_users += user_ref
|
||||||
|
// Turn on the console
|
||||||
|
if(length(concurrent_users) == 1 && is_living)
|
||||||
|
playsound(tgui_host(), 'sound/machines/terminal_on.ogg', 25, FALSE)
|
||||||
|
// Register map objects
|
||||||
|
user.client.register_map_obj(cam_screen)
|
||||||
|
for(var/plane in cam_plane_masters)
|
||||||
|
user.client.register_map_obj(plane)
|
||||||
|
user.client.register_map_obj(cam_background)
|
||||||
|
user.client.register_map_obj(cam_foreground)
|
||||||
|
// Open UI
|
||||||
|
ui = new(user, src, tgui_id, name)
|
||||||
|
ui.open()
|
||||||
|
|
||||||
|
/datum/tgui_module/camera/tgui_data()
|
||||||
|
var/list/data = list()
|
||||||
|
data["activeCamera"] = null
|
||||||
|
if(active_camera)
|
||||||
|
differential_check()
|
||||||
|
data["activeCamera"] = list(
|
||||||
|
name = active_camera.c_tag,
|
||||||
|
status = active_camera.status,
|
||||||
|
)
|
||||||
|
return data
|
||||||
|
|
||||||
|
/datum/tgui_module/camera/tgui_static_data(mob/user)
|
||||||
|
var/list/data = list()
|
||||||
|
data["mapRef"] = map_name
|
||||||
|
var/list/cameras = get_available_cameras(user)
|
||||||
|
data["cameras"] = list()
|
||||||
|
data["allNetworks"] = list()
|
||||||
|
for(var/i in cameras)
|
||||||
|
var/obj/machinery/camera/C = cameras[i]
|
||||||
|
data["cameras"] += list(list(
|
||||||
|
name = C.c_tag,
|
||||||
|
networks = C.network
|
||||||
|
))
|
||||||
|
data["allNetworks"] |= C.network
|
||||||
|
return data
|
||||||
|
|
||||||
|
/datum/tgui_module/camera/tgui_act(action, params)
|
||||||
|
if(..())
|
||||||
|
return
|
||||||
|
|
||||||
|
if(action == "switch_camera")
|
||||||
|
var/c_tag = params["name"]
|
||||||
|
var/list/cameras = get_available_cameras(usr)
|
||||||
|
var/obj/machinery/camera/C = cameras["[ckey(c_tag)]"]
|
||||||
|
active_camera = C
|
||||||
|
playsound(tgui_host(), get_sfx("terminal_type"), 25, FALSE)
|
||||||
|
|
||||||
|
reload_cameraview()
|
||||||
|
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
/datum/tgui_module/camera/proc/differential_check()
|
||||||
|
var/turf/T = get_turf(active_camera)
|
||||||
|
if(T)
|
||||||
|
var/new_x = T.x
|
||||||
|
var/new_y = T.y
|
||||||
|
var/new_z = T.z
|
||||||
|
if((new_x != camera_diff_x) || (new_y != camera_diff_y) || (new_z != camera_diff_z))
|
||||||
|
reload_cameraview()
|
||||||
|
|
||||||
|
/datum/tgui_module/camera/proc/reload_cameraview()
|
||||||
|
// Show static if can't use the camera
|
||||||
|
if(!active_camera?.can_use())
|
||||||
|
show_camera_static()
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
var/turf/camTurf = get_turf(active_camera)
|
||||||
|
|
||||||
|
camera_diff_x = camTurf.x
|
||||||
|
camera_diff_y = camTurf.y
|
||||||
|
camera_diff_z = camTurf.z
|
||||||
|
|
||||||
|
var/list/visible_turfs = list()
|
||||||
|
for(var/turf/T in (active_camera.isXRay() \
|
||||||
|
? range(active_camera.view_range, camTurf) \
|
||||||
|
: view(active_camera.view_range, camTurf)))
|
||||||
|
visible_turfs += T
|
||||||
|
|
||||||
|
var/list/bbox = get_bbox_of_atoms(visible_turfs)
|
||||||
|
var/size_x = bbox[3] - bbox[1] + 1
|
||||||
|
var/size_y = bbox[4] - bbox[2] + 1
|
||||||
|
|
||||||
|
cam_screen.vis_contents = visible_turfs
|
||||||
|
cam_background.icon_state = "clear"
|
||||||
|
cam_background.fill_rect(1, 1, size_x, size_y)
|
||||||
|
|
||||||
|
cam_foreground.fill_rect(1, 1, size_x, size_y)
|
||||||
|
|
||||||
|
local_skybox.cut_overlays()
|
||||||
|
local_skybox.add_overlay(SSskybox.get_skybox(get_z(camTurf)))
|
||||||
|
local_skybox.scale_to_view(size_x)
|
||||||
|
local_skybox.set_position("CENTER", "CENTER", (world.maxx>>1) - camTurf.x, (world.maxy>>1) - camTurf.y)
|
||||||
|
|
||||||
|
// Returns the list of cameras accessible from this computer
|
||||||
|
// This proc operates in two distinct ways depending on the context in which the module is created.
|
||||||
|
// It can either return a list of cameras sharing the same the internal `network` variable, or
|
||||||
|
// It can scan all station networks and determine what cameras to show based on the access of the user.
|
||||||
|
/datum/tgui_module/camera/proc/get_available_cameras(mob/user)
|
||||||
|
var/list/all_networks = list()
|
||||||
|
// Access Based
|
||||||
|
if(access_based)
|
||||||
|
for(var/network in using_map.station_networks)
|
||||||
|
if(can_access_network(user, get_camera_access(network), 1))
|
||||||
|
all_networks.Add(network)
|
||||||
|
for(var/network in using_map.secondary_networks)
|
||||||
|
if(can_access_network(user, get_camera_access(network), 0))
|
||||||
|
all_networks.Add(network)
|
||||||
|
// Network Based
|
||||||
|
else
|
||||||
|
all_networks = network.Copy()
|
||||||
|
|
||||||
|
if(additional_networks)
|
||||||
|
all_networks += additional_networks
|
||||||
|
|
||||||
|
var/list/D = list()
|
||||||
|
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||||
|
if(!C.network)
|
||||||
|
stack_trace("Camera in a cameranet has no camera network")
|
||||||
|
continue
|
||||||
|
if(!(islist(C.network)))
|
||||||
|
stack_trace("Camera in a cameranet has a non-list camera network")
|
||||||
|
continue
|
||||||
|
var/list/tempnetwork = C.network & all_networks
|
||||||
|
if(tempnetwork.len)
|
||||||
|
D["[ckey(C.c_tag)]"] = C
|
||||||
|
return D
|
||||||
|
|
||||||
|
/datum/tgui_module/camera/proc/can_access_network(mob/user, network_access, station_network = 0)
|
||||||
|
// No access passed, or 0 which is considered no access requirement. Allow it.
|
||||||
|
if(!network_access)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
if(station_network)
|
||||||
|
return check_access(user, network_access) || check_access(user, access_security) || check_access(user, access_heads)
|
||||||
|
else
|
||||||
|
return check_access(user, network_access)
|
||||||
|
|
||||||
|
/datum/tgui_module/camera/proc/show_camera_static()
|
||||||
|
cam_screen.vis_contents.Cut()
|
||||||
|
cam_background.icon_state = "scanline2"
|
||||||
|
cam_background.fill_rect(1, 1, default_map_size, default_map_size)
|
||||||
|
local_skybox.cut_overlays()
|
||||||
|
|
||||||
|
/datum/tgui_module/camera/tgui_close(mob/user)
|
||||||
|
. = ..()
|
||||||
|
var/user_ref = REF(user)
|
||||||
|
var/is_living = isliving(user)
|
||||||
|
// living creature or not, we remove you anyway.
|
||||||
|
concurrent_users -= user_ref
|
||||||
|
// Unregister map objects
|
||||||
|
if(user.client)
|
||||||
|
user.client.clear_map(map_name)
|
||||||
|
// Turn off the console
|
||||||
|
if(length(concurrent_users) == 0 && is_living)
|
||||||
|
active_camera = null
|
||||||
|
playsound(tgui_host(), 'sound/machines/terminal_off.ogg', 25, FALSE)
|
||||||
|
|
||||||
|
// NTOS Version
|
||||||
|
// Please note, this isn't a very good replacement for converting modular computers 100% to TGUI
|
||||||
|
// If/when that is done, just move all the PC_ specific data and stuff to the modular computers themselves
|
||||||
|
// instead of copying this approach here.
|
||||||
|
/datum/tgui_module/camera/ntos
|
||||||
|
tgui_id = "NtosCameraConsole"
|
||||||
|
|
||||||
|
/datum/tgui_module/camera/ntos/tgui_state()
|
||||||
|
return GLOB.tgui_ntos_state
|
||||||
|
|
||||||
|
/datum/tgui_module/camera/ntos/tgui_static_data()
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
var/datum/computer_file/program/host = tgui_host()
|
||||||
|
if(istype(host) && host.computer)
|
||||||
|
. += host.computer.get_header_data()
|
||||||
|
|
||||||
|
/datum/tgui_module/camera/ntos/tgui_act(action, params)
|
||||||
|
if(..())
|
||||||
|
return
|
||||||
|
|
||||||
|
var/datum/computer_file/program/host = tgui_host()
|
||||||
|
if(istype(host) && host.computer)
|
||||||
|
if(action == "PC_exit")
|
||||||
|
host.computer.kill_program()
|
||||||
|
return TRUE
|
||||||
|
if(action == "PC_shutdown")
|
||||||
|
host.computer.shutdown_computer()
|
||||||
|
return TRUE
|
||||||
|
if(action == "PC_minimize")
|
||||||
|
host.computer.minimize_program(usr)
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
// ERT Version provides some additional networks.
|
||||||
|
/datum/tgui_module/camera/ntos/ert
|
||||||
|
additional_networks = list(NETWORK_ERT, NETWORK_CRESCENT)
|
||||||
|
|
||||||
|
// Hacked version also provides some additional networks,
|
||||||
|
// but we want it to show *all* the networks 24/7, so we convert it into a non-access-based UI.
|
||||||
|
/datum/tgui_module/camera/ntos/hacked
|
||||||
|
additional_networks = list(NETWORK_MERCENARY, NETWORK_ERT, NETWORK_CRESCENT)
|
||||||
|
|
||||||
|
/datum/tgui_module/camera/ntos/hacked/New(host)
|
||||||
|
. = ..(host, using_map.station_networks.Copy())
|
||||||
100
code/modules/tgui/modules/crew_monitor.dm
Normal file
100
code/modules/tgui/modules/crew_monitor.dm
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/datum/tgui_module/crew_monitor
|
||||||
|
name = "Crew monitor"
|
||||||
|
tgui_id = "CrewMonitor"
|
||||||
|
|
||||||
|
/datum/tgui_module/crew_monitor/tgui_act(action, params, datum/tgui/ui)
|
||||||
|
if(..())
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
var/turf/T = get_turf(usr)
|
||||||
|
if(!T || !(T.z in using_map.player_levels))
|
||||||
|
to_chat(usr, "<span class='warning'><b>Unable to establish a connection</b>: You're too far away from the station!</span>")
|
||||||
|
return FALSE
|
||||||
|
|
||||||
|
switch(action)
|
||||||
|
if("track")
|
||||||
|
if(isAI(usr))
|
||||||
|
var/mob/living/silicon/ai/AI = usr
|
||||||
|
var/mob/living/carbon/human/H = locate(params["track"]) in mob_list
|
||||||
|
if(hassensorlevel(H, SUIT_SENSOR_TRACKING))
|
||||||
|
AI.ai_actual_track(H)
|
||||||
|
return TRUE
|
||||||
|
if("setZLevel")
|
||||||
|
ui.set_map_z_level(params["mapZLevel"])
|
||||||
|
SStgui.update_uis(src)
|
||||||
|
|
||||||
|
/datum/tgui_module/crew_monitor/tgui_interact(mob/user, datum/tgui/ui = null)
|
||||||
|
var/z = get_z(user)
|
||||||
|
var/list/map_levels = using_map.get_map_levels(z, TRUE, om_range = DEFAULT_OVERMAP_RANGE)
|
||||||
|
|
||||||
|
if(!map_levels.len)
|
||||||
|
to_chat(user, "<span class='warning'>The crew monitor doesn't seem like it'll work here.</span>")
|
||||||
|
if(ui)
|
||||||
|
ui.close()
|
||||||
|
return null
|
||||||
|
|
||||||
|
ui = SStgui.try_update_ui(user, src, ui)
|
||||||
|
if(!ui)
|
||||||
|
ui = new(user, src, tgui_id, name)
|
||||||
|
ui.autoupdate = TRUE
|
||||||
|
ui.open()
|
||||||
|
|
||||||
|
|
||||||
|
/datum/tgui_module/crew_monitor/tgui_data(mob/user, ui_key = "main", datum/tgui_state/state = GLOB.tgui_default_state)
|
||||||
|
var/data[0]
|
||||||
|
|
||||||
|
data["isAI"] = isAI(user)
|
||||||
|
|
||||||
|
var/z = get_z(user)
|
||||||
|
var/list/map_levels = uniquelist(using_map.get_map_levels(z, TRUE, om_range = DEFAULT_OVERMAP_RANGE))
|
||||||
|
data["map_levels"] = map_levels
|
||||||
|
|
||||||
|
data["crewmembers"] = list()
|
||||||
|
for(var/zlevel in map_levels)
|
||||||
|
data["crewmembers"] += crew_repository.health_data(zlevel)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
/datum/tgui_module/crew_monitor/ntos
|
||||||
|
tgui_id = "NtosCrewMonitor"
|
||||||
|
|
||||||
|
/datum/tgui_module/crew_monitor/ntos/tgui_state(mob/user)
|
||||||
|
return GLOB.tgui_ntos_state
|
||||||
|
|
||||||
|
/datum/tgui_module/crew_monitor/ntos/tgui_static_data()
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
var/datum/computer_file/program/host = tgui_host()
|
||||||
|
if(istype(host) && host.computer)
|
||||||
|
. += host.computer.get_header_data()
|
||||||
|
|
||||||
|
/datum/tgui_module/crew_monitor/ntos/tgui_act(action, params)
|
||||||
|
if(..())
|
||||||
|
return
|
||||||
|
|
||||||
|
var/datum/computer_file/program/host = tgui_host()
|
||||||
|
if(istype(host) && host.computer)
|
||||||
|
if(action == "PC_exit")
|
||||||
|
host.computer.kill_program()
|
||||||
|
return TRUE
|
||||||
|
if(action == "PC_shutdown")
|
||||||
|
host.computer.shutdown_computer()
|
||||||
|
return TRUE
|
||||||
|
if(action == "PC_minimize")
|
||||||
|
host.computer.minimize_program(usr)
|
||||||
|
return TRUE
|
||||||
|
|
||||||
|
// Subtype for glasses_state
|
||||||
|
/datum/tgui_module/crew_monitor/glasses
|
||||||
|
/datum/tgui_module/crew_monitor/glasses/tgui_state(mob/user)
|
||||||
|
return GLOB.tgui_glasses_state
|
||||||
|
|
||||||
|
// Subtype for self_state
|
||||||
|
/datum/tgui_module/crew_monitor/robot
|
||||||
|
/datum/tgui_module/crew_monitor/robot/tgui_state(mob/user)
|
||||||
|
return GLOB.tgui_self_state
|
||||||
|
|
||||||
|
// Subtype for nif_state
|
||||||
|
/datum/tgui_module/crew_monitor/nif
|
||||||
|
/datum/tgui_module/crew_monitor/nif/tgui_state(mob/user)
|
||||||
|
return GLOB.tgui_nif_state
|
||||||
125
code/modules/tgui/states.dm
Normal file
125
code/modules/tgui/states.dm
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
/**
|
||||||
|
* Base state and helpers for states. Just does some sanity checks,
|
||||||
|
* implement a proper state for in-depth checks.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public
|
||||||
|
*
|
||||||
|
* Checks the UI state for a mob.
|
||||||
|
*
|
||||||
|
* required user mob The mob who opened/is using the UI.
|
||||||
|
* required state datum/ui_state The state to check.
|
||||||
|
*
|
||||||
|
* return UI_state The state of the UI.
|
||||||
|
*/
|
||||||
|
/datum/proc/tgui_status(mob/user, datum/tgui_state/state)
|
||||||
|
var/src_object = tgui_host(user)
|
||||||
|
. = STATUS_CLOSE
|
||||||
|
if(!state)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(isobserver(user))
|
||||||
|
// // If they turn on ghost AI control, admins can always interact.
|
||||||
|
// if(user.client.advanced_admin_interaction)
|
||||||
|
// . = max(., STATUS_INTERACTIVE)
|
||||||
|
|
||||||
|
// Regular ghosts can always at least view if in range.
|
||||||
|
if(user.client)
|
||||||
|
var/clientviewlist = getviewsize(user.client.view)
|
||||||
|
if(get_dist(src_object, user) < max(clientviewlist[1], clientviewlist[2]))
|
||||||
|
. = max(., STATUS_UPDATE)
|
||||||
|
|
||||||
|
// Check if the state allows interaction
|
||||||
|
var/result = state.can_use_topic(src_object, user)
|
||||||
|
. = max(., result)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* private
|
||||||
|
*
|
||||||
|
* Checks if a user can use src_object's UI, and returns the state.
|
||||||
|
* Can call a mob proc, which allows overrides for each mob.
|
||||||
|
*
|
||||||
|
* required src_object datum The object/datum which owns the UI.
|
||||||
|
* required user mob The mob who opened/is using the UI.
|
||||||
|
*
|
||||||
|
* return UI_state The state of the UI.
|
||||||
|
*/
|
||||||
|
/datum/tgui_state/proc/can_use_topic(src_object, mob/user)
|
||||||
|
// Don't allow interaction by default.
|
||||||
|
return STATUS_CLOSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public
|
||||||
|
*
|
||||||
|
* Standard interaction/sanity checks. Different mob types may have overrides.
|
||||||
|
*
|
||||||
|
* return UI_state The state of the UI.
|
||||||
|
*/
|
||||||
|
/mob/proc/shared_tgui_interaction(src_object)
|
||||||
|
// Close UIs if mindless.
|
||||||
|
if(!client)
|
||||||
|
return STATUS_CLOSE
|
||||||
|
// Disable UIs if unconcious.
|
||||||
|
else if(stat)
|
||||||
|
return STATUS_DISABLED
|
||||||
|
// Update UIs if incapicitated but concious.
|
||||||
|
else if(incapacitated())
|
||||||
|
return STATUS_UPDATE
|
||||||
|
return STATUS_INTERACTIVE
|
||||||
|
|
||||||
|
/mob/living/silicon/ai/shared_tgui_interaction(src_object)
|
||||||
|
// Disable UIs if the AI is unpowered.
|
||||||
|
if(lacks_power())
|
||||||
|
return STATUS_DISABLED
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/mob/living/silicon/robot/shared_tgui_interaction(src_object)
|
||||||
|
// Disable UIs if the Borg is unpowered or locked.
|
||||||
|
if(!cell || cell.charge <= 0 || lockcharge)
|
||||||
|
return STATUS_DISABLED
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public
|
||||||
|
*
|
||||||
|
* Check the distance for a living mob.
|
||||||
|
* Really only used for checks outside the context of a mob.
|
||||||
|
* Otherwise, use shared_living_ui_distance().
|
||||||
|
*
|
||||||
|
* required src_object The object which owns the UI.
|
||||||
|
* required user mob The mob who opened/is using the UI.
|
||||||
|
*
|
||||||
|
* return UI_state The state of the UI.
|
||||||
|
*/
|
||||||
|
/atom/proc/contents_tgui_distance(src_object, mob/living/user)
|
||||||
|
// Just call this mob's check.
|
||||||
|
return user.shared_living_tgui_distance(src_object)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* public
|
||||||
|
*
|
||||||
|
* Distance versus interaction check.
|
||||||
|
*
|
||||||
|
* required src_object atom/movable The object which owns the UI.
|
||||||
|
*
|
||||||
|
* return UI_state The state of the UI.
|
||||||
|
*/
|
||||||
|
/mob/living/proc/shared_living_tgui_distance(atom/movable/src_object, viewcheck = TRUE)
|
||||||
|
// If the object is obscured, close it.
|
||||||
|
if(viewcheck && !(src_object in view(src)))
|
||||||
|
return STATUS_CLOSE
|
||||||
|
|
||||||
|
var/dist = get_dist(src_object, src)
|
||||||
|
if(dist <= 1) // Open and interact if 1-0 tiles away.
|
||||||
|
return STATUS_INTERACTIVE
|
||||||
|
else if(dist <= 2) // View only if 2-3 tiles away.
|
||||||
|
return STATUS_UPDATE
|
||||||
|
else if(dist <= 5) // Disable if 5 tiles away.
|
||||||
|
return STATUS_DISABLED
|
||||||
|
return STATUS_CLOSE // Otherwise, we got nothing.
|
||||||
|
|
||||||
|
/mob/living/carbon/human/shared_living_tgui_distance(atom/movable/src_object)
|
||||||
|
if((TK in mutations) && (get_dist(src, src_object) <= 2))
|
||||||
|
return STATUS_INTERACTIVE
|
||||||
|
return ..()
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user