//Config stuff #define SUPPLY_DOCKZ 2 //Z-level of the Dock. #define SUPPLY_STATIONZ 1 //Z-level of the Station. #define SUPPLY_POINTSPER 10 //Points per tick. #define SUPPLY_POINTDELAY 3000 //Delay between ticks in milliseconds. #define SUPPLY_MOVETIME 1800 //Time to station is milliseconds. #define SUPPLY_POINTSPERCRATE 5 //Points per crate sent back. #define SUPPLY_STATION_AREATYPE "/area/supply/station" //Type of the supply shuttle area for station #define SUPPLY_DOCK_AREATYPE "/area/supply/dock" //Type of the supply shuttle area for dock #define SUPPLY_POINTSPERSLIP 2 //points per packing slip sent back stamped. var/supply_shuttle_moving = 0 var/supply_shuttle_at_station = 0 var/list/supply_shuttle_shoppinglist = new/list() var/list/supply_shuttle_requestlist = new/list() var/supply_shuttle_can_send = 1 var/supply_shuttle_time = 0 var/supply_shuttle_timeleft = 0 var/supply_shuttle_points = 50 var/ordernum=0 /area/supply/station //DO NOT TURN THE SD_LIGHTING STUFF ON FOR SHUTTLES. IT BREAKS THINGS. name = "supply shuttle" icon_state = "shuttle3" luminosity = 1 sd_lighting = 0 requires_power = 0 /area/supply/dock //DO NOT TURN THE SD_LIGHTING STUFF ON FOR SHUTTLES. IT BREAKS THINGS. name = "supply shuttle" icon_state = "shuttle3" luminosity = 1 sd_lighting = 0 requires_power = 0 //SUPPLY PACKS MOVED TO /code/defines/obj/supplypacks.dm /obj/structure/plasticflaps //HOW DO YOU CALL THOSE THINGS ANYWAY name = "\improper Plastic flaps" desc = "I definitely cant get past those. No way." icon = 'stationobjs.dmi' //Change this. icon_state = "plasticflaps" density = 0 anchored = 1 layer = 4 /obj/structure/plasticflaps/CanPass(atom/A, turf/T) if(istype(A) && A.checkpass(PASSGLASS)) return prob(60) else if(istype(A, /mob/living)) // You Shall Not Pass! var/mob/living/M = A if(!M.lying && !istype(M, /mob/living/carbon/monkey) && !istype(M, /mob/living/carbon/metroid)) //If your not laying down, or a small creature, no pass. return 0 return ..() /obj/structure/plasticflaps/ex_act(severity) switch(severity) if (1) del(src) if (2) if (prob(50)) del(src) if (3) if (prob(5)) del(src) /obj/structure/plasticflaps/mining //A specific type for mining that doesn't allow airflow because of them damn crates name = "\improper Airtight plastic flaps" desc = "Heavy duty, airtight, plastic flaps." New() //set the turf below the flaps to block air var/turf/T = get_turf(src.loc) if(T) T.blocks_air = 1 ..() Del() //lazy hack to set the turf to allow air to pass if it's a simulated floor var/turf/T = get_turf(src.loc) if(T) if(istype(T, /turf/simulated/floor)) T.blocks_air = 0 ..() /area/supplyshuttle name = "Supply Shuttle" icon_state = "supply" requires_power = 0 /obj/machinery/computer/supplycomp name = "Supply shuttle console" icon = 'computer.dmi' icon_state = "supply" req_access = list(access_cargo) circuit = "/obj/item/weapon/circuitboard/supplycomp" var/temp = null var/hacked = 0 var/can_order_contraband = 0 /obj/machinery/computer/ordercomp name = "Supply ordering console" icon = 'computer.dmi' icon_state = "request" circuit = "/obj/item/weapon/circuitboard/ordercomp" var/temp = null var/reqtime = 0 //Cooldown for requisitions - Quarxink /obj/effect/marker/supplymarker icon_state = "X" icon = 'mark.dmi' name = "X" invisibility = 101 anchored = 1 opacity = 0 /datum/supply_order var/datum/supply_packs/object = null var/orderedby = null var/comment = null /datum/supply_packs var/name = null var/list/contains = new/list() var/amount = null var/cost = null var/containertype = null var/containername = null var/access = null var/hidden = 0 var/contraband = 0 /proc/supply_ticker() //world << "Supply ticker ticked : Adding [SUPPLY_POINTSPER] to [supply_shuttle_points]." supply_shuttle_points += SUPPLY_POINTSPER //world << "New SP total is [supply_shuttle_points]" spawn(SUPPLY_POINTDELAY) supply_ticker() /proc/supply_process() while(supply_shuttle_time - world.timeofday > 0) var/ticksleft = supply_shuttle_time - world.timeofday if(ticksleft > 1e5) supply_shuttle_time = world.timeofday + 10 // midnight rollover supply_shuttle_timeleft = round( ((ticksleft / 10)/60) ) sleep(10) supply_shuttle_moving = 0 send_supply_shuttle() /proc/supply_can_move() if(supply_shuttle_moving) return 0 //I know this is an absolutly horrendous way to do this, very inefficient, but it's the only reliable way I can think of. //Check for mobs for(var/mob/living/M in world) var/area/A = get_area(M) if(!A || !A.type) continue if(A.type == /area/supply/station) return 0 //Check for beacons for(var/obj/item/device/radio/beacon/B in world) var/area/A = get_area(B) if(!A || !A.type) continue if(A.type == /area/supply/station) return 0 //Check for mechs. I think this was added because people were somehow on centcomm and bringing back centcomm mechs. for(var/obj/mecha/Mech in world) var/area/A = get_area(Mech) if(!A || !A.type) continue if(A.type == /area/supply/station) return 0 //Check for nuke disk This also prevents multiple nuke disks from being made -Nodrak for(var/obj/item/weapon/disk/nuclear/N) var/area/A = get_area(N) if(!A || !A.type) continue if(A.type == /area/supply/station) return 0 return 1 /* Teleport beacon -> wrapping paper -> backpack -> bodybag -> crate -> wrapping paper -> loaded on a mulebot That would be a teleport beacon inside of 6-layers deep in contents. Meaning you would have to add more loops or more checks. This method wont take into account storage items developed in the future and doesn't take into account the storage items we have currently. -Nodrak var/shuttleat = supply_shuttle_at_station ? SUPPLY_STATION_AREATYPE : SUPPLY_DOCK_AREATYPE for(var/turf/T in get_area_turfs(shuttleat) ) //if((locate(/mob/living) in T) && (!locate(/mob/living/carbon/monkey) in T)) return 0 //old check for living excluded monkeys if((locate(/mob/living) in T)) return 0 if((locate(/obj/item/device/radio/beacon) in T)) return 0 if((locate(/obj/mecha) in T)) return 0 if((locate(/obj/structure/closet/body_bag) in T)) return 0 for(var/atom/ATM in T) if((locate(/mob/living) in ATM)) return 0 if((locate(/obj/item/device/radio/beacon) in ATM)) return 0 if((locate(/obj/mecha ) in ATM)) return 0 if((locate(/obj/structure/closet/body_bag) in ATM)) return 0 for(var/atom/ATMM in ATM) // okay jesus christ how many recursive packaging options are we going to have guys come on - Quarxink if((locate(/mob/living) in ATMM)) return 0 if((locate(/obj/item/device/radio/beacon) in ATMM)) return 0 if((locate(/obj/mecha ) in ATMM)) return 0 if((locate(/obj/structure/closet/body_bag) in ATMM)) return 0 return 1 */ /proc/sell_crates() var/shuttleat = supply_shuttle_at_station ? SUPPLY_STATION_AREATYPE : SUPPLY_DOCK_AREATYPE for(var/turf/T in get_area_turfs(shuttleat) ) var/obj/item/weapon/paper/slip = locate(/obj/item/weapon/paper/manifest) in T if(slip) if(slip.stamped && slip.stamped.len) //yes, the clown stamp will work. clown is the highest authority on the station, it makes sense supply_shuttle_points += SUPPLY_POINTSPERSLIP del(slip) var/crate = locate(/obj/structure/closet/crate) in T if(crate) del(crate) supply_shuttle_points += SUPPLY_POINTSPERCRATE /obj/item/weapon/paper/manifest name = "Supply Manifest" /proc/process_supply_order() var/shuttleat = supply_shuttle_at_station ? SUPPLY_STATION_AREATYPE : SUPPLY_DOCK_AREATYPE var/list/markers = new/list() if(!supply_shuttle_shoppinglist.len) return for(var/turf/T in get_area_turfs(shuttleat)) for(var/obj/effect/marker/supplymarker/D in T) markers += D for(var/S in supply_shuttle_shoppinglist) var/pickedloc = 0 var/found = 0 for(var/C in markers) if ((locate(/obj/structure/closet/crate) in get_turf(C)) || (locate(/obj/structure/largecrate) in get_turf(C))) continue found = 1 pickedloc = get_turf(C) if (!found) pickedloc = get_turf(pick(markers)) var/datum/supply_order/SO = S var/datum/supply_packs/SP = SO.object var/atom/A = new SP.containertype ( pickedloc ) A.name = "[SP.containername] [SO.comment ? "([SO.comment])":"" ]" //supply manifest generation begin if(ordernum) ordernum++ else ordernum = rand(500,5000) //pick a random number to start with var/obj/item/weapon/paper/manifest/slip = new /obj/item/weapon/paper/manifest (A) slip.info = "" slip.info +="

