mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-26 21:48:21 +01:00
Assault Pods & Fixes
Fixes: - Lighting system bandaid: Lighting overlays can't go below 0 lum ever - -tg- shuttles now use changeTurf() and forceMove() appropriately - forceMove() actually bothers to update lighting now - Fixed teleportlocs including prohibited areas. Sorry wizards, no more area teleporting to Central Command. Misc changes: - Moved the emergency shuttle stuff to the modules/shuttles/ folder - Moved the cargo shuttle stuff to the modules/shuttles/ folder Features: - Added nukeops assault-pod. Nuke ops may purchase a destination setter for 30 telecrystals. The assault pod is a shuttle, equipped with 8 turrets that use weakbullet3. When an area is selected, a destination will be randomly placed in one of the turfs in that area. The pod will gib anyone standing in the area where it lands, and overwrite any turfs.
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
/obj/docking_port/mobile/assault_pod
|
||||
name = "assault pod"
|
||||
id = "steel_rain"
|
||||
dwidth = 3
|
||||
width = 7
|
||||
height = 7
|
||||
|
||||
/obj/docking_port/mobile/assault_pod/request()
|
||||
if(z == initial(src.z)) //No launching pods that have already launched
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/docking_port/mobile/assault_pod/dock(obj/docking_port/stationary/S1)
|
||||
..()
|
||||
if(!istype(S1, /obj/docking_port/stationary/transit))
|
||||
playsound(get_turf(src.loc), 'sound/effects/Explosion1.ogg',50,1)
|
||||
|
||||
|
||||
|
||||
/obj/item/device/assault_pod
|
||||
name = "Assault Pod Targetting Device"
|
||||
icon_state = "gangtool-red"
|
||||
item_state = "walkietalkie"
|
||||
desc = "Used to select a landing zone for assault pods."
|
||||
var/shuttle_id = "steel_rain"
|
||||
var/dwidth = 3
|
||||
var/dheight = 0
|
||||
var/width = 7
|
||||
var/height = 7
|
||||
var/lz_dir = 1
|
||||
|
||||
|
||||
/obj/item/device/assault_pod/attack_self(mob/living/user)
|
||||
var/target_area
|
||||
target_area = input("Area to land", "Select a Landing Zone", target_area) in teleportlocs
|
||||
var/area/picked_area = teleportlocs[target_area]
|
||||
if(!src || qdeleted(src))
|
||||
return
|
||||
|
||||
var/turf/T = safepick(get_area_turfs(picked_area))
|
||||
if(!T)
|
||||
return
|
||||
var/obj/docking_port/stationary/landing_zone = new /obj/docking_port/stationary(T)
|
||||
landing_zone.id = "assault_pod(\ref[src])"
|
||||
landing_zone.name = "Landing Zone"
|
||||
landing_zone.dwidth = dwidth
|
||||
landing_zone.dheight = dheight
|
||||
landing_zone.width = width
|
||||
landing_zone.height = height
|
||||
landing_zone.dir = lz_dir
|
||||
landing_zone.register() //new docking ports must be registered
|
||||
|
||||
for(var/obj/machinery/computer/shuttle/S in machines)
|
||||
if(S.shuttleId == shuttle_id)
|
||||
S.possible_destinations = "[landing_zone.id]"
|
||||
|
||||
user << "Landing zone set."
|
||||
|
||||
qdel(src)
|
||||
@@ -0,0 +1,288 @@
|
||||
/obj/machinery/computer/emergency_shuttle
|
||||
name = "emergency shuttle console"
|
||||
desc = "For shuttle control."
|
||||
icon_screen = "shuttle"
|
||||
icon_keyboard = "tech_key"
|
||||
var/auth_need = 3
|
||||
var/list/authorized = list()
|
||||
|
||||
/obj/machinery/computer/emergency_shuttle/attackby(obj/item/weapon/card/W, mob/user, params)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
if(!istype(W, /obj/item/weapon/card))
|
||||
return
|
||||
if(shuttle_master.emergency.mode != SHUTTLE_DOCKED)
|
||||
return
|
||||
if(!user)
|
||||
return
|
||||
if(shuttle_master.emergency.timeLeft() < 11)
|
||||
return
|
||||
if (istype(W, /obj/item/weapon/card/id)||istype(W, /obj/item/device/pda))
|
||||
if (istype(W, /obj/item/device/pda))
|
||||
var/obj/item/device/pda/pda = W
|
||||
W = pda.id
|
||||
if (!W:access) //no access
|
||||
user << "The access level of [W:registered_name]\'s card is not high enough. "
|
||||
return
|
||||
|
||||
var/list/cardaccess = W:access
|
||||
if(!istype(cardaccess, /list) || !cardaccess.len) //no access
|
||||
user << "The access level of [W:registered_name]\'s card is not high enough. "
|
||||
return
|
||||
|
||||
if(!(access_heads in W:access)) //doesn't have this access
|
||||
user << "The access level of [W:registered_name]\'s card is not high enough. "
|
||||
return 0
|
||||
|
||||
var/choice = alert(user, text("Would you like to (un)authorize a shortened launch time? [] authorization\s are still needed. Use abort to cancel all authorizations.", src.auth_need - src.authorized.len), "Shuttle Launch", "Authorize", "Repeal", "Abort")
|
||||
if(shuttle_master.emergency.mode != SHUTTLE_DOCKED || user.get_active_hand() != W)
|
||||
return 0
|
||||
|
||||
var/seconds = shuttle_master.emergency.timeLeft()
|
||||
if(seconds <= 10)
|
||||
return 0
|
||||
|
||||
switch(choice)
|
||||
if("Authorize")
|
||||
if(!authorized.Find(W:registered_name))
|
||||
authorized += W:registered_name
|
||||
if(auth_need - authorized.len > 0)
|
||||
message_admins("[key_name_admin(user)] has authorized early shuttle launch.")
|
||||
log_game("[key_name(user)] has authorized early shuttle launch in ([x], [y], [z]).")
|
||||
minor_announcement.Announce("[auth_need - authorized.len] more authorization(s) needed until shuttle is launched early")
|
||||
else
|
||||
message_admins("[key_name_admin(user)] has launched the emergency shuttle [seconds] seconds before launch.")
|
||||
log_game("[key_name(user)] has launched the emergency shuttle in ([x], [y], [z]) [seconds] seconds before launch.")
|
||||
minor_announcement.Announce("The emergency shuttle will launch in 10 seconds")
|
||||
shuttle_master.emergency.setTimer(100)
|
||||
|
||||
if("Repeal")
|
||||
if(authorized.Remove(W:registered_name))
|
||||
minor_announcement.Announce("[auth_need - authorized.len] authorizations needed until shuttle is launched early")
|
||||
|
||||
if("Abort")
|
||||
if(authorized.len)
|
||||
minor_announcement.Announce("All authorizations to launch the shuttle early have been revoked.")
|
||||
authorized.Cut()
|
||||
|
||||
/obj/machinery/computer/emergency_shuttle/emag_act(mob/user)
|
||||
if(!emagged && shuttle_master.emergency.mode == SHUTTLE_DOCKED)
|
||||
var/time = shuttle_master.emergency.timeLeft()
|
||||
message_admins("[key_name_admin(user)] has emagged the emergency shuttle: [time] seconds before launch.")
|
||||
log_game("[key_name(user)] has emagged the emergency shuttle in ([x], [y], [z]): [time] seconds before launch.")
|
||||
minor_announcement.Announce("The emergency shuttle will launch in 10 seconds", "SYSTEM ERROR:")
|
||||
shuttle_master.emergency.setTimer(100)
|
||||
emagged = 1
|
||||
|
||||
|
||||
/obj/docking_port/mobile/emergency
|
||||
name = "emergency shuttle"
|
||||
id = "emergency"
|
||||
|
||||
dwidth = 9
|
||||
width = 22
|
||||
height = 11
|
||||
dir = 4
|
||||
travelDir = 0
|
||||
roundstart_move = "emergency_away"
|
||||
var/sound_played = 0 //If the launch sound has been sent to all players on the shuttle itself
|
||||
|
||||
var/datum/announcement/priority/emergency_shuttle_docked = new(0, new_sound = sound('sound/AI/shuttledock.ogg'))
|
||||
var/datum/announcement/priority/emergency_shuttle_called = new(0, new_sound = sound('sound/AI/shuttlecalled.ogg'))
|
||||
var/datum/announcement/priority/emergency_shuttle_recalled = new(0, new_sound = sound('sound/AI/shuttlerecalled.ogg'))
|
||||
|
||||
/obj/docking_port/mobile/emergency/register()
|
||||
if(!..())
|
||||
return 0 //shuttle master not initialized
|
||||
|
||||
shuttle_master.emergency = src
|
||||
return 1
|
||||
|
||||
/obj/docking_port/mobile/emergency/timeLeft(divisor)
|
||||
if(divisor <= 0)
|
||||
divisor = 10
|
||||
if(!timer)
|
||||
return round(shuttle_master.emergencyCallTime/divisor, 1)
|
||||
|
||||
var/dtime = world.time - timer
|
||||
switch(mode)
|
||||
if(SHUTTLE_ESCAPE)
|
||||
dtime = max(shuttle_master.emergencyEscapeTime - dtime, 0)
|
||||
if(SHUTTLE_DOCKED)
|
||||
dtime = max(shuttle_master.emergencyDockTime - dtime, 0)
|
||||
else
|
||||
|
||||
dtime = max(shuttle_master.emergencyCallTime - dtime, 0)
|
||||
return round(dtime/divisor, 1)
|
||||
|
||||
/obj/docking_port/mobile/emergency/request(obj/docking_port/stationary/S, coefficient=1, area/signalOrigin, reason, redAlert)
|
||||
shuttle_master.emergencyCallTime = initial(shuttle_master.emergencyCallTime) * coefficient
|
||||
switch(mode)
|
||||
if(SHUTTLE_RECALL)
|
||||
mode = SHUTTLE_CALL
|
||||
timer = world.time - timeLeft(1)
|
||||
if(SHUTTLE_IDLE)
|
||||
mode = SHUTTLE_CALL
|
||||
timer = world.time
|
||||
if(SHUTTLE_CALL)
|
||||
if(world.time < timer) //this is just failsafe
|
||||
timer = world.time
|
||||
else
|
||||
return
|
||||
|
||||
if(prob(70))
|
||||
shuttle_master.emergencyLastCallLoc = signalOrigin
|
||||
else
|
||||
shuttle_master.emergencyLastCallLoc = null
|
||||
|
||||
emergency_shuttle_called.Announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][shuttle_master.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ]")
|
||||
|
||||
/obj/docking_port/mobile/emergency/cancel(area/signalOrigin)
|
||||
if(mode != SHUTTLE_CALL)
|
||||
return
|
||||
|
||||
timer = world.time - timeLeft(1)
|
||||
mode = SHUTTLE_RECALL
|
||||
|
||||
if(prob(70))
|
||||
shuttle_master.emergencyLastCallLoc = signalOrigin
|
||||
else
|
||||
shuttle_master.emergencyLastCallLoc = null
|
||||
emergency_shuttle_recalled.Announce("The emergency shuttle has been recalled.[shuttle_master.emergencyLastCallLoc ? " Recall signal traced. Results can be viewed on any communications console." : "" ]")
|
||||
|
||||
/*
|
||||
/obj/docking_port/mobile/emergency/findTransitDock()
|
||||
. = shuttle_master.getDock("emergency_transit")
|
||||
if(.) return .
|
||||
return ..()
|
||||
*/
|
||||
|
||||
|
||||
/obj/docking_port/mobile/emergency/check()
|
||||
if(!timer)
|
||||
return
|
||||
|
||||
var/time_left = timeLeft(1)
|
||||
switch(mode)
|
||||
if(SHUTTLE_RECALL)
|
||||
if(time_left <= 0)
|
||||
mode = SHUTTLE_IDLE
|
||||
timer = 0
|
||||
if(SHUTTLE_CALL)
|
||||
if(time_left <= 0)
|
||||
//move emergency shuttle to station
|
||||
if(dock(shuttle_master.getDock("emergency_home")))
|
||||
setTimer(20)
|
||||
return
|
||||
mode = SHUTTLE_DOCKED
|
||||
timer = world.time
|
||||
send2irc("Server", "The Emergency Shuttle has docked with the station.")
|
||||
emergency_shuttle_docked.Announce("The Emergency Shuttle has docked with the station. You have [timeLeft(600)] minutes to board the Emergency Shuttle.")
|
||||
|
||||
/*
|
||||
//Gangs only have one attempt left if the shuttle has docked with the station to prevent suffering from dominator delays
|
||||
for(var/datum/gang/G in ticker.mode.gangs)
|
||||
if(isnum(G.dom_timer))
|
||||
G.dom_attempts = 0
|
||||
else
|
||||
G.dom_attempts = min(1,G.dom_attempts)
|
||||
*/
|
||||
if(SHUTTLE_DOCKED)
|
||||
|
||||
if(time_left <= 0 && shuttle_master.emergencyNoEscape)
|
||||
priority_announcement.Announce("Hostile environment detected. Departure has been postponed indefinitely pending conflict resolution.")
|
||||
sound_played = 0
|
||||
mode = SHUTTLE_STRANDED
|
||||
|
||||
if(time_left <= 50 && !sound_played) //4 seconds left - should sync up with the launch
|
||||
sound_played = 1
|
||||
for(var/area/shuttle/escape/E in world)
|
||||
E << 'sound/effects/hyperspace_begin.ogg'
|
||||
|
||||
if(time_left <= 0 && !shuttle_master.emergencyNoEscape)
|
||||
//move each escape pod to its corresponding transit dock
|
||||
for(var/obj/docking_port/mobile/pod/M in shuttle_master.mobile)
|
||||
if(M.z == ZLEVEL_STATION) //Will not launch from the mine/planet
|
||||
M.enterTransit()
|
||||
//now move the actual emergency shuttle to its transit dock
|
||||
for(var/area/shuttle/escape/E in world)
|
||||
E << 'sound/effects/hyperspace_progress.ogg'
|
||||
enterTransit()
|
||||
mode = SHUTTLE_ESCAPE
|
||||
timer = world.time
|
||||
priority_announcement.Announce("The Emergency Shuttle has left the station. Estimate [timeLeft(600)] minutes until the shuttle docks at Central Command.")
|
||||
if(SHUTTLE_ESCAPE)
|
||||
if(time_left <= 0)
|
||||
//move each escape pod to its corresponding escape dock
|
||||
for(var/obj/docking_port/mobile/pod/M in shuttle_master.mobile)
|
||||
M.dock(shuttle_master.getDock("[M.id]_away"))
|
||||
//now move the actual emergency shuttle to centcomm
|
||||
for(var/area/shuttle/escape/E in world)
|
||||
E << 'sound/effects/hyperspace_end.ogg'
|
||||
dock(shuttle_master.getDock("emergency_away"))
|
||||
mode = SHUTTLE_ENDGAME
|
||||
timer = 0
|
||||
open_dock()
|
||||
|
||||
/obj/docking_port/mobile/emergency/proc/open_dock();
|
||||
/*
|
||||
for(var/obj/machinery/door/poddoor/shuttledock/D in airlocks)
|
||||
var/turf/T = get_step(D, D.checkdir)
|
||||
if(!istype(T,/turf/space))
|
||||
spawn(0)
|
||||
D.open()
|
||||
*/ //Leaving this here incase someone decides to port -tg-'s escape shuttle stuff:
|
||||
// This basically opens a big-ass row of blast doors when the shuttle arrives at centcom
|
||||
/obj/docking_port/mobile/pod
|
||||
name = "escape pod"
|
||||
id = "pod"
|
||||
|
||||
dwidth = 1
|
||||
width = 3
|
||||
height = 4
|
||||
|
||||
/obj/docking_port/mobile/pod/New()
|
||||
if(id == "pod")
|
||||
WARNING("[type] id has not been changed from the default. Use the id convention \"pod1\" \"pod2\" etc.")
|
||||
..()
|
||||
|
||||
/obj/docking_port/mobile/pod/cancel()
|
||||
return
|
||||
|
||||
/*
|
||||
findTransitDock()
|
||||
. = shuttle_master.getDock("[id]_transit")
|
||||
if(.) return .
|
||||
return ..()
|
||||
*/
|
||||
|
||||
/obj/machinery/computer/shuttle/pod
|
||||
name = "pod control computer"
|
||||
admin_controlled = 1
|
||||
shuttleId = "pod"
|
||||
possible_destinations = "pod_asteroid"
|
||||
icon = 'icons/obj/terminals.dmi'
|
||||
icon_state = "dorm_available"
|
||||
density = 0
|
||||
|
||||
/obj/machinery/computer/shuttle/pod/update_icon()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/shuttle/pod/emag_act(mob/user as mob)
|
||||
user << "<span class='warning'> Access requirements overridden. The pod may now be launched manually at any time.</span>"
|
||||
admin_controlled = 0
|
||||
icon_state = "dorm_emag"
|
||||
|
||||
/obj/docking_port/stationary/random
|
||||
name = "escape pod"
|
||||
id = "pod"
|
||||
dwidth = 1
|
||||
width = 3
|
||||
height = 4
|
||||
var/target_area = /area/mine/unexplored
|
||||
|
||||
/obj/docking_port/stationary/random/initialize()
|
||||
..()
|
||||
var/list/turfs = get_area_turfs(target_area)
|
||||
var/turf/T = pick(turfs)
|
||||
src.loc = T
|
||||
@@ -396,7 +396,7 @@
|
||||
var/obj/O = AM
|
||||
if(istype(O, /obj/docking_port/stationary))
|
||||
continue
|
||||
O.loc = T1
|
||||
O.forceMove(T1)
|
||||
|
||||
//close open doors
|
||||
if(istype(O, /obj/machinery/door))
|
||||
@@ -415,7 +415,7 @@
|
||||
var/mob/M = AM
|
||||
if(!M.move_on_shuttle)
|
||||
continue
|
||||
M.loc = T1
|
||||
M.forceMove(T1)
|
||||
|
||||
//docking turbulence
|
||||
if(M.client)
|
||||
@@ -433,15 +433,12 @@
|
||||
T1.shuttleRotate(rotation)
|
||||
|
||||
//lighting stuff
|
||||
T1.reconsider_lights()
|
||||
T1.lighting_build_overlays()
|
||||
air_master.remove_from_active(T1)
|
||||
T1.CalculateAdjacentTurfs()
|
||||
air_master.add_to_active(T1,1)
|
||||
|
||||
T0.ChangeTurf(turf_type)
|
||||
|
||||
T0.reconsider_lights()
|
||||
air_master.remove_from_active(T0)
|
||||
T0.CalculateAdjacentTurfs()
|
||||
air_master.add_to_active(T0,1)
|
||||
@@ -515,7 +512,8 @@
|
||||
if(!AM.anchored)
|
||||
step(AM, dir)
|
||||
else
|
||||
qdel(AM)
|
||||
if(AM.simulated) //lighting overlays are static
|
||||
qdel(AM)
|
||||
/*
|
||||
//used to check if atom/A is within the shuttle's bounding box
|
||||
/obj/docking_port/mobile/proc/onShuttleCheck(atom/A)
|
||||
@@ -604,7 +602,7 @@
|
||||
M = D
|
||||
shuttleId = M.id
|
||||
break
|
||||
else if(!possible_destinations)
|
||||
else if(!possible_destinations && istext(possible_destinations)) //possible destinations should **not** always exist; so, if it's specifically set to null, don't make it exist
|
||||
M = shuttle_master.getShuttle(shuttleId)
|
||||
|
||||
if(M && !possible_destinations)
|
||||
@@ -707,30 +705,6 @@
|
||||
shuttleId = "whiteship"
|
||||
possible_destinations = "whiteship_away;whiteship_home;whiteship_z4"
|
||||
|
||||
#define SYNDICATE_CHALLENGE_TIMER 12000 //20 minutes
|
||||
|
||||
/obj/machinery/computer/shuttle/syndicate
|
||||
name = "syndicate shuttle terminal"
|
||||
icon_screen = "syndishuttle"
|
||||
icon_keyboard = "syndie_key"
|
||||
req_access = list(access_syndicate)
|
||||
shuttleId = "syndicate"
|
||||
possible_destinations = "syndicate_away;syndicate_z5;syndicate_z3;syndicate_ne;syndicate_nw;syndicate_n;syndicate_se;syndicate_sw;syndicate_s"
|
||||
var/challenge = FALSE
|
||||
|
||||
/obj/machinery/computer/shuttle/syndicate/recall
|
||||
name = "syndicate shuttle recall terminal"
|
||||
possible_destinations = "syndicate_away"
|
||||
|
||||
/obj/machinery/computer/shuttle/syndicate/Topic(href, href_list)
|
||||
if(href_list["move"])
|
||||
if(challenge && world.time < SYNDICATE_CHALLENGE_TIMER)
|
||||
usr << "<span class='warning'>You've issued a combat challenge to the station! You've got to give them at least [round(((SYNDICATE_CHALLENGE_TIMER - world.time) / 10) / 60)] more minutes to allow them to prepare.</span>"
|
||||
return 0
|
||||
..()
|
||||
|
||||
#undef SYNDICATE_CHALLENGE_TIMER
|
||||
|
||||
/obj/machinery/computer/shuttle/vox
|
||||
name = "skipjack control console"
|
||||
req_access = list(access_vox)
|
||||
@@ -764,7 +738,7 @@
|
||||
if(underlays.len) //we have underlays, which implies some sort of transparency, so we want to a snapshot of the previous turf as an underlay
|
||||
O = new()
|
||||
O.underlays.Add(T)
|
||||
T = new type(T)
|
||||
T.ChangeTurf(type)
|
||||
if(underlays.len)
|
||||
T.underlays = O.underlays
|
||||
if(T.icon_state != icon_state)
|
||||
|
||||
@@ -0,0 +1,846 @@
|
||||
#define ORDER_SCREEN_WIDTH 625 //width of order computer interaction window
|
||||
#define ORDER_SCREEN_HEIGHT 580 //height of order computer interaction window
|
||||
#define SUPPLY_SCREEN_WIDTH 625 //width of supply computer interaction window
|
||||
#define SUPPLY_SCREEN_HEIGHT 620 //height of supply computer interaction window
|
||||
|
||||
/obj/item/weapon/paper/manifest
|
||||
name = "supply manifest"
|
||||
var/erroneous = 0
|
||||
var/points = 0
|
||||
var/ordernumber = 0
|
||||
|
||||
/obj/docking_port/mobile/supply
|
||||
name = "supply shuttle"
|
||||
id = "supply"
|
||||
callTime = 1200
|
||||
|
||||
dir = 8
|
||||
travelDir = 90
|
||||
width = 12
|
||||
dwidth = 5
|
||||
height = 7
|
||||
roundstart_move = "supply_away"
|
||||
|
||||
/obj/docking_port/mobile/supply/register()
|
||||
if(!..())
|
||||
return 0
|
||||
shuttle_master.supply = src
|
||||
return 1
|
||||
|
||||
/obj/docking_port/mobile/supply/canMove()
|
||||
if(z == ZLEVEL_STATION)
|
||||
return forbidden_atoms_check(areaInstance)
|
||||
return ..()
|
||||
|
||||
/obj/docking_port/mobile/supply/request(obj/docking_port/stationary/S)
|
||||
if(mode != SHUTTLE_IDLE)
|
||||
return 2
|
||||
return ..()
|
||||
|
||||
/obj/docking_port/mobile/supply/dock()
|
||||
. = ..()
|
||||
if(.) return .
|
||||
|
||||
buy()
|
||||
sell()
|
||||
|
||||
/obj/docking_port/mobile/supply/proc/buy()
|
||||
if(z != ZLEVEL_STATION) //we only buy when we are -at- the station
|
||||
return 1
|
||||
|
||||
if(!shuttle_master.shoppinglist.len)
|
||||
return 2
|
||||
|
||||
var/list/emptyTurfs = list()
|
||||
for(var/turf/simulated/T in areaInstance)
|
||||
if(T.density)
|
||||
continue
|
||||
|
||||
var/contcount
|
||||
for(var/atom/A in T.contents)
|
||||
if(istype(A,/atom/movable/lighting_overlay))
|
||||
continue
|
||||
if(istype(A,/obj/machinery/light))
|
||||
continue //hacky but whatever, shuttles need three spots each for this shit
|
||||
if(!A.simulated)
|
||||
continue
|
||||
contcount++
|
||||
|
||||
if(contcount)
|
||||
continue
|
||||
|
||||
emptyTurfs += T
|
||||
|
||||
for(var/datum/supply_order/SO in shuttle_master.shoppinglist)
|
||||
if(!SO.object)
|
||||
throw EXCEPTION("Supply Order [SO] has no object associated with it.")
|
||||
continue
|
||||
|
||||
var/turf/T = pick_n_take(emptyTurfs) //turf we will place it in
|
||||
if(!T)
|
||||
shuttle_master.shoppinglist.Cut(1, shuttle_master.shoppinglist.Find(SO))
|
||||
return
|
||||
|
||||
var/errors = 0
|
||||
if(prob(5))
|
||||
errors |= MANIFEST_ERROR_COUNT
|
||||
if(prob(5))
|
||||
errors |= MANIFEST_ERROR_NAME
|
||||
if(prob(5))
|
||||
errors |= MANIFEST_ERROR_ITEM
|
||||
SO.createObject(T, errors)
|
||||
|
||||
shuttle_master.shoppinglist.Cut()
|
||||
|
||||
/obj/docking_port/mobile/supply/proc/sell()
|
||||
if(z != ZLEVEL_CENTCOMM) //we only sell when we are -at- centcomm
|
||||
return 1
|
||||
|
||||
var/plasma_count = 0
|
||||
var/intel_count = 0
|
||||
var/crate_count = 0
|
||||
|
||||
var/msg = ""
|
||||
var/pointsEarned
|
||||
|
||||
for(var/atom/movable/MA in areaInstance)
|
||||
if(MA.anchored) continue
|
||||
shuttle_master.sold_atoms += " [MA.name]"
|
||||
|
||||
// Must be in a crate (or a critter crate)!
|
||||
if(istype(MA,/obj/structure/closet/crate) || istype(MA,/obj/structure/closet/critter))
|
||||
shuttle_master.sold_atoms += ":"
|
||||
if(!MA.contents.len)
|
||||
shuttle_master.sold_atoms += " (empty)"
|
||||
++crate_count
|
||||
|
||||
var/find_slip = 1
|
||||
for(var/thing in MA)
|
||||
// Sell manifests
|
||||
shuttle_master.sold_atoms += " [thing:name]"
|
||||
if(find_slip && istype(thing,/obj/item/weapon/paper/manifest))
|
||||
var/obj/item/weapon/paper/manifest/slip = thing
|
||||
// TODO: Check for a signature, too.
|
||||
if(slip.stamped && slip.stamped.len) //yes, the clown stamp will work. clown is the highest authority on the station, it makes sense
|
||||
// Did they mark it as erroneous?
|
||||
var/denied = 0
|
||||
for(var/i=1,i<=slip.stamped.len,i++)
|
||||
if(slip.stamped[i] == /obj/item/weapon/stamp/denied)
|
||||
denied = 1
|
||||
if(slip.erroneous && denied) // Caught a mistake by Centcom (IDEA: maybe Centcom rarely gets offended by this)
|
||||
pointsEarned = slip.points - shuttle_master.points_per_crate
|
||||
shuttle_master.points += pointsEarned // For now, give a full refund for paying attention (minus the crate cost)
|
||||
msg += "<span class='good'>+[pointsEarned]</span>: Station correctly denied package [slip.ordernumber]: "
|
||||
if(slip.erroneous & MANIFEST_ERROR_NAME)
|
||||
msg += "Destination station incorrect. "
|
||||
else if(slip.erroneous & MANIFEST_ERROR_COUNT)
|
||||
msg += "Packages incorrectly counted. "
|
||||
else if(slip.erroneous & MANIFEST_ERROR_ITEM)
|
||||
msg += "Package incomplete. "
|
||||
msg += "Points refunded.<br>"
|
||||
else if(!slip.erroneous && !denied) // Approving a proper order awards the relatively tiny points_per_slip
|
||||
shuttle_master.points += shuttle_master.points_per_slip
|
||||
msg += "<span class='good'>+[shuttle_master.points_per_slip]</span>: Package [slip.ordernumber] accorded.<br>"
|
||||
else // You done goofed.
|
||||
if(slip.erroneous)
|
||||
msg += "<span class='good'>+0</span>: Station approved package [slip.ordernumber] despite error: "
|
||||
if(slip.erroneous & MANIFEST_ERROR_NAME)
|
||||
msg += "Destination station incorrect."
|
||||
else if(slip.erroneous & MANIFEST_ERROR_COUNT)
|
||||
msg += "Packages incorrectly counted."
|
||||
else if(slip.erroneous & MANIFEST_ERROR_ITEM)
|
||||
msg += "We found unshipped items on our dock."
|
||||
msg += " Be more vigilant.<br>"
|
||||
else
|
||||
pointsEarned = round(shuttle_master.points_per_crate - slip.points)
|
||||
shuttle_master.points += pointsEarned
|
||||
msg += "<span class='bad'>[pointsEarned]</span>: Station denied package [slip.ordernumber]. Our records show no fault on our part.<br>"
|
||||
find_slip = 0
|
||||
continue
|
||||
|
||||
// Sell plasma
|
||||
if(istype(thing, /obj/item/stack/sheet/mineral/plasma))
|
||||
var/obj/item/stack/sheet/mineral/plasma/P = thing
|
||||
plasma_count += P.amount
|
||||
|
||||
// Sell syndicate intel
|
||||
if(istype(thing, /obj/item/documents/syndicate))
|
||||
++intel_count
|
||||
|
||||
// Sell tech levels
|
||||
if(istype(thing, /obj/item/weapon/disk/tech_disk))
|
||||
var/obj/item/weapon/disk/tech_disk/disk = thing
|
||||
if(!disk.stored) continue
|
||||
var/datum/tech/tech = disk.stored
|
||||
|
||||
var/cost = tech.getCost(shuttle_master.techLevels[tech.id])
|
||||
if(cost)
|
||||
shuttle_master.techLevels[tech.id] = tech.level
|
||||
shuttle_master.points += cost
|
||||
for(var/mob/M in player_list)
|
||||
if(M.mind)
|
||||
for(var/datum/job_objective/further_research/objective in M.mind.job_objectives)
|
||||
objective.unit_completed(cost)
|
||||
msg += "<span class='good'>+[cost]</span>: [tech.name] - new data.<br>"
|
||||
|
||||
// Sell max reliablity designs
|
||||
if(istype(thing, /obj/item/weapon/disk/design_disk))
|
||||
var/obj/item/weapon/disk/design_disk/disk = thing
|
||||
if(!disk.blueprint) continue
|
||||
var/datum/design/design = disk.blueprint
|
||||
if(design.id in shuttle_master.researchDesigns) continue
|
||||
|
||||
if(initial(design.reliability) < 100 && design.reliability >= 100)
|
||||
// Maxed out reliability designs only.
|
||||
shuttle_master.points += shuttle_master.points_per_design
|
||||
shuttle_master.researchDesigns += design.id
|
||||
msg += "<span class='good'>+[shuttle_master.points_per_design]</span>: Reliable [design.name] design.<br>"
|
||||
|
||||
// Sell exotic plants
|
||||
if(istype(thing, /obj/item/seeds))
|
||||
var/obj/item/seeds/S = thing
|
||||
if(S.seed.get_trait(TRAIT_RARITY) == 0) // Mundane species
|
||||
msg += "<span class='bad'>+0</span>: We don't need samples of mundane species \"[capitalize(S.seed.seed_name)]\".<br>"
|
||||
else if(shuttle_master.discoveredPlants[S.type]) // This species has already been sent to CentComm
|
||||
var/potDiff = S.seed.get_trait(TRAIT_POTENCY) - shuttle_master.discoveredPlants[S.type] // Compare it to the previous best
|
||||
if(potDiff > 0) // This sample is better
|
||||
shuttle_master.discoveredPlants[S.type] = S.seed.get_trait(TRAIT_POTENCY)
|
||||
msg += "<span class='good'>+[potDiff]</span>: New sample of \"[capitalize(S.seed.seed_name)]\" is superior. Good work.<br>"
|
||||
shuttle_master.points += potDiff
|
||||
else // This sample is worthless
|
||||
msg += "<span class='bad'>+0</span>: New sample of \"[capitalize(S.seed.seed_name)]\" is not more potent than existing sample ([shuttle_master.discoveredPlants[S.type]] potency).<br>"
|
||||
else // This is a new discovery!
|
||||
shuttle_master.discoveredPlants[S.type] = S.seed.get_trait(TRAIT_POTENCY)
|
||||
msg += "<span class='good'>+[S.seed.get_trait(TRAIT_RARITY)]</span>: New species discovered: \"[capitalize(S.seed.seed_name)]\". Excellent work.<br>"
|
||||
shuttle_master.points += S.seed.get_trait(TRAIT_RARITY) // That's right, no bonus for potency. Send a crappy sample first to "show improvement" later
|
||||
qdel(MA)
|
||||
shuttle_master.sold_atoms += "."
|
||||
|
||||
if(plasma_count > 0)
|
||||
pointsEarned = round(plasma_count * shuttle_master.points_per_plasma)
|
||||
msg += "<span class='good'>+[pointsEarned]</span>: Received [plasma_count] unit(s) of exotic material.<br>"
|
||||
shuttle_master.points += pointsEarned
|
||||
|
||||
if(intel_count > 0)
|
||||
pointsEarned = round(intel_count * shuttle_master.points_per_intel)
|
||||
msg += "<span class='good'>+[pointsEarned]</span>: Received [intel_count] article(s) of enemy intelligence.<br>"
|
||||
shuttle_master.points += pointsEarned
|
||||
|
||||
if(crate_count > 0)
|
||||
pointsEarned = round(crate_count * shuttle_master.points_per_crate)
|
||||
msg += "<span class='good'>+[pointsEarned]</span>: Received [crate_count] crate(s).<br>"
|
||||
shuttle_master.points += pointsEarned
|
||||
|
||||
shuttle_master.centcom_message = msg
|
||||
|
||||
/proc/forbidden_atoms_check(atom/A)
|
||||
var/list/blacklist = list(
|
||||
/mob/living,
|
||||
/obj/effect/blob,
|
||||
/obj/effect/spider/spiderling,
|
||||
/obj/item/weapon/disk/nuclear,
|
||||
/obj/machinery/nuclearbomb,
|
||||
/obj/item/device/radio/beacon,
|
||||
/obj/machinery/the_singularitygen,
|
||||
/obj/singularity,
|
||||
/obj/machinery/teleport/station,
|
||||
/obj/machinery/teleport/hub,
|
||||
/obj/machinery/telepad,
|
||||
/obj/machinery/clonepod
|
||||
)
|
||||
if(A)
|
||||
if(is_type_in_list(A, blacklist))
|
||||
return 1
|
||||
for(var/thing in A)
|
||||
if(.(thing))
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/********************
|
||||
SUPPLY ORDER
|
||||
********************/
|
||||
/datum/supply_order
|
||||
var/ordernum
|
||||
var/datum/supply_packs/object = null
|
||||
var/orderedby = null
|
||||
var/orderedbyRank
|
||||
var/comment = null
|
||||
var/crates
|
||||
|
||||
/datum/controller/process/shuttle/proc/generateSupplyOrder(packId, _orderedby, _orderedbyRank, _comment, _crates)
|
||||
if(!packId)
|
||||
return
|
||||
var/datum/supply_packs/P = supply_packs["[packId]"]
|
||||
if(!P)
|
||||
return
|
||||
|
||||
var/datum/supply_order/O = new()
|
||||
O.ordernum = ordernum++
|
||||
O.object = P
|
||||
O.orderedby = _orderedby
|
||||
O.orderedbyRank = _orderedbyRank
|
||||
O.comment = _comment
|
||||
O.crates = _crates
|
||||
|
||||
requestlist += O
|
||||
|
||||
return O
|
||||
|
||||
/datum/supply_order/proc/generateRequisition(atom/_loc)
|
||||
if(!object)
|
||||
return
|
||||
|
||||
var/obj/item/weapon/paper/reqform = new /obj/item/weapon/paper(_loc)
|
||||
playsound(_loc, "sound/goonstation/machines/printer_thermal.ogg", 50, 1)
|
||||
reqform.name = "Requisition Form - [crates] '[object.name]' for [orderedby]"
|
||||
reqform.info += "<h3>[station_name] Supply Requisition Form</h3><hr>"
|
||||
reqform.info += "INDEX: #[shuttle_master.ordernum]<br>"
|
||||
reqform.info += "REQUESTED BY: [orderedby]<br>"
|
||||
reqform.info += "RANK: [orderedbyRank]<br>"
|
||||
reqform.info += "REASON: [comment]<br>"
|
||||
reqform.info += "SUPPLY CRATE TYPE: [object.name]<br>"
|
||||
reqform.info += "NUMBER OF CRATES: [crates]<br>"
|
||||
reqform.info += "ACCESS RESTRICTION: [object.access ? get_access_desc(object.access) : "None"]<br>"
|
||||
reqform.info += "CONTENTS:<br>"
|
||||
reqform.info += object.manifest
|
||||
reqform.info += "<hr>"
|
||||
reqform.info += "STAMP BELOW TO APPROVE THIS REQUISITION:<br>"
|
||||
|
||||
reqform.update_icon() //Fix for appearing blank when printed.
|
||||
|
||||
return reqform
|
||||
|
||||
/datum/supply_order/proc/createObject(atom/_loc, errors=0)
|
||||
if(!object)
|
||||
return
|
||||
|
||||
//create the crate
|
||||
var/atom/Crate = new object.containertype(_loc)
|
||||
Crate.name = "[object.containername] [comment ? "([comment])":"" ]"
|
||||
if(object.access)
|
||||
Crate:req_access = list(text2num(object.access))
|
||||
|
||||
//create the manifest slip
|
||||
var/obj/item/weapon/paper/manifest/slip = new /obj/item/weapon/paper/manifest()
|
||||
slip.erroneous = errors
|
||||
slip.points = object.cost
|
||||
slip.ordernumber = ordernum
|
||||
|
||||
var/stationName = (errors & MANIFEST_ERROR_NAME) ? new_station_name() : station_name()
|
||||
var/packagesAmt = shuttle_master.shoppinglist.len + ((errors & MANIFEST_ERROR_COUNT) ? rand(1,2) : 0)
|
||||
|
||||
slip.name = "Shipping Manifest - '[object.name]' for [orderedby]"
|
||||
slip.info = "<h3>[command_name()] Shipping Manifest</h3><hr><br>"
|
||||
slip.info +="Order: #[ordernum]<br>"
|
||||
slip.info +="Destination: [stationName]<br>"
|
||||
slip.info +="Requested By: [orderedby]<br>"
|
||||
slip.info +="Rank: [orderedbyRank]<br>"
|
||||
slip.info +="Reason: [comment]<br>"
|
||||
slip.info +="Supply Crate Type: [object.name]<br>"
|
||||
slip.info +="Access Restriction: [object.access ? get_access_desc(object.access) : "None"]<br>"
|
||||
slip.info +="[packagesAmt] PACKAGES IN THIS SHIPMENT<br>"
|
||||
slip.info +="CONTENTS:<br><ul>"
|
||||
|
||||
//we now create the actual contents
|
||||
var/list/contains
|
||||
if(istype(object, /datum/supply_packs/misc/randomised))
|
||||
var/datum/supply_packs/misc/randomised/SO = object
|
||||
contains = list()
|
||||
if(object.contains.len)
|
||||
for(var/j=1, j<=SO.num_contained, j++)
|
||||
contains += pick(object.contains)
|
||||
else
|
||||
contains = object.contains
|
||||
|
||||
for(var/typepath in contains)
|
||||
if(!typepath) continue
|
||||
var/atom/A = new typepath(Crate)
|
||||
if(object.amount && A.vars.Find("amount") && A:amount)
|
||||
A:amount = object.amount
|
||||
slip.info += "<li>[A.name]</li>" //add the item to the manifest (even if it was misplaced)
|
||||
|
||||
if(istype(Crate, /obj/structure/closet/critter)) // critter crates do not actually spawn mobs yet and have no contains var, but the manifest still needs to list them
|
||||
var/obj/structure/closet/critter/CritCrate = Crate
|
||||
if(CritCrate.content_mob)
|
||||
var/mob/crittername = CritCrate.content_mob
|
||||
slip.info += "<li>[initial(crittername.name)]</li>"
|
||||
|
||||
if((errors & MANIFEST_ERROR_ITEM))
|
||||
//secure and large crates cannot lose items
|
||||
if(findtext("[object.containertype]", "/secure/") || findtext("[object.containertype]","/largecrate/"))
|
||||
errors &= ~MANIFEST_ERROR_ITEM
|
||||
else
|
||||
var/lostAmt = max(round(Crate.contents.len/10), 1)
|
||||
//lose some of the items
|
||||
while(--lostAmt >= 0)
|
||||
qdel(pick(Crate.contents))
|
||||
|
||||
//manifest finalisation
|
||||
slip.info += "</ul><br>"
|
||||
slip.info += "CHECK CONTENTS AND STAMP BELOW THE LINE TO CONFIRM RECEIPT OF GOODS<hr>" // And now this is actually meaningful.
|
||||
slip.loc = Crate
|
||||
if(istype(Crate, /obj/structure/closet/crate))
|
||||
var/obj/structure/closet/crate/CR = Crate
|
||||
CR.manifest = slip
|
||||
CR.update_icon()
|
||||
if(istype(Crate, /obj/structure/largecrate))
|
||||
var/obj/structure/largecrate/LC = Crate
|
||||
LC.manifest = slip
|
||||
LC.update_icon()
|
||||
|
||||
return Crate
|
||||
|
||||
/***************************
|
||||
ORDER/REQUESTS CONSOLE
|
||||
**************************/
|
||||
/obj/machinery/computer/supplycomp
|
||||
name = "Supply Shuttle Console"
|
||||
desc = "Used to order supplies."
|
||||
icon_screen = "supply"
|
||||
req_access = list(access_cargo)
|
||||
circuit = /obj/item/weapon/circuitboard/supplycomp
|
||||
var/temp = null
|
||||
var/reqtime = 0
|
||||
var/hacked = 0
|
||||
var/can_order_contraband = 0
|
||||
var/last_viewed_group = "categories"
|
||||
var/datum/supply_packs/content_pack
|
||||
|
||||
/obj/machinery/computer/ordercomp
|
||||
name = "Supply Ordering Console"
|
||||
desc = "Used to order supplies from cargo staff."
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_screen = "request"
|
||||
circuit = /obj/item/weapon/circuitboard/ordercomp
|
||||
var/reqtime = 0
|
||||
var/last_viewed_group = "categories"
|
||||
var/datum/supply_packs/content_pack
|
||||
|
||||
/obj/machinery/computer/ordercomp/attack_ai(var/mob/user as mob)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/machinery/computer/ordercomp/attack_hand(var/mob/user as mob)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/ordercomp/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
|
||||
var/data[0]
|
||||
data["last_viewed_group"] = last_viewed_group
|
||||
|
||||
var/category_list[0]
|
||||
for(var/category in all_supply_groups)
|
||||
category_list.Add(list(list("name" = get_supply_group_name(category), "category" = category)))
|
||||
data["categories"] = category_list
|
||||
|
||||
var/cat = text2num(last_viewed_group)
|
||||
var/packs_list[0]
|
||||
for(var/set_name in shuttle_master.supply_packs)
|
||||
var/datum/supply_packs/pack = shuttle_master.supply_packs[set_name]
|
||||
if(!pack.contraband && !pack.hidden && pack.group == cat)
|
||||
// 0/1 after the pack name (set_name) is a boolean for ordering multiple crates
|
||||
packs_list.Add(list(list("name" = pack.name, "amount" = pack.amount, "cost" = pack.cost, "command1" = list("doorder" = "[set_name]0"), "command2" = list("doorder" = "[set_name]1"), "command3" = list("contents" = set_name))))
|
||||
|
||||
data["supply_packs"] = packs_list
|
||||
if(content_pack)
|
||||
var/pack_name = sanitize(content_pack.name)
|
||||
data["contents_name"] = pack_name
|
||||
data["contents"] = content_pack.manifest
|
||||
data["contents_access"] = content_pack.access ? get_access_desc(content_pack.access) : "None"
|
||||
|
||||
var/requests_list[0]
|
||||
for(var/set_name in shuttle_master.requestlist)
|
||||
var/datum/supply_order/SO = set_name
|
||||
if(SO)
|
||||
// Check if the user owns the request, so they can cancel requests
|
||||
var/obj/item/weapon/card/id/I = user.get_id_card()
|
||||
var/owned = 0
|
||||
if(I && SO.orderedby == I.registered_name)
|
||||
owned = 1
|
||||
requests_list.Add(list(list("ordernum" = SO.ordernum, "supply_type" = SO.object.name, "orderedby" = SO.orderedby, "owned" = owned, "command1" = list("rreq" = SO.ordernum))))
|
||||
data["requests"] = requests_list
|
||||
|
||||
var/orders_list[0]
|
||||
for(var/set_name in shuttle_master.shoppinglist)
|
||||
var/datum/supply_order/SO = set_name
|
||||
if(SO)
|
||||
orders_list.Add(list(list("ordernum" = SO.ordernum, "supply_type" = SO.object.name, "orderedby" = SO.orderedby)))
|
||||
data["orders"] = orders_list
|
||||
|
||||
data["points"] = round(shuttle_master.points)
|
||||
data["send"] = list("send" = 1)
|
||||
|
||||
data["moving"] = shuttle_master.supply.mode != SHUTTLE_IDLE
|
||||
data["at_station"] = shuttle_master.supply.getDockedId() == "supply_home"
|
||||
data["timeleft"] = shuttle_master.supply.timeLeft(600)
|
||||
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "order_console.tmpl", name, ORDER_SCREEN_WIDTH, ORDER_SCREEN_HEIGHT)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/ordercomp/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if (href_list["doorder"])
|
||||
if(world.time < reqtime)
|
||||
visible_message("<b>[src]</b>'s monitor flashes, \"[world.time - reqtime] seconds remaining until another requisition form may be printed.\"")
|
||||
nanomanager.update_uis(src)
|
||||
return 1
|
||||
|
||||
var/index = copytext(href_list["doorder"], 1, lentext(href_list["doorder"])) //text2num(copytext(href_list["doorder"], 1))
|
||||
var/multi = text2num(copytext(href_list["doorder"], -1))
|
||||
if(!isnum(multi))
|
||||
return 1
|
||||
var/datum/supply_packs/P = shuttle_master.supply_packs[index]
|
||||
if(!istype(P))
|
||||
return 1
|
||||
var/crates = 1
|
||||
if(multi)
|
||||
var/num_input = input(usr, "Amount:", "How many crates?") as null|num
|
||||
if(!num_input || ..())
|
||||
return 1
|
||||
crates = Clamp(round(num_input), 1, 20)
|
||||
|
||||
var/timeout = world.time + 600
|
||||
var/reason = input(usr,"Reason:","Why do you require this item?","") as null|text
|
||||
if(world.time > timeout || !reason || ..())
|
||||
return 1
|
||||
reason = sanitize(copytext(reason, 1, MAX_MESSAGE_LEN))
|
||||
|
||||
var/idname = "*None Provided*"
|
||||
var/idrank = "*None Provided*"
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/H = usr
|
||||
idname = H.get_authentification_name()
|
||||
idrank = H.get_assignment()
|
||||
else if(issilicon(usr))
|
||||
idname = usr.real_name
|
||||
|
||||
reqtime = (world.time + 5) % 1e5
|
||||
|
||||
//make our supply_order datums
|
||||
for(var/i = 1; i <= crates; i++)
|
||||
var/datum/supply_order/O = shuttle_master.generateSupplyOrder(index, idname, idrank, reason, crates)
|
||||
if(!O) return
|
||||
if(i == 1)
|
||||
O.generateRequisition(loc)
|
||||
|
||||
else if (href_list["rreq"])
|
||||
var/ordernum = text2num(href_list["rreq"])
|
||||
var/obj/item/weapon/card/id/I = usr.get_id_card()
|
||||
for(var/i=1, i<=shuttle_master.requestlist.len, i++)
|
||||
var/datum/supply_order/SO = shuttle_master.requestlist[i]
|
||||
if(SO.ordernum == ordernum && (I && SO.orderedby == I.registered_name))
|
||||
shuttle_master.requestlist.Cut(i,i+1)
|
||||
break
|
||||
|
||||
else if (href_list["last_viewed_group"])
|
||||
content_pack = null
|
||||
last_viewed_group = text2num(href_list["last_viewed_group"])
|
||||
|
||||
else if (href_list["contents"])
|
||||
var/topic = href_list["contents"]
|
||||
if(topic == 1)
|
||||
content_pack = null
|
||||
else
|
||||
var/datum/supply_packs/P = shuttle_master.supply_packs[topic]
|
||||
content_pack = P
|
||||
|
||||
add_fingerprint(usr)
|
||||
nanomanager.update_uis(src)
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/supplycomp/attack_ai(var/mob/user as mob)
|
||||
return attack_hand(user)
|
||||
|
||||
/obj/machinery/computer/supplycomp/attack_hand(var/mob/user as mob)
|
||||
if(!allowed(user) && !isobserver(user))
|
||||
user << "<span class='warning'>Access denied.</span>"
|
||||
return 1
|
||||
|
||||
post_signal("supply")
|
||||
ui_interact(user)
|
||||
return
|
||||
|
||||
/obj/machinery/computer/supplycomp/emag_act(user as mob)
|
||||
if(!hacked)
|
||||
user << "<span class='notice'>Special supplies unlocked.</span>"
|
||||
hacked = 1
|
||||
return
|
||||
|
||||
/obj/machinery/computer/supplycomp/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
|
||||
// data to send to ui
|
||||
var/data[0]
|
||||
data["last_viewed_group"] = last_viewed_group
|
||||
|
||||
var/category_list[0]
|
||||
for(var/category in all_supply_groups)
|
||||
category_list.Add(list(list("name" = get_supply_group_name(category), "category" = category)))
|
||||
data["categories"] = category_list
|
||||
|
||||
var/cat = text2num(last_viewed_group)
|
||||
var/packs_list[0]
|
||||
for(var/set_name in shuttle_master.supply_packs)
|
||||
var/datum/supply_packs/pack = shuttle_master.supply_packs[set_name]
|
||||
if((pack.hidden && src.hacked) || (pack.contraband && src.can_order_contraband) || (!pack.contraband && !pack.hidden))
|
||||
if(pack.group == cat)
|
||||
// 0/1 after the pack name (set_name) is a boolean for ordering multiple crates
|
||||
packs_list.Add(list(list("name" = pack.name, "amount" = pack.amount, "cost" = pack.cost, "command1" = list("doorder" = "[set_name]0"), "command2" = list("doorder" = "[set_name]1"), "command3" = list("contents" = set_name))))
|
||||
|
||||
data["supply_packs"] = packs_list
|
||||
if(content_pack)
|
||||
var/pack_name = sanitize(content_pack.name)
|
||||
data["contents_name"] = pack_name
|
||||
data["contents"] = content_pack.manifest
|
||||
data["contents_access"] = content_pack.access ? get_access_desc(content_pack.access) : "None"
|
||||
|
||||
var/requests_list[0]
|
||||
for(var/set_name in shuttle_master.requestlist)
|
||||
var/datum/supply_order/SO = set_name
|
||||
if(SO)
|
||||
if(!SO.comment)
|
||||
SO.comment = "No comment."
|
||||
requests_list.Add(list(list("ordernum" = SO.ordernum, "supply_type" = SO.object.name, "orderedby" = SO.orderedby, "comment" = SO.comment, "command1" = list("confirmorder" = SO.ordernum), "command2" = list("rreq" = SO.ordernum))))
|
||||
data["requests"] = requests_list
|
||||
|
||||
var/orders_list[0]
|
||||
for(var/set_name in shuttle_master.shoppinglist)
|
||||
var/datum/supply_order/SO = set_name
|
||||
if(SO)
|
||||
orders_list.Add(list(list("ordernum" = SO.ordernum, "supply_type" = SO.object.name, "orderedby" = SO.orderedby, "comment" = SO.comment)))
|
||||
data["orders"] = orders_list
|
||||
|
||||
data["canapprove"] = (shuttle_master.supply.getDockedId() == "supply_away") && !(shuttle_master.supply.mode != SHUTTLE_IDLE)
|
||||
data["points"] = round(shuttle_master.points)
|
||||
data["send"] = list("send" = 1)
|
||||
data["message"] = shuttle_master.centcom_message ? shuttle_master.centcom_message : "Remember to stamp and send back the supply manifests."
|
||||
|
||||
data["moving"] = shuttle_master.supply.mode != SHUTTLE_IDLE
|
||||
data["at_station"] = shuttle_master.supply.getDockedId() == "supply_home"
|
||||
data["timeleft"] = shuttle_master.supply.timeLeft(600)
|
||||
data["can_launch"] = !shuttle_master.supply.canMove()
|
||||
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "supply_console.tmpl", name, SUPPLY_SCREEN_WIDTH, SUPPLY_SCREEN_HEIGHT)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/supplycomp/proc/is_authorized(user)
|
||||
if(allowed(user))
|
||||
return 1
|
||||
|
||||
if(isobserver(user) && check_rights(R_ADMIN, 0))
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/obj/machinery/computer/supplycomp/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(!is_authorized(usr))
|
||||
return 1
|
||||
|
||||
if(!shuttle_master)
|
||||
log_to_dd("## ERROR: The shuttle_master controller datum is missing somehow.")
|
||||
return 1
|
||||
|
||||
if(href_list["send"])
|
||||
if(shuttle_master.supply.canMove())
|
||||
usr << "<span class='warning'>For safety reasons the automated supply shuttle cannot transport live organisms, classified nuclear weaponry or homing beacons.</span>"
|
||||
else if(shuttle_master.supply.getDockedId() == "supply_home")
|
||||
shuttle_master.toggleShuttle("supply", "supply_home", "supply_away", 1)
|
||||
investigate_log("[key_name(usr)] has sent the supply shuttle away. Remaining points: [shuttle_master.points]. Shuttle contents: [shuttle_master.sold_atoms]", "cargo")
|
||||
else if(!shuttle_master.supply.request(shuttle_master.getDock("supply_home")))
|
||||
post_signal("supply")
|
||||
|
||||
else if (href_list["doorder"])
|
||||
if(world.time < reqtime)
|
||||
visible_message("<b>[src]</b>'s monitor flashes, \"[world.time - reqtime] seconds remaining until another requisition form may be printed.\"")
|
||||
nanomanager.update_uis(src)
|
||||
return 1
|
||||
|
||||
var/index = copytext(href_list["doorder"], 1, lentext(href_list["doorder"])) //text2num(copytext(href_list["doorder"], 1))
|
||||
var/multi = text2num(copytext(href_list["doorder"], -1))
|
||||
if(!isnum(multi))
|
||||
return 1
|
||||
var/datum/supply_packs/P = shuttle_master.supply_packs[index]
|
||||
if(!istype(P))
|
||||
return 1
|
||||
var/crates = 1
|
||||
if(multi)
|
||||
var/num_input = input(usr, "Amount:", "How many crates?") as null|num
|
||||
if(!num_input || !is_authorized(usr) || ..())
|
||||
return 1
|
||||
crates = Clamp(round(num_input), 1, 20)
|
||||
|
||||
var/timeout = world.time + 600
|
||||
var/reason = input(usr,"Reason:","Why do you require this item?","") as null|text
|
||||
if(world.time > timeout || !reason || !is_authorized(usr) || ..())
|
||||
return 1
|
||||
reason = sanitize(copytext(reason, 1, MAX_MESSAGE_LEN))
|
||||
|
||||
var/idname = "*None Provided*"
|
||||
var/idrank = "*None Provided*"
|
||||
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/H = usr
|
||||
idname = H.get_authentification_name()
|
||||
idrank = H.get_assignment()
|
||||
else if(issilicon(usr))
|
||||
idname = usr.real_name
|
||||
|
||||
//make our supply_order datums
|
||||
for(var/i = 1; i <= crates; i++)
|
||||
var/datum/supply_order/O = shuttle_master.generateSupplyOrder(index, idname, idrank, reason, crates)
|
||||
if(!O) return 1
|
||||
if(i == 1)
|
||||
O.generateRequisition(loc)
|
||||
|
||||
else if(href_list["confirmorder"])
|
||||
if(shuttle_master.supply.getDockedId() != "supply_away" || shuttle_master.supply.mode != SHUTTLE_IDLE)
|
||||
return 1
|
||||
var/ordernum = text2num(href_list["confirmorder"])
|
||||
var/datum/supply_order/O
|
||||
var/datum/supply_packs/P
|
||||
for(var/i=1, i<=shuttle_master.requestlist.len, i++)
|
||||
var/datum/supply_order/SO = shuttle_master.requestlist[i]
|
||||
if(SO.ordernum == ordernum)
|
||||
O = SO
|
||||
P = O.object
|
||||
if(shuttle_master.points >= P.cost)
|
||||
shuttle_master.requestlist.Cut(i,i+1)
|
||||
shuttle_master.points -= P.cost
|
||||
shuttle_master.shoppinglist += O
|
||||
investigate_log("[key_name(usr)] has authorized an order for [P.name]. Remaining points: [shuttle_master.points].", "cargo")
|
||||
else
|
||||
usr << "<span class='warning'>There are insufficient supply points for this request.</span>"
|
||||
break
|
||||
|
||||
else if (href_list["rreq"])
|
||||
var/ordernum = text2num(href_list["rreq"])
|
||||
for(var/i=1, i<=shuttle_master.requestlist.len, i++)
|
||||
var/datum/supply_order/SO = shuttle_master.requestlist[i]
|
||||
if(SO.ordernum == ordernum)
|
||||
shuttle_master.requestlist.Cut(i,i+1)
|
||||
break
|
||||
|
||||
else if (href_list["last_viewed_group"])
|
||||
content_pack = null
|
||||
last_viewed_group = text2num(href_list["last_viewed_group"])
|
||||
|
||||
else if (href_list["contents"])
|
||||
var/topic = href_list["contents"]
|
||||
if(topic == 1)
|
||||
content_pack = null
|
||||
else
|
||||
var/datum/supply_packs/P = shuttle_master.supply_packs[topic]
|
||||
content_pack = P
|
||||
|
||||
add_fingerprint(usr)
|
||||
nanomanager.update_uis(src)
|
||||
return 1
|
||||
|
||||
/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)
|
||||
|
||||
/**********
|
||||
MISC
|
||||
**********/
|
||||
/area/supply/station
|
||||
name = "Supply Shuttle"
|
||||
icon_state = "shuttle3"
|
||||
requires_power = 0
|
||||
|
||||
/area/supply/dock
|
||||
name = "Supply Shuttle"
|
||||
icon_state = "shuttle3"
|
||||
requires_power = 0
|
||||
|
||||
/obj/structure/plasticflaps
|
||||
name = "\improper plastic flaps"
|
||||
desc = "Completely impassable - or are they?"
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "plasticflaps"
|
||||
density = 0
|
||||
anchored = 1
|
||||
layer = 4
|
||||
var/list/mobs_can_pass = list(
|
||||
/mob/living/carbon/slime,
|
||||
/mob/living/simple_animal/mouse,
|
||||
/mob/living/silicon/robot/drone
|
||||
)
|
||||
|
||||
/obj/structure/plasticflaps/CanPass(atom/A, turf/T)
|
||||
if(istype(A) && A.checkpass(PASSGLASS))
|
||||
return prob(60)
|
||||
|
||||
var/obj/structure/stool/bed/B = A
|
||||
if (istype(A, /obj/structure/stool/bed) && B.buckled_mob)//if it's a bed/chair and someone is buckled, it will not pass
|
||||
return 0
|
||||
|
||||
if (istype(A, /obj/structure/closet/cardboard))
|
||||
var/obj/structure/closet/cardboard/C = A
|
||||
if(C.move_delay)
|
||||
return 0
|
||||
|
||||
if(istype(A, /obj/vehicle)) //no vehicles
|
||||
return 0
|
||||
|
||||
var/mob/living/M = A
|
||||
if(istype(M))
|
||||
if(M.lying)
|
||||
return ..()
|
||||
for(var/mob_type in mobs_can_pass)
|
||||
if(istype(A, mob_type))
|
||||
return ..()
|
||||
if(istype(A, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.species.is_small)
|
||||
return ..()
|
||||
return 0
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/structure/plasticflaps/ex_act(severity)
|
||||
switch(severity)
|
||||
if (1)
|
||||
qdel(src)
|
||||
if (2)
|
||||
if (prob(50))
|
||||
qdel(src)
|
||||
if (3)
|
||||
if (prob(5))
|
||||
qdel(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."
|
||||
|
||||
/obj/structure/plasticflaps/mining/New()
|
||||
air_update_turf(1)
|
||||
..()
|
||||
|
||||
/obj/structure/plasticflaps/mining/Destroy()
|
||||
air_update_turf(1)
|
||||
return ..()
|
||||
|
||||
/obj/structure/plasticflaps/mining/CanAtmosPass(turf/T)
|
||||
return 0
|
||||
|
||||
#undef ORDER_SCREEN_WIDTH
|
||||
#undef ORDER_SCREEN_HEIGHT
|
||||
#undef SUPPLY_SCREEN_WIDTH
|
||||
#undef SUPPLY_SCREEN_HEIGHT
|
||||
@@ -0,0 +1,38 @@
|
||||
#define SYNDICATE_CHALLENGE_TIMER 12000 //20 minutes
|
||||
|
||||
/obj/machinery/computer/shuttle/syndicate
|
||||
name = "syndicate shuttle terminal"
|
||||
icon_screen = "syndishuttle"
|
||||
icon_keyboard = "syndie_key"
|
||||
req_access = list(access_syndicate)
|
||||
shuttleId = "syndicate"
|
||||
possible_destinations = "syndicate_away;syndicate_z5;syndicate_z3;syndicate_ne;syndicate_nw;syndicate_n;syndicate_se;syndicate_sw;syndicate_s"
|
||||
var/challenge = FALSE
|
||||
|
||||
/obj/machinery/computer/shuttle/syndicate/recall
|
||||
name = "syndicate shuttle recall terminal"
|
||||
possible_destinations = "syndicate_away"
|
||||
|
||||
/obj/machinery/computer/shuttle/syndicate/Topic(href, href_list)
|
||||
if(href_list["move"])
|
||||
if(challenge && world.time < SYNDICATE_CHALLENGE_TIMER)
|
||||
usr << "<span class='warning'>You've issued a combat challenge to the station! You've got to give them at least [round(((SYNDICATE_CHALLENGE_TIMER - world.time) / 10) / 60)] more minutes to allow them to prepare.</span>"
|
||||
return 0
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/shuttle/syndicate/drop_pod
|
||||
name = "syndicate assault pod control"
|
||||
icon = 'icons/obj/terminals.dmi'
|
||||
icon_state = "dorm_available"
|
||||
req_access = list(access_syndicate)
|
||||
shuttleId = "steel_rain"
|
||||
possible_destinations = null
|
||||
|
||||
/obj/machinery/computer/shuttle/syndicate/drop_pod/Topic(href, href_list)
|
||||
if(href_list["move"])
|
||||
if(z != ZLEVEL_CENTCOMM)
|
||||
usr << "<span class='warning'>Pods are one way!</span>"
|
||||
return 0
|
||||
..()
|
||||
|
||||
#undef SYNDICATE_CHALLENGE_TIMER
|
||||
Reference in New Issue
Block a user