Fixes merge conflicts again.

This commit is contained in:
Neerti
2020-03-28 19:06:14 -04:00
220 changed files with 18234 additions and 2788 deletions
+17
View File
@@ -0,0 +1,17 @@
SUBSYSTEM_DEF(assets)
name = "Assets"
init_order = INIT_ORDER_ASSETS
flags = SS_NO_FIRE
var/list/cache = list()
var/list/preload = list()
/datum/controller/subsystem/assets/Initialize(timeofday)
for(var/type in typesof(/datum/asset) - list(/datum/asset, /datum/asset/simple))
var/datum/asset/A = new type()
A.register()
preload = cache.Copy() //don't preload assets generated during the round
for(var/client/C in GLOB.clients)
addtimer(CALLBACK(GLOBAL_PROC, .proc/getFilesSlow, C, preload, FALSE), 10)
return ..()
+87
View File
@@ -0,0 +1,87 @@
SUBSYSTEM_DEF(chat)
name = "Chat"
flags = SS_TICKER
wait = 1 // SS_TICKER means this runs every tick
priority = FIRE_PRIORITY_CHAT
init_order = INIT_ORDER_CHAT
var/list/msg_queue = list()
/datum/controller/subsystem/chat/Initialize(timeofday)
init_vchat()
..()
/datum/controller/subsystem/chat/fire()
var/list/msg_queue = src.msg_queue // Local variable for sanic speed.
for(var/i in msg_queue)
var/client/C = i
var/list/messages = msg_queue[C]
msg_queue -= C
if (C)
C << output(jsEncode(messages), "htmloutput:putmessage")
if(MC_TICK_CHECK)
return
/datum/controller/subsystem/chat/stat_entry()
..("C:[msg_queue.len]")
/datum/controller/subsystem/chat/proc/queue(target, time, message, handle_whitespace = TRUE)
if(!target || !message)
return
if(!istext(message))
stack_trace("to_chat called with invalid input type")
return
// Currently to_chat(world, ...) gets sent individually to each client. Consider.
if(target == world)
target = GLOB.clients
//Some macros remain in the string even after parsing and fuck up the eventual output
var/original_message = message
message = replacetext(message, "\n", "<br>")
message = replacetext(message, "\improper", "")
message = replacetext(message, "\proper", "")
if(isnull(time))
time = world.time
var/list/messageStruct = list("time" = time, "message" = message);
if(islist(target))
for(var/I in target)
var/client/C = CLIENT_FROM_VAR(I) //Grab us a client if possible
if(!C)
return
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
//Send it to the old style output window.
DIRECT_OUTPUT(C, original_message)
continue
// // Client still loading, put their messages in a queue - Actually don't, logged already in database.
// if(!C.chatOutput.loaded && C.chatOutput.message_queue && islist(C.chatOutput.message_queue))
// C.chatOutput.message_queue[++C.chatOutput.message_queue.len] = messageStruct
// continue
LAZYINITLIST(msg_queue[C])
msg_queue[C][++msg_queue[C].len] = messageStruct
else
var/client/C = CLIENT_FROM_VAR(target) //Grab us a client if possible
if(!C)
return
if(!C?.chatOutput || C.chatOutput.broken) //A player who hasn't updated his skin file.
DIRECT_OUTPUT(C, original_message)
return
// // Client still loading, put their messages in a queue - Actually don't, logged already in database.
// if(!C.chatOutput.loaded && C.chatOutput.message_queue && islist(C.chatOutput.message_queue))
// C.chatOutput.message_queue[++C.chatOutput.message_queue.len] = messageStruct
// return
LAZYINITLIST(msg_queue[C])
msg_queue[C][++msg_queue[C].len] = messageStruct
+1 -32
View File
@@ -1,41 +1,17 @@
SUBSYSTEM_DEF(nanoui)
name = "NanoUI"
wait = 5
flags = SS_NO_INIT
// a list of current open /nanoui UIs, grouped by src_object and ui_key
var/list/open_uis = list()
// a list of current open /nanoui UIs, not grouped, for use in processing
var/list/processing_uis = list()
// a list of asset filenames which are to be sent to the client on user logon
var/list/asset_files = list()
/datum/controller/subsystem/nanoui/Initialize()
var/list/nano_asset_dirs = list(\
"nano/css/",\
"nano/images/",\
"nano/images/status_icons/",\
"nano/images/modular_computers/",\
"nano/js/",\
"nano/templates/"\
)
var/list/filenames = null
for (var/path in nano_asset_dirs)
filenames = flist(path)
for(var/filename in filenames)
if(copytext(filename, length(filename)) != "/") // filenames which end in "/" are actually directories, which we want to ignore
if(fexists(path + filename))
asset_files.Add(fcopy_rsc(path + filename)) // add this file to asset_files for sending to clients when they connect
.=..()
for(var/i in GLOB.clients)
send_resources(i)
/datum/controller/subsystem/nanoui/Recover()
if(SSnanoui.open_uis)
open_uis |= SSnanoui.open_uis
if(SSnanoui.processing_uis)
processing_uis |= SSnanoui.processing_uis
if(SSnanoui.asset_files)
asset_files |= SSnanoui.asset_files
/datum/controller/subsystem/nanoui/stat_entry()
return ..("[processing_uis.len] UIs")
@@ -44,10 +20,3 @@ SUBSYSTEM_DEF(nanoui)
for(var/thing in processing_uis)
var/datum/nanoui/UI = thing
UI.process()
//Sends asset files to a client, called on client/New()
/datum/controller/subsystem/nanoui/proc/send_resources(client)
if(!subsystem_initialized)
return
for(var/file in asset_files)
client << browse_rsc(file) // send the file to the client
+40 -44
View File
@@ -15,7 +15,6 @@ SUBSYSTEM_DEF(shuttles)
flags = SS_KEEP_TIMING|SS_NO_TICK_CHECK
runlevels = RUNLEVEL_GAME|RUNLEVEL_POSTGAME
// TODO OVERMAP - These two are unused for now
var/overmap_halted = FALSE // Whether ships can move on the overmap; used for adminbus.
var/list/ships = list() // List of all ships.
@@ -99,14 +98,13 @@ SUBSYSTEM_DEF(shuttles)
registered_shuttle_landmarks[shuttle_landmark_tag] = shuttle_landmark
last_landmark_registration_time = world.time
// TODO - Uncomment once overmap sectors are ported
//var/obj/effect/overmap/visitable/O = landmarks_still_needed[shuttle_landmark_tag]
//if(O) //These need to be added to sectors, which we handle.
// try_add_landmark_tag(shuttle_landmark_tag, O)
// landmarks_still_needed -= shuttle_landmark_tag
//else if(istype(shuttle_landmark, /obj/effect/shuttle_landmark/automatic)) //These find their sector automatically
// O = map_sectors["[shuttle_landmark.z]"]
// O ? O.add_landmark(shuttle_landmark, shuttle_landmark.shuttle_restricted) : (landmarks_awaiting_sector += shuttle_landmark)
var/obj/effect/overmap/visitable/O = landmarks_still_needed[shuttle_landmark_tag]
if(O) //These need to be added to sectors, which we handle.
try_add_landmark_tag(shuttle_landmark_tag, O)
landmarks_still_needed -= shuttle_landmark_tag
else if(istype(shuttle_landmark, /obj/effect/shuttle_landmark/automatic)) //These find their sector automatically
O = map_sectors["[shuttle_landmark.z]"]
O ? O.add_landmark(shuttle_landmark, shuttle_landmark.shuttle_restricted) : (landmarks_awaiting_sector += shuttle_landmark)
/datum/controller/subsystem/shuttles/proc/get_landmark(var/shuttle_landmark_tag)
return registered_shuttle_landmarks[shuttle_landmark_tag]
@@ -114,39 +112,37 @@ SUBSYSTEM_DEF(shuttles)
//Checks if the given sector's landmarks have initialized; if so, registers them with the sector, if not, marks them for assignment after they come in.
//Also adds automatic landmarks that were waiting on their sector to spawn.
/datum/controller/subsystem/shuttles/proc/initialize_sector(obj/effect/overmap/visitable/given_sector)
return // TODO - Uncomment once overmap sectors are ported
// given_sector.populate_sector_objects() // This is a late init operation that sets up the sector's map_z and does non-overmap-related init tasks.
given_sector.populate_sector_objects() // This is a late init operation that sets up the sector's map_z and does non-overmap-related init tasks.
// for(var/landmark_tag in given_sector.initial_generic_waypoints)
// if(!try_add_landmark_tag(landmark_tag, given_sector))
// landmarks_still_needed[landmark_tag] = given_sector // Landmark isn't registered yet, queue it to be added once it is.
for(var/landmark_tag in given_sector.initial_generic_waypoints)
if(!try_add_landmark_tag(landmark_tag, given_sector))
landmarks_still_needed[landmark_tag] = given_sector // Landmark isn't registered yet, queue it to be added once it is.
// for(var/shuttle_name in given_sector.initial_restricted_waypoints)
// for(var/landmark_tag in given_sector.initial_restricted_waypoints[shuttle_name])
// if(!try_add_landmark_tag(landmark_tag, given_sector))
// landmarks_still_needed[landmark_tag] = given_sector // Landmark isn't registered yet, queue it to be added once it is.
for(var/shuttle_name in given_sector.initial_restricted_waypoints)
for(var/landmark_tag in given_sector.initial_restricted_waypoints[shuttle_name])
if(!try_add_landmark_tag(landmark_tag, given_sector))
landmarks_still_needed[landmark_tag] = given_sector // Landmark isn't registered yet, queue it to be added once it is.
// var/landmarks_to_check = landmarks_awaiting_sector.Copy()
// for(var/thing in landmarks_to_check)
// var/obj/effect/shuttle_landmark/automatic/landmark = thing
// if(landmark.z in given_sector.map_z)
// given_sector.add_landmark(landmark, landmark.shuttle_restricted)
// landmarks_awaiting_sector -= landmark
var/landmarks_to_check = landmarks_awaiting_sector.Copy()
for(var/thing in landmarks_to_check)
var/obj/effect/shuttle_landmark/automatic/landmark = thing
if(landmark.z in given_sector.map_z)
given_sector.add_landmark(landmark, landmark.shuttle_restricted)
landmarks_awaiting_sector -= landmark
// TODO - Uncomment once overmap sectors are ported
//// Attempts to add a landmark instance with a sector (returns false if landmark isn't registered yet)
///datum/controller/subsystem/shuttles/proc/try_add_landmark_tag(landmark_tag, obj/effect/overmap/visitable/given_sector)
// var/obj/effect/shuttle_landmark/landmark = get_landmark(landmark_tag)
// if(!landmark)
// return
// Attempts to add a landmark instance with a sector (returns false if landmark isn't registered yet)
/datum/controller/subsystem/shuttles/proc/try_add_landmark_tag(landmark_tag, obj/effect/overmap/visitable/given_sector)
var/obj/effect/shuttle_landmark/landmark = get_landmark(landmark_tag)
if(!landmark)
return
// if(landmark.landmark_tag in given_sector.initial_generic_waypoints)
// given_sector.add_landmark(landmark)
// . = 1
// for(var/shuttle_name in given_sector.initial_restricted_waypoints)
// if(landmark.landmark_tag in given_sector.initial_restricted_waypoints[shuttle_name])
// given_sector.add_landmark(landmark, shuttle_name)
// . = 1
if(landmark.landmark_tag in given_sector.initial_generic_waypoints)
given_sector.add_landmark(landmark)
. = 1
for(var/shuttle_name in given_sector.initial_restricted_waypoints)
if(landmark.landmark_tag in given_sector.initial_restricted_waypoints[shuttle_name])
given_sector.add_landmark(landmark, shuttle_name)
. = 1
/datum/controller/subsystem/shuttles/proc/initialize_shuttle(var/shuttle_type)
var/datum/shuttle/shuttle = shuttle_type
@@ -170,13 +166,13 @@ SUBSYSTEM_DEF(shuttles)
error("Shuttle [S] was unable to find mothership [mothership]!")
// Admin command to halt/resume overmap
// /datum/controller/subsystem/shuttles/proc/toggle_overmap(new_setting)
// if(overmap_halted == new_setting)
// return
// overmap_halted = !overmap_halted
// for(var/ship in ships)
// var/obj/effect/overmap/visitable/ship/ship_effect = ship
// overmap_halted ? ship_effect.halt() : ship_effect.unhalt()
/datum/controller/subsystem/shuttles/proc/toggle_overmap(new_setting)
if(overmap_halted == new_setting)
return
overmap_halted = !overmap_halted
for(var/ship in ships)
var/obj/effect/overmap/visitable/ship/ship_effect = ship
overmap_halted ? ship_effect.halt() : ship_effect.unhalt()
/datum/controller/subsystem/shuttles/stat_entry()
..("Shuttles:[process_shuttles.len]/[shuttles.len], Ships:[ships.len], L:[registered_shuttle_landmarks.len][overmap_halted ? ", HALT" : ""]")
+82
View File
@@ -0,0 +1,82 @@
//Exists to handle a few global variables that change enough to justify this. Technically a parallax, but it exhibits a skybox effect.
SUBSYSTEM_DEF(skybox)
name = "Space skybox"
init_order = INIT_ORDER_SKYBOX
flags = SS_NO_FIRE
var/list/skybox_cache = list()
/datum/controller/subsystem/skybox/Initialize()
. = ..()
/datum/controller/subsystem/skybox/Recover()
skybox_cache = SSskybox.skybox_cache
/datum/controller/subsystem/skybox/proc/get_skybox(z)
if(!skybox_cache["[z]"])
skybox_cache["[z]"] = generate_skybox(z)
if(global.using_map.use_overmap)
var/obj/effect/overmap/visitable/O = map_sectors["[z]"]
if(istype(O))
for(var/zlevel in O.map_z)
skybox_cache["[zlevel]"] = skybox_cache["[z]"]
return skybox_cache["[z]"]
/datum/controller/subsystem/skybox/proc/generate_skybox(z)
var/datum/skybox_settings/settings = global.using_map.get_skybox_datum(z)
var/image/res = image(settings.icon)
res.appearance_flags = KEEP_TOGETHER
var/image/base = image(settings.icon, settings.icon_state)
base.color = settings.color
if(settings.use_stars)
var/image/stars = image(settings.icon, settings.star_state)
stars.appearance_flags = RESET_COLOR
base.overlays += stars
res.overlays += base
if(global.using_map.use_overmap && settings.use_overmap_details)
var/obj/effect/overmap/visitable/O = map_sectors["[z]"]
if(istype(O))
var/image/overmap = image(settings.icon)
overmap.overlays += O.generate_skybox()
for(var/obj/effect/overmap/visitable/other in O.loc)
if(other != O)
overmap.overlays += other.get_skybox_representation()
overmap.appearance_flags = RESET_COLOR
res.overlays += overmap
// TODO - Allow events to apply custom overlays to skybox! (Awesome!)
//for(var/datum/event/E in SSevent.active_events)
// if(E.has_skybox_image && E.isRunning && (z in E.affecting_z))
// res.overlays += E.get_skybox_image()
return res
/datum/controller/subsystem/skybox/proc/rebuild_skyboxes(var/list/zlevels)
for(var/z in zlevels)
skybox_cache["[z]"] = generate_skybox(z)
for(var/client/C)
C.update_skybox(1)
// Settings datum that maps can override to play with their skyboxes
/datum/skybox_settings
var/icon = 'icons/skybox/skybox.dmi' //Path to our background. Lets us use anything we damn well please. Skyboxes need to be 736x736
var/icon_state = "dyable"
var/color
var/random_color = FALSE
var/use_stars = TRUE
var/star_icon = 'icons/skybox/skybox.dmi'
var/star_state = "stars"
var/use_overmap_details = TRUE //Do we try to draw overmap visitables in our sector on the map?
/datum/skybox_settings/New()
..()
if(random_color)
color = rgb(rand(0,255), rand(0,255), rand(0,255))
+395
View File
@@ -0,0 +1,395 @@
//Supply packs are in /code/datums/supplypacks
//Computers are in /code/game/machinery/computer/supply.dm
SUBSYSTEM_DEF(supply)
name = "Supply"
wait = 20 SECONDS
priority = FIRE_PRIORITY_SUPPLY
//Initializes at default time
flags = SS_NO_TICK_CHECK
//supply points
var/points = 50
var/points_per_process = 1.0 // Processes every 20 seconds, so this is 3 per minute
var/points_per_slip = 2
var/points_per_money = 0.02 // 1 point for $50
//control
var/ordernum
var/list/shoppinglist = list() // Approved orders
var/list/supply_pack = list() // All supply packs
var/list/exported_crates = list() // Crates sent from the station
var/list/order_history = list() // History of orders, showing edits made by users
var/list/adm_order_history = list() // Complete history of all orders, for admin use
var/list/adm_export_history = list() // Complete history of all crates sent back on the shuttle, for admin use
//shuttle movement
var/movetime = 1200
var/datum/shuttle/autodock/ferry/supply/shuttle
var/list/material_points_conversion = list( // Any materials not named in this list are worth 0 points
"phoron" = 5,
"platinum" = 5
)
/datum/controller/subsystem/supply/Initialize()
ordernum = rand(1,9000)
// build master supply list
for(var/typepath in subtypesof(/datum/supply_pack))
var/datum/supply_pack/P = new typepath()
if(P.name)
supply_pack[P.name] = P
else
qdel(P)
// TODO - Auto-build material_points_conversion from material datums
. = ..()
// Supply shuttle ticker - handles supply point regeneration. Just add points over time.
/datum/controller/subsystem/supply/fire()
points += points_per_process
/datum/controller/subsystem/supply/stat_entry()
..("Points: [points]")
//To stop things being sent to CentCom which should not be sent to centcomm. Recursively checks for these types.
/datum/controller/subsystem/supply/proc/forbidden_atoms_check(atom/A)
if(isliving(A))
return 1
if(istype(A,/obj/item/weapon/disk/nuclear))
return 1
if(istype(A,/obj/machinery/nuclearbomb))
return 1
if(istype(A,/obj/item/device/radio/beacon))
return 1
for(var/atom/B in A.contents)
if(.(B))
return 1
//Selling
/datum/controller/subsystem/supply/proc/sell()
// Loop over each area in the supply shuttle
for(var/area/subarea in shuttle.shuttle_area)
callHook("sell_shuttle", list(subarea));
for(var/atom/movable/MA in subarea)
if(MA.anchored)
continue
var/datum/exported_crate/EC = new /datum/exported_crate()
EC.name = "\proper[MA.name]"
EC.value = 0
EC.contents = list()
var/base_value = 0
// Must be in a crate!
if(istype(MA,/obj/structure/closet/crate))
var/obj/structure/closet/crate/CR = MA
callHook("sell_crate", list(CR, subarea))
points += CR.points_per_crate
if(CR.points_per_crate)
base_value = CR.points_per_crate
var/find_slip = 1
for(var/atom/A in CR)
EC.contents[++EC.contents.len] = list(
"object" = "\proper[A.name]",
"value" = 0,
"quantity" = 1
)
// Sell manifests
if(find_slip && istype(A,/obj/item/weapon/paper/manifest))
var/obj/item/weapon/paper/manifest/slip = A
if(!slip.is_copy && slip.stamped && slip.stamped.len) //yes, the clown stamp will work. clown is the highest authority on the station, it makes sense
points += points_per_slip
EC.contents[EC.contents.len]["value"] = points_per_slip
find_slip = 0
continue
// Sell phoron and platinum
if(istype(A, /obj/item/stack))
var/obj/item/stack/P = A
if(material_points_conversion[P.get_material_name()])
EC.contents[EC.contents.len]["value"] = P.get_amount() * material_points_conversion[P.get_material_name()]
EC.contents[EC.contents.len]["quantity"] = P.get_amount()
EC.value += EC.contents[EC.contents.len]["value"]
//Sell spacebucks
if(istype(A, /obj/item/weapon/spacecash))
var/obj/item/weapon/spacecash/cashmoney = A
EC.contents[EC.contents.len]["value"] = cashmoney.worth * points_per_money
EC.contents[EC.contents.len]["quantity"] = cashmoney.worth
EC.value += EC.contents[EC.contents.len]["value"]
// Make a log of it, but it wasn't shipped properly, and so isn't worth anything
else
EC.contents = list(
"error" = "Error: Product was improperly packaged. Payment rendered null under terms of agreement."
)
exported_crates += EC
points += EC.value
EC.value += base_value
// Duplicate the receipt for the admin-side log
var/datum/exported_crate/adm = new()
adm.name = EC.name
adm.value = EC.value
adm.contents = deepCopyList(EC.contents)
adm_export_history += adm
qdel(MA)
/datum/controller/subsystem/supply/proc/get_clear_turfs()
var/list/clear_turfs = list()
for(var/area/subarea in shuttle.shuttle_area)
for(var/turf/T in subarea)
if(T.density)
continue
var/occupied = 0
for(var/atom/A in T.contents)
if(!A.simulated)
continue
occupied = 1
break
if(!occupied)
clear_turfs += T
return clear_turfs
//Buying
/datum/controller/subsystem/supply/proc/buy()
var/list/shoppinglist = list()
for(var/datum/supply_order/SO in order_history)
if(SO.status == SUP_ORDER_APPROVED)
shoppinglist += SO
if(!shoppinglist.len)
return
var/orderedamount = shoppinglist.len
var/list/clear_turfs = get_clear_turfs()
for(var/datum/supply_order/SO in shoppinglist)
if(!clear_turfs.len)
break
var/i = rand(1,clear_turfs.len)
var/turf/pickedloc = clear_turfs[i]
clear_turfs.Cut(i,i+1)
SO.status = SUP_ORDER_SHIPPED
var/datum/supply_pack/SP = SO.object
var/obj/A = new SP.containertype(pickedloc)
A.name = "[SP.containername] [SO.comment ? "([SO.comment])":"" ]"
//supply manifest generation begin
var/obj/item/weapon/paper/manifest/slip
if(!SP.contraband)
slip = new /obj/item/weapon/paper/manifest(A)
slip.is_copy = 0
slip.info = "<h3>[command_name()] Shipping Manifest</h3><hr><br>"
slip.info +="Order #[SO.ordernum]<br>"
slip.info +="Destination: [station_name()]<br>"
slip.info +="[orderedamount] PACKAGES IN THIS SHIPMENT<br>"
slip.info +="CONTENTS:<br><ul>"
//spawn the stuff, finish generating the manifest while you're at it
if(SP.access)
if(isnum(SP.access))
A.req_access = list(SP.access)
else if(islist(SP.access) && SP.one_access)
var/list/L = SP.access // access var is a plain var, we need a list
A.req_one_access = L.Copy()
A.req_access.Cut()
else if(islist(SP.access) && !SP.one_access)
var/list/L = SP.access
A.req_access = L.Copy()
else
log_debug("<span class='danger'>Supply pack with invalid access restriction [SP.access] encountered!</span>")
var/list/contains
if(istype(SP,/datum/supply_pack/randomised))
var/datum/supply_pack/randomised/SPR = SP
contains = list()
if(SPR.contains.len)
for(var/j=1,j<=SPR.num_contained,j++)
contains += pick(SPR.contains)
else
contains = SP.contains
for(var/typepath in contains)
if(!typepath)
continue
var/number_of_items = max(1, contains[typepath])
for(var/j = 1 to number_of_items)
var/atom/B2 = new typepath(A)
if(slip)
slip.info += "<li>[B2.name]</li>" //add the item to the manifest
//manifest finalisation
if(slip)
slip.info += "</ul><br>"
slip.info += "CHECK CONTENTS AND STAMP BELOW THE LINE TO CONFIRM RECEIPT OF GOODS<hr>"
return
// Will attempt to purchase the specified order, returning TRUE on success, FALSE on failure
/datum/controller/subsystem/supply/proc/approve_order(var/datum/supply_order/O, var/mob/user)
// Not enough points to purchase the crate
if(points <= O.object.cost)
return FALSE
// Based on the current model, there shouldn't be any entries in order_history, requestlist, or shoppinglist, that aren't matched in adm_order_history
var/datum/supply_order/adm_order
for(var/datum/supply_order/temp in adm_order_history)
if(temp.ordernum == O.ordernum)
adm_order = temp
break
var/idname = "*None Provided*"
if(ishuman(user))
var/mob/living/carbon/human/H = user
idname = H.get_authentification_name()
else if(issilicon(user))
idname = user.real_name
// Update order status
O.status = SUP_ORDER_APPROVED
O.approved_by = idname
O.approved_at = stationdate2text() + " - " + stationtime2text()
// Update admin-side mirror
adm_order.status = SUP_ORDER_APPROVED
adm_order.approved_by = idname
adm_order.approved_at = stationdate2text() + " - " + stationtime2text()
// Deduct cost
points -= O.object.cost
return TRUE
// Will deny the specified order. Only useful if the order is currently requested, but available at any status
/datum/controller/subsystem/supply/proc/deny_order(var/datum/supply_order/O, var/mob/user)
// Based on the current model, there shouldn't be any entries in order_history, requestlist, or shoppinglist, that aren't matched in adm_order_history
var/datum/supply_order/adm_order
for(var/datum/supply_order/temp in adm_order_history)
if(temp.ordernum == O.ordernum)
adm_order = temp
break
var/idname = "*None Provided*"
if(ishuman(user))
var/mob/living/carbon/human/H = user
idname = H.get_authentification_name()
else if(issilicon(user))
idname = user.real_name
// Update order status
O.status = SUP_ORDER_DENIED
O.approved_by = idname
O.approved_at = stationdate2text() + " - " + stationtime2text()
// Update admin-side mirror
adm_order.status = SUP_ORDER_DENIED
adm_order.approved_by = idname
adm_order.approved_at = stationdate2text() + " - " + stationtime2text()
return
// Will deny all requested orders
/datum/controller/subsystem/supply/proc/deny_all_pending(var/mob/user)
for(var/datum/supply_order/O in order_history)
if(O.status == SUP_ORDER_REQUESTED)
deny_order(O, user)
// Will delete the specified order from the user-side list
/datum/controller/subsystem/supply/proc/delete_order(var/datum/supply_order/O, var/mob/user)
// Making sure they know what they're doing
if(alert(user, "Are you sure you want to delete this record? If it has been approved, cargo points will NOT be refunded!", "Delete Record","No","Yes") == "Yes")
if(alert(user, "Are you really sure? There is no way to recover the order once deleted.", "Delete Record", "No", "Yes") == "Yes")
log_admin("[key_name(user)] has deleted supply order \ref[O] [O] from the user-side order history.")
order_history -= O
return
// Will generate a new, requested order, for the given supply pack type
/datum/controller/subsystem/supply/proc/create_order(var/datum/supply_pack/S, var/mob/user, var/reason)
var/datum/supply_order/new_order = new()
var/datum/supply_order/adm_order = new() // Admin-recorded order must be a separate copy in memory, or user-made edits will corrupt it
var/idname = "*None Provided*"
if(ishuman(user))
var/mob/living/carbon/human/H = user
idname = H.get_authentification_name()
else if(issilicon(user))
idname = user.real_name
new_order.ordernum = ++ordernum // Ordernum is used to track the order between the playerside list of orders and the adminside list
new_order.index = new_order.ordernum // Index can be fabricated, or falsified. Ordernum is a permanent marker used to track the order
new_order.object = S
new_order.name = S.name
new_order.cost = S.cost
new_order.ordered_by = idname
new_order.comment = reason
new_order.ordered_at = stationdate2text() + " - " + stationtime2text()
new_order.status = SUP_ORDER_REQUESTED
adm_order.ordernum = new_order.ordernum
adm_order.index = new_order.index
adm_order.object = new_order.object
adm_order.name = new_order.name
adm_order.cost = new_order.cost
adm_order.ordered_by = new_order.ordered_by
adm_order.comment = new_order.comment
adm_order.ordered_at = new_order.ordered_at
adm_order.status = new_order.status
order_history += new_order
adm_order_history += adm_order
// Will delete the specified export receipt from the user-side list
/datum/controller/subsystem/supply/proc/delete_export(var/datum/exported_crate/E, var/mob/user)
// Making sure they know what they're doing
if(alert(user, "Are you sure you want to delete this record?", "Delete Record","No","Yes") == "Yes")
if(alert(user, "Are you really sure? There is no way to recover the receipt once deleted.", "Delete Record", "No", "Yes") == "Yes")
log_admin("[key_name(user)] has deleted export receipt \ref[E] [E] from the user-side export history.")
exported_crates -= E
return
// Will add an item entry to the specified export receipt on the user-side list
/datum/controller/subsystem/supply/proc/add_export_item(var/datum/exported_crate/E, var/mob/user)
var/new_name = input(user, "Name", "Please enter the name of the item.") as null|text
if(!new_name)
return
var/new_quantity = input(user, "Name", "Please enter the quantity of the item.") as null|num
if(!new_quantity)
return
var/new_value = input(user, "Name", "Please enter the value of the item.") as null|num
if(!new_value)
return
E.contents[++E.contents.len] = list(
"object" = new_name,
"quantity" = new_quantity,
"value" = new_value
)
/datum/exported_crate
var/name
var/value
var/list/contents
/datum/supply_order
var/ordernum // Unfabricatable index
var/index // Fabricatable index
var/datum/supply_pack/object = null
var/cost // Cost of the supply pack (Fabricatable) (Changes not reflected when purchasing supply packs, this is cosmetic only)
var/name // Name of the supply pack datum (Fabricatable)
var/ordered_by = null // Who requested the order
var/comment = null // What reason was given for the order
var/approved_by = null // Who approved the order
var/ordered_at // Date and time the order was requested at
var/approved_at // Date and time the order was approved at
var/status // [Requested, Accepted, Denied, Shipped]