[command_name()] Shipping Manifest



" slip.info +="Order #: [ordernum]
" slip.info +="Destination: [station_name]
" slip.info +="[supply_shuttle_shoppinglist.len] PACKAGES IN THIS SHIPMENT
" slip.info +="CONTENTS:

" slip.info += "CHECK CONTENTS AND STAMP BELOW THE LINE TO CONFIRM RECEIPT OF GOODS
" return /obj/machinery/computer/ordercomp/attack_ai(var/mob/user as mob) return src.attack_hand(user) /obj/machinery/computer/ordercomp/attack_paw(var/mob/user as mob) return src.attack_hand(user) /obj/machinery/computer/supplycomp/attack_ai(var/mob/user as mob) return src.attack_hand(user) /obj/machinery/computer/supplycomp/attack_paw(var/mob/user as mob) return src.attack_hand(user) /obj/machinery/computer/ordercomp/attack_hand(var/mob/user as mob) if(..()) return user.machine = src var/dat if (src.temp) dat = src.temp else dat += {"
Supply shuttle
Location: [supply_shuttle_moving ? "Moving to station ([supply_shuttle_timeleft] Mins.)":supply_shuttle_at_station ? "Station":"Dock"]

Supply points: [supply_shuttle_points]

\nRequest items

View approved orders

