mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-28 07:38:05 +01:00
Routine Cargo Departmental Deliveries (#61992)
About The Pull Request Document: https://hackmd.io/@bazelart/HkY-SO9VF Each department's request console is upgraded. Instead of making requests, they are only able to see crates related to their department that helps the department. They can order one for free (so not out of anyone's wallet) and it will arrive at cargo. Cargo gets the price of the ordered crate for bringing it to the department that ordered it (via an area check, of which the crate will remain locked until satisfied, emitter cracking aside). Ordering a crate puts the console on a cooldown depending on the price of the crate ordered. The time ranges from 10 minutes at the lowest value, to capped at 20 minutes at 4x the default crate's price. the price in time follows a ease in out circular function, where the time increases slowly as the time goes up, but a lot in the middle. towards the higher end it slows down again. Cargo will start with far less money, but this is countered by the new source of income. Finish Mapping it Finish tgui panel for department orders Testmerge it for balance and feedback who cares Maybe give multiple destination areas, just in case one area gets obliterated who cares! Why It's Good For The Game Cargo starts with a budget to spend on themselves, which lets them order their department rewards before doing anything. There is no inherent reward to delivering to other departments other than social expectations of filling the job, which means cargo will simply ignore deliveries and requests if there are more self-important things going on, since those deliveries both cost cargo and do not help cargo in any way Changelog cl add: replaced the request consoles in each department with department order consoles, which order for free on a cooldown. cargo gets these orders and delivers the crates, which are locked until delivery. upon delivery, cargo gets paid the value of the crate, and can then sell the crate back on the shuttle. balance: cargo doesn't start with a budget, other departments get what their budget was split up amongst them /cl
This commit is contained in:
@@ -3803,7 +3803,7 @@
|
||||
/obj/effect/turf_decal/trimline/brown/filled/line{
|
||||
dir = 10
|
||||
},
|
||||
/obj/machinery/computer/cargo/request{
|
||||
/obj/machinery/computer/department_orders/security{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
@@ -28391,8 +28391,8 @@
|
||||
"dFg" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/effect/turf_decal/bot,
|
||||
/obj/machinery/computer/cargo/request,
|
||||
/obj/effect/turf_decal/trimline/brown/filled/line,
|
||||
/obj/machinery/computer/department_orders/science,
|
||||
/turf/open/floor/iron,
|
||||
/area/science/research)
|
||||
"dFs" = (
|
||||
@@ -57959,10 +57959,10 @@
|
||||
/obj/effect/turf_decal/trimline/brown/filled/line{
|
||||
dir = 10
|
||||
},
|
||||
/obj/machinery/computer/cargo/request{
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/disposalpipe/segment{
|
||||
/obj/machinery/computer/department_orders/engineering{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
@@ -62724,7 +62724,7 @@
|
||||
/obj/effect/turf_decal/trimline/brown/filled/line{
|
||||
dir = 1
|
||||
},
|
||||
/obj/machinery/computer/cargo/request{
|
||||
/obj/machinery/computer/department_orders/service{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
@@ -98390,7 +98390,7 @@
|
||||
/obj/effect/turf_decal/trimline/brown/filled/line{
|
||||
dir = 5
|
||||
},
|
||||
/obj/machinery/computer/cargo/request{
|
||||
/obj/machinery/computer/department_orders/medical{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
|
||||
@@ -10529,11 +10529,6 @@
|
||||
/obj/effect/spawner/structure/window/reinforced,
|
||||
/turf/open/floor/plating,
|
||||
/area/tcommsat/computer)
|
||||
"bZw" = (
|
||||
/obj/structure/chair/stool/directional/east,
|
||||
/obj/effect/landmark/start/assistant,
|
||||
/turf/open/floor/iron,
|
||||
/area/commons/locker)
|
||||
"bZC" = (
|
||||
/obj/structure/chair/stool/directional/west,
|
||||
/obj/effect/turf_decal/tile/green{
|
||||
@@ -13995,12 +13990,12 @@
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
|
||||
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
|
||||
/obj/machinery/computer/cargo/request{
|
||||
dir = 1
|
||||
},
|
||||
/obj/effect/turf_decal/trimline/brown/filled/end{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/computer/department_orders/security{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
/area/security/office)
|
||||
"dhJ" = (
|
||||
@@ -29295,11 +29290,6 @@
|
||||
},
|
||||
/turf/open/floor/iron/white,
|
||||
/area/medical/medbay/central)
|
||||
"lcq" = (
|
||||
/obj/structure/chair/stool/directional/east,
|
||||
/obj/effect/landmark/start/assistant,
|
||||
/turf/open/floor/iron,
|
||||
/area/commons/dorms)
|
||||
"lcz" = (
|
||||
/obj/effect/turf_decal/tile/red/full,
|
||||
/obj/effect/turf_decal/siding/white/corner,
|
||||
@@ -30371,10 +30361,10 @@
|
||||
/turf/open/floor/iron/white,
|
||||
/area/science/lab)
|
||||
"lIj" = (
|
||||
/obj/machinery/computer/cargo/request,
|
||||
/obj/effect/turf_decal/trimline/brown/filled/end{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/computer/department_orders/medical,
|
||||
/turf/open/floor/iron,
|
||||
/area/medical/medbay/aft)
|
||||
"lIw" = (
|
||||
@@ -30647,10 +30637,6 @@
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
/area/security/office)
|
||||
"lPE" = (
|
||||
/obj/structure/chair/stool/directional/east,
|
||||
/turf/open/floor/iron,
|
||||
/area/commons/dorms)
|
||||
"lPM" = (
|
||||
/obj/structure/chair{
|
||||
dir = 1
|
||||
@@ -34640,10 +34626,6 @@
|
||||
/obj/structure/cable,
|
||||
/turf/open/floor/iron,
|
||||
/area/hallway/primary/central)
|
||||
"nQn" = (
|
||||
/obj/structure/chair/stool/directional/north,
|
||||
/turf/open/floor/iron,
|
||||
/area/security/prison)
|
||||
"nQw" = (
|
||||
/obj/effect/spawner/structure/window/reinforced,
|
||||
/obj/machinery/atmospherics/pipe/layer_manifold/dark,
|
||||
@@ -34756,10 +34738,10 @@
|
||||
/turf/open/floor/iron/dark,
|
||||
/area/science/breakroom)
|
||||
"nSm" = (
|
||||
/obj/machinery/computer/chef_order{
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
/obj/machinery/modular_computer/console/preset/cargochat/service{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plating,
|
||||
@@ -44967,10 +44949,6 @@
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
/area/ai_monitored/command/storage/eva)
|
||||
"tjn" = (
|
||||
/obj/structure/chair/stool/directional/east,
|
||||
/turf/open/floor/iron,
|
||||
/area/commons/locker)
|
||||
"tjs" = (
|
||||
/obj/structure/table,
|
||||
/obj/item/paper_bin{
|
||||
@@ -50412,9 +50390,6 @@
|
||||
/turf/open/floor/iron,
|
||||
/area/science/storage)
|
||||
"vUo" = (
|
||||
/obj/machinery/computer/cargo/request{
|
||||
dir = 1
|
||||
},
|
||||
/obj/effect/turf_decal/tile/brown{
|
||||
dir = 8
|
||||
},
|
||||
@@ -50423,6 +50398,9 @@
|
||||
},
|
||||
/obj/machinery/bounty_board/directional/south,
|
||||
/obj/machinery/light/directional/south,
|
||||
/obj/machinery/computer/department_orders/science{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
/area/science/lab)
|
||||
"vUu" = (
|
||||
@@ -50688,7 +50666,6 @@
|
||||
/turf/open/floor/iron/freezer,
|
||||
/area/command/heads_quarters/captain)
|
||||
"wbm" = (
|
||||
/obj/machinery/computer/cargo/request,
|
||||
/obj/effect/turf_decal/tile/brown,
|
||||
/obj/effect/turf_decal/tile/brown{
|
||||
dir = 4
|
||||
@@ -50699,6 +50676,7 @@
|
||||
/obj/effect/turf_decal/tile/brown{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/computer/department_orders/engineering,
|
||||
/turf/open/floor/iron/dark,
|
||||
/area/engineering/lobby)
|
||||
"wbB" = (
|
||||
@@ -51925,10 +51903,10 @@
|
||||
/turf/open/floor/iron,
|
||||
/area/service/janitor)
|
||||
"wIs" = (
|
||||
/obj/machinery/computer/cargo/request{
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
/obj/machinery/computer/department_orders/service{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plating,
|
||||
|
||||
@@ -2081,7 +2081,7 @@
|
||||
/area/maintenance/starboard)
|
||||
"ajq" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/machinery/computer/cargo/request{
|
||||
/obj/machinery/computer/department_orders/service{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/plating{
|
||||
@@ -11887,12 +11887,12 @@
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/computer/cargo/request{
|
||||
dir = 1
|
||||
},
|
||||
/obj/effect/turf_decal/trimline/brown/filled/end{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/computer/department_orders/science{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/floor/iron/dark,
|
||||
/area/science/research)
|
||||
"bgo" = (
|
||||
@@ -20972,7 +20972,7 @@
|
||||
/turf/open/floor/iron,
|
||||
/area/security/brig)
|
||||
"cmB" = (
|
||||
/obj/machinery/computer/cargo/request{
|
||||
/obj/machinery/computer/department_orders/engineering{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/floor/iron/dark,
|
||||
@@ -32669,10 +32669,10 @@
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/cable,
|
||||
/obj/machinery/computer/cargo/request{
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/obj/machinery/computer/department_orders/medical{
|
||||
dir = 8
|
||||
},
|
||||
/obj/structure/disposalpipe/segment,
|
||||
/turf/open/floor/iron/showroomfloor,
|
||||
/area/medical/medbay/central)
|
||||
"fuO" = (
|
||||
@@ -70007,12 +70007,12 @@
|
||||
/obj/effect/turf_decal/tile/neutral{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/computer/cargo/request{
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/computer/department_orders/security{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/floor/iron/dark,
|
||||
/area/security/office)
|
||||
"tas" = (
|
||||
|
||||
@@ -13896,7 +13896,7 @@
|
||||
/turf/open/floor/iron/white,
|
||||
/area/medical/surgery)
|
||||
"cXm" = (
|
||||
/obj/machinery/computer/cargo/request{
|
||||
/obj/machinery/computer/department_orders/science{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
@@ -26632,13 +26632,13 @@
|
||||
/turf/open/floor/iron,
|
||||
/area/commons/fitness/recreation)
|
||||
"hoa" = (
|
||||
/obj/machinery/computer/cargo/request,
|
||||
/obj/effect/turf_decal/trimline/brown/filled/line{
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/turf_decal/trimline/yellow/filled/warning{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/computer/department_orders/engineering,
|
||||
/turf/open/floor/iron,
|
||||
/area/engineering/break_room)
|
||||
"hoe" = (
|
||||
@@ -27385,7 +27385,7 @@
|
||||
/obj/effect/turf_decal/trimline/red/filled/warning{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/computer/cargo/request{
|
||||
/obj/machinery/computer/department_orders/security{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
@@ -38223,7 +38223,7 @@
|
||||
/area/science/misc_lab)
|
||||
"lGw" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/machinery/computer/cargo/request{
|
||||
/obj/machinery/computer/department_orders/service{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
@@ -57752,7 +57752,7 @@
|
||||
/obj/effect/turf_decal/trimline/blue/filled/line{
|
||||
dir = 1
|
||||
},
|
||||
/obj/machinery/computer/cargo/request{
|
||||
/obj/machinery/computer/department_orders/medical{
|
||||
dir = 1
|
||||
},
|
||||
/turf/open/floor/iron/dark,
|
||||
|
||||
@@ -8673,12 +8673,12 @@
|
||||
/turf/open/floor/iron/dark,
|
||||
/area/ai_monitored/turret_protected/ai_upload_foyer)
|
||||
"bmm" = (
|
||||
/obj/machinery/computer/cargo/request,
|
||||
/obj/effect/turf_decal/trimline/neutral/filled/line{
|
||||
dir = 5
|
||||
},
|
||||
/obj/machinery/airalarm/directional/north,
|
||||
/obj/machinery/light/directional/east,
|
||||
/obj/machinery/computer/department_orders/service,
|
||||
/turf/open/floor/iron,
|
||||
/area/hallway/primary/central)
|
||||
"bmz" = (
|
||||
@@ -10787,7 +10787,7 @@
|
||||
/obj/effect/turf_decal/trimline/red/filled/warning{
|
||||
dir = 6
|
||||
},
|
||||
/obj/machinery/computer/cargo/request,
|
||||
/obj/machinery/computer/department_orders/security,
|
||||
/turf/open/floor/iron,
|
||||
/area/security/office)
|
||||
"cim" = (
|
||||
@@ -50287,9 +50287,6 @@
|
||||
/turf/open/floor/plating,
|
||||
/area/ai_monitored/turret_protected/aisat/foyer)
|
||||
"rgq" = (
|
||||
/obj/machinery/computer/cargo/request{
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/trimline/brown/filled/line{
|
||||
dir = 5
|
||||
},
|
||||
@@ -50299,6 +50296,9 @@
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/computer/department_orders/engineering{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
/area/engineering/break_room)
|
||||
"rgz" = (
|
||||
@@ -54304,7 +54304,7 @@
|
||||
"sMu" = (
|
||||
/obj/effect/turf_decal/trimline/brown/filled/line,
|
||||
/obj/effect/turf_decal/trimline/blue/filled/warning,
|
||||
/obj/machinery/computer/cargo/request,
|
||||
/obj/machinery/computer/department_orders/medical,
|
||||
/turf/open/floor/iron,
|
||||
/area/medical/medbay/central)
|
||||
"sMv" = (
|
||||
@@ -67928,9 +67928,6 @@
|
||||
dir = 1;
|
||||
pixel_y = 1
|
||||
},
|
||||
/obj/machinery/computer/cargo/request{
|
||||
dir = 8
|
||||
},
|
||||
/obj/effect/turf_decal/tile/brown,
|
||||
/obj/effect/turf_decal/tile/brown{
|
||||
dir = 8
|
||||
@@ -67941,6 +67938,9 @@
|
||||
/obj/effect/turf_decal/tile/brown{
|
||||
dir = 1
|
||||
},
|
||||
/obj/machinery/computer/department_orders/science{
|
||||
dir = 8
|
||||
},
|
||||
/turf/open/floor/iron,
|
||||
/area/science/research)
|
||||
"xRY" = (
|
||||
|
||||
@@ -67,6 +67,9 @@
|
||||
///from SSsecurity_level when the security level changes : (new_level)
|
||||
#define COMSIG_SECURITY_LEVEL_CHANGED "security_level_changed"
|
||||
|
||||
///from SSshuttle when the supply shuttle starts spawning orders : ()
|
||||
#define COMSIG_SUPPLY_SHUTTLE_BUY "supply_shuttle_buy"
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// /datum signals
|
||||
@@ -940,6 +943,15 @@
|
||||
///used to interrupt insertion
|
||||
#define COMPONENT_CLOSET_INSERT_INTERRUPT (1<<0)
|
||||
|
||||
///From open: (forced)
|
||||
#define COMSIG_CLOSET_PRE_OPEN "closet_pre_open"
|
||||
#define BLOCK_OPEN (1<<0)
|
||||
///From open: (forced)
|
||||
#define COMSIG_CLOSET_POST_OPEN "closet_post_open"
|
||||
|
||||
///a deliver_first element closet was successfully delivered
|
||||
#define COMSIG_CLOSET_DELIVERED "crate_delivered"
|
||||
|
||||
///Eigenstasium
|
||||
///From base of [/datum/controller/subsystem/eigenstates/proc/use_eigenlinked_atom]: (var/target)
|
||||
#define COMSIG_EIGENSTATE_ACTIVATE "eigenstate_activate"
|
||||
|
||||
@@ -51,11 +51,15 @@ SUBSYSTEM_DEF(economy)
|
||||
var/mail_blocked = FALSE
|
||||
|
||||
/datum/controller/subsystem/economy/Initialize(timeofday)
|
||||
var/budget_to_hand_out = round(budget_pool / department_accounts.len)
|
||||
//removes cargo from the split
|
||||
var/budget_to_hand_out = round(budget_pool / department_accounts.len -1)
|
||||
if(time2text(world.timeofday, "DDD") == SUNDAY)
|
||||
mail_blocked = TRUE
|
||||
for(var/A in department_accounts)
|
||||
new /datum/bank_account/department(A, budget_to_hand_out)
|
||||
for(var/dep_id in department_accounts)
|
||||
if(dep_id == ACCOUNT_CAR) //cargo starts with NOTHING
|
||||
new /datum/bank_account/department(dep_id, 0)
|
||||
continue
|
||||
new /datum/bank_account/department(dep_id, budget_to_hand_out)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/economy/Recover()
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* # deliver first element!
|
||||
*
|
||||
* bespoke element (1 per set of specific arguments in existence) that makes crates unable to be sold UNTIL they are opened once (to where this element, and the block, are removed)
|
||||
* Used for non-cargo orders to not get turned into a quick buck
|
||||
*
|
||||
* for the future coders or just me: please convert this into a component to allow for more feedback on the crate's status (clicking when unlocked, overlays, etc)
|
||||
*/
|
||||
/datum/element/deliver_first
|
||||
element_flags = ELEMENT_DETACH | ELEMENT_BESPOKE
|
||||
id_arg_index = 2
|
||||
///typepath of the area we will be allowed to be opened in
|
||||
var/goal_area_type
|
||||
///how much is earned on delivery of the crate
|
||||
var/payment
|
||||
|
||||
/datum/element/deliver_first/Attach(datum/target, goal_area_type, payment)
|
||||
. = ..()
|
||||
if(!istype(target, /obj/structure/closet))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
src.goal_area_type = goal_area_type
|
||||
src.payment = payment
|
||||
RegisterSignal(target, COMSIG_PARENT_EXAMINE, .proc/on_examine)
|
||||
RegisterSignal(target, COMSIG_MOVABLE_MOVED, .proc/on_moved)
|
||||
RegisterSignal(target, COMSIG_ATOM_EMAG_ACT, .proc/on_emag)
|
||||
RegisterSignal(target, COMSIG_CLOSET_POST_OPEN, .proc/on_post_open)
|
||||
ADD_TRAIT(target, TRAIT_BANNED_FROM_CARGO_SHUTTLE, src)
|
||||
//registers pre_open when appropriate
|
||||
area_check(target)
|
||||
|
||||
/datum/element/deliver_first/Detach(datum/target)
|
||||
. = ..()
|
||||
REMOVE_TRAIT(target, TRAIT_BANNED_FROM_CARGO_SHUTTLE, src)
|
||||
UnregisterSignal(target, list(
|
||||
COMSIG_PARENT_EXAMINE,
|
||||
COMSIG_MOVABLE_MOVED,
|
||||
COMSIG_ATOM_EMAG_ACT,
|
||||
COMSIG_CLOSET_PRE_OPEN,
|
||||
COMSIG_CLOSET_POST_OPEN,
|
||||
))
|
||||
|
||||
///signal sent from examining target
|
||||
/datum/element/deliver_first/proc/on_examine(obj/structure/closet/target, mob/user, list/examine_list)
|
||||
SIGNAL_HANDLER
|
||||
examine_list += span_warning("An electronic delivery lock prevents this from opening until it reaches its destination, [GLOB.areas_by_type[goal_area_type]].")
|
||||
examine_list += span_warning("This crate cannot be sold until it is opened.")
|
||||
|
||||
///registers the signal that blocks target from opening when outside of the valid area, returns if it is now unlocked
|
||||
/datum/element/deliver_first/proc/area_check(obj/structure/closet/target)
|
||||
var/area/target_area = get_area(target)
|
||||
if(target_area.type == goal_area_type)
|
||||
UnregisterSignal(target, COMSIG_CLOSET_PRE_OPEN)
|
||||
return TRUE
|
||||
else
|
||||
RegisterSignal(target, COMSIG_CLOSET_PRE_OPEN, .proc/on_pre_open, override = TRUE) //very purposefully overriding
|
||||
return FALSE
|
||||
|
||||
/datum/element/deliver_first/proc/on_moved(obj/structure/closet/target, atom/oldloc, direction)
|
||||
SIGNAL_HANDLER
|
||||
area_check(target)
|
||||
|
||||
/datum/element/deliver_first/proc/on_emag(obj/structure/closet/target, mob/emagger)
|
||||
SIGNAL_HANDLER
|
||||
emagger.balloon_alert(emagger, "delivery lock bypassed")
|
||||
remove_lock(target)
|
||||
|
||||
///signal called before opening target, blocks opening
|
||||
/datum/element/deliver_first/proc/on_pre_open(obj/structure/closet/target, mob/living/user, force)
|
||||
SIGNAL_HANDLER
|
||||
if(force)
|
||||
return
|
||||
if(istype(target, /obj/structure/closet/crate))
|
||||
var/obj/structure/closet/crate/opening_crate = target
|
||||
if(opening_crate.manifest) //we don't want to send feedback if they're just tearing off the manifest
|
||||
return BLOCK_OPEN
|
||||
if(user)
|
||||
target.balloon_alert(user, "access denied until delivery!")
|
||||
playsound(target, 'sound/machines/buzz-two.ogg', 30, TRUE)
|
||||
return BLOCK_OPEN
|
||||
|
||||
///signal called by successfully opening target
|
||||
/datum/element/deliver_first/proc/on_post_open(obj/structure/closet/target, force)
|
||||
SIGNAL_HANDLER
|
||||
if(area_check(target))
|
||||
//noice, delivered!
|
||||
var/datum/bank_account/cargo_account = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
||||
cargo_account.adjust_money(payment)
|
||||
remove_lock(target)
|
||||
|
||||
///called to remove the element in a flavorful way, either from delivery or from emagging/breaking open the crate
|
||||
/datum/element/deliver_first/proc/remove_lock(obj/structure/closet/target)
|
||||
target.visible_message(span_notice("[target]'s delivery lock self destructs, spewing sparks from the mechanism!"))
|
||||
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread()
|
||||
spark_system.set_up(4, 0, target.loc)
|
||||
spark_system.start()
|
||||
playsound(src, "sparks", 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE)
|
||||
target.RemoveElement(/datum/element/deliver_first, goal_area_type, payment)
|
||||
@@ -255,6 +255,8 @@
|
||||
return
|
||||
if(opened)
|
||||
return
|
||||
if(SEND_SIGNAL(src, COMSIG_CLOSET_PRE_OPEN, user, force) & BLOCK_OPEN)
|
||||
return
|
||||
welded = FALSE
|
||||
locked = FALSE
|
||||
playsound(loc, open_sound, open_sound_volume, TRUE, -3)
|
||||
@@ -264,7 +266,9 @@
|
||||
dump_contents()
|
||||
animate_door(FALSE)
|
||||
update_appearance()
|
||||
|
||||
after_open(user, force)
|
||||
SEND_SIGNAL(src, COMSIG_CLOSET_POST_OPEN, force)
|
||||
return TRUE
|
||||
|
||||
///Proc to override for effects after opening a door
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
|
||||
///cooldown for each department, assoc type 2 cooldown. global, so rebuilding the console doesn't refresh the cd
|
||||
GLOBAL_LIST_INIT(department_order_cooldowns, list(
|
||||
/obj/machinery/computer/department_orders/service = 0,
|
||||
/obj/machinery/computer/department_orders/engineering = 0,
|
||||
/obj/machinery/computer/department_orders/science = 0,
|
||||
/obj/machinery/computer/department_orders/security = 0,
|
||||
/obj/machinery/computer/department_orders/medical = 0,
|
||||
))
|
||||
|
||||
/obj/machinery/computer/department_orders
|
||||
name = "department order console"
|
||||
desc = "Used to order supplies for a department. Crates ordered this way will be locked until they reach their destination."
|
||||
icon_screen = "supply"
|
||||
circuit = /obj/item/circuitboard/computer/cargo
|
||||
light_color = COLOR_BRIGHT_ORANGE
|
||||
///reference to the order we've made UNTIL it gets sent on the supply shuttle. this is so heads can cancel it
|
||||
var/datum/supply_order/department_order
|
||||
///access required to override an order - this should be a head of staff for the department
|
||||
var/override_access
|
||||
///where this computer expects deliveries to need to go, passed onto orders
|
||||
var/department_delivery_area
|
||||
///which groups this computer can order from
|
||||
var/list/dep_groups = list()
|
||||
|
||||
/obj/machinery/computer/department_orders/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "DepartmentOrders")
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/department_orders/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
var/cooldown = GLOB.department_order_cooldowns[type] - world.time
|
||||
if(cooldown < 0)
|
||||
data["time_left"] = 0
|
||||
else
|
||||
data["time_left"] = DisplayTimeText(cooldown, 1)
|
||||
data["can_override"] = department_order ? TRUE : FALSE
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/department_orders/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
var/list/supply_data = list() //each item in this needs to be a Category
|
||||
for(var/pack_key in SSshuttle.supply_packs)
|
||||
var/datum/supply_pack/pack = SSshuttle.supply_packs[pack_key]
|
||||
//skip groups we do not offer
|
||||
if(!(pack.group in dep_groups))
|
||||
continue
|
||||
//find which group this belongs to, make the group if it doesn't exist
|
||||
var/list/target_group
|
||||
for(var/list/possible_group in supply_data)
|
||||
if(possible_group["name"] == pack.group)
|
||||
target_group = possible_group
|
||||
break
|
||||
if(!target_group)
|
||||
target_group = list(
|
||||
"name" = pack.group,
|
||||
"packs" = list(),
|
||||
)
|
||||
supply_data += list(target_group)
|
||||
//skip packs we should not show, even if we should show the group
|
||||
if((pack.hidden && !(obj_flags & EMAGGED)) || (pack.special && !pack.special_enabled) || pack.DropPodOnly || pack.goody)
|
||||
continue
|
||||
//finally the pack data itself
|
||||
target_group["packs"] += list(list(
|
||||
"name" = pack.name,
|
||||
"cost" = pack.get_cost(),
|
||||
"id" = pack.type,
|
||||
"desc" = pack.desc || pack.name, // If there is a description, use it. Otherwise use the pack's name.
|
||||
))
|
||||
data["supplies"] = supply_data
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/department_orders/ui_act(action, list/params)
|
||||
. = ..()
|
||||
|
||||
if(!isliving(usr))
|
||||
return
|
||||
var/mob/living/orderer = usr
|
||||
|
||||
var/obj/item/card/id/id_card = orderer.get_idcard(hand_first = TRUE)
|
||||
|
||||
//needs to come BEFORE preventing actions!
|
||||
if(action == "override_order")
|
||||
if(!(override_access in id_card.GetAccess()))
|
||||
balloon_alert(usr, "requires head of staff access!")
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE)
|
||||
return
|
||||
|
||||
if(department_order && (department_order in SSshuttle.shoppinglist))
|
||||
GLOB.department_order_cooldowns[type] = 0
|
||||
SSshuttle.shoppinglist -= department_order
|
||||
department_order = null
|
||||
UnregisterSignal(SSshuttle, COMSIG_SUPPLY_SHUTTLE_BUY)
|
||||
return TRUE
|
||||
|
||||
if(GLOB.department_order_cooldowns[type] > world.time)
|
||||
return
|
||||
|
||||
if(!check_access(id_card))
|
||||
balloon_alert(usr, "access denied!")
|
||||
playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE)
|
||||
return
|
||||
|
||||
. = TRUE
|
||||
var/id = text2path(params["id"])
|
||||
var/datum/supply_pack/pack = SSshuttle.supply_packs[id]
|
||||
var/name = "*None Provided*"
|
||||
var/rank = "*None Provided*"
|
||||
var/ckey = usr.ckey
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/human_orderer = usr
|
||||
name = human_orderer.get_authentification_name()
|
||||
rank = human_orderer.get_assignment(hand_first = TRUE)
|
||||
else if(issilicon(usr))
|
||||
name = usr.real_name
|
||||
rank = "Silicon"
|
||||
//already have a signal to finalize the order
|
||||
var/already_signalled = department_order ? TRUE : FALSE
|
||||
department_order = new(pack, name, rank, ckey, "", null, department_delivery_area, null)
|
||||
SSshuttle.shoppinglist += department_order
|
||||
if(!already_signalled)
|
||||
RegisterSignal(SSshuttle, COMSIG_SUPPLY_SHUTTLE_BUY, .proc/finalize_department_order)
|
||||
say("Order processed. Cargo will deliver the crate when it comes in on their shuttle. NOTICE: Heads of staff may override the order.")
|
||||
calculate_cooldown(pack.cost)
|
||||
|
||||
///signal when the supply shuttle begins to spawn orders. we forget the current order preventing it from being overridden (since it's already past the point of no return on undoing the order)
|
||||
/obj/machinery/computer/department_orders/proc/finalize_department_order(datum/subsystem)
|
||||
SIGNAL_HANDLER
|
||||
if(department_order && (department_order in SSshuttle.shoppinglist))
|
||||
department_order = null
|
||||
UnregisterSignal(subsystem, COMSIG_SUPPLY_SHUTTLE_BUY)
|
||||
|
||||
/obj/machinery/computer/department_orders/proc/calculate_cooldown(credits)
|
||||
//minimum almost the lowest value of a crate
|
||||
var/min = CARGO_CRATE_VALUE * 1.6
|
||||
//maximum fairly expensive crate at 3000
|
||||
var/max = CARGO_CRATE_VALUE * 15
|
||||
credits = clamp(credits, min, max)
|
||||
var/time_y = (credits - min)/(max - min) + 1 //convert to between 1 and 2
|
||||
time_y = 10 MINUTES * time_y
|
||||
GLOB.department_order_cooldowns[type] = world.time + time_y
|
||||
|
||||
/obj/machinery/computer/department_orders/service
|
||||
name = "service order console"
|
||||
department_delivery_area = /area/hallway/secondary/service
|
||||
override_access = ACCESS_HOP
|
||||
req_one_access = list(ACCESS_KITCHEN, ACCESS_BAR, ACCESS_HYDROPONICS, ACCESS_JANITOR)
|
||||
dep_groups = list("Service", "Food & Hydroponics", "Livestock", "Costumes & Toys")
|
||||
|
||||
/obj/machinery/computer/department_orders/engineering
|
||||
name = "engineering order console"
|
||||
department_delivery_area = /area/engineering/main
|
||||
override_access = ACCESS_CE
|
||||
req_one_access = REGION_ACCESS_ENGINEERING
|
||||
dep_groups = list("Engineering", "Engine Construction", "Canisters & Materials")
|
||||
|
||||
/obj/machinery/computer/department_orders/science
|
||||
name = "science order console"
|
||||
department_delivery_area = /area/science/research
|
||||
override_access = ACCESS_RD
|
||||
req_one_access = REGION_ACCESS_RESEARCH
|
||||
dep_groups = list("Science", "Livestock")
|
||||
|
||||
/obj/machinery/computer/department_orders/security
|
||||
name = "security order console"
|
||||
department_delivery_area = /area/security/brig
|
||||
override_access = ACCESS_HOS
|
||||
req_one_access = REGION_ACCESS_SECURITY
|
||||
dep_groups = list("Security", "Armory")
|
||||
|
||||
/obj/machinery/computer/department_orders/medical
|
||||
name = "medical order console"
|
||||
department_delivery_area = /area/medical/medbay/central
|
||||
override_access = ACCESS_CMO
|
||||
req_one_access = REGION_ACCESS_MEDBAY
|
||||
dep_groups = list("Medical")
|
||||
@@ -28,11 +28,13 @@
|
||||
var/orderer_ckey
|
||||
var/reason
|
||||
var/discounted_pct
|
||||
///area this order wants to reach, if not null then it will come with the deliver_first component set to this area
|
||||
var/department_destination
|
||||
var/datum/supply_pack/pack
|
||||
var/datum/bank_account/paying_account
|
||||
var/obj/item/coupon/applied_coupon
|
||||
|
||||
/datum/supply_order/New(datum/supply_pack/pack, orderer, orderer_rank, orderer_ckey, reason, paying_account, coupon)
|
||||
/datum/supply_order/New(datum/supply_pack/pack, orderer, orderer_rank, orderer_ckey, reason, paying_account, department_destination, coupon)
|
||||
id = SSshuttle.ordernum++
|
||||
src.pack = pack
|
||||
src.orderer = orderer
|
||||
@@ -40,6 +42,7 @@
|
||||
src.orderer_ckey = orderer_ckey
|
||||
src.reason = reason
|
||||
src.paying_account = paying_account
|
||||
src.department_destination = department_destination
|
||||
src.applied_coupon = coupon
|
||||
|
||||
/datum/supply_order/proc/generateRequisition(turf/T)
|
||||
@@ -114,9 +117,11 @@
|
||||
account_holder = paying_account.account_holder
|
||||
else
|
||||
account_holder = "Cargo"
|
||||
var/obj/structure/closet/crate/C = pack.generate(A, paying_account)
|
||||
generateManifest(C, account_holder, pack, pack.cost)
|
||||
return C
|
||||
var/obj/structure/closet/crate/crate = pack.generate(A, paying_account)
|
||||
if(department_destination)
|
||||
crate.AddElement(/datum/element/deliver_first, department_destination, pack.cost)
|
||||
generateManifest(crate, account_holder, pack, pack.cost)
|
||||
return crate
|
||||
|
||||
/datum/supply_order/proc/generateCombo(miscbox, misc_own, misc_contents, misc_cost)
|
||||
for (var/I in misc_contents)
|
||||
|
||||
@@ -121,7 +121,8 @@
|
||||
"cost" = SO.pack.get_cost(),
|
||||
"id" = SO.id,
|
||||
"orderer" = SO.orderer,
|
||||
"paid" = !isnull(SO.paying_account) //paid by requester
|
||||
"paid" = !isnull(SO.paying_account), //paid by requester
|
||||
"dep_order" = SO.department_destination ? TRUE : FALSE
|
||||
))
|
||||
|
||||
data["requests"] = list()
|
||||
@@ -138,7 +139,6 @@
|
||||
|
||||
/obj/machinery/computer/cargo/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["requestonly"] = requestonly
|
||||
data["supplies"] = list()
|
||||
for(var/pack in SSshuttle.supply_packs)
|
||||
var/datum/supply_pack/P = SSshuttle.supply_packs[pack]
|
||||
@@ -257,7 +257,7 @@
|
||||
break
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
var/datum/supply_order/SO = new(pack, name, rank, ckey, reason, account, applied_coupon)
|
||||
var/datum/supply_order/SO = new(pack, name, rank, ckey, reason, account, null, applied_coupon)
|
||||
SO.generateRequisition(T)
|
||||
if(requestonly && !self_paid)
|
||||
SSshuttle.requestlist += SO
|
||||
@@ -272,15 +272,22 @@
|
||||
if("remove")
|
||||
var/id = text2num(params["id"])
|
||||
for(var/datum/supply_order/SO in SSshuttle.shoppinglist)
|
||||
if(SO.id == id)
|
||||
if(SO.applied_coupon)
|
||||
say("Coupon refunded.")
|
||||
SO.applied_coupon.forceMove(get_turf(src))
|
||||
SSshuttle.shoppinglist -= SO
|
||||
. = TRUE
|
||||
break
|
||||
if(SO.id != id)
|
||||
continue
|
||||
if(SO.department_destination)
|
||||
say("Only the department that ordered this item may cancel it.")
|
||||
return
|
||||
if(SO.applied_coupon)
|
||||
say("Coupon refunded.")
|
||||
SO.applied_coupon.forceMove(get_turf(src))
|
||||
SSshuttle.shoppinglist -= SO
|
||||
. = TRUE
|
||||
break
|
||||
if("clear")
|
||||
SSshuttle.shoppinglist.Cut()
|
||||
for(var/datum/supply_order/cancelled_order in SSshuttle.shoppinglist)
|
||||
if(cancelled_order.department_destination)
|
||||
continue //don't cancel other department's orders
|
||||
SSshuttle.shoppinglist -= cancelled_order
|
||||
. = TRUE
|
||||
if("approve")
|
||||
var/id = text2num(params["id"])
|
||||
|
||||
@@ -90,6 +90,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
|
||||
sell()
|
||||
|
||||
/obj/docking_port/mobile/supply/proc/buy()
|
||||
SEND_SIGNAL(SSshuttle, COMSIG_SUPPLY_SHUTTLE_BUY)
|
||||
var/list/obj/miscboxes = list() //miscboxes are combo boxes that contain all goody orders grouped
|
||||
var/list/misc_order_num = list() //list of strings of order numbers, so that the manifest can show all orders in a box
|
||||
var/list/misc_contents = list() //list of lists of items that each box will contain
|
||||
@@ -122,50 +123,56 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
|
||||
var/purchases = 0
|
||||
var/list/goodies_by_buyer = list() // if someone orders more than GOODY_FREE_SHIPPING_MAX goodies, we upcharge to a normal crate so they can't carry around 20 combat shotties
|
||||
|
||||
for(var/datum/supply_order/SO in SSshuttle.shoppinglist)
|
||||
for(var/datum/supply_order/spawning_order in SSshuttle.shoppinglist)
|
||||
if(!empty_turfs.len)
|
||||
break
|
||||
var/price = SO.pack.get_cost()
|
||||
if(SO.applied_coupon)
|
||||
price *= (1 - SO.applied_coupon.discount_pct_off)
|
||||
var/price = spawning_order.pack.get_cost()
|
||||
if(spawning_order.applied_coupon)
|
||||
price *= (1 - spawning_order.applied_coupon.discount_pct_off)
|
||||
|
||||
var/datum/bank_account/D
|
||||
if(SO.paying_account) //Someone paid out of pocket
|
||||
D = SO.paying_account
|
||||
var/list/current_buyer_orders = goodies_by_buyer[SO.paying_account] // so we can access the length a few lines down
|
||||
if(!SO.pack.goody)
|
||||
price *= 1.1 //TODO make this customizable by the quartermaster
|
||||
var/datum/bank_account/paying_for_this
|
||||
|
||||
// note this is before we increment, so this is the GOODY_FREE_SHIPPING_MAX + 1th goody to ship. also note we only increment off this step if they successfully pay the fee, so there's no way around it
|
||||
else if(LAZYLEN(current_buyer_orders) == GOODY_FREE_SHIPPING_MAX)
|
||||
price += CRATE_TAX
|
||||
D.bank_card_talk("Goody order size exceeds free shipping limit: Assessing [CRATE_TAX] credit S&H fee.")
|
||||
else
|
||||
D = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
||||
if(D)
|
||||
if(!D.adjust_money(-price))
|
||||
if(SO.paying_account)
|
||||
D.bank_card_talk("Cargo order #[SO.id] rejected due to lack of funds. Credits required: [price]")
|
||||
continue
|
||||
//department orders EARN money for cargo, not the other way around
|
||||
if(!spawning_order.department_destination)
|
||||
if(spawning_order.paying_account) //Someone paid out of pocket
|
||||
paying_for_this = spawning_order.paying_account
|
||||
var/list/current_buyer_orders = goodies_by_buyer[spawning_order.paying_account] // so we can access the length a few lines down
|
||||
if(!spawning_order.pack.goody)
|
||||
price *= 1.1 //TODO make this customizable by the quartermaster
|
||||
|
||||
if(SO.paying_account)
|
||||
if(SO.pack.goody)
|
||||
LAZYADD(goodies_by_buyer[SO.paying_account], SO)
|
||||
D.bank_card_talk("Cargo order #[SO.id] has shipped. [price] credits have been charged to your bank account.")
|
||||
// note this is before we increment, so this is the GOODY_FREE_SHIPPING_MAX + 1th goody to ship. also note we only increment off this step if they successfully pay the fee, so there's no way around it
|
||||
else if(LAZYLEN(current_buyer_orders) == GOODY_FREE_SHIPPING_MAX)
|
||||
price += CRATE_TAX
|
||||
paying_for_this.bank_card_talk("Goody order size exceeds free shipping limit: Assessing [CRATE_TAX] credit S&H fee.")
|
||||
else
|
||||
paying_for_this = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
||||
if(paying_for_this)
|
||||
if(!paying_for_this.adjust_money(-price))
|
||||
if(spawning_order.paying_account)
|
||||
paying_for_this.bank_card_talk("Cargo order #[spawning_order.id] rejected due to lack of funds. Credits required: [price]")
|
||||
continue
|
||||
|
||||
if(spawning_order.paying_account)
|
||||
if(spawning_order.pack.goody)
|
||||
LAZYADD(goodies_by_buyer[spawning_order.paying_account], spawning_order)
|
||||
paying_for_this.bank_card_talk("Cargo order #[spawning_order.id] has shipped. [price] credits have been charged to your bank account.")
|
||||
var/datum/bank_account/department/cargo = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
||||
cargo.adjust_money(price - SO.pack.get_cost()) //Cargo gets the handling fee
|
||||
value += SO.pack.get_cost()
|
||||
SSshuttle.shoppinglist -= SO
|
||||
SSshuttle.orderhistory += SO
|
||||
QDEL_NULL(SO.applied_coupon)
|
||||
cargo.adjust_money(price - spawning_order.pack.get_cost()) //Cargo gets the handling fee
|
||||
value += spawning_order.pack.get_cost()
|
||||
SSshuttle.shoppinglist -= spawning_order
|
||||
SSshuttle.orderhistory += spawning_order
|
||||
QDEL_NULL(spawning_order.applied_coupon)
|
||||
|
||||
if(!SO.pack.goody) //we handle goody crates below
|
||||
SO.generate(pick_n_take(empty_turfs))
|
||||
if(!spawning_order.pack.goody) //we handle goody crates below
|
||||
spawning_order.generate(pick_n_take(empty_turfs))
|
||||
|
||||
SSblackbox.record_feedback("nested tally", "cargo_imports", 1, list("[SO.pack.get_cost()]", "[SO.pack.name]"))
|
||||
investigate_log("Order #[SO.id] ([SO.pack.name], placed by [key_name(SO.orderer_ckey)]), paid by [D.account_holder] has shipped.", INVESTIGATE_CARGO)
|
||||
if(SO.pack.dangerous)
|
||||
message_admins("\A [SO.pack.name] ordered by [ADMIN_LOOKUPFLW(SO.orderer_ckey)], paid by [D.account_holder] has shipped.")
|
||||
SSblackbox.record_feedback("nested tally", "cargo_imports", 1, list("[spawning_order.pack.get_cost()]", "[spawning_order.pack.name]"))
|
||||
|
||||
var/from_whom = paying_for_this?.account_holder || "nobody (department order)"
|
||||
|
||||
investigate_log("Order #[spawning_order.id] ([spawning_order.pack.name], placed by [key_name(spawning_order.orderer_ckey)]), paid by [from_whom] has shipped.", INVESTIGATE_CARGO)
|
||||
if(spawning_order.pack.dangerous)
|
||||
message_admins("\A [spawning_order.pack.name] ordered by [ADMIN_LOOKUPFLW(spawning_order.orderer_ckey)], paid by [from_whom] has shipped.")
|
||||
purchases++
|
||||
|
||||
// we handle packing all the goodies last, since the type of crate we use depends on how many goodies they ordered. If it's more than GOODY_FREE_SHIPPING_MAX
|
||||
|
||||
@@ -788,6 +788,7 @@
|
||||
#include "code\datums\elements\death_drops.dm"
|
||||
#include "code\datums\elements\deferred_aquarium_content.dm"
|
||||
#include "code\datums\elements\delete_on_drop.dm"
|
||||
#include "code\datums\elements\deliver_first.dm"
|
||||
#include "code\datums\elements\digitalcamo.dm"
|
||||
#include "code\datums\elements\drag_pickup.dm"
|
||||
#include "code\datums\elements\dryable.dm"
|
||||
@@ -2092,6 +2093,7 @@
|
||||
#include "code\modules\cargo\bounty.dm"
|
||||
#include "code\modules\cargo\centcom_podlauncher.dm"
|
||||
#include "code\modules\cargo\coupon.dm"
|
||||
#include "code\modules\cargo\department_order.dm"
|
||||
#include "code\modules\cargo\export_scanner.dm"
|
||||
#include "code\modules\cargo\exports.dm"
|
||||
#include "code\modules\cargo\expressconsole.dm"
|
||||
|
||||
@@ -354,18 +354,28 @@ const CargoCart = (props, context) => {
|
||||
<b>[Paid Privately]</b>
|
||||
)}
|
||||
</Table.Cell>
|
||||
<Table.Cell collapsing textAlign="right">
|
||||
{formatMoney(entry.cost)} cr
|
||||
</Table.Cell>
|
||||
<Table.Cell collapsing>
|
||||
{can_send &&(
|
||||
<Button
|
||||
icon="minus"
|
||||
onClick={() => act('remove', {
|
||||
id: entry.id,
|
||||
})} />
|
||||
)}
|
||||
</Table.Cell>
|
||||
{entry.dep_order && (
|
||||
<Table.Cell collapsing textAlign="right">
|
||||
{formatMoney(entry.cost)} cr earned on delivery
|
||||
</Table.Cell>
|
||||
) || (
|
||||
<>
|
||||
<Table.Cell collapsing textAlign="right">
|
||||
{formatMoney(entry.cost)} cr
|
||||
</Table.Cell>
|
||||
<Table.Cell collapsing>
|
||||
{can_send &&(
|
||||
<Button
|
||||
icon="minus"
|
||||
onClick={() => act('remove', {
|
||||
id: entry.id,
|
||||
})} />
|
||||
)}
|
||||
</Table.Cell>
|
||||
</>
|
||||
)}
|
||||
|
||||
|
||||
</Table.Row>
|
||||
))}
|
||||
</Table>
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
import { BooleanLike } from 'common/react';
|
||||
import { useBackend, useLocalState } from '../backend';
|
||||
import { Box, Button, Dimmer, Icon, NoticeBox, Section, Stack, Tabs, Tooltip } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
|
||||
// 15x crate value
|
||||
const COST_UPPER_BOUND = 3000;
|
||||
|
||||
type Pack = {
|
||||
name: string;
|
||||
cost: number;
|
||||
id: string;
|
||||
desc: string;
|
||||
goody: string;
|
||||
}
|
||||
|
||||
type Category = {
|
||||
name: string;
|
||||
packs: Pack[];
|
||||
}
|
||||
|
||||
type Info = {
|
||||
can_override: BooleanLike;
|
||||
time_left: number;
|
||||
supplies: Category[];
|
||||
};
|
||||
|
||||
const CooldownEstimate = (props) => {
|
||||
const {
|
||||
cost,
|
||||
} = props;
|
||||
const cooldownColor = cost > COST_UPPER_BOUND * 0.75 && "red"
|
||||
|| cost > COST_UPPER_BOUND * 0.25 && "orange"
|
||||
|| "green";
|
||||
const cooldownText = cost > COST_UPPER_BOUND * 0.75 && "long"
|
||||
|| cost > COST_UPPER_BOUND * 0.25 && "moderate"
|
||||
|| "short";
|
||||
return (
|
||||
<Box as="span" textColor={cooldownColor}>
|
||||
{cooldownText} cooldown.
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export const DepartmentOrders = (props, context) => {
|
||||
const { data } = useBackend<Info>(context);
|
||||
const {
|
||||
time_left,
|
||||
} = data;
|
||||
return (
|
||||
<Window
|
||||
title="Department Orders"
|
||||
width={620}
|
||||
height={580} >
|
||||
<Window.Content>
|
||||
{!!time_left
|
||||
&& <CooldownDimmer />
|
||||
|| (
|
||||
<Stack vertical fill>
|
||||
<Stack.Item grow>
|
||||
<Stack fill vertical>
|
||||
<Stack.Item>
|
||||
<NoticeBox info>
|
||||
As employees of Nanotrasen, the selection of orders
|
||||
here are completely free of charge, only incurring
|
||||
a cooldown on the service. Cheaper items will make
|
||||
you wait for less time before Nanotrasen allows
|
||||
another purchase, to encourage tasteful spending.
|
||||
</NoticeBox>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
<DepartmentCatalog />
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
)}
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
const CooldownDimmer = (props, context) => {
|
||||
const { act, data } = useBackend<Info>(context);
|
||||
const {
|
||||
can_override,
|
||||
time_left,
|
||||
} = data;
|
||||
return (
|
||||
<Dimmer>
|
||||
<Stack vertical>
|
||||
<Stack.Item textAlign="center">
|
||||
<Icon
|
||||
color="orange"
|
||||
name="route"
|
||||
size={20}
|
||||
/>
|
||||
</Stack.Item>
|
||||
<Stack.Item fontSize="18px" color="orange">
|
||||
Ready for another order in {time_left}...
|
||||
</Stack.Item>
|
||||
<Stack.Item textAlign="center" color="orange">
|
||||
<Button
|
||||
width="300px"
|
||||
lineHeight={2}
|
||||
tooltip={!!can_override
|
||||
&& "This action requires Head of Staff access!"
|
||||
|| "Crate already shipped! No cancelling now!"}
|
||||
fontSize="14px"
|
||||
color="red"
|
||||
disabled={!can_override}
|
||||
onClick={() => act("override_order")}>
|
||||
<Box fontSize="22px">
|
||||
Override
|
||||
</Box>
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Dimmer>
|
||||
);
|
||||
};
|
||||
|
||||
const DepartmentCatalog = (props, context) => {
|
||||
const { act, data } = useBackend<Info>(context);
|
||||
const {
|
||||
supplies,
|
||||
} = data;
|
||||
const [
|
||||
tabCategory,
|
||||
setTabCategory,
|
||||
] = useLocalState(context, 'tabName', supplies[0]);
|
||||
return (
|
||||
<Stack vertical fill>
|
||||
<Stack.Item>
|
||||
<Tabs textAlign="center" fluid>
|
||||
{supplies.map(cat => (
|
||||
<Tabs.Tab
|
||||
key={cat}
|
||||
selected={tabCategory === cat}
|
||||
onClick={() => (setTabCategory(cat))}>
|
||||
{cat.name}
|
||||
</Tabs.Tab>
|
||||
))}
|
||||
</Tabs>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
<Section fill scrollable>
|
||||
<Stack vertical>
|
||||
{tabCategory.packs.map(pack => (
|
||||
<Stack.Item className="candystripe" key={pack.name}>
|
||||
<Stack fill>
|
||||
<Stack.Item grow>
|
||||
<Tooltip content={pack.desc}>
|
||||
<Box as="span" style={{
|
||||
"border-bottom": "2px dotted rgba(255, 255, 255, 0.8)",
|
||||
}}>
|
||||
{pack.name}
|
||||
</Box>
|
||||
</Tooltip>
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<CooldownEstimate cost={pack.cost} />
|
||||
 
|
||||
<Button
|
||||
onClick={() => act("order", {
|
||||
id: pack.id,
|
||||
})}>
|
||||
Order
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
))}
|
||||
</Stack>
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user