//Supply packs are in /code/datums/supplypacks //Computers are in /code/game/machinery/computer/supply.dm SUBSYSTEM_DEF(supply) name = "Supply" wait = 20 SECONDS priority = FIRE_PRIORITY_SUPPLY //Initializes at default time flags = SS_NO_TICK_CHECK //supply points var/points = 50 var/points_per_process = 1.0 // Processes every 20 seconds, so this is 3 per minute var/points_per_slip = 2 var/points_per_money = 0.02 // 1 point for $50 //control var/ordernum = 0 // Start at zero, it's per-shift tracking var/list/shoppinglist = list() // Approved orders var/list/supply_pack = list() // All supply packs var/list/exported_crates = list() // Crates sent from the station var/list/order_history = list() // History of orders, showing edits made by users var/list/adm_order_history = list() // Complete history of all orders, for admin use var/list/adm_export_history = list() // Complete history of all crates sent back on the shuttle, for admin use //shuttle movement var/movetime = 1200 var/datum/shuttle/autodock/ferry/supply/shuttle /datum/controller/subsystem/supply/Initialize() // build master supply list for(var/typepath in subtypesof(/datum/supply_pack)) var/datum/supply_pack/P = new typepath() if(P.name) supply_pack[P.name] = P else qdel(P) return SS_INIT_SUCCESS // Supply shuttle ticker - handles supply point regeneration. Just add points over time. /datum/controller/subsystem/supply/fire() points += points_per_process /datum/controller/subsystem/supply/stat_entry(msg) msg = "Points: [points]" return ..() //To stop things being sent to CentCom which should not be sent to centcomm. Recursively checks for these types. /datum/controller/subsystem/supply/proc/forbidden_atoms_check(atom/A) if(isliving(A)) return 1 if(istype(A,/obj/item/disk/nuclear)) return 1 if(istype(A,/obj/machinery/nuclearbomb)) return 1 if(istype(A,/obj/item/radio/beacon)) return 1 if(istype(A,/obj/item/perfect_tele_beacon)) //VOREStation Addition: Translocator beacons return 1 //VOREStation Addition: Translocator beacons if(istype(A,/obj/machinery/power/quantumpad)) // //VOREStation Add: Quantum pads return 1 //VOREStation Add: Quantum pads if(istype(A,/obj/structure/extraction_point )) // CHOMPStation Add: Fulton beacons return 1 for(var/atom/B in A.contents) if(.(B)) return 1 //Selling /datum/controller/subsystem/supply/proc/sell() // Loop over each area in the supply shuttle for(var/area/subarea in shuttle.shuttle_area) callHook("sell_shuttle", list(subarea)); for(var/atom/movable/MA in subarea) if(MA.anchored) continue var/datum/exported_crate/EC = new /datum/exported_crate() EC.name = "\proper[MA.name]" EC.value = 0 EC.contents = list() var/base_value = 0 // Must be in a crate! if(istype(MA,/obj/structure/closet/crate)) var/obj/structure/closet/crate/CR = MA callHook("sell_crate", list(CR, subarea)) points += CR.points_per_crate if(CR.points_per_crate) base_value = CR.points_per_crate var/find_slip = 1 for(var/atom/A in CR) EC.contents[++EC.contents.len] = list( "object" = "\proper[A.name]", "value" = 0, "quantity" = 1 ) // Sell manifests if(find_slip && istype(A,/obj/item/paper/manifest)) var/obj/item/paper/manifest/slip = A if(!slip.is_copy && slip.stamped && slip.stamped.len) //yes, the clown stamp will work. clown is the highest authority on the station, it makes sense points += points_per_slip EC.contents[EC.contents.len]["value"] = points_per_slip find_slip = 0 continue // Sell phoron and platinum if(istype(A, /obj/item/stack)) var/obj/item/stack/P = A var/datum/material/mat = P.get_material() if(mat?.supply_conversion_value) EC.contents[EC.contents.len]["value"] = P.get_amount() * mat.supply_conversion_value EC.contents[EC.contents.len]["quantity"] = P.get_amount() EC.value += EC.contents[EC.contents.len]["value"] //Sell spacebucks if(istype(A, /obj/item/spacecash)) var/obj/item/spacecash/cashmoney = A EC.contents[EC.contents.len]["value"] = cashmoney.worth * points_per_money EC.contents[EC.contents.len]["quantity"] = cashmoney.worth EC.value += EC.contents[EC.contents.len]["value"] if(istype(A, /obj/item/reagent_containers/glass/bottle/vaccine)) var/obj/item/reagent_containers/glass/bottle/vaccine/sale_bottle = A if(!istype(CR, /obj/structure/closet/crate/freezer)) EC.contents = list( "error" = "Error: Product was improperly packaged. Send conents in freezer crate to preserve contents for transport." ) else if(sale_bottle.reagents.reagent_list.len != 1 || sale_bottle.reagents.get_reagent_amount(REAGENT_ID_VACCINE) < sale_bottle.volume) EC.contents = list( "error" = "Error: Tainted product in batch. Was opened, contaminated, or was full. Payment rendered null under terms of agreement." ) else EC.contents[EC.contents.len]["value"] = 5 EC.value += EC.contents[EC.contents.len]["value"] // CHOMPAdd Start - Sell salvage if(istype(A, /obj/item/salvage)) var/obj/item/salvage/salvagedStuff = A EC.contents[EC.contents.len]["value"] = salvagedStuff.worth // CHOMPAdd End // CHOMPedit begin - Selling engineered organs if(istype(A, /obj/item/organ/internal)) var/obj/item/organ/internal/organ_stuff = A if(!istype(CR,/obj/structure/closet/crate/freezer)) EC.contents = list( "error" = "Error: Product was improperly packaged. Send contents in freezer crate to preserve contents for transport." ) else if(organ_stuff.health != initial(organ_stuff.health) ) EC.contents = list( "error" = "Error: Product was damaged on arrival." ) else EC.contents[EC.contents.len]["value"] = organ_stuff.supply_conversion_value EC.value += EC.contents[EC.contents.len]["value"] // CHOMPedit end // Make a log of it, but it wasn't shipped properly, and so isn't worth anything else EC.contents = list( "error" = "Error: Product was improperly packaged. Payment rendered null under terms of agreement." ) exported_crates += EC points += EC.value EC.value += base_value // Duplicate the receipt for the admin-side log var/datum/exported_crate/adm = new() adm.name = EC.name adm.value = EC.value adm.contents = deepCopyList(EC.contents) adm_export_history += adm qdel(MA) /datum/controller/subsystem/supply/proc/get_clear_turfs() var/list/clear_turfs = list() for(var/area/subarea in shuttle.shuttle_area) for(var/turf/T in subarea) if(T.density) continue var/occupied = 0 for(var/atom/A in T.contents) if(!A.simulated) continue occupied = 1 break if(!occupied) clear_turfs += T return clear_turfs //Buying /datum/controller/subsystem/supply/proc/buy() var/list/shoppinglist = list() for(var/datum/supply_order/SO in order_history) if(SO.status == SUP_ORDER_APPROVED) shoppinglist += SO if(!shoppinglist.len) return var/orderedamount = shoppinglist.len var/list/clear_turfs = get_clear_turfs() var/shopping_log = "SUPPLY_BUY: " for(var/datum/supply_order/SO in shoppinglist) if(!clear_turfs.len) break var/i = rand(1,clear_turfs.len) var/turf/pickedloc = clear_turfs[i] clear_turfs.Cut(i,i+1) SO.status = SUP_ORDER_SHIPPED var/datum/supply_pack/SP = SO.object shopping_log += "[SP.name];" var/obj/A if(SP.containertype) A = new SP.containertype(pickedloc) A.name = "[SP.containername] [SO.comment ? "([SO.comment])":"" ]" if(SP.access) if(isnum(SP.access)) A.req_access = list(SP.access) else if(islist(SP.access) && SP.one_access) var/list/L = SP.access // access var is a plain var, we need a list A.req_one_access = L.Copy() LAZYCLEARLIST(A.req_access) else if(islist(SP.access) && !SP.one_access) var/list/L = SP.access A.req_access = L.Copy() LAZYCLEARLIST(A.req_one_access) else log_debug(span_danger("Supply pack with invalid access restriction [SP.access] encountered!")) //supply manifest generation begin var/obj/item/paper/manifest/slip if(!SP.contraband) if(A) slip = new /obj/item/paper/manifest(A) else slip = new /obj/item/paper/manifest(pickedloc) slip.is_copy = 0 slip.info = "