View requests

Close"} user << browse(dat, "window=computer;size=575x450") onclose(user, "computer") return /obj/machinery/computer/ordercomp/Topic(href, href_list) if(..()) return if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) usr.machine = src if (href_list["order"]) src.temp = "Supply points: [supply_shuttle_points]


Request what?

" for(var/S in (typesof(/datum/supply_packs) - /datum/supply_packs) ) var/datum/supply_packs/N = new S() if(N.hidden || N.contraband) continue //Have to send the type instead of a reference to src.temp += "[N.name] Cost: [N.cost] " //the obj because it would get caught by the garbage src.temp += "Print Requisition
" //collector. oh well. src.temp += "
OK" else if (href_list["doorder"]) var/datum/supply_order/O = new/datum/supply_order () var/supplytype = href_list["doorder"] var/datum/supply_packs/P = new supplytype () O.object = P O.orderedby = usr.name supply_shuttle_requestlist += O src.temp = "Thanks for your request. The cargo team will process it as soon as possible.
" src.temp += "
OK" else if (href_list["printform"]) if (!reqtime) var/supplytype = href_list["printform"] var/datum/supply_packs/P = new supplytype () var/obj/item/weapon/paper/reqform = new /obj/item/weapon/paper(src.loc) var/idname = "Unknown" var/idrank = "Unknown" var/reason = copytext(sanitize(input(usr,"Reason:","Why do you require this item?","")),1,MAX_MESSAGE_LEN) if(!reason) reason = "Unknown" reqform.name = "Requisition Form - [P.name]" reqform.info += "

[station_name] Supply Requisition Form


" if (istype(usr:wear_id, /obj/item/weapon/card/id)) if(usr:wear_id.registered_name) idname = usr:wear_id.registered_name if(usr:wear_id.assignment) idrank = usr:wear_id.assignment if (istype(usr:wear_id, /obj/item/device/pda)) var/obj/item/device/pda/pda = usr:wear_id if(pda.owner) idname = pda.owner if(pda.ownjob) idrank = pda.ownjob else idname = usr.name reqform.info += "REQUESTED BY: [idname]
" reqform.info += "RANK: [idrank]
" reqform.info += "REASON: [reason]
" reqform.info += "SUPPLY CRATE TYPE: [P.name]
" reqform.info += "Contents:

" reqform.info += "STAMP BELOW TO APPROVE THIS REQUISITION:
" reqform.update_icon() //Fix for appearing blank when printed. reqtime = 5 //5 second cooldown initiated after each printed req, change the number to change the cooldown (in seconds) - Quarxink spawn(0) while(reqtime >=1 && src) sleep(10) reqtime -- reqtime = 0 else for (var/mob/V in hearers(src)) V.show_message("[src]'s monitor flashes, \"[reqtime] seconds remaining until another requisition form may be printed.\"") else if (href_list["vieworders"]) src.temp = "Current approved orders:

