diff --git a/__DEFINES/global.dm b/__DEFINES/global.dm index 2fe0887490c..2aa21af2d61 100644 --- a/__DEFINES/global.dm +++ b/__DEFINES/global.dm @@ -233,7 +233,8 @@ var/recall_time_limit = 72000 //NO FUCKING EXCUSE FOR THE ATROCITY THAT WAS var/list/score=list( "crewscore" = 0, //This is the overall var/score for the whole round - "stuffshipped" = 0, //How many useful items have cargo shipped out? Currently broken + "plasmashipped" = 0,//How much plasma has been sent to centcom? + "stuffshipped" = 0, //How many centcom orders have cargo fulfilled? "stuffharvested" = 0, //How many harvests have hydroponics done (per crop)? "oremined" = 0, //How many chunks of ore were smelted "eventsendured" = 0, //How many random events did the station endure? diff --git a/__DEFINES/setup.dm b/__DEFINES/setup.dm index c91d9d0d059..ffb719969bf 100644 --- a/__DEFINES/setup.dm +++ b/__DEFINES/setup.dm @@ -1605,6 +1605,11 @@ var/proccalls = 1 #define HUMAN_DNA 1 #define XENO_DNA 2 +// Buffer datatype flags. +#define DNA2_BUF_UI 1 +#define DNA2_BUF_UE 2 +#define DNA2_BUF_SE 4 + #define DEFAULT_BLOOD "#A10808" #define DEFAULT_FLESH "#FFC896" #define ALIEN_BLOOD "#05EE05" diff --git a/code/controllers/shuttle_controller.dm b/code/controllers/shuttle_controller.dm index 48f78305579..143a0a88691 100644 --- a/code/controllers/shuttle_controller.dm +++ b/code/controllers/shuttle_controller.dm @@ -285,6 +285,27 @@ datum/emergency_shuttle/proc/shuttle_phase(var/phase, var/casual = 1) vote_preload() location = 2 + //if the crew brought items ordered by centcom with them, they get paid for those as if it were the supply shuttle + for(var/atom/movable/MA in shuttle.linked_area) + if(MA.anchored && !ismecha(MA)) + continue + + if(istype(MA,/obj/structure/closet/crate)) + for(var/obj/A in MA) + SSsupply_shuttle.SellObjToOrders(A,1,TRUE) + else + SSsupply_shuttle.SellObjToOrders(MA,0,TRUE) + + for(var/datum/centcomm_order/O in SSsupply_shuttle.centcomm_orders) + O.cargo_contribution = 0//Cargo doesn't get their 10% bonus when items are shipped this way. + if(O.CheckFulfilled()) + if (!istype(O, /datum/centcomm_order/per_unit)) + O.Pay()//per_unit payments are handled by CheckFulfilled() + SSsupply_shuttle.centcomm_orders.Remove(O) + for(var/obj/machinery/computer/supplycomp/S in SSsupply_shuttle.supply_consoles)//juiciness! + S.say("Central Command request fulfilled!") + playsound(S, 'sound/machines/info.ogg', 50, 1) + if(ticker) ticker.mode.ShuttleDocked(2) diff --git a/code/controllers/subsystem/supply_shuttle.dm b/code/controllers/subsystem/supply_shuttle.dm index 557956520e7..224d8a7c691 100644 --- a/code/controllers/subsystem/supply_shuttle.dm +++ b/code/controllers/subsystem/supply_shuttle.dm @@ -7,6 +7,9 @@ #define REASON_LEN 140 // max length for reason message, nanoui appears to not like long strings. +#define CENTCOMM_ORDER_DELAY_MIN (20 MINUTES) +#define CENTCOMM_ORDER_DELAY_MAX (40 MINUTES) + var/datum/subsystem/supply_shuttle/SSsupply_shuttle /datum/subsystem/supply_shuttle @@ -34,6 +37,8 @@ var/datum/subsystem/supply_shuttle/SSsupply_shuttle var/datum/materials/materials_list var/restriction = 1 //Who can approve orders? 0 = autoapprove; 1 = has access; 2 = has an ID (omits silicons); 3 = actions require PIN var/requisition = 0 //Are orders being paid for by the department? 0 = no; 1 = auto; possible future: allow with pin? + var/centcomm_order_cooldown = 9999 + var/centcomm_last_order = 0 /datum/subsystem/supply_shuttle/New() NEW_SS_GLOBAL(SSsupply_shuttle) @@ -47,6 +52,10 @@ var/datum/subsystem/supply_shuttle/SSsupply_shuttle var/datum/supply_packs/P = new typepath supply_packs[P.name] = P + add_centcomm_order(new /datum/centcomm_order/per_unit/plasma) + + centcomm_last_order = world.time + centcomm_order_cooldown = rand(CENTCOMM_ORDER_DELAY_MIN,CENTCOMM_ORDER_DELAY_MAX) ..() /datum/subsystem/supply_shuttle/fire(resumed = FALSE) @@ -59,6 +68,27 @@ var/datum/subsystem/supply_shuttle/SSsupply_shuttle eta = 0 send() + if (world.time > (centcomm_last_order + centcomm_order_cooldown)) + + + //1 more simultaneous order for every 10 players. + //Centcomm uses the crew manifest to determine how many people actually are on the station. + var/new_orders = 1 + round(data_core.general.len / 10) + for (var/i = 1 to new_orders) + create_weighted_order() + + //If the are less than 1 order per 5 crew members, the next order will come sooner, otherwise later. + var/new_cooldown = 1 + round(data_core.general.len / 5) + var/modified_min = CENTCOMM_ORDER_DELAY_MIN + var/modified_max = CENTCOMM_ORDER_DELAY_MAX + + var/delta = (centcomm_orders.len - new_cooldown)// Sign tells us if we need to add or substract time + new_cooldown = centcomm_orders.len + modified_max = max(modified_min, modified_max - 5 * delta MINUTES) + + centcomm_last_order = world.time + centcomm_order_cooldown = rand(modified_min,modified_max) + /datum/supply_order var/ordernum var/datum/supply_packs/object = null @@ -108,19 +138,22 @@ var/datum/subsystem/supply_shuttle/SSsupply_shuttle return 1 -/datum/subsystem/supply_shuttle/proc/SellObjToOrders(var/atom/A,var/in_crate) +/datum/subsystem/supply_shuttle/proc/SellObjToOrders(var/atom/A,var/in_crate,var/preserve = FALSE) + if (istype(A,/obj/item/weapon/storage/lockbox)) + for (var/atom/A2 in A) + SellObjToOrders(A2, 1) + if(A2 && !preserve) + qdel(A2) // Per-unit orders run last so they don't steal shit. - var/list/deferred_order_checks=list() - var/order_idx=0 + var/list/deferred_orders = list() for(var/datum/centcomm_order/O in centcomm_orders) - order_idx++ if(istype(O,/datum/centcomm_order/per_unit)) - deferred_order_checks += order_idx - if(O.CheckShuttleObject(A,in_crate)) + deferred_orders += O + continue + if(O.CheckShuttleObject(A,in_crate,preserve)) return - for(var/oid in deferred_order_checks) - var/datum/centcomm_order/O = centcomm_orders[oid] - if(O.CheckShuttleObject(A,in_crate)) + for(var/datum/centcomm_order/O in deferred_orders) + if(O.CheckShuttleObject(A,in_crate,preserve)) return /datum/subsystem/supply_shuttle/proc/sell() @@ -131,51 +164,22 @@ var/datum/subsystem/supply_shuttle/SSsupply_shuttle var/datum/money_account/cargo_acct = department_accounts["Cargo"] + var/recycled_crates = 0 for(var/atom/movable/MA in shuttle) - if(MA.anchored) + if(MA.anchored && !ismecha(MA)) continue - if(istype(MA, /obj/item/stack/sheet/mineral/plasma)) - var/obj/item/stack/sheet/mineral/plasma/P = MA - if(P.redeemed) - continue - var/datum/material/mat = materials_list.getMaterial(P.mat_type) - var/amount = (mat.value * 10) * P.amount - cargo_acct.money += amount - var/datum/transaction/T = new() - T.target_name = cargo_acct.owner_name - T.purpose = "Central Command Plasma sale" - T.amount = amount - T.date = current_date_string - T.time = worldtime2text() - cargo_acct.transaction_log.Add(T) - // Must be in a crate! - else if(istype(MA,/obj/structure/closet/crate)) - cargo_acct.money += credits_per_crate - var/find_slip = 1 + if(istype(MA,/obj/structure/closet/crate)) + recycled_crates++ + var/find_slip = 1 for(var/obj/A in MA) - if(istype(A, /obj/item/stack/sheet/mineral/plasma)) - var/obj/item/stack/sheet/mineral/plasma/P = A - if(P.redeemed) - continue - var/datum/material/mat = materials_list.getMaterial(P.mat_type) - var/amount = (mat.value * 10) * P.amount - cargo_acct.money += amount - var/datum/transaction/T = new() - T.target_name = cargo_acct.owner_name - T.purpose = "Central Command Plasma sale" - T.amount = amount - T.date = current_date_string - T.time = worldtime2text() - cargo_acct.transaction_log.Add(T) - continue if(find_slip && istype(A,/obj/item/weapon/paper/manifest)) var/obj/item/weapon/paper/slip = A if(slip.stamped && slip.stamped.len) //yes, the clown stamp will work. clown is the highest authority on the station, it makes sense var/datum/transaction/T = new() - T.target_name = cargo_acct.owner_name - T.purpose = "Central Command purchase confirmation (Stamped Slip) [A]" + T.target_name = "Central Command Administration" + T.purpose = "Purchase confirmation (Stamped Slip) [A]" T.amount = credits_per_slip T.date = current_date_string T.time = worldtime2text() @@ -195,10 +199,24 @@ var/datum/subsystem/supply_shuttle/SSsupply_shuttle // PAY UP BITCHES for(var/datum/centcomm_order/O in centcomm_orders) if(O.CheckFulfilled()) - O.Pay() + if (!istype(O, /datum/centcomm_order/per_unit)) + O.Pay()//per_unit payments are handled by CheckFulfilled() centcomm_orders.Remove(O) - qdel(MA) + for(var/obj/machinery/computer/supplycomp/S in supply_consoles)//juiciness! + S.say("Central Command request fulfilled!") + playsound(S, 'sound/machines/info.ogg', 50, 1) + if(MA) + qdel(MA) + if (recycled_crates) + var/datum/transaction/T = new() + T.target_name = "Central Command Recycling" + T.purpose = "[recycled_crates] recycled crate[recycled_crates > 1 ? "s" : ""]" + T.amount = credits_per_crate*recycled_crates + T.date = current_date_string + T.time = worldtime2text() + cargo_acct.transaction_log.Add(T) + cargo_acct.money += credits_per_crate*recycled_crates /datum/subsystem/supply_shuttle/proc/buy() if(!shoppinglist.len) @@ -333,7 +351,7 @@ var/datum/subsystem/supply_shuttle/SSsupply_shuttle /datum/subsystem/supply_shuttle/proc/add_centcomm_order(var/datum/centcomm_order/C) centcomm_orders.Add(C) var/name = "External order form - [C.name] order number [C.id]" - var/info = {"