" for(var/S in supply_shuttle_shoppinglist) var/datum/supply_order/SO = S src.temp += "[SO.object.name] approved by [SO.orderedby] [SO.comment ? "([SO.comment])":""]
" src.temp += "
OK" else if (href_list["viewrequests"]) src.temp = "Current requests:

" for(var/S in supply_shuttle_requestlist) var/datum/supply_order/SO = S src.temp += "[SO.object.name] requested by [SO.orderedby]
" src.temp += "
OK" else if (href_list["mainmenu"]) src.temp = null src.add_fingerprint(usr) src.updateUsrDialog() return /obj/machinery/computer/supplycomp/attack_hand(var/mob/user as mob) if(!src.allowed(user)) user << "\red Access Denied." return if(..()) return user.machine = src post_signal("supply") var/dat if (src.temp) dat = src.temp else dat += {"
Supply shuttle
\nLocation: [supply_shuttle_moving ? "Moving to station ([supply_shuttle_timeleft] Mins.)":supply_shuttle_at_station ? "Station":"Away"]

\nSupply points: [supply_shuttle_points]
\n
[supply_shuttle_moving ? "\n*Must be away to order items*
\n
":supply_shuttle_at_station ? "\n*Must be away to order items*
\n
":"\nOrder items
\n
"] [supply_shuttle_moving ? "\n*Shuttle already called*
\n
":supply_shuttle_at_station ? "\nSend away
\n
":"\nSend to station
\n
"] \nView requests
\n
\nView orders
\n
\nClose"} user << browse(dat, "window=computer;size=575x450") onclose(user, "computer") return /obj/machinery/computer/supplycomp/attackby(I as obj, user as mob) if(istype(I,/obj/item/weapon/card/emag) && !hacked) user << "\blue Special supplies unlocked." src.hacked = 1 return if(istype(I, /obj/item/weapon/screwdriver)) playsound(src.loc, 'Screwdriver.ogg', 50, 1) if(do_after(user, 20)) if (src.stat & BROKEN) user << "\blue The broken glass falls out." var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) new /obj/item/weapon/shard( src.loc ) var/obj/item/weapon/circuitboard/supplycomp/M = new /obj/item/weapon/circuitboard/supplycomp( A ) for (var/obj/C in src) C.loc = src.loc A.circuit = M A.state = 3 A.icon_state = "3" A.anchored = 1 del(src) else user << "\blue You disconnect the monitor." var/obj/structure/computerframe/A = new /obj/structure/computerframe( src.loc ) var/obj/item/weapon/circuitboard/supplycomp/M = new /obj/item/weapon/circuitboard/supplycomp( A ) if(src.can_order_contraband) M.contraband_enabled = 1 for (var/obj/C in src) C.loc = src.loc A.circuit = M A.state = 4 A.icon_state = "4" A.anchored = 1 del(src) else src.attack_hand(user) return /obj/machinery/computer/supplycomp/Topic(href, href_list) if(..()) return if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon))) usr.machine = src //From Station to Centcomm if (href_list["sendtodock"]) if(!supply_shuttle_at_station || supply_shuttle_moving) return if (!supply_can_move()) usr << "\red The supply shuttle can not transport station employees, exosuits, classified nuclear codes or homing beacons." return src.temp = "Shuttle sent.

OK" src.updateUsrDialog() post_signal("supply") supply_shuttle_shoppinglist = null supply_shuttle_shoppinglist = new/list() sell_crates() //Remove anything or anyone that was either left behind or that bypassed supply_can_move() -Nodrak for(var/area/supply/station/A in world) for(var/obj/item/I in A.contents) del(I) for(var/mob/living/M in A.contents) del(M) send_supply_shuttle() //From Centcomm to Station else if (href_list["sendtostation"]) if(supply_shuttle_at_station || supply_shuttle_moving) return if (!supply_can_move()) usr << "\red The supply shuttle can not transport station employees, exosuits, classified nuclear codes or homing beacons." return post_signal("supply") usr << "\blue The supply shuttle has been called and will arrive in [round(((SUPPLY_MOVETIME/10)/60))] minutes." src.temp = "Shuttle sent.

OK" src.updateUsrDialog() supply_shuttle_moving = 1 process_supply_order() supply_shuttle_time = world.timeofday + SUPPLY_MOVETIME spawn(0) supply_process() if (href_list["order"]) if(supply_shuttle_moving) return src.temp = "Supply points: [supply_shuttle_points]


Request what?

" for(var/S in (typesof(/datum/supply_packs) - /datum/supply_packs) ) var/datum/supply_packs/N = new S() if(N.hidden && !src.hacked) continue //Have to send the type instead of a reference to if(N.contraband && !src.can_order_contraband){continue;} //Agouri -Kavalamarker src.temp += "[N.name] Cost: [N.cost]
" //the obj because it would get caught by the garbage src.temp += "
OK" //collector. oh well. else if (href_list["doorder"]) if(locate(href_list["doorder"])) //Comes from the requestlist var/datum/supply_order/O = locate(href_list["doorder"]) var/datum/supply_packs/P = O.object supply_shuttle_requestlist -= O if(supply_shuttle_points >= P.cost) supply_shuttle_points -= P.cost O.object = P O.orderedby = usr.name O.comment = copytext(sanitize(input(usr,"Comment:","Enter comment","")),1,MAX_MESSAGE_LEN) supply_shuttle_shoppinglist += O src.temp = "Thanks for your order.
" src.temp += "
OK" else src.temp = "Not enough supply points.
" src.temp += "
OK" else //Comes from the orderform var/datum/supply_order/O = new/datum/supply_order () var/supplytype = href_list["doorder"] var/datum/supply_packs/P = new supplytype () if(supply_shuttle_points >= P.cost) supply_shuttle_points -= P.cost O.object = P O.orderedby = usr.name O.comment = copytext(sanitize(input(usr,"Comment:","Enter comment","")),1,MAX_MESSAGE_LEN) supply_shuttle_shoppinglist += O src.temp = "Thanks for your order.
" src.temp += "
OK" else src.temp = "Not enough supply points.
" src.temp += "
OK" else if (href_list["vieworders"]) src.temp = "Current approved orders:

" for(var/S in supply_shuttle_shoppinglist) var/datum/supply_order/SO = S src.temp += "[SO.object.name] approved by [SO.orderedby][SO.comment ? " ([SO.comment])":""]
"// (Cancel)
" src.temp += "
OK" /* else if (href_list["cancelorder"]) var/datum/supply_order/remove_supply = href_list["cancelorder"] supply_shuttle_shoppinglist -= remove_supply supply_shuttle_points += remove_supply.object.cost src.temp += "Canceled: [remove_supply.object.name]


" for(var/S in supply_shuttle_shoppinglist) var/datum/supply_order/SO = S src.temp += "[SO.object.name] approved by [SO.orderedby][SO.comment ? " ([SO.comment])":""] (Cancel)
" src.temp += "
OK" */ else if (href_list["viewrequests"]) src.temp = "Current requests:

" for(var/S in supply_shuttle_requestlist) var/datum/supply_order/SO = S src.temp += "[SO.object.name] requested by [SO.orderedby] [supply_shuttle_moving ? "":supply_shuttle_at_station ? "":"Approve Remove"]
" src.temp += "
Clear list" src.temp += "
OK" else if (href_list["rreq"]) supply_shuttle_requestlist -= locate(href_list["rreq"]) src.temp = "Request removed.
" src.temp += "
OK" else if (href_list["clearreq"]) supply_shuttle_requestlist = null supply_shuttle_requestlist = new/list() src.temp = "List cleared.
" src.temp += "
OK" else if (href_list["mainmenu"]) src.temp = null src.add_fingerprint(usr) src.updateUsrDialog() return /obj/machinery/computer/supplycomp/proc/post_signal(var/command) var/datum/radio_frequency/frequency = radio_controller.return_frequency(1435) if(!frequency) return var/datum/signal/status_signal = new status_signal.source = src status_signal.transmission_method = 1 status_signal.data["command"] = command frequency.post_signal(src, status_signal) /proc/send_supply_shuttle() if (supply_shuttle_moving) return var/area/the_shuttles_way = locate(SUPPLY_STATION_AREATYPE) //Do I really need to explain this loop? for(var/mob/living/unlucky_person in the_shuttles_way) unlucky_person.gib() var/shuttleat = supply_shuttle_at_station ? SUPPLY_STATION_AREATYPE : SUPPLY_DOCK_AREATYPE var/shuttleto = !supply_shuttle_at_station ? SUPPLY_STATION_AREATYPE : SUPPLY_DOCK_AREATYPE var/area/from = locate(shuttleat) var/area/dest = locate(shuttleto) if(!from || !dest) return from.move_contents_to(dest) supply_shuttle_at_station = !supply_shuttle_at_station