Central command supply requisition form
+ var/info = {"

Central Command supply requisition form
INDEX: #[C.id]
REQUESTED BY: [C.name]
MUST BE IN CRATE: [C.must_be_in_crate ? "YES" : "NO"]
@@ -341,9 +359,30 @@ var/datum/subsystem/supply_shuttle/SSsupply_shuttle [C.getRequestsByName(1)] WORTH: [C.worth] credits TO [C.acct_by_string] "} + if (C.silent) + return for(var/obj/machinery/computer/supplycomp/S in supply_consoles) var/obj/item/weapon/paper/reqform = new /obj/item/weapon/paper(S.loc) reqform.name = name reqform.info = info reqform.update_icon() - S.say("New central command request available") + S.say("New Central Command request available!") + playsound(S, 'sound/machines/twobeep.ogg', 50, 1) + + for (var/obj/machinery/message_server/MS in message_servers) + if(MS.is_functioning()) + for (var/obj/machinery/requests_console/Console in requests_consoles) + if (Console.department in C.request_consoles_to_notify) + Console.screen = 8 + if(Console.newmessagepriority < 1) + Console.newmessagepriority = 1 + Console.icon_state = "req_comp2" + if(!Console.silent) + playsound(Console.loc, 'sound/machines/request.ogg', 50, 1) + Console.visible_message("The [src] beeps; New Order from [C.name]") + Console.messages += "[name]
[info]" + Console.set_light(2) + + +#undef CENTCOMM_ORDER_DELAY_MIN +#undef CENTCOMM_ORDER_DELAY_MAX diff --git a/code/game/centcomm_orders.dm b/code/game/centcomm_orders.dm deleted file mode 100644 index 4bad6d69d60..00000000000 --- a/code/game/centcomm_orders.dm +++ /dev/null @@ -1,303 +0,0 @@ -/******************** -* Track orders made by centcomm -* -* Used for the new cargo system -*********************/ -var/global/current_centcomm_order_id=124901 - -/datum/centcomm_order - var/id = 0 // Some bullshit ID we use for fluff. - var/name = "CentComm" // Name of the ordering entity. Fluff. - var/datum/money_account/acct // account we pay to - var/acct_by_string = "unknown" - - // Amount decided upon - var/worth = 0 - - var/must_be_in_crate = 1 - var/recurring = 0 - - // /type = amount - var/list/requested=list() - var/list/fulfilled=list() - -/datum/centcomm_order/New() - ..() - id = current_centcomm_order_id++ - name = command_name() - -/datum/centcomm_order/proc/CheckShuttleObject(var/obj/O, var/in_crate) - if(must_be_in_crate && !in_crate) - return 0 - if(!O) - return 0 - if(O.type in requested) - var/amount = 1 - if(istype(O, /obj/item/stack)) - var/obj/item/stack/S = O - amount = S.amount - if(!(O.type in fulfilled)) - fulfilled[O.type]=0 - // Don't claim stuff that other orders may want. - if(fulfilled[O.type]==requested[O.type]) - return 0 - fulfilled[O.type]+=amount - qdel(O) - return 1 - -/datum/centcomm_order/proc/CheckFulfilled(var/obj/O, var/in_crate) - for(var/typepath in requested) - if(!(typepath in fulfilled) || fulfilled[typepath] < requested[typepath]) - return 0 - return 1 - -/datum/centcomm_order/proc/Pay() - acct.charge(-worth,null,"Payment for order #[id]",dest_name = name) - -/datum/centcomm_order/proc/getRequestsByName(var/html_format = 0) - var/manifest = "" - if(html_format) - manifest = "" - return manifest - -/datum/centcomm_order/proc/getFulfilledByName(var/html_format = 0) - var/manifest = "" - if(html_format) - manifest = "" - return manifest - -/datum/centcomm_order/proc/OnPostUnload() - return - -// These run *last*. -/datum/centcomm_order/per_unit - recurring=1 - var/list/unit_prices=list() - -// Same as normal, but will take every last bit of what you provided. -/datum/centcomm_order/per_unit/CheckShuttleObject(var/obj/O, var/in_crate) - if(must_be_in_crate && !in_crate) - return 0 - if(!O) - return 0 - if(O.type in requested) - if(!(O.type in fulfilled)) - fulfilled[O.type]=0 - fulfilled[O.type]=fulfilled[O.type]+1 - - qdel(O) - return 1 - -/datum/centcomm_order/per_unit/CheckFulfilled() - var/toPay=0 - for(var/typepath in fulfilled) - var/worth_per_unit = unit_prices[typepath] - var/amount = fulfilled[typepath] - toPay += amount * worth_per_unit - if(requested[typepath]!=INFINITY) - requested[typepath] = max(0,requested[typepath] - fulfilled[typepath]) - fulfilled[typepath]=0 - if(toPay) - acct.charge(-toPay,null,"Payment for order #[id]",dest_name = name) - return - -////////////////////////////////////////////// -// ORDERS START HERE -////////////////////////////////////////////// -/datum/centcomm_order/per_unit/plasma - name = "Nanotrasen" - recurring = 1 - requested = list( - /obj/item/stack/sheet/mineral/plasma = INFINITY - ) - unit_prices=list( - /obj/item/stack/sheet/mineral/plasma = 0.5 // 1 credit per two plasma sheets. - ) - -/datum/centcomm_order/department/New() - ..() - acct = department_accounts[acct_by_string] - -/datum/centcomm_order/department/cargo //Orders that cargo can manage - acct_by_string = "Cargo" - -/datum/centcomm_order/department/cargo/diamonds/New() - ..() - requested = list( - /obj/item/stack/sheet/mineral/diamond = rand(5,50) - ) - worth = (VALUE_DIAMOND+rand(1,3))*requested[requested[1]] - -/datum/centcomm_order/department/cargo/uranium/New() - ..() - requested = list( - /obj/item/stack/sheet/mineral/uranium = rand(5,50) - ) - worth = (VALUE_URANIUM*rand(1,3))*requested[requested[1]] - -/datum/centcomm_order/department/cargo/gold/New() - ..() - requested = list( - /obj/item/stack/sheet/mineral/gold = rand(5,50) - ) - worth = (VALUE_GOLD*rand(1,3))*requested[requested[1]] - -/datum/centcomm_order/department/cargo/silver/New() - ..() - requested = list( - /obj/item/stack/sheet/mineral/silver = rand(5,50) - ) - worth = (VALUE_SILVER*rand(1,3))*requested[requested[1]] - -/datum/centcomm_order/department/cargo/phazon/New() - ..() - requested = list( - /obj/item/stack/sheet/mineral/phazon = rand(1,10) - ) - worth = (VALUE_PHAZON*rand(1,3))*requested[requested[1]] - -/datum/centcomm_order/department/cargo/clown/New() - ..() - requested = list( - /obj/item/stack/sheet/mineral/clown = rand(1,10) - ) - worth = (VALUE_CLOWN*rand(1,3))*requested[requested[1]] - - -/datum/centcomm_order/department/science //Orders that science can manage - acct_by_string = "Science" - -/datum/centcomm_order/department/science/nuclear_gun/New() - ..() - requested = list( - /obj/item/weapon/gun/energy/gun/nuclear = rand(1,5) - ) - worth = rand(350,750)*requested[requested[1]] - -/datum/centcomm_order/department/science/subspace_tunnel/New() - ..() - requested = list( - /obj/item/weapon/subspacetunneler = rand(1,3) - ) - worth = rand(350,750)*requested[requested[1]] - -/datum/centcomm_order/department/medical - acct_by_string = "Medical" - -/datum/centcomm_order/department/medical/kidneys/New() - ..() - requested = list( - /obj/item/organ/internal/kidneys = rand(1,3) - ) - worth = rand(100,300)*requested[requested[1]] - -/datum/centcomm_order/department/civilian - acct_by_string = "Civilian" - -/datum/centcomm_order/department/civilian/pie/New() - ..() - requested = list( - /obj/item/weapon/reagent_containers/food/snacks/pie = rand(3,12) - ) - worth = rand(15,30)*requested[requested[1]] - name = "Clown Federation" //honk - -/datum/centcomm_order/department/civilian/poutinecitadel/New() - ..() - requested = list( - /obj/structure/poutineocean/poutinecitadel = 1 - ) - must_be_in_crate = 0 - worth = rand(1000,3000)*requested[requested[1]] - -/datum/centcomm_order/department/civilian/sweetsundaeramen/New() - ..() - requested = list( - /obj/item/weapon/reagent_containers/food/snacks/sweetsundaeramen = rand(1,3) - ) - worth = rand(150,300)*requested[requested[1]] - -/datum/centcomm_order/department/civilian/superburger/New() - ..() - requested = list( - /obj/item/weapon/reagent_containers/food/snacks/superbiteburger = rand(1,3) - ) - worth = rand(250,500)*requested[requested[1]] - -/datum/centcomm_order/department/civilian/turkey/New() - ..() - requested = list( - /obj/item/weapon/reagent_containers/food/snacks/sliceable/turkey = rand(1,2) - ) - worth = rand(200,400)*requested[requested[1]] - -/datum/centcomm_order/department/civilian/popcake/New() - ..() - requested = list( - /obj/structure/popout_cake = 1 - ) - must_be_in_crate = 0 - worth = rand(600,1200)*requested[requested[1]] - -/datum/centcomm_order/department/civilian/bkipper/New() - ..() - requested = list( - /obj/item/weapon/reagent_containers/food/snacks/bleachkipper = rand(2,5) - ) - worth = rand(120,500)*requested[requested[1]] - -/datum/centcomm_order/department/civilian/potentham/New() - ..() - requested = list( - /obj/item/weapon/reagent_containers/food/snacks/potentham = rand(1,2) - ) - worth = rand(400,2001)*requested[requested[1]] - -/datum/centcomm_order/department/civilian/sundayroast/New() - ..() - requested = list( - /obj/item/weapon/reagent_containers/food/snacks/sundayroast = rand(1,2) - ) - worth = rand(400,900)*requested[requested[1]] - -/proc/create_centcomm_order(var/datum/centcomm_order/C) - SSsupply_shuttle.add_centcomm_order(C) - -/proc/get_potential_orders() - var/list/orders = list() - orders.Add(subtypesof(/datum/centcomm_order/department/cargo)) - orders.Add(subtypesof(/datum/centcomm_order/department/science)) - orders.Add(subtypesof(/datum/centcomm_order/department/medical)) - orders.Add(subtypesof(/datum/centcomm_order/department/civilian)) - - return orders - -/proc/create_random_order() - var/choice = pick(get_potential_orders()) - create_centcomm_order(new choice) - -/proc/create_random_orders(var/num_orders) - var/list/choices = get_potential_orders() - for(var/i = 1 to num_orders) - var/choice = pick_n_take(choices) - create_centcomm_order(new choice) \ No newline at end of file diff --git a/code/game/centcomm_orders/centcomm_orders.dm b/code/game/centcomm_orders/centcomm_orders.dm new file mode 100644 index 00000000000..b8f44b729c5 --- /dev/null +++ b/code/game/centcomm_orders/centcomm_orders.dm @@ -0,0 +1,377 @@ +/******************** +* Track orders made by centcomm +* +* Used for the new cargo system +*********************/ +var/global/current_centcomm_order_id=124901 + +/datum/centcomm_order + var/id = 0 // Some bullshit ID we use for fluff. + var/name = "Central Command" // Name of the ordering entity. Fluff. + var/datum/money_account/acct // account we pay to + var/acct_by_string = "" + var/silent = 0 + + // Amount decided upon + var/worth = 0 + + var/cargo_contribution = 0.1 + + var/must_be_in_crate = 1 + + var/extra_requirements = ""//specify when you want the items to have been modified in a certain way or have certain properties. + //then use ExtraChecks() to verify that the shipped item has those requested properties + //for example: to verify that a shipped organ is still alive. + + // /type = amount + var/list/requested=list() + var/list/fulfilled=list() + + var/list/name_override=list()//use when you want the requested to appear with a different name, useful when you want to be more descriptive + //for example: "vials of infected blood" + + var/list/request_consoles_to_notify=list()//when the order is created, Request Consoles in this list will immediately + + var/hidden = FALSE //orders that we don't want to see randomly appear + +/* list of all request consoles "department" vars currently used in our maps. + Engineering + "Chief Engineer's Desk" + "Atmospherics" + "Engineering" + "Pod Bay" + "Mechanics" + + Medbay + "Chief Medical Officer's Desk" + "Medbay" + "Chemistry" + "Genetics" + "Virology" + + Security + "Head of Security's Desk" + "Security" + + Service + "Head of Personnel's Desk" + "Kitchen" + "Bar" + "Hydroponics" + "Cargo Bay" + "Janitorial" + "Chapel" + + Science + "Research Director's Desk" + "Science" + "Robotics" + "Telecoms Admin" + + probably won't even need to notify need those + "AI" + "Bridge" + "Captain's Desk" + "Locker Room" + "Tool Storage" + "Arrival Shuttle" + "EVA" +*/ + +/datum/centcomm_order/New() + ..() + id = current_centcomm_order_id++ + + if (acct_by_string) + acct = department_accounts[acct_by_string] + else + acct = station_account + acct_by_string = station_name() + +/datum/centcomm_order/Destroy() + acct = null + ..() + +/datum/centcomm_order/proc/ExtraChecks(var/atom/movable/AM) + return 1 + +/datum/centcomm_order/proc/CheckShuttleObject(var/obj/O, var/in_crate, var/preserve = FALSE) + if(must_be_in_crate && !in_crate) + return 0 + if(!O) + return 0 + if(is_type_in_list(O, requested)) + var/amount = 1 + if(istype(O, /obj/item/stack)) + var/obj/item/stack/S = O + amount = S.amount + if(!is_type_in_list(O, fulfilled)) + fulfilled[O.type] = 0 + // Don't claim stuff that other orders may want. + if(fulfilled[O.type] == requested[O.type]) + return 0 + if (!ExtraChecks(O)) + return 0 + fulfilled[O.type] += amount + if (!preserve) + qdel(O) + return 1 + return 0 + +/datum/centcomm_order/proc/CheckFulfilled() + for(var/typepath in requested) + if(!(typepath in fulfilled) || fulfilled[typepath] < requested[typepath]) + return FALSE + score["stuffshipped"]++ + return TRUE + +/datum/centcomm_order/proc/Pay(var/complete = TRUE) + acct.charge(-worth,null,"Payment for order #[id]",dest_name = name) + + if (cargo_contribution > 0 && acct_by_string != "Cargo")//cargo gets some extra coin from every order shipped + var/datum/money_account/cargo_acct = department_accounts["Cargo"] + cargo_acct.charge(round(-worth/10),null,"Contribution for order #[id]",dest_name = name) + + +/datum/centcomm_order/proc/getRequestsByName(var/html_format = 0) + var/manifest = "" + if(html_format) + manifest = "" + if (extra_requirements) + if(html_format) + manifest += "[extra_requirements]
" + return manifest + +/datum/centcomm_order/proc/getFulfilledByName(var/html_format = 0) + var/manifest = "" + if(html_format) + manifest = "" + return manifest + +/datum/centcomm_order/proc/OnPostUnload() + return + +// These run *last*. +/datum/centcomm_order/per_unit + var/list/unit_prices = list() + var/left_to_check = list() + var/toPay = 0 + + +/datum/centcomm_order/per_unit/Pay(var/complete = TRUE) + if(toPay) + if(complete) + acct.charge(-toPay,null,"Complete payment for per-unit order #[id]",dest_name = name) + score["stuffshipped"]++ + else + acct.charge(-toPay,null,"Partial payment for per-unit order #[id]",dest_name = name) + + if (cargo_contribution > 0 && acct_by_string != "Cargo")//cargo gets some extra coin from every order shipped + var/datum/money_account/cargo_acct = department_accounts["Cargo"] + cargo_acct.charge(round(-worth * cargo_contribution),null,"Contribution for partial order #[id]",dest_name = name) + toPay = 0 + +// Same as normal, but will take every last bit of what you provided. +/datum/centcomm_order/per_unit/CheckShuttleObject(var/obj/O, var/in_crate, var/preserve = FALSE) + if(must_be_in_crate && !in_crate) + return 0 + if(!O) + return 0 + if(is_type_in_list(O, requested)) + var/amount = 1 + if(istype(O, /obj/item/stack)) + var/obj/item/stack/S = O + amount = S.amount + if(!is_type_in_list(O, left_to_check)) + left_to_check[O.type]=0 + if (!ExtraChecks(O)) + return 0 + left_to_check[O.type] += amount + if (!preserve) + qdel(O) + return 1 + return 0 + +/datum/centcomm_order/per_unit/CheckFulfilled() + toPay = 0 + for(var/typepath in left_to_check) + var/worth_per_unit = unit_prices[typepath] + var/amount = left_to_check[typepath] + toPay += amount * worth_per_unit + if(requested[typepath] != INFINITY) + requested[typepath] = max(0,requested[typepath] - left_to_check[typepath]) + if(!(typepath in fulfilled)) + fulfilled[typepath] = 0 + fulfilled[typepath] += left_to_check[typepath] + left_to_check[typepath] = 0 + . = ..() + Pay(.) + +/////////////////////////////// + +/proc/create_random_orders(var/num_orders)//This one is used at roundstart to add a couple random orders immediately + var/list/choices = get_all_orders() + for(var/i = 1 to num_orders) + var/choice = pick_n_take(choices) + var/datum/centcomm_order/new_order = new choice + SSsupply_shuttle.add_centcomm_order(new_order) + +/proc/get_all_orders() + var/list/orders = list() + orders.Add(subtypesof(/datum/centcomm_order/per_unit/department/cargo)) + orders.Add(subtypesof(/datum/centcomm_order/department/science)) + orders.Add(subtypesof(/datum/centcomm_order/department/medical)) + orders.Add(subtypesof(/datum/centcomm_order/department/engineering)) + orders.Add(subtypesof(/datum/centcomm_order/department/civilian)) + orders.Add(subtypesof(/datum/centcomm_order/per_unit/department/civilian)) + return orders + + +/////////////////////////////////////// + +/proc/create_weighted_order() + var/list/active_with_role = get_dept_pop() + + var/list/department_weights = list( + "Cargo" = 3, + "Civilian" = 5, + "Medical" = 5, + "Science" = 5, + "Engineering" = 5, + ) + + for(var/dept in department_weights) + if(active_with_role[dept] < 1) + department_weights[dept] = 1//departments with no employees are very unlikely to receive an order + + var/list/order_exists = list( + "Cargo" = 0, + "Civilian" = 0, + "Medical" = 0, + "Science" = 0, + "Engineering" = 0, + ) + + for(var/datum/centcomm_order/O in SSsupply_shuttle.centcomm_orders) + if (O.acct_by_string in order_exists) + order_exists[O.acct_by_string] += 1 + + for(var/dept in order_exists) + department_weights[dept] = max(1, department_weights[dept] - order_exists[dept])//the more active orders a department has, the less likely it'll get another one + + var/chosen_dept = pick( + department_weights["Cargo"];"Cargo", + department_weights["Civilian"];"Civilian", + department_weights["Medical"];"Medical", + department_weights["Science"];"Science", + department_weights["Engineering"];"Engineering") + + var/list/orders = list() + switch(chosen_dept) + if ("Cargo") + orders.Add(subtypesof(/datum/centcomm_order/per_unit/department/cargo)) + if ("Civilian") + orders.Add(subtypesof(/datum/centcomm_order/department/civilian)) + orders.Add(subtypesof(/datum/centcomm_order/per_unit/department/civilian)) + if ("Medical") + orders.Add(subtypesof(/datum/centcomm_order/department/medical)) + if ("Science") + orders.Add(subtypesof(/datum/centcomm_order/department/science)) + if ("Engineering") + orders.Add(subtypesof(/datum/centcomm_order/department/engineering)) + + orders -= SSsupply_shuttle.centcomm_orders//we don't want a duplicate order + + for (var/O in orders)//removing hidden orders + var/datum/centcomm_order/CO = O + if (initial(CO.hidden)) + orders -= O + + if (!orders.len) + return + + var/chosen_order = pick(orders) + SSsupply_shuttle.add_centcomm_order(new chosen_order) + + +/proc/get_dept_pop() + var/list/active_with_role = list() + active_with_role["Cargo"] = 0 + active_with_role["Service"] = 0 + active_with_role["Medical"] = 0 + active_with_role["Science"] = 0 + active_with_role["Engineering"] = 0 + + for(var/mob/M in player_list) + if(!M.mind || !M.client || M.client.inactivity > 10 * 10 * 60) // longer than 10 minutes AFK counts them as inactive + continue + + if(M.mind.assigned_role in engineering_positions) + active_with_role["Engineer"]++ + + if(M.mind.assigned_role in medical_positions) + active_with_role["Medical"]++ + + if(M.mind.assigned_role in science_positions) + active_with_role["Scientist"]++ + + if(M.mind.assigned_role in (service_positions - "Head of Personnel"))//HoP has stuff to do + active_with_role["Service"]++ + + /* Since Cargo orders are mining only, we'll exclusively check the miner count for now + if(M.mind.assigned_role in (cargo_positions - "Head of Personnel")) + active_with_role["Cargo"]++ + */ + if(M.mind.assigned_role == "Shaft Miner") + active_with_role["Cargo"]++ + + return active_with_role + +/proc/get_dept_leaderboard() + var/list/dept_leaderboard = list() + var/list/depts = list( + "Cargo", + "Science", + "Medical", + "Civilian", + "Engineering") + for (var/dept in depts) + var/datum/money_account/acct = department_accounts[dept] + dept_leaderboard[dept] = acct.money + for (var/i = dept_leaderboard.len, i > 1, i--) + if (dept_leaderboard[dept_leaderboard[i]] > dept_leaderboard[dept_leaderboard[i-1]]) + dept_leaderboard.Swap(i,i-1) + return dept_leaderboard diff --git a/code/game/centcomm_orders/orders_cargo.dm b/code/game/centcomm_orders/orders_cargo.dm new file mode 100644 index 00000000000..c02ffef2424 --- /dev/null +++ b/code/game/centcomm_orders/orders_cargo.dm @@ -0,0 +1,101 @@ + +/datum/centcomm_order/per_unit/plasma//Centcom always wants plasma + name = "Nanotrasen" + worth = "1$ per sheet" + silent = 1//so we don't hear the announcement at every round start + requested = list( + /obj/item/stack/sheet/mineral/plasma = INFINITY + ) + unit_prices=list( + /obj/item/stack/sheet/mineral/plasma = VALUE_PLASMA * 2 + ) + +/datum/centcomm_order/per_unit/plasma/CheckShuttleObject(var/obj/O, var/in_crate) + if(!in_crate) + return 0 + if(!O) + return 0 + if(istype(O, /obj/item/stack/sheet/mineral/plasma)) + var/obj/item/stack/sheet/mineral/plasma/P = O + if(!(O.type in left_to_check)) + left_to_check[O.type] = 0 + left_to_check[O.type] += P.amount + score["plasmashipped"] += P.amount + qdel(O) + return 1 + return 0 + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// // +// MINING ORDERS // +// // +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//6 orders + +/datum/centcomm_order/per_unit/department/cargo + name = "Nanotrasen Industries Inc." + acct_by_string = "Cargo" + request_consoles_to_notify = list( + "Cargo Bay", + ) + +/datum/centcomm_order/per_unit/department/cargo/diamonds/New() + ..() + requested = list( + /obj/item/stack/sheet/mineral/diamond = rand (8,12) + ) + unit_prices=list( + /obj/item/stack/sheet/mineral/diamond = VALUE_DIAMOND * 3 + ) + worth = "[VALUE_DIAMOND+3]$ per sheet" + +/datum/centcomm_order/per_unit/department/cargo/uranium/New() + ..() + requested = list( + /obj/item/stack/sheet/mineral/uranium = rand (40,60) + ) + unit_prices=list( + /obj/item/stack/sheet/mineral/uranium = VALUE_URANIUM * 3 + ) + worth = "[VALUE_URANIUM*3]$ per sheet" + +/datum/centcomm_order/per_unit/department/cargo/gold/New() + ..() + requested = list( + /obj/item/stack/sheet/mineral/gold = rand (40,60) + ) + unit_prices=list( + /obj/item/stack/sheet/mineral/gold = VALUE_GOLD * 3 + ) + worth = "[VALUE_GOLD*3]$ per sheet" + +/datum/centcomm_order/per_unit/department/cargo/silver/New() + ..() + requested = list( + /obj/item/stack/sheet/mineral/silver = rand (40,60) + ) + unit_prices=list( + /obj/item/stack/sheet/mineral/silver = VALUE_SILVER * 3 + ) + worth = "[VALUE_SILVER*3]$ per sheet" + +/datum/centcomm_order/per_unit/department/cargo/phazon/New() + ..() + requested = list( + /obj/item/stack/sheet/mineral/phazon = rand (8,12) + ) + unit_prices=list( + /obj/item/stack/sheet/mineral/phazon = VALUE_PHAZON * 3 + ) + worth = "[VALUE_PHAZON*3]$ per sheet" + +/datum/centcomm_order/per_unit/department/cargo/clown/New() + ..() + requested = list( + /obj/item/stack/sheet/mineral/clown = rand (8,12) + ) + unit_prices=list( + /obj/item/stack/sheet/mineral/clown = VALUE_CLOWN * 3 + ) + worth = "[VALUE_CLOWN*3]$ per sheet" diff --git a/code/game/centcomm_orders/orders_engineering.dm b/code/game/centcomm_orders/orders_engineering.dm new file mode 100644 index 00000000000..be98731bc78 --- /dev/null +++ b/code/game/centcomm_orders/orders_engineering.dm @@ -0,0 +1,69 @@ + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// // +// ENGINEERING ORDERS // +// // +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//2 orders + +/datum/centcomm_order/department/engineering + acct_by_string = "Engineering" + request_consoles_to_notify = list( + "Chief Engineer's Desk", + "Engineering", + ) + +//----------------------------------------------Engineering---------------------------------------------------- + + +/datum/centcomm_order/department/engineering/portable_smes/New() + ..() + request_consoles_to_notify = list( + "Chief Engineer's Desk", + "Engineering", + "Mechanics", + ) + must_be_in_crate = 0 + requested = list( + /obj/machinery/power/battery/portable = 1 + ) + name_override = list( + /obj/machinery/power/battery/portable = "Portable Power Storage Unit" + ) + extra_requirements = "The battery must be filled to full capacity." + worth = 800 + +/datum/centcomm_order/department/engineering/portable_smes/ExtraChecks(var/obj/machinery/power/battery/portable/P) + if (!istype(P)) + return 0 + if (P.charge < P.capacity) + return 0 + return 1 + + +//----------------------------------------------Atmospherics---------------------------------------------------- + + +/datum/centcomm_order/department/engineering/cold_canister/New() + ..() + request_consoles_to_notify = list( + "Chief Engineer's Desk", + "Atmospherics", + ) + must_be_in_crate = 0 + requested = list( + /obj/machinery/portable_atmospherics/canister = 1 + ) + name_override = list( + /obj/machinery/portable_atmospherics/canister = "Cold Plasma Canister" + ) + extra_requirements = "Filled with over 1000 kPa of plasma bellow 2K." + worth = 1300 + +/datum/centcomm_order/department/engineering/cold_canister/ExtraChecks(var/obj/machinery/portable_atmospherics/canister/C) + if (!istype(C)) + return 0 + var/datum/gas_mixture/GM = C.return_air() + if ((GM.gas?.len == 1) && (GAS_PLASMA in GM.gas) && (GM.return_temperature() < 2) && (GM.pressure > 1000)) + return 1 + return 0 diff --git a/code/game/centcomm_orders/orders_medical.dm b/code/game/centcomm_orders/orders_medical.dm new file mode 100644 index 00000000000..33b738f9ff0 --- /dev/null +++ b/code/game/centcomm_orders/orders_medical.dm @@ -0,0 +1,319 @@ + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// // +// MEDICAL ORDERS // +// // +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//9 orders + +//----------------------------------------------Surgery---------------------------------------------------- + +/datum/centcomm_order/department/medical + request_consoles_to_notify = list( + "Chief Medical Officer's Desk", + "Medbay", + ) + acct_by_string = "Medical" + +/datum/centcomm_order/department/medical/kidneys/New() + ..() + requested = list( + /obj/item/organ/internal/kidneys = rand(1,2) + ) + name_override = list( + /obj/item/organ/internal/kidneys = "human kidneys" + ) + extra_requirements = "The organs needs to be fresh, use a medical crate or a freezer." + worth = 200*requested[requested[1]] + +/datum/centcomm_order/department/medical/kidneys/ExtraChecks(var/obj/item/organ/internal/kidneys/I) + if (!istype(I)) + return 0 + if (I.health > 0) + return 1 + return 0 + +/datum/centcomm_order/department/medical/heart/New() + ..() + requested = list( + /obj/item/organ/internal/heart = 1 + ) + name_override = list( + /obj/item/organ/internal/heart = "human heart" + ) + extra_requirements = "The organ needs to be fresh, use a medical crate or a freezer." + worth = 400 + +/datum/centcomm_order/department/medical/heart/ExtraChecks(var/obj/item/organ/internal/heart/I) + if (!istype(I)) + return 0 + if (I.health > 0) + return 1 + return 0 + +//----------------------------------------------Virology---------------------------------------------------- + +//Vaccine +/datum/centcomm_order/department/medical/vaccine + request_consoles_to_notify = list( + "Chief Medical Officer's Desk", + "Virology", + ) + var/required_vac + +/datum/centcomm_order/department/medical/vaccine/New() + ..() + requested = list( + /obj/item/weapon/reagent_containers/glass/beaker/vial = 1 + ) + name_override = list( + /obj/item/weapon/reagent_containers/glass/beaker/vial = "Vial of Vaccine" + ) + var/difficulty = rand(1,4) + switch (difficulty) + if (1) + required_vac = pick(blood_antigens) + worth = 200 + if (2) + required_vac = pick(common_antigens) + worth = 400 + if (3) + required_vac = pick(rare_antigens) + worth = 800 + if (4) + required_vac = pick(alien_antigens) + worth = 1600 + extra_requirements = "Must contain [required_vac] antibodies." + +/datum/centcomm_order/department/medical/vaccine/ExtraChecks(var/obj/item/weapon/reagent_containers/glass/beaker/vial/V) + if (!istype(V)) + return 0 + for(var/datum/reagent/vaccine/vaccine in V.reagents?.reagent_list) + for (var/A in vaccine.data["antigen"]) + if (A == required_vac) + return 1 + return 0 + +//Dangerous Disease Vial +/datum/centcomm_order/department/medical/harmful_disease/New() + ..() + request_consoles_to_notify = list( + "Chief Medical Officer's Desk", + "Virology", + ) + requested = list( + /obj/item/weapon/reagent_containers/glass/beaker/vial = 1 + ) + name_override = list( + /obj/item/weapon/reagent_containers/glass/beaker/vial = "Vial of Infected Blood" + ) + + extra_requirements = "Must contain a dangerous disease with a combined Effect Danger level of at least 13, and a Strength of at least 80." + worth = 600 + +/datum/centcomm_order/department/medical/harmful_disease/ExtraChecks(var/obj/item/weapon/reagent_containers/glass/beaker/vial/V) + if (!istype(V)) + return 0 + var/datum/reagent/blood/blood = locate() in V.reagents.reagent_list + if (blood?.data["virus2"]) + var/list/blood_viruses = blood.data["virus2"] + for (var/ID in blood_viruses) + var/datum/disease2/disease/D = blood_viruses[ID] + if (D.strength >= 80) + var/total_badness = 0 + for(var/datum/disease2/effect/e in D.effects) + total_badness += e.badness + if (total_badness >= 13) + return 1 + + return 0 + +//Beneficial Disease Vial +/datum/centcomm_order/department/medical/beneficial_disease/New() + ..() + request_consoles_to_notify = list( + "Chief Medical Officer's Desk", + "Virology", + ) + requested = list( + /obj/item/weapon/reagent_containers/glass/beaker/vial = 1 + ) + name_override = list( + /obj/item/weapon/reagent_containers/glass/beaker/vial = "Vial of Infected Blood" + ) + + extra_requirements = "Must contain a beneficial disease with a combined Effect Danger level of at most 2." + worth = 1000 + +/datum/centcomm_order/department/medical/beneficial_disease/ExtraChecks(var/obj/item/weapon/reagent_containers/glass/beaker/vial/V) + if (!istype(V)) + return 0 + var/datum/reagent/blood/blood = locate() in V.reagents.reagent_list + if (blood?.data["virus2"]) + var/list/blood_viruses = blood.data["virus2"] + for (var/ID in blood_viruses) + var/datum/disease2/disease/D = blood_viruses[ID] + var/total_badness = 0 + for(var/datum/disease2/effect/e in D.effects) + total_badness += e.badness + if (total_badness <= 2) + return 1 + + return 0 + +//Specific GNA Disks +/datum/centcomm_order/department/medical/gna_disk + var/already_goten = list() + var/req_stage + request_consoles_to_notify = list( + "Chief Medical Officer's Desk", + "Virology", + ) + +/datum/centcomm_order/department/medical/gna_disk/New() + ..() + req_stage = rand(1,4) + requested = list( + /obj/item/weapon/disk/disease = rand (2,5) + ) + name_override = list( + /obj/item/weapon/disk/disease = "GNA Disks" + ) + + extra_requirements = "Each must contain a different Stage [req_stage] symptom." + worth = 300 * requested[requested[1]] + +/datum/centcomm_order/department/medical/gna_disk/ExtraChecks(var/obj/item/weapon/disk/disease/Disk) + if (!istype(Disk)) + return 0 + if ((Disk.stage == req_stage) && Disk.effect && !(Disk.effect.type in already_goten)) + already_goten += Disk.effect.type + return 1 + return 0 + +//----------------------------------------------Genetics---------------------------------------------------- + +//Clean SE +/datum/centcomm_order/department/medical/clean_se/New() + ..() + request_consoles_to_notify = list( + "Chief Medical Officer's Desk", + "Genetics", + ) + requested = list( + /obj/item/weapon/dnainjector = rand (1,5) + ) + name_override = list( + /obj/item/weapon/dnainjector = "Clean SE Injector" + ) + worth = 100 * requested[requested[1]] + +/datum/centcomm_order/department/medical/vaccine/ExtraChecks(var/obj/item/weapon/dnainjector/I) + if (!istype(I)) + return 0 + if (!I.block && I.buf)//Not a block injector + var/datum/dna2/record/R = I.buf + if (R.types & DNA2_BUF_SE)//SE Injector + for (var/block in R.dna.SE) + if (I.buf.dna.SE >= 2050) + return 0 + return 1 + return 0 + +//Specific Superpowers +/datum/centcomm_order/department/medical/xray/New() + ..() + request_consoles_to_notify = list( + "Chief Medical Officer's Desk", + "Genetics", + ) + requested = list( + /obj/item/weapon/dnainjector = rand (1,3) + ) + name_override = list( + /obj/item/weapon/dnainjector = "X-Ray SE Block Injector" + ) + worth = 200 * requested[requested[1]] + +/datum/centcomm_order/department/medical/xray/ExtraChecks(var/obj/item/weapon/dnainjector/I) + if (!istype(I)) + return 0 + if (I.block == XRAYBLOCK && I.buf)//Block Injector + var/datum/dna2/record/R = I.buf + if (R.types & DNA2_BUF_SE)//SE Injector + var/bstate = R.dna.GetSEState(XRAYBLOCK) + return bstate + return 0 + +/datum/centcomm_order/department/medical/hulk/New() + ..() + request_consoles_to_notify = list( + "Chief Medical Officer's Desk", + "Genetics", + ) + requested = list( + /obj/item/weapon/dnainjector = rand (1,3) + ) + name_override = list( + /obj/item/weapon/dnainjector = "Hulk SE Block Injector" + ) + worth = 300 * requested[requested[1]] + +/datum/centcomm_order/department/medical/hulk/ExtraChecks(var/obj/item/weapon/dnainjector/I) + if (!istype(I)) + return 0 + if (I.block == HULKBLOCK && I.buf)//Block Injector + var/datum/dna2/record/R = I.buf + if (R.types & DNA2_BUF_SE)//SE Injector + var/bstate = R.dna.GetSEState(HULKBLOCK) + return bstate + return 0 + +/datum/centcomm_order/department/medical/telepathy/New() + ..() + request_consoles_to_notify = list( + "Chief Medical Officer's Desk", + "Genetics", + ) + requested = list( + /obj/item/weapon/dnainjector = rand (1,3) + ) + name_override = list( + /obj/item/weapon/dnainjector = "Telepathy SE Block Injector" + ) + worth = 300 * requested[requested[1]] + +/datum/centcomm_order/department/medical/telepathy/ExtraChecks(var/obj/item/weapon/dnainjector/I) + if (!istype(I)) + return 0 + if (I.block == REMOTETALKBLOCK && I.buf)//Block Injector + var/datum/dna2/record/R = I.buf + if (R.types & 4)//SE Injector + var/bstate = R.dna.GetSEState(REMOTETALKBLOCK) + return bstate + return 0 + +/datum/centcomm_order/department/medical/remoteview/New() + ..() + request_consoles_to_notify = list( + "Chief Medical Officer's Desk", + "Genetics", + ) + requested = list( + /obj/item/weapon/dnainjector = rand (1,3) + ) + name_override = list( + /obj/item/weapon/dnainjector = "Remote View SE Block Injector" + ) + worth = 300 * requested[requested[1]] + +/datum/centcomm_order/department/medical/remoteview/ExtraChecks(var/obj/item/weapon/dnainjector/I) + if (!istype(I)) + return 0 + if (I.block == REMOTEVIEWBLOCK && I.buf)//Block Injector + var/datum/dna2/record/R = I.buf + if (R.types & DNA2_BUF_SE)//SE Injector + var/bstate = R.dna.GetSEState(REMOTEVIEWBLOCK) + return bstate + return 0 + diff --git a/code/game/centcomm_orders/orders_science.dm b/code/game/centcomm_orders/orders_science.dm new file mode 100644 index 00000000000..27aff6b5afc --- /dev/null +++ b/code/game/centcomm_orders/orders_science.dm @@ -0,0 +1,464 @@ + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// // +// SCIENCE ORDERS // +// // +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//30 orders + +/datum/centcomm_order/department/science + acct_by_string = "Science" + request_consoles_to_notify = list( + "Research Director's Desk", + "Science", + ) + +//--------------------------------------------R&D stuff---------------------------------------------------- + + +/datum/centcomm_order/department/science/technology + var/required_tech + var/required_level + var/tech + +//Technology Data Disk, with a set tech and level required +/datum/centcomm_order/department/science/technology/New() + ..() + name = "Nanotrasen R&D" + tech = rand(1,4) + switch(tech) + if (1) + required_tech = /datum/tech/materials + required_level = 8 + if (2) + required_tech = /datum/tech/bluespace + required_level = 4 + if (3) + required_tech = /datum/tech/combat + required_level = 5 + if (4) + required_tech = /datum/tech/magnets + required_level = 5 + requested = list( + /obj/item/weapon/disk/tech_disk = 1 + ) + name_override = list( + /obj/item/weapon/disk/tech_disk = "Technology Data Disk" + ) + var/datum/tech/DT = required_tech + extra_requirements = "tech required: [initial(DT.name)] (Level [required_level])" + worth = 750 + +/datum/centcomm_order/department/science/technology/ExtraChecks(var/obj/item/weapon/disk/tech_disk/TD) + if (!istype(TD)) + return 0 + if (istype(TD.stored, required_tech)) + var/datum/tech/DT = TD.stored + if (DT.level >= required_level) + return 1 + return 0 + + +//Component Design Disk, with a set blueprint required +/datum/centcomm_order/department/science/design + var/required_comp + var/comp + +/datum/centcomm_order/department/science/design/New() + ..() + name = "Nanotrasen R&D" + var/comp = rand(1,5) + switch(comp) + if (1) + required_comp = /datum/design/rad_cell + worth = 800 + if (2) + required_comp = /datum/design/night_vision_goggles + worth = 500 + if (3) + required_comp = /datum/design/plasmabeaker + worth = 500 + if (4) + required_comp = /datum/design/bag_holding + worth = 700 + if (5) + required_comp = /datum/design/gravitywell + worth = 1000 + requested = list( + /obj/item/weapon/disk/design_disk = 1 + ) + name_override = list( + /obj/item/weapon/disk/design_disk = "Component Design Disk" + ) + var/obj/item/I = required_comp + extra_requirements = "blueprint required: [initial(I.name)]" + +/datum/centcomm_order/department/science/design/ExtraChecks(var/obj/item/weapon/disk/design_disk/DD) + if (!istype(DD)) + return 0 + if (istype(DD.blueprint, required_comp)) + return 1 + return 0 + +//Protolathe orders +/datum/centcomm_order/department/science/nuclear_gun/New() + ..() + name = "CentComm's ERT" + requested = list( + /obj/item/weapon/gun/energy/gun/nuclear = rand(1,5) + ) + worth = 750*requested[requested[1]] + +/datum/centcomm_order/department/science/plasmacutter/New() + ..() + requested = list( + /obj/item/weapon/pickaxe/plasmacutter/accelerator = rand(1,5) + ) + worth = 500*requested[requested[1]] + +/datum/centcomm_order/department/science/lasercannon/New() + ..() + requested = list( + /obj/item/weapon/gun/energy/laser/cannon = rand(1,5) + ) + worth = 500*requested[requested[1]] + +/datum/centcomm_order/department/science/assaultrifle/New() + ..() + requested = list( + /obj/item/weapon/gun/projectile/automatic/xcom = rand(1,5) + ) + worth = 500*requested[requested[1]] + +//Circuit Printer orders +/datum/centcomm_order/department/science/long_range_ai_upload/New() + ..() + requested = list( + /obj/item/weapon/circuitboard/aiupload/longrange = 1 + ) + worth = 500 + +/datum/centcomm_order/department/science/supermatter_board/New() + ..() + requested = list( + /obj/item/weapon/circuitboard/supermatter = 1 + ) + worth = 500 + +/datum/centcomm_order/department/science/telestation/New() + ..() + requested = list( + /obj/item/weapon/circuitboard/telestation = 1 + ) + worth = 500 + +/datum/centcomm_order/department/science/rust_core/New() + ..() + requested = list( + /obj/item/weapon/circuitboard/rust_core = 1 + ) + worth = 500 + + +//----------------------------------------------Robotics---------------------------------------------------- + +//So that means we either let cargo pilot the mechas and trust that they're not gonna steal them +//Or have the roboticist pilot them all the way to the supply shuttle +//We should find some other way to displace mechas later + +/datum/centcomm_order/department/science/phazon/New() + ..() + request_consoles_to_notify = list( + "Research Director's Desk", + "Robotics", + ) + must_be_in_crate = 0 + requested = list( + /obj/mecha/combat/phazon = 1 + ) + worth = 1200 + +/datum/centcomm_order/department/science/phazon/ExtraChecks(var/obj/mecha/M) + if (!istype(M)) + return 0 + M.wreckage = null + return 1 + +/datum/centcomm_order/department/science/durand/New() + ..() + request_consoles_to_notify = list( + "Research Director's Desk", + "Robotics", + ) + must_be_in_crate = 0 + requested = list( + /obj/mecha/combat/durand = 1 + ) + worth = 900 + +/datum/centcomm_order/department/science/durand/ExtraChecks(var/obj/mecha/M) + if (!istype(M)) + return 0 + M.wreckage = null + return 1 + +/datum/centcomm_order/department/science/gygax/New() + ..() + request_consoles_to_notify = list( + "Research Director's Desk", + "Robotics", + ) + must_be_in_crate = 0 + requested = list( + /obj/mecha/combat/gygax = 1 + ) + worth = 700 + +/datum/centcomm_order/department/science/gygax/ExtraChecks(var/obj/mecha/M) + if (!istype(M)) + return 0 + M.wreckage = null + return 1 + +/datum/centcomm_order/department/science/odysseus/New() + ..() + request_consoles_to_notify = list( + "Research Director's Desk", + "Robotics", + ) + must_be_in_crate = 0 + requested = list( + /obj/mecha/medical/odysseus = 1 + ) + worth = 600 + +/datum/centcomm_order/department/science/odysseus/ExtraChecks(var/obj/mecha/M) + if (!istype(M)) + return 0 + M.wreckage = null + return 1 + +/datum/centcomm_order/department/science/ripley/New() + ..() + request_consoles_to_notify = list( + "Research Director's Desk", + "Robotics", + ) + must_be_in_crate = 0 + requested = list( + /obj/mecha/working/ripley = 1 + ) + worth = 500 + +/datum/centcomm_order/department/science/ripley/ExtraChecks(var/obj/mecha/M) + if (!istype(M)) + return 0 + M.wreckage = null + return 1 + +/datum/centcomm_order/department/science/clarke/New() + ..() + request_consoles_to_notify = list( + "Research Director's Desk", + "Robotics", + ) + must_be_in_crate = 0 + requested = list( + /obj/mecha/working/clarke = 1 + ) + worth = 500 + +/datum/centcomm_order/department/science/clarke/ExtraChecks(var/obj/mecha/M) + if (!istype(M)) + return 0 + M.wreckage = null + return 1 + +/datum/centcomm_order/department/science/robot/New() + ..() + request_consoles_to_notify = list( + "Research Director's Desk", + "Robotics", + ) + must_be_in_crate = 0 + requested = list( + /obj/item/robot_parts/robot_suit = 1 + ) + name_override = list( + /obj/item/robot_parts/robot_suit = "Assembled Robot Chassis" + ) + extra_requirements = "A robot endoskeleton with arms, legs, head and torso assembled." + worth = 500 + +/datum/centcomm_order/department/science/robot/ExtraChecks(var/obj/item/robot_parts/robot_suit/RS) + if (!istype(RS)) + return 0 + if (RS.l_arm && RS.r_arm && RS.l_leg && RS.r_leg && RS.chest && RS.head) + return 1 + return 0 + +//-------------------------------------------Plasma Research------------------------------------------------ + +//what, you mean there's a reason for non-antags to make bombs now? and send them to cargo? oh boy this will be fun. + +/datum/centcomm_order/department/science/bomb + name = "CentComm Armory" + extra_requirements = "Epicenter Radius has to be X or more." + var/required_dev = 0 + +/datum/centcomm_order/department/science/bomb/New() + ..() + requested = list( + /obj/item/device/transfer_valve = 1 + ) + name_override = list( + /obj/item/device/transfer_valve = "TTV Explosive" + ) + required_dev = rand(2,5) + worth = required_dev * 500 - 500 + extra_requirements = "Epicenter Radius has to be [required_dev] or more." + +/datum/centcomm_order/department/science/bomb/ExtraChecks(var/obj/item/device/transfer_valve/TTV) + if (!istype(TTV)) + return 0 + if (TTV.simulate_merge() < required_dev) + return 0 + return 1 + +//----------------------------------------------Xenobiology---------------------------------------------------- + +//High-tier slime cores +/datum/centcomm_order/department/science/pyrite/New() + ..() + must_be_in_crate = 0 + requested = list( + /obj/item/slime_extract/pyrite = rand(1,3) + ) + worth = 600*requested[requested[1]] + +/datum/centcomm_order/department/science/cerulean/New() + ..() + must_be_in_crate = 0 + requested = list( + /obj/item/slime_extract/cerulean = rand(1,3) + ) + worth = 600*requested[requested[1]] + +/datum/centcomm_order/department/science/sepia/New() + ..() + must_be_in_crate = 0 + requested = list( + /obj/item/slime_extract/sepia = rand(1,3) + ) + worth = 600*requested[requested[1]] + +/datum/centcomm_order/department/science/bluespace/New() + ..() + must_be_in_crate = 0 + requested = list( + /obj/item/slime_extract/bluespace = rand(1,3) + ) + worth = 600*requested[requested[1]] + +/datum/centcomm_order/department/science/adamantine/New() + ..() + must_be_in_crate = 0 + requested = list( + /obj/item/slime_extract/adamantine = rand(1,3) + ) + worth = 600*requested[requested[1]] + +/datum/centcomm_order/department/science/oil/New() + ..() + must_be_in_crate = 0 + requested = list( + /obj/item/slime_extract/oil = rand(1,3) + ) + worth = 600*requested[requested[1]] + +/datum/centcomm_order/department/science/black/New() + ..() + must_be_in_crate = 0 + requested = list( + /obj/item/slime_extract/black = rand(1,3) + ) + worth = 600*requested[requested[1]] + +/datum/centcomm_order/department/science/lightpink/New() + ..() + must_be_in_crate = 0 + requested = list( + /obj/item/slime_extract/lightpink = rand(1,3) + ) + worth = 600*requested[requested[1]] + + +//----------------------------------------------Xenoarchaeology---------------------------------------------------- + +//Contained Large Artifacts +/datum/centcomm_order/department/science/artifact/New() + ..() + name = "Nanotrasen's Secure Containment Precinct" + must_be_in_crate = 0 + requested = list( + /obj/structure/anomaly_container = 1 + ) + name_override = list( + /obj/structure/anomaly_container = "Contained Large Anomaly" + ) + worth = 1500 + extra_requirements = "Must be shipped in an Anomaly Container, stamped with its Analysis Report, and after having been activated at least once." + +/datum/centcomm_order/department/science/artifact/ExtraChecks(var/obj/structure/anomaly_container/AC) + if (!istype(AC)) + return 0 + if (istype(AC.contained) && istype(AC.report)) + var/obj/machinery/artifact/contained = AC.contained + var/obj/item/weapon/paper/anomaly/report = AC.report + if ((report.artifact == contained) && contained.primary_effect?.triggered) + return 1 + return 0 + +//Full Supermatter. yes, the round-ending one. +/datum/centcomm_order/department/science/supermatter + hidden = TRUE + +/datum/centcomm_order/department/science/supermatter/New() + ..() + name = "Nanotrasen" + must_be_in_crate = 0 + requested = list( + /obj/machinery/power/supermatter = 1 + ) + worth = 5000 + extra_requirements = "A single of those can produce enough shards to power countless stations. Though extremely rare, Nanotrasen would be most grateful if you found one." + +//Large Crystals +/datum/centcomm_order/department/science/crystal/New() + ..() + name = "CentComm Beautification Department" + must_be_in_crate = 0 + requested = list( + /obj/structure/crystal = 1 + ) + worth = 300 + +//Assembled Alien Skeleton +/datum/centcomm_order/department/science/skeleton/New() + ..() + must_be_in_crate = 0 + requested = list( + /obj/structure/skeleton = 1 + ) + name_override = list( + /obj/structure/skeleton = "Complete Alien Skeleton" + ) + worth = 900 + extra_requirements = "The alien skeleton display needs to feature all its bones." + +/datum/centcomm_order/department/science/skeleton/ExtraChecks(var/obj/structure/skeleton/S) + if (!istype(S)) + return 0 + if (S.bstate) + return 1 + return 0 diff --git a/code/game/centcomm_orders/orders_service.dm b/code/game/centcomm_orders/orders_service.dm new file mode 100644 index 00000000000..a9cfa8e01a4 --- /dev/null +++ b/code/game/centcomm_orders/orders_service.dm @@ -0,0 +1,291 @@ + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// // +// SERVICE ORDERS // +// // +////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//8 orders + +//-------------------------------------------------Chef---------------------------------------------------- + +/datum/centcomm_order/department/civilian + acct_by_string = "Civilian" + +/datum/centcomm_order/per_unit/department/civilian + name = "Nanotrasen Farmers United" + acct_by_string = "Civilian" + +/datum/centcomm_order/department/civilian/food + var/sauce = 0//I SAID I WANTED KETCHUP + request_consoles_to_notify = list( + "Kitchen", + "Hydroponics", + ) + +/datum/centcomm_order/department/civilian/food/New() + ..() + var/chosen_food = rand(1,7) + switch(chosen_food) + if (1) + requested = list( + /obj/item/weapon/reagent_containers/food/snacks/pie = rand(3,12) + ) + worth = 30*requested[requested[1]] + name = "Clown Federation" //honk + //no sauce for those, we know they're not gonna eat them + if (2) + requested = list( + /obj/item/weapon/reagent_containers/food/snacks/sweetsundaeramen = rand(1,3) + ) + worth = 200*requested[requested[1]] + sauce = 1 + if (3) + requested = list( + /obj/item/weapon/reagent_containers/food/snacks/superbiteburger = rand(1,3) + ) + worth = 300*requested[requested[1]] + sauce = 2 + if (4) + requested = list( + /obj/item/weapon/reagent_containers/food/snacks/sliceable/turkey = rand(1,2) + ) + worth = 400*requested[requested[1]] + sauce = 2 + if (5) + requested = list( + /obj/item/weapon/reagent_containers/food/snacks/bleachkipper = rand(2,5) + ) + worth = 300*requested[requested[1]] + if (6) + requested = list( + /obj/item/weapon/reagent_containers/food/snacks/potentham = rand(1,2) + ) + worth = 1000*requested[requested[1]] + if (7) + requested = list( + /obj/item/weapon/reagent_containers/food/snacks/sundayroast = rand(1,2) + ) + worth = 700*requested[requested[1]] + sauce = 2 + if (sauce && prob(60)) + worth += 100 + switch (sauce) + if (1)//sweet + sauce = pick( + /datum/reagent/sugar, + /datum/reagent/caramel, + /datum/reagent/honey, + /datum/reagent/honey/royal_jelly, + /datum/reagent/cinnamon, + /datum/reagent/coco) + else//salty + sauce = pick( + /datum/reagent/mayo, + /datum/reagent/ketchup, + /datum/reagent/mustard, + /datum/reagent/capsaicin, + /datum/reagent/soysauce, + /datum/reagent/vinegar) + var/datum/reagent/R = sauce + extra_requirements = "With some [initial(R.name)] as well. Don't forget the sauce or the dish won't be accepted." + + +/datum/centcomm_order/department/civilian/food/ExtraChecks(var/obj/item/weapon/reagent_containers/food/snacks/F) + if (!istype(F)) + return 0 + if (!sauce) + return 1 + if (F.reagents?.has_reagent_type(sauce, amount = -1, strict = 1)) + return 1 + return 0 + + +/datum/centcomm_order/department/civilian/poutinecitadel/New() + ..() + request_consoles_to_notify = list( + "Kitchen", + ) + requested = list( + /obj/structure/poutineocean/poutinecitadel = 1 + ) + must_be_in_crate = 0 + worth = 1200 + +/datum/centcomm_order/department/civilian/popcake/New() + ..() + request_consoles_to_notify = list( + "Kitchen", + ) + requested = list( + /obj/structure/popout_cake = 1 + ) + must_be_in_crate = 0 + worth = 1000 + +//-------------------------------------------------Botany---------------------------------------------------- + + +/datum/centcomm_order/department/civilian/novaflower/New() + ..() + request_consoles_to_notify = list( + "Hydroponics", + ) + requested = list( + /obj/item/weapon/grown/novaflower = rand(3,8) + ) + worth = 70*requested[requested[1]] + + +/datum/centcomm_order/per_unit/department/civilian/potato/New() + ..() + request_consoles_to_notify = list( + "Hydroponics", + ) + requested = list( + /obj/item/weapon/reagent_containers/food/snacks/grown/potato = rand(50,200) + ) + unit_prices=list( + /obj/item/weapon/reagent_containers/food/snacks/grown/potato = 5 + ) + worth = "5$ per potato" + + +/datum/centcomm_order/per_unit/department/civilian/honeycomb + var/flavor + request_consoles_to_notify = list( + "Hydroponics", + ) + +/datum/centcomm_order/per_unit/department/civilian/honeycomb/New() + ..() + requested = list( + /obj/item/weapon/reagent_containers/food/snacks/honeycomb = rand(4,20) + ) + if (prob(50)) + unit_prices=list( + /obj/item/weapon/reagent_containers/food/snacks/honeycomb = 20 + ) + worth = "20$ per honeycomb" + flavor = pick( + /datum/reagent/drink/applejuice, + /datum/reagent/drink/grapejuice, + /datum/reagent/drink/banana, + ) + else + unit_prices=list( + /obj/item/weapon/reagent_containers/food/snacks/honeycomb = 60 + ) + worth = "60$ per honeycomb" + flavor = pick( + /datum/reagent/blood, + /datum/reagent/psilocybin, + /datum/reagent/hyperzine/cocaine, + )//we've got some interesting honey enthusiasts over at Central Command + + var/datum/reagent/F = flavor + name_override = list( + /obj/item/weapon/reagent_containers/food/snacks/honeycomb = "[initial(F.name)]-flavored Honeycombs" + ) + extra_requirements = "The flavor has to be natural, and not injected into the honeycomb." + +/datum/centcomm_order/per_unit/department/civilian/honeycomb/ExtraChecks(var/obj/item/weapon/reagent_containers/food/snacks/honeycomb/H) + if (!istype(H)) + return 0 + if (!flavor) + return 1 + if (!H.verify()) + return 0 + if (H.reagents?.has_reagent_type(flavor, amount = -1, strict = 1)) + return 1 + return 0 + +/datum/centcomm_order/department/civilian/salmon/New() + ..() + request_consoles_to_notify = list( + "Hydroponics", + ) + requested = list( + /obj/item/weapon/reagent_containers/food/snacks/salmonmeat = rand(3,8) + ) + worth = 130*requested[requested[1]] + + +//---------------------------------------------------Bar---------------------------------------------------- + + +/datum/centcomm_order/department/civilian/custom_drink + var/grown + request_consoles_to_notify = list( + "Bar", + ) + +/datum/centcomm_order/department/civilian/custom_drink/New() + ..() + grown = pick( + /obj/item/weapon/reagent_containers/food/snacks/grown/apple, + /obj/item/weapon/reagent_containers/food/snacks/grown/goldapple, + /obj/item/weapon/reagent_containers/food/snacks/grown/grapes, + /obj/item/weapon/reagent_containers/food/snacks/grown/greengrapes, + /obj/item/weapon/reagent_containers/food/snacks/grown/lime, + /obj/item/weapon/reagent_containers/food/snacks/grown/lemon, + /obj/item/weapon/reagent_containers/food/snacks/grown/orange, + /obj/item/weapon/reagent_containers/food/snacks/grown/banana, + /obj/item/weapon/reagent_containers/food/snacks/grown/killertomato, + /obj/item/weapon/reagent_containers/food/snacks/grown/pear, + /obj/item/weapon/reagent_containers/food/snacks/grown/aloe, + ) + var/obj/item/weapon/reagent_containers/food/snacks/grown/G = grown + var/chosen_drink = rand(1,5) + switch(chosen_drink) + if (1) + requested = list( + /obj/item/weapon/reagent_containers/food/drinks/bottle/customizable/wine = rand(1,6) + ) + name_override = list( + /obj/item/weapon/reagent_containers/food/drinks/bottle/customizable/wine = "[initial(G.name)] wine" + ) + if (2) + requested = list( + /obj/item/weapon/reagent_containers/food/drinks/bottle/customizable/whiskey = rand(1,6) + ) + name_override = list( + /obj/item/weapon/reagent_containers/food/drinks/bottle/customizable/whiskey = "[initial(G.name)] whiskey" + ) + if (3) + requested = list( + /obj/item/weapon/reagent_containers/food/drinks/bottle/customizable/vermouth = rand(1,6) + ) + name_override = list( + /obj/item/weapon/reagent_containers/food/drinks/bottle/customizable/vermouth = "[initial(G.name)] vermouth" + ) + if (4) + requested = list( + /obj/item/weapon/reagent_containers/food/drinks/bottle/customizable/vodka = rand(1,6) + ) + name_override = list( + /obj/item/weapon/reagent_containers/food/drinks/bottle/customizable/vodka = "[initial(G.name)] vodka" + ) + if (5) + requested = list( + /obj/item/weapon/reagent_containers/food/drinks/bottle/customizable/ale = rand(1,6) + ) + name_override = list( + /obj/item/weapon/reagent_containers/food/drinks/bottle/customizable/ale = "[initial(G.name)] ale" + ) + worth = 100*requested[requested[1]] + +/datum/centcomm_order/department/civilian/custom_drink/ExtraChecks(var/obj/item/weapon/reagent_containers/food/drinks/bottle/customizable/C) + if (!istype(C)) + return 0 + if (!grown) + return 1 + for(var/obj/item/weapon/reagent_containers/food/snacks/S in C.ingredients) + var/ok = 0 + var/ruined = 0 + if (istype(S, grown)) + ok = 1 + else + ruined = 1 + if (ok && !ruined) + return 1 + return 0 diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 422918e3246..028b3b668e2 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -1,10 +1,5 @@ #define DNA_BLOCK_SIZE 3 -// Buffer datatype flags. -#define DNA2_BUF_UI 1 -#define DNA2_BUF_UE 2 -#define DNA2_BUF_SE 4 - #define MAX_RADIATION_DURATION 20 #define MAX_RADIATION_INTENSITY 10 diff --git a/code/game/gamemodes/scoreboard.dm b/code/game/gamemodes/scoreboard.dm index 73e42b4e02a..0f94f9bf089 100644 --- a/code/game/gamemodes/scoreboard.dm +++ b/code/game/gamemodes/scoreboard.dm @@ -273,7 +273,8 @@ messpoints = score["mess"] //If there are any messes, let's count them //--Supply-- - //var/shipping = score["stuffshipped"] * 5 //Does not work currently + var/shipping = score["stuffshipped"] * 100 //Centcom Orders fulfilled + var/plasmashipped = score["plasmashipped"] * 0.5 //Plasma Sheets shipped var/mining = score["oremined"] * 1 //Not actually counted at mining, but at processing. One ore smelted is one point //--Engineering-- @@ -331,7 +332,8 @@ score["crewscore"] -= comdeadpts*/ //Good Things - //score["crewscore"] += shipping + score["crewscore"] += plasmashipped + score["crewscore"] += shipping score["crewscore"] += harvests score["crewscore"] += mining score["crewscore"] += eventpoints @@ -518,6 +520,8 @@ Meals Prepared: [score["meals"]] ([score["meals"] * 5] Points)
Hydroponics Harvests: [score["stuffharvested"]] ([score["stuffharvested"] * 1] Points)
Ultra-Clean Station: [score["messbonus"] ? "Yes" : "No"] ([score["messbonus"] * 10000] Points)
+ Plasma Shipped: [score["plasmashipped"]] ([score["plasmashipped"] * 0.5] Points)
+ Centcom Orders Fulfilled: [score["stuffshipped"]] ([score["stuffshipped"] * 100] Points)
Ore Smelted: [score["oremined"]] ([score["oremined"] * 1] Points)
Whole Station Powered: [score["powerbonus"] ? "Yes" : "No"] ([score["powerbonus"] * 2500] Points)
Isolated Vaccines: [score["disease_vaccine"]] ([score["disease_vaccine_score"]] Points)
@@ -602,9 +606,15 @@ if(score["dmgestdamage"]) dat += "Most Battered Escapee: [score["dmgestname"]], [score["dmgestjob"]]: [score["dmgestdamage"]] damage ([score["dmgestkey"]])
" if(score["richestcash"]) - dat += "Richest Escapee: [score["richestname"]], [score["richestjob"]]: [score["richestcash"]] space credits ([score["richestkey"]])
" + dat += "Richest Escapee: [score["richestname"]], [score["richestjob"]]: $[score["richestcash"]] ([score["richestkey"]])
" else dat += "The station wasn't evacuated or there were no survivors!
" + + dat += "Department Leaderboard:
" + var/list/dept_leaderboard = get_dept_leaderboard() + for (var/i = 1 to dept_leaderboard.len) + dat += "#[i] - [dept_leaderboard[i]] ($[dept_leaderboard[dept_leaderboard[i]]])
" + dat += {"

FINAL SCORE: [score["crewscore"]]
"} diff --git a/code/game/jobs/jobs.dm b/code/game/jobs/jobs.dm index 20f0a09fe23..754ec57b362 100644 --- a/code/game/jobs/jobs.dm +++ b/code/game/jobs/jobs.dm @@ -95,6 +95,12 @@ var/list/civilian_positions = list( "Assistant" ) +var/list/service_positions = list( + "Bartender", + "Botanist", + "Chef", +) + var/list/cargo_positions = list( "Head of Personnel", "Quartermaster", diff --git a/code/game/machinery/bees_apiary.dm b/code/game/machinery/bees_apiary.dm index a397654fbb0..3d0fa99533c 100644 --- a/code/game/machinery/bees_apiary.dm +++ b/code/game/machinery/bees_apiary.dm @@ -331,6 +331,7 @@ var/list/apiaries_list = list() H.icon_state = "[species.prefix]honeycomb-base" H.overlays += I reagents.trans_to(H,reagents_per_honeycomb) + H.authentify() return 1 diff --git a/code/game/machinery/computer/cargo.dm b/code/game/machinery/computer/cargo.dm index 3dedcee0c3b..a6d6cb8b717 100644 --- a/code/game/machinery/computer/cargo.dm +++ b/code/game/machinery/computer/cargo.dm @@ -269,7 +269,10 @@ For vending packs, see vending_packs.dm*/ var/centcomm_list[0] for(var/datum/centcomm_order/O in SSsupply_shuttle.centcomm_orders) - centcomm_list.Add(list(list("id" = O.id, "requested" = O.getRequestsByName(), "fulfilled" = O.getFulfilledByName(), "name" = O.name, "worth" = O.worth, "to" = O.acct_by_string))) + var/displayworth = O.worth + if (isnum(O.worth)) + displayworth = "[O.worth]$" + centcomm_list.Add(list(list("id" = O.id, "requested" = O.getRequestsByName(), "extra" = O.extra_requirements, "fulfilled" = O.getFulfilledByName(), "name" = O.name, "worth" = displayworth, "to" = O.acct_by_string))) data["centcomm_orders"] = centcomm_list var/datum/money_account/account = current_acct["account"] diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 02b80bb20c5..bb1bc9362c6 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -162,6 +162,35 @@ temp = tank_one.air_contents.remove_ratio(1) tank_two.air_contents.merge(temp) +/obj/item/device/transfer_valve/proc/simulate_merge() + //This proc basically reproduces step by step the gas changes that would lead to an explosion + //And returns said explosion's Epicenter radius (aka Devastation radius, or "Dev") + + var/datum/gas_mixture/temp_first = new (tank_one.air_contents) + var/datum/gas_mixture/temp_second = new (tank_two.air_contents) + + temp_first.merge(temp_second) + + temp_first.react() + + var/pressure = temp_first.return_pressure()/2 + + if(pressure <= TANK_FRAGMENT_PRESSURE) + return 0 + + temp_first.react() + temp_first.react() + temp_first.react() + + pressure = temp_first.return_pressure()/2 + + var/range = (pressure-TANK_FRAGMENT_PRESSURE)/TANK_FRAGMENT_SCALE + + var/dev = round(range*0.25) + + return dev + + /obj/item/device/transfer_valve/proc/split_gases() if (!valve_open || !tank_one || !tank_two) return diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm index 06f59bd50d9..29dde71f009 100644 --- a/code/game/objects/items/weapons/storage/lockbox.dm +++ b/code/game/objects/items/weapons/storage/lockbox.dm @@ -342,6 +342,7 @@ icon_state = "map_diskbox" item_state = "diskbox" can_only_hold = list("/obj/item/weapon/disk") + cant_hold = list("/obj/item/weapon/disk/harddiskdrive") fits_max_w_class = 3 w_class = W_CLASS_MEDIUM max_combined_w_class = 14 //The sum of the w_classes of all the items in this storage item. diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index 0631fc8a07f..30278d2017e 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -247,7 +247,9 @@ return 0 var/pressure = air_contents.return_pressure() + if(pressure > TANK_FRAGMENT_PRESSURE) + if(!istype(src.loc,/obj/item/device/transfer_valve)) message_admins("Explosive tank rupture! last key to touch the tank was [src.fingerprintslast].") log_game("Explosive tank rupture! last key to touch the tank was [src.fingerprintslast].") diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 952899f0c97..60ba9c3c446 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -131,6 +131,7 @@ var/list/admin_verbs_fun = list( /client/proc/set_teleport_pref, /client/proc/deadchat_singularity, /client/proc/view_all_rods, + /client/proc/add_centcomm_order, ) var/list/admin_verbs_spawn = list( /datum/admins/proc/spawn_atom, // Allows us to spawn instances diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 213c1b6550a..36f3ee43142 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -1319,6 +1319,18 @@ client/proc/check_convertables() error_cache.show_to(src) +/client/proc/add_centcomm_order() + set category = "Fun" + set name = "Central Command Request" + set desc = "Send a Central Command Request" + + if (!check_rights(R_FUN)) + return + + var/ordertype = input("Select a Request.","Central Command Request",1) as null|anything in (subtypesof(/datum/centcomm_order) - /datum/centcomm_order/per_unit) + if (ordertype) + SSsupply_shuttle.add_centcomm_order(new ordertype) + /client/proc/emergency_shuttle_panel() set name = "Emergency Shuttle Panel" set category = "Debug" diff --git a/code/modules/events/centcomm_order.dm b/code/modules/events/centcomm_order.dm deleted file mode 100644 index e1d6460e8d1..00000000000 --- a/code/modules/events/centcomm_order.dm +++ /dev/null @@ -1,9 +0,0 @@ -//Refer to game/centcomm_orders.dm - -/datum/event/centcomm_order - -/datum/event/centcomm_order/can_start() - return 25 - -/datum/event/centcomm_order/start() - create_random_order() \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/bees/bees_items.dm b/code/modules/mob/living/simple_animal/bees/bees_items.dm index 3adcdd1e230..f322d332f55 100644 --- a/code/modules/mob/living/simple_animal/bees/bees_items.dm +++ b/code/modules/mob/living/simple_animal/bees/bees_items.dm @@ -170,6 +170,7 @@ name = "honeycomb" icon_state = "honeycomb" desc = "Dripping with sugary sweetness. Grind it to separate the honey." + var/list/authentic = list() /obj/item/weapon/reagent_containers/food/snacks/honeycomb/New() . = ..() @@ -200,6 +201,22 @@ icon_state = "chill_honeycomb-base" overlays += I +/obj/item/weapon/reagent_containers/food/snacks/honeycomb/proc/authentify() + authentic = list() + for (var/datum/reagent/R in reagents.reagent_list) + authentic[R.id] = R.volume + +/obj/item/weapon/reagent_containers/food/snacks/honeycomb/proc/verify() + for (var/datum/reagent/R in reagents.reagent_list) + if (!(R.id in authentic) || (authentic[R.id] != R.volume))//making sure that no reagent has been added or changed + return FALSE + else + authentic -= R.id + + if (authentic.len <= 0)//are we sure no reagent has been removed shomehow + return TRUE + return FALSE + /obj/item/weapon/book/manual/hydroponics_beekeeping name = "The Ins and Outs of Apiculture - A Precise Art" icon_state ="bookHydroponicsBees" diff --git a/code/modules/organs/organ_objects.dm b/code/modules/organs/organ_objects.dm index 79a792dd5fc..e13d2534f8f 100644 --- a/code/modules/organs/organ_objects.dm +++ b/code/modules/organs/organ_objects.dm @@ -29,6 +29,14 @@ "immunity" = null, ) + var/static/list/safe_containers = list( + /obj/item/device/mmi, + /obj/item/bodybag/cryobag, + /obj/structure/closet/crate/freezer, + /obj/structure/closet/crate/medical, + /obj/structure/closet/crate/secure/medsec, + ) + /obj/item/organ/internal/attack_self(mob/user as mob) // Convert it to an edible form, yum yum. @@ -69,11 +77,10 @@ processing_objects -= src return - // Don't process if we're in a freezer, an MMI or a stasis bag. //TODO: ambient temperature? - if(istype(loc,/obj/item/device/mmi) || istype(loc,/obj/item/bodybag/cryobag) || istype(loc,/obj/structure/closet/crate/freezer)) + //TODO: ambient temperature? + if(is_type_in_list(loc,safe_containers)) return - if(istype(loc,/obj/item/weapon/reagent_containers/glass/jar)) var/obj/item/weapon/reagent_containers/glass/jar/J = loc if(J.safe_holder()) diff --git a/code/modules/research/xenoarchaeology/artifact/artifact.dm b/code/modules/research/xenoarchaeology/artifact/artifact.dm index 8be985fa3bc..7093e7ec793 100644 --- a/code/modules/research/xenoarchaeology/artifact/artifact.dm +++ b/code/modules/research/xenoarchaeology/artifact/artifact.dm @@ -140,6 +140,11 @@ var/list/boulders = list() var/spawn_type = artifact_find.artifact_find_type if (spawn_type == /obj/machinery/artifact) new spawn_type(get_turf(src), artifact_find.artifact_id) + else if (spawn_type == /obj/machinery/power/supermatter) + spawn(rand(10 MINUTES, 30 MINUTES))//The time it takes for Nanotrasen to detect it and make the Science dept an offer they cannot refuse. + if (!(locate(/datum/centcomm_order/department/science/supermatter) in SSsupply_shuttle.centcomm_orders)) + SSsupply_shuttle.add_centcomm_order(new /datum/centcomm_order/department/science/supermatter) + new spawn_type(get_turf(src)) else var/atom/movable/AM = new spawn_type(get_turf(src)) excavated_large_artifacts[artifact_find.artifact_id] = AM diff --git a/nano/templates/supply_console.tmpl b/nano/templates/supply_console.tmpl index 6aa4a23a478..8438da0529e 100644 --- a/nano/templates/supply_console.tmpl +++ b/nano/templates/supply_console.tmpl @@ -160,9 +160,14 @@ Used In File(s): \code\game\supplyshuttle.dm #{{:value.id}}
Requested:
{{:value.requested}}
+ {{if value.extra}} + {{:value.extra}}
+ {{/if}} Fulfilled:
- {{:value.fulfilled}}
- for {{:value.name}}: worth {{:value.worth}} to {{:value.to}}
+ {{if value.fulfilled}} + {{:value.fulfilled}}
+ {{/if}} + for {{:value.name}}: worth {{:value.worth}} to {{:value.to}}
{{empty}} No active requests. diff --git a/vgstation13.dme b/vgstation13.dme index 0deba680659..f1be4edd6a1 100644 --- a/vgstation13.dme +++ b/vgstation13.dme @@ -515,7 +515,6 @@ #include "code\game\asteroid.dm" #include "code\game\atoms.dm" #include "code\game\atoms_movable.dm" -#include "code\game\centcomm_orders.dm" #include "code\game\communications.dm" #include "code\game\data_huds.dm" #include "code\game\say.dm" @@ -528,6 +527,12 @@ #include "code\game\area\areas.dm" #include "code\game\area\shadows.dm" #include "code\game\area\Space Station 13 areas.dm" +#include "code\game\centcomm_orders\centcomm_orders.dm" +#include "code\game\centcomm_orders\orders_cargo.dm" +#include "code\game\centcomm_orders\orders_engineering.dm" +#include "code\game\centcomm_orders\orders_medical.dm" +#include "code\game\centcomm_orders\orders_science.dm" +#include "code\game\centcomm_orders\orders_service.dm" #include "code\game\dna\dna2.dm" #include "code\game\dna\dna2_domutcheck.dm" #include "code\game\dna\dna2_helpers.dm" @@ -1505,7 +1510,6 @@ #include "code\modules\events\bluespaceanomaly.dm" #include "code\modules\events\brand_intelligence.dm" #include "code\modules\events\carp_migration.dm" -#include "code\modules\events\centcomm_order.dm" #include "code\modules\events\communications_blackout.dm" #include "code\modules\events\disease_outbreak.dm" #include "code\modules\events\electrical_storm.dm"