Absolute paths for the files in the Controllers folder

This commit is contained in:
Firecage
2014-08-16 12:57:38 +02:00
parent 74c22755be
commit b1feb2c215
6 changed files with 748 additions and 749 deletions
+108 -108
View File
@@ -33,7 +33,7 @@
#define LIGHTING_LAYER 10 //Drawing layer for lighting overlays
#define LIGHTING_ICON 'icons/effects/ss13_dark_alpha6.dmi' //Icon used for lighting shading effects
datum/light_source
/datum/light_source
var/atom/owner
var/changed = 1
var/list/effect = list()
@@ -41,76 +41,76 @@ datum/light_source
var/__y = 0 //y coordinate at last update
New(atom/A)
if(!istype(A))
CRASH("The first argument to the light object's constructor must be the atom that is the light source. Expected atom, received '[A]' instead.")
..()
owner = A
/datum/light_source/New(atom/A)
if(!istype(A))
CRASH("The first argument to the light object's constructor must be the atom that is the light source. Expected atom, received '[A]' instead.")
..()
owner = A
__x = owner.x
__y = owner.y
// the lighting object maintains a list of all light sources
lighting_controller.lights += src
//Check a light to see if its effect needs reprocessing. If it does, remove any old effect and create a new one
/datum/light_source/proc/check()
if(!owner)
remove_effect()
return 1 //causes it to be removed from our list of lights. The garbage collector will then destroy it.
// check to see if we've moved since last update
if(owner.x != __x || owner.y != __y)
__x = owner.x
__y = owner.y
// the lighting object maintains a list of all light sources
lighting_controller.lights += src
changed = 1
if(changed)
changed = 0
remove_effect()
return add_effect()
return 0
//Check a light to see if its effect needs reprocessing. If it does, remove any old effect and create a new one
proc/check()
if(!owner)
remove_effect()
return 1 //causes it to be removed from our list of lights. The garbage collector will then destroy it.
/datum/light_source/proc/remove_effect()
// before we apply the effect we remove the light's current effect.
for(var/turf/T in effect) // negate the effect of this light source
T.update_lumcount(-effect[T])
effect.Cut() // clear the effect list
// check to see if we've moved since last update
if(owner.x != __x || owner.y != __y)
__x = owner.x
__y = owner.y
changed = 1
/datum/light_source/proc/add_effect()
// only do this if the light is turned on and is on the map
if(owner.loc && owner.luminosity > 0)
effect = list()
for(var/turf/T in view(owner.get_light_range(),owner))
var/delta_lumen = lum(T)
if(delta_lumen > 0)
effect[T] = delta_lumen
T.update_lumcount(delta_lumen)
if(changed)
changed = 0
remove_effect()
return add_effect()
return 0
else
owner.light = null
return 1 //cause the light to be removed from the lights list and garbage collected once it's no
//longer referenced by the queue
proc/remove_effect()
// before we apply the effect we remove the light's current effect.
for(var/turf/T in effect) // negate the effect of this light source
T.update_lumcount(-effect[T])
effect.Cut() // clear the effect list
proc/add_effect()
// only do this if the light is turned on and is on the map
if(owner.loc && owner.luminosity > 0)
effect = list()
for(var/turf/T in view(owner.get_light_range(),owner))
var/delta_lumen = lum(T)
if(delta_lumen > 0)
effect[T] = delta_lumen
T.update_lumcount(delta_lumen)
return 0
else
owner.light = null
return 1 //cause the light to be removed from the lights list and garbage collected once it's no
//longer referenced by the queue
proc/lum(turf/A)
if (owner.trueLuminosity < 1)
return 0
var/dist
if(!A)
dist = 0
else
/datum/light_source/proc/lum(turf/A)
if (owner.trueLuminosity < 1)
return 0
var/dist
if(!A)
dist = 0
else
#ifdef LIGHTING_CIRCULAR
dist = cheap_hypotenuse(A.x, A.y, __x, __y)
dist = cheap_hypotenuse(A.x, A.y, __x, __y)
#else
dist = max(abs(A.x - __x), abs(A.y - __y))
dist = max(abs(A.x - __x), abs(A.y - __y))
#endif
if (owner.trueLuminosity > 100) // This will never happen... right?
return sqrt(owner.trueLuminosity) - dist
else
return sqrtTable[owner.trueLuminosity] - dist
if (owner.trueLuminosity > 100) // This will never happen... right?
return sqrt(owner.trueLuminosity) - dist
else
return sqrtTable[owner.trueLuminosity] - dist
atom
/atom
var/datum/light_source/light
var/trueLuminosity = 0 // Typically 'luminosity' squared. The builtin luminosity must remain linear.
// We may read it, but NEVER set it directly.
@@ -118,7 +118,7 @@ atom
//Turfs with opacity when they are constructed will trigger nearby lights to update
//Turfs and atoms with luminosity when they are constructed will create a light_source automatically
turf/New()
/turf/New()
..()
if(luminosity)
if(light) WARNING("[type] - Don't set lights up manually during New(), We do it automatically.")
@@ -127,7 +127,7 @@ turf/New()
//Movable atoms with opacity when they are constructed will trigger nearby lights to update
//Movable atoms with luminosity when they are constructed will create a light_source automatically
atom/movable/New()
/atom/movable/New()
..()
if(opacity)
if(isturf(loc))
@@ -139,7 +139,7 @@ atom/movable/New()
light = new(src)
//Objects with opacity will trigger nearby lights to update at next lighting process.
atom/movable/Destroy()
/atom/movable/Destroy()
if(opacity)
if(isturf(loc))
if(loc:lighting_lumcount > 1)
@@ -151,7 +151,7 @@ atom/movable/Destroy()
//If we are setting luminosity to 0 the light will be cleaned up by the controller and garbage collected once all its
//queues are complete.
//if we have a light already it is merely updated, rather than making a new one.
atom/proc/SetLuminosity(new_luminosity, trueLum = FALSE)
/atom/proc/SetLuminosity(new_luminosity, trueLum = FALSE)
if(new_luminosity < 0)
new_luminosity = 0
if(!trueLum)
@@ -170,19 +170,19 @@ atom/proc/SetLuminosity(new_luminosity, trueLum = FALSE)
else
luminosity = sqrt(trueLuminosity)
atom/proc/AddLuminosity(delta_luminosity)
/atom/proc/AddLuminosity(delta_luminosity)
if(delta_luminosity > 0)
SetLuminosity(trueLuminosity + delta_luminosity*delta_luminosity, TRUE)
else if(delta_luminosity < 0)
SetLuminosity(trueLuminosity - delta_luminosity*delta_luminosity, TRUE)
area/SetLuminosity(new_luminosity) //we don't want dynamic lighting for areas
/area/SetLuminosity(new_luminosity) //we don't want dynamic lighting for areas
luminosity = !!new_luminosity
trueLuminosity = luminosity
//change our opacity (defaults to toggle), and then update all lights that affect us.
atom/proc/SetOpacity(new_opacity)
/atom/proc/SetOpacity(new_opacity)
if(new_opacity == null)
new_opacity = !opacity //default = toggle opacity
else if(opacity == new_opacity)
@@ -190,7 +190,7 @@ atom/proc/SetOpacity(new_opacity)
opacity = new_opacity //update opacity, the below procs now call light updates.
return 1
turf/SetOpacity(new_opacity)
/turf/SetOpacity(new_opacity)
if(..()==1) //only bother if opacity changed
if(lighting_lumcount) //only bother with an update if our turf is currently affected by a light
UpdateAffectingLights()
@@ -203,24 +203,24 @@ turf/SetOpacity(new_opacity)
UpdateAffectingLights()
turf
/turf
var/lighting_lumcount = 0
var/lighting_changed = 0
turf/space
/turf/space
lighting_lumcount = 4 //starlight
turf/proc/update_lumcount(amount)
/turf/proc/update_lumcount(amount)
lighting_lumcount += amount
if(!lighting_changed)
lighting_controller.changed_turfs += src
lighting_changed = 1
turf/proc/lighting_tag(var/level)
/turf/proc/lighting_tag(var/level)
var/area/A = loc
return A.tagbase + "sd_L[level]"
turf/proc/build_lighting_area(var/tag, var/level)
/turf/proc/build_lighting_area(var/tag, var/level)
var/area/Area = loc
var/area/A = new Area.type() // create area if it wasn't found
// replicate vars
@@ -238,7 +238,7 @@ turf/proc/build_lighting_area(var/tag, var/level)
Area.related += A
return A
turf/proc/shift_to_subarea()
/turf/proc/shift_to_subarea()
lighting_changed = 0
var/area/Area = loc
@@ -257,54 +257,54 @@ turf/proc/shift_to_subarea()
// Dedicated lighting sublevel for space turfs
// helps us depower things in space, remove space fire alarms,
// and evens out space lighting
turf/space/lighting_tag(var/level)
/turf/space/lighting_tag(var/level)
var/area/A = loc
return A.tagbase + "sd_L_space"
turf/space/build_lighting_area(var/tag,var/level)
/turf/space/build_lighting_area(var/tag,var/level)
var/area/A = ..(tag,4)
A.lighting_space = 1
A.SetLightLevel(4)
A.icon_state = null
return A
area
/area
var/lighting_use_dynamic = 1 //Turn this flag off to prevent sd_DynamicAreaLighting from affecting this area
var/image/lighting_overlay //tracks the darkness image of the area for easy removal
var/lighting_subarea = 0 //tracks whether we're a lighting sub-area
var/lighting_space = 0 // true for space-only lighting subareas
var/tagbase
proc/SetLightLevel(light)
if(!src) return
if(light <= 0)
light = 0
luminosity = 0
else
if(light > lighting_controller.lighting_states)
light = lighting_controller.lighting_states
luminosity = 1
/area/proc/SetLightLevel(light)
if(!src) return
if(light <= 0)
light = 0
luminosity = 0
else
if(light > lighting_controller.lighting_states)
light = lighting_controller.lighting_states
luminosity = 1
if(lighting_overlay)
overlays -= lighting_overlay
lighting_overlay.icon_state = "[light]"
else
lighting_overlay = image(LIGHTING_ICON,,num2text(light),LIGHTING_LAYER)
if(lighting_overlay)
overlays -= lighting_overlay
lighting_overlay.icon_state = "[light]"
else
lighting_overlay = image(LIGHTING_ICON,,num2text(light),LIGHTING_LAYER)
overlays += lighting_overlay
overlays += lighting_overlay
proc/SetDynamicLighting()
/area/proc/SetDynamicLighting()
src.lighting_use_dynamic = 1
for(var/turf/T in src.contents)
T.update_lumcount(0)
src.lighting_use_dynamic = 1
for(var/turf/T in src.contents)
T.update_lumcount(0)
proc/InitializeLighting() //TODO: could probably improve this bit ~Carn
tagbase = "[type]"
if(!tag) tag = tagbase
if(!lighting_use_dynamic)
if(!lighting_subarea) // see if this is a lighting subarea already
//show the dark overlay so areas, not yet in a lighting subarea, won't be bright as day and look silly.
SetLightLevel(4)
/area/proc/InitializeLighting() //TODO: could probably improve this bit ~Carn
tagbase = "[type]"
if(!tag) tag = tagbase
if(!lighting_use_dynamic)
if(!lighting_subarea) // see if this is a lighting subarea already
//show the dark overlay so areas, not yet in a lighting subarea, won't be bright as day and look silly.
SetLightLevel(4)
#undef LIGHTING_LAYER
#undef LIGHTING_CIRCULAR
@@ -316,24 +316,24 @@ area
//set the changed status of all lights which could have possibly lit this atom.
//We don't need to worry about lights which lit us but moved away, since they will have change status set already
//This proc can cause lots of lights to be updated. :(
atom/proc/UpdateAffectingLights()
/atom/proc/UpdateAffectingLights()
for(var/atom/A in oview(LIGHTING_MAX_LUMINOSITY_STATIC-1,src))
if(A.light)
A.light.changed = 1 //force it to update at next process()
//caps luminosity effects max-range based on what type the light's owner is.
atom/proc/get_light_range()
/atom/proc/get_light_range()
return min(luminosity, LIGHTING_MAX_LUMINOSITY_STATIC)
atom/movable/get_light_range()
/atom/movable/get_light_range()
return min(luminosity, LIGHTING_MAX_LUMINOSITY_MOBILE)
obj/machinery/light/get_light_range()
/obj/machinery/light/get_light_range()
return min(luminosity, LIGHTING_MAX_LUMINOSITY_STATIC)
turf/get_light_range()
/turf/get_light_range()
return min(luminosity, LIGHTING_MAX_LUMINOSITY_TURF)
#undef LIGHTING_MAX_LUMINOSITY_STATIC
#undef LIGHTING_MAX_LUMINOSITY_MOBILE
#undef LIGHTING_MAX_LUMINOSITY_TURF
#undef LIGHTING_MAX_LUMINOSITY_TURF
+5 -5
View File
@@ -1,6 +1,6 @@
var/datum/controller/lighting/lighting_controller = new ()
datum/controller/lighting
/datum/controller/lighting
var/processing = 0
var/processing_interval = 5 //setting this too low will probably kill the server. Don't be silly with it!
var/process_cost = 0
@@ -17,7 +17,7 @@ datum/controller/lighting
var/list/changed_turfs = list()
var/changed_turfs_workload_max = 0
datum/controller/lighting/New()
/datum/controller/lighting/New()
lighting_states = max( 0, length(icon_states(LIGHTING_ICON))-1 )
if(lighting_controller != src)
if(istype(lighting_controller,/datum/controller/lighting))
@@ -31,7 +31,7 @@ datum/controller/lighting/New()
//All queue lists prune themselves, which will cause lights with no luminosity to be garbage collected (cheaper and safer
//than deleting them). Processing interval should be roughly half a second for best results.
//By using queues we are ensuring we don't perform more updates than are necessary
datum/controller/lighting/proc/process()
/datum/controller/lighting/proc/process()
processing = 1
spawn(0)
set background = BACKGROUND_ENABLED
@@ -65,7 +65,7 @@ datum/controller/lighting/proc/process()
//Does not loop. Should be run prior to process() being called for the first time.
//Note: if we get additional z-levels at runtime (e.g. if the gateway thin ever gets finished) we can initialize specific
//z-levels with the z_level argument
datum/controller/lighting/proc/Initialize(var/z_level)
/datum/controller/lighting/proc/Initialize(var/z_level)
processing = 0
spawn(-1)
set background = BACKGROUND_ENABLED
@@ -95,7 +95,7 @@ datum/controller/lighting/proc/Initialize(var/z_level)
//Used to strip valid information from an existing controller and transfer it to a replacement
//It works by using spawn(-1) to transfer the data, if there is a runtime the data does not get transfered but the loop
//does not crash
datum/controller/lighting/proc/Recover()
/datum/controller/lighting/proc/Recover()
if(!istype(lighting_controller.changed_turfs,/list))
lighting_controller.changed_turfs = list()
if(!istype(lighting_controller.lights,/list))
+14 -14
View File
@@ -11,7 +11,7 @@ var/global/last_tick_duration = 0
var/global/air_processing_killed = 0
var/global/pipe_processing_killed = 0
datum/controller/game_controller
/datum/controller/game_controller
var/processing = 0
var/breather_ticks = 2 //a somewhat crude attempt to iron over the 'bumps' caused by high-cpu use by letting the MC have a breather for this many ticks after every loop
var/minimum_ticks = 20 //The minimum length of time between MC ticks
@@ -37,7 +37,7 @@ datum/controller/game_controller
var/last_thing_processed
datum/controller/game_controller/New()
/datum/controller/game_controller/New()
//There can be only one master_controller. Out with the old and in with the new.
if(master_controller != src)
if(istype(master_controller))
@@ -69,7 +69,7 @@ datum/controller/game_controller/New()
if(!emergency_shuttle) emergency_shuttle = new /datum/shuttle_controller/emergency_shuttle()
if(!supply_shuttle) supply_shuttle = new /datum/controller/supply_shuttle()
datum/controller/game_controller/proc/setup()
/datum/controller/game_controller/proc/setup()
world.tick_lag = config.Ticklag
setup_objects()
@@ -80,7 +80,7 @@ datum/controller/game_controller/proc/setup()
if(ticker)
ticker.pregame()
datum/controller/game_controller/proc/setup_objects()
/datum/controller/game_controller/proc/setup_objects()
world << "\red \b Initializing objects..."
sleep(-1)
for(var/atom/movable/object in world)
@@ -110,7 +110,7 @@ datum/controller/game_controller/proc/setup_objects()
sleep(-1)
datum/controller/game_controller/proc/process()
/datum/controller/game_controller/proc/process()
processing = 1
spawn(0)
set background = BACKGROUND_ENABLED
@@ -223,7 +223,7 @@ datum/controller/game_controller/proc/process()
sleep(10)
/*
datum/controller/game_controller/proc/process_liquid()
/datum/controller/game_controller/proc/process_liquid()
last_thing_processed = /datum/puddle
var/i = 1
while(i<=puddles.len)
@@ -235,7 +235,7 @@ datum/controller/game_controller/proc/process_liquid()
puddles.Cut(i,i+1)
*/
datum/controller/game_controller/proc/process_mobs()
/datum/controller/game_controller/proc/process_mobs()
var/i = 1
while(i<=mob_list.len)
var/mob/M = mob_list[i]
@@ -246,7 +246,7 @@ datum/controller/game_controller/proc/process_mobs()
continue
mob_list.Cut(i,i+1)
datum/controller/game_controller/proc/process_diseases()
/datum/controller/game_controller/proc/process_diseases()
var/i = 1
while(i<=active_diseases.len)
var/datum/disease/Disease = active_diseases[i]
@@ -257,7 +257,7 @@ datum/controller/game_controller/proc/process_diseases()
continue
active_diseases.Cut(i,i+1)
datum/controller/game_controller/proc/process_machines()
/datum/controller/game_controller/proc/process_machines()
var/i = 1
while(i<=machines.len)
var/obj/machinery/Machine = machines[i]
@@ -271,7 +271,7 @@ datum/controller/game_controller/proc/process_machines()
continue
machines.Cut(i,i+1)
datum/controller/game_controller/proc/process_objects()
/datum/controller/game_controller/proc/process_objects()
var/i = 1
while(i<=processing_objects.len)
var/obj/Object = processing_objects[i]
@@ -282,7 +282,7 @@ datum/controller/game_controller/proc/process_objects()
continue
processing_objects.Cut(i,i+1)
datum/controller/game_controller/proc/process_pipenets()
/datum/controller/game_controller/proc/process_pipenets()
last_thing_processed = /datum/pipe_network
var/i = 1
while(i<=pipe_networks.len)
@@ -293,7 +293,7 @@ datum/controller/game_controller/proc/process_pipenets()
continue
pipe_networks.Cut(i,i+1)
datum/controller/game_controller/proc/process_powernets()
/datum/controller/game_controller/proc/process_powernets()
last_thing_processed = /datum/powernet
var/i = 1
while(i<=powernets.len)
@@ -304,7 +304,7 @@ datum/controller/game_controller/proc/process_powernets()
continue
powernets.Cut(i,i+1)
datum/controller/game_controller/proc/process_nano()
/datum/controller/game_controller/proc/process_nano()
var/i = 1
while(i<=nanomanager.processing_uis.len)
var/datum/nanoui/ui = nanomanager.processing_uis[i]
@@ -314,7 +314,7 @@ datum/controller/game_controller/proc/process_nano()
continue
nanomanager.processing_uis.Cut(i,i+1)
datum/controller/game_controller/proc/Recover() //Mostly a placeholder for now.
/datum/controller/game_controller/proc/Recover() //Mostly a placeholder for now.
var/msg = "## DEBUG: [time2text(world.timeofday)] MC restarted. Reports:\n"
for(var/varname in master_controller.vars)
switch(varname)
+157 -158
View File
@@ -18,7 +18,7 @@
var/global/datum/shuttle_controller/emergency_shuttle/emergency_shuttle
datum/shuttle_controller
/datum/shuttle_controller
var/location = UNDOCKED //
var/online = 0
var/direction = 1 //-1 = going back to central command, 1 = going to SS13. Only important for recalling
@@ -37,150 +37,149 @@ datum/shuttle_controller
// call the shuttle
// if not called before, set the endtime to T+600 seconds
// otherwise if outgoing, switch to incoming
proc/incall(coeff = 1, var/signal_origin)
/datum/shuttle_controller/proc/incall(coeff = 1, var/signal_origin)
if(endtime)
if(direction == -1)
setdirection(1)
if(endtime)
if(direction == -1)
setdirection(1)
else
if(signal_origin && prob(60)) //40% chance the signal tracing will fail
last_call_loc = signal_origin
else
if(signal_origin && prob(60)) //40% chance the signal tracing will fail
last_call_loc = signal_origin
last_call_loc = null
settimeleft(SHUTTLEARRIVETIME*coeff)
online = 1
if(always_fake_recall)
if ((seclevel2num(get_security_level()) == SEC_LEVEL_RED))
fake_recall = rand(SHUTTLEARRIVETIME / 4, SHUTTLEARRIVETIME - 100 / 2)
else
last_call_loc = null
settimeleft(SHUTTLEARRIVETIME*coeff)
online = 1
if(always_fake_recall)
fake_recall = rand(SHUTTLEARRIVETIME / 2, SHUTTLEARRIVETIME - 100)
if ((seclevel2num(get_security_level()) == SEC_LEVEL_RED))
fake_recall = rand(SHUTTLEARRIVETIME / 4, SHUTTLEARRIVETIME - 100 / 2)
else
fake_recall = rand(SHUTTLEARRIVETIME / 2, SHUTTLEARRIVETIME - 100)
/datum/shuttle_controller/proc/recall(var/signal_origin)
if(direction == 1)
var/timeleft = timeleft()
if(timeleft >= SHUTTLEARRIVETIME)
online = 0
direction = 1
endtime = null
return
proc/recall(var/signal_origin)
recall_count ++
if(recall_count > 2 && signal_origin && prob(60)) //40% chance the signal tracing will fail
last_call_loc = signal_origin
else
last_call_loc = null
if(recall_count == 2)
priority_announce("The emergency shuttle has been recalled.\n\nExcessive number of emergency shuttle calls detected. We will attempt to trace all future calls and recalls to their source. Tracing results can be viewed on any communications console.", null, 'sound/AI/shuttlerecalled.ogg')
else
priority_announce("The emergency shuttle has been recalled.", null, 'sound/AI/shuttlerecalled.ogg', "Priority")
setdirection(-1)
online = 1
// returns the time (in seconds) before shuttle arrival
// note if direction = -1, gives a count-up to SHUTTLEARRIVETIME
/datum/shuttle_controller/proc/timeleft()
if(online)
var/timeleft = round((endtime - world.timeofday)/10 ,1)
if(timeleft > (MIDNIGHT_ROLLOVER/10)) // midnight rollover protection
endtime -= MIDNIGHT_ROLLOVER // subtract 24 hours from endtime
timeleft = round((endtime - world.timeofday)/10 ,1) // recalculate timeleft
if(direction == 1)
var/timeleft = timeleft()
if(timeleft >= SHUTTLEARRIVETIME)
return timeleft
else
return SHUTTLEARRIVETIME-timeleft
else
return SHUTTLEARRIVETIME
// sets the time left to a given delay (in seconds)
/datum/shuttle_controller/proc/settimeleft(var/delay)
endtime = world.timeofday + delay * 10
timelimit = delay
// sets the shuttle direction
// 1 = towards SS13, -1 = back to centcom
/datum/shuttle_controller/proc/setdirection(var/dirn)
if(direction == dirn)
return
direction = dirn
// if changing direction, flip the timeleft by SHUTTLEARRIVETIME
var/ticksleft = endtime - world.timeofday
endtime = world.timeofday + (SHUTTLEARRIVETIME*10 - ticksleft)
return
//calls the shuttle if there's no live active AI or powered non broken comms console,
/datum/shuttle_controller/proc/autoshuttlecall()
var/callshuttle = 1
for(var/SC in shuttle_caller_list)
if(istype(SC,/mob/living/silicon/ai))
var/mob/living/silicon/ai/AI = SC
if(AI.stat || !AI.client)
continue
if(istype(SC,/obj/machinery/computer/communications))
var/obj/machinery/computer/communications/C = SC
if(C.stat & BROKEN)
continue
var/turf/T = get_turf(SC)
if(T && T.z == 1)
callshuttle = 0 //if there's an alive AI or a powered non broken communication console on the station z level, we don't call the shuttle
break
if(callshuttle)
if(!online && direction == 1) //we don't call the shuttle if it's already coming
incall(SHUTTLEAUTOCALLTIMER) //X minutes! If they want to recall, they have X-(X-5) minutes to do so
log_game("All the communications consoles were destroyed and all AIs are inactive. Shuttle called.")
message_admins("All the communications consoles were destroyed and all AIs are inactive. Shuttle called.", 1)
priority_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.", null, 'sound/AI/shuttlecalled.ogg', "Priority")
/datum/shuttle_controller/proc/move_shuttles()
var/datum/shuttle_manager/s
for(var/t in pods)
s = shuttles[t]
s.move_shuttle()
/datum/shuttle_controller/proc/process()
/datum/shuttle_controller/emergency_shuttle/process()
if(!online)
return
var/timeleft = timeleft()
if(location == UNDOCKED)
if(direction == -1)
if(timeleft >= timelimit) // Shuttle reaches CentCom after being recalled.
online = 0
direction = 1
endtime = null
return
recall_count ++
if(recall_count > 2 && signal_origin && prob(60)) //40% chance the signal tracing will fail
last_call_loc = signal_origin
else
last_call_loc = null
if(recall_count == 2)
priority_announce("The emergency shuttle has been recalled.\n\nExcessive number of emergency shuttle calls detected. We will attempt to trace all future calls and recalls to their source. Tracing results can be viewed on any communications console.", null, 'sound/AI/shuttlerecalled.ogg')
else
priority_announce("The emergency shuttle has been recalled.", null, 'sound/AI/shuttlerecalled.ogg', "Priority")
setdirection(-1)
online = 1
// returns the time (in seconds) before shuttle arrival
// note if direction = -1, gives a count-up to SHUTTLEARRIVETIME
proc/timeleft()
if(online)
var/timeleft = round((endtime - world.timeofday)/10 ,1)
if(timeleft > (MIDNIGHT_ROLLOVER/10)) // midnight rollover protection
endtime -= MIDNIGHT_ROLLOVER // subtract 24 hours from endtime
timeleft = round((endtime - world.timeofday)/10 ,1) // recalculate timeleft
if(direction == 1)
return timeleft
else
return SHUTTLEARRIVETIME-timeleft
else
return SHUTTLEARRIVETIME
// sets the time left to a given delay (in seconds)
proc/settimeleft(var/delay)
endtime = world.timeofday + delay * 10
timelimit = delay
// sets the shuttle direction
// 1 = towards SS13, -1 = back to centcom
proc/setdirection(var/dirn)
if(direction == dirn)
return
direction = dirn
// if changing direction, flip the timeleft by SHUTTLEARRIVETIME
var/ticksleft = endtime - world.timeofday
endtime = world.timeofday + (SHUTTLEARRIVETIME*10 - ticksleft)
return
//calls the shuttle if there's no live active AI or powered non broken comms console,
proc/autoshuttlecall()
var/callshuttle = 1
for(var/SC in shuttle_caller_list)
if(istype(SC,/mob/living/silicon/ai))
var/mob/living/silicon/ai/AI = SC
if(AI.stat || !AI.client)
continue
if(istype(SC,/obj/machinery/computer/communications))
var/obj/machinery/computer/communications/C = SC
if(C.stat & BROKEN)
continue
var/turf/T = get_turf(SC)
if(T && T.z == 1)
callshuttle = 0 //if there's an alive AI or a powered non broken communication console on the station z level, we don't call the shuttle
break
if(callshuttle)
if(!online && direction == 1) //we don't call the shuttle if it's already coming
incall(SHUTTLEAUTOCALLTIMER) //X minutes! If they want to recall, they have X-(X-5) minutes to do so
log_game("All the communications consoles were destroyed and all AIs are inactive. Shuttle called.")
message_admins("All the communications consoles were destroyed and all AIs are inactive. Shuttle called.", 1)
priority_announce("The emergency shuttle has been called. It will arrive in [round(emergency_shuttle.timeleft()/60)] minutes.", null, 'sound/AI/shuttlecalled.ogg', "Priority")
proc/move_shuttles()
var/datum/shuttle_manager/s
for(var/t in pods)
s = shuttles[t]
s.move_shuttle()
proc/process()
emergency_shuttle
process()
if(!online)
return
var/timeleft = timeleft()
if(location == UNDOCKED)
if(direction == -1)
if(timeleft >= timelimit) // Shuttle reaches CentCom after being recalled.
online = 0
direction = 1
endtime = null
return 0
else if(fake_recall && (timeleft <= fake_recall))
recall()
fake_recall = 0
return 0
else if(timeleft <= 0)
var/datum/shuttle_manager/s = shuttles["escape"]
s.move_shuttle()
location = DOCKED
settimeleft(SHUTTLELEAVETIME)
send2irc("Server", "The Emergency Shuttle has docked with the station.")
priority_announce("The Emergency Shuttle has docked with the station. You have [round(timeleft()/60,1)] minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg', "Priority")
else if(timeleft <= 0) //Nothing happens if time's not up and the ship's docked or later
if(location == DOCKED)
move_shuttles()
location = TRANSIT
settimeleft(SHUTTLETRANSITTIME)
priority_announce("The Emergency Shuttle has left the station. Estimate [round(timeleft()/60,1)] minutes until the shuttle docks at Central Command.", null, null, "Priority")
else if(location == TRANSIT)
move_shuttles()
//message_admins("Shuttles have attempted to move to Centcom")
location = ENDGAME
online = 0
endtime = null
return 1
return 0
else if(fake_recall && (timeleft <= fake_recall))
recall()
fake_recall = 0
return 0
else if(timeleft <= 0)
var/datum/shuttle_manager/s = shuttles["escape"]
s.move_shuttle()
location = DOCKED
settimeleft(SHUTTLELEAVETIME)
send2irc("Server", "The Emergency Shuttle has docked with the station.")
priority_announce("The Emergency Shuttle has docked with the station. You have [round(timeleft()/60,1)] minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg', "Priority")
else if(timeleft <= 0) //Nothing happens if time's not up and the ship's docked or later
if(location == DOCKED)
move_shuttles()
location = TRANSIT
settimeleft(SHUTTLETRANSITTIME)
priority_announce("The Emergency Shuttle has left the station. Estimate [round(timeleft()/60,1)] minutes until the shuttle docks at Central Command.", null, null, "Priority")
else if(location == TRANSIT)
move_shuttles()
//message_admins("Shuttles have attempted to move to Centcom")
location = ENDGAME
online = 0
endtime = null
return 1
return 0
/*
Some slapped-together star effects for maximum spess immershuns. Basically consists of a
@@ -194,23 +193,23 @@ datum/shuttle_controller
var/direction = SOUTH
layer = 2 // TURF_LAYER
New()
..()
pixel_x += rand(-2,30)
pixel_y += rand(-2,30)
var/starnum = pick("1", "1", "1", "2", "3", "4")
/obj/effect/bgstar/New()
..()
pixel_x += rand(-2,30)
pixel_y += rand(-2,30)
var/starnum = pick("1", "1", "1", "2", "3", "4")
icon_state = "star"+starnum
icon_state = "star"+starnum
speed = rand(2, 5)
speed = rand(2, 5)
proc/startmove()
/obj/effect/bgstar/proc/startmove()
while(src)
sleep(speed)
step(src, direction)
for(var/obj/effect/starender/E in loc)
qdel(src)
while(src)
sleep(speed)
step(src, direction)
for(var/obj/effect/starender/E in loc)
qdel(src)
/obj/effect/starender
@@ -221,17 +220,17 @@ datum/shuttle_controller
var/spawndir = SOUTH
var/spawning = 0
West
spawndir = WEST
/obj/effect/starspawner/West
spawndir = WEST
proc/startspawn()
spawning = 1
while(spawning)
sleep(rand(2, 30))
var/obj/effect/bgstar/S = new/obj/effect/bgstar(locate(x,y,z))
S.direction = spawndir
spawn()
S.startmove()
/obj/effect/starspawner/proc/startspawn()
spawning = 1
while(spawning)
sleep(rand(2, 30))
var/obj/effect/bgstar/S = new/obj/effect/bgstar(locate(x,y,z))
S.direction = spawndir
spawn()
S.startmove()
/proc/push_mob_back(var/mob/living/L, var/dir)
+225 -225
View File
@@ -61,18 +61,18 @@ var/global/datum/controller/supply_shuttle/supply_shuttle
name = "airtight plastic flaps"
desc = "Heavy duty, airtight, plastic flaps."
New() //set the turf below the flaps to block air
var/turf/T = get_turf(loc)
if(T)
T.blocks_air = 1
..()
/obj/structure/plasticflaps/mining/New() //set the turf below the flaps to block air
var/turf/T = get_turf(loc)
if(T)
T.blocks_air = 1
..()
Destroy() //lazy hack to set the turf to allow air to pass if it's a simulated floor //wow this is terrible
var/turf/T = get_turf(loc)
if(T)
if(istype(T, /turf/simulated/floor))
T.blocks_air = 0
..()
/obj/structure/plasticflaps/mining/Destroy() //lazy hack to set the turf to allow air to pass if it's a simulated floor //wow this is terrible
var/turf/T = get_turf(loc)
if(T)
if(istype(T, /turf/simulated/floor))
T.blocks_air = 0
..()
/obj/machinery/computer/supplycomp
name = "supply shuttle console"
@@ -140,269 +140,269 @@ var/global/datum/controller/supply_shuttle/supply_shuttle
//shuttle loan
var/datum/round_event/shuttle_loan/shuttle_loan
New()
ordernum = rand(1,9000)
for(var/typepath in (typesof(/datum/supply_packs) - /datum/supply_packs))
var/datum/supply_packs/P = new typepath()
if(P.name == "HEADER") continue // To filter out group headers
supply_packs[P.name] = P
/datum/controller/supply_shuttle/New()
ordernum = rand(1,9000)
for(var/typepath in (typesof(/datum/supply_packs) - /datum/supply_packs))
var/datum/supply_packs/P = new typepath()
if(P.name == "HEADER") continue // To filter out group headers
supply_packs[P.name] = P
//Supply shuttle ticker - handles supply point regenertion and shuttle travelling between centcom and the station
proc/process()
//Supply shuttle ticker - handles supply point regenertion and shuttle travelling between centcom and the station
/datum/controller/supply_shuttle/proc/process()
spawn(0)
set background = BACKGROUND_ENABLED
while(1)
if(processing)
iteration++
points += points_per_process
spawn(0)
set background = BACKGROUND_ENABLED
while(1)
if(processing)
iteration++
points += points_per_process
if(moving == 1)
var/ticksleft = (eta_timeofday - world.timeofday)
if(ticksleft > 0)
eta = round(ticksleft/600,1)
else
eta = 0
send()
if(moving == 1)
var/ticksleft = (eta_timeofday - world.timeofday)
if(ticksleft > 0)
eta = round(ticksleft/600,1)
else
eta = 0
send()
sleep(processing_interval)
sleep(processing_interval)
proc/send()
var/area/from
var/area/dest
switch(at_station)
if(1)
from = locate(SUPPLY_STATION_AREATYPE)
dest = locate(SUPPLY_DOCK_AREATYPE)
at_station = 0
if(0)
from = locate(SUPPLY_DOCK_AREATYPE)
dest = locate(SUPPLY_STATION_AREATYPE)
at_station = 1
dest.clear_docking_area()
moving = 0
/datum/controller/supply_shuttle/proc/send()
var/area/from
var/area/dest
switch(at_station)
if(1)
from = locate(SUPPLY_STATION_AREATYPE)
dest = locate(SUPPLY_DOCK_AREATYPE)
at_station = 0
if(0)
from = locate(SUPPLY_DOCK_AREATYPE)
dest = locate(SUPPLY_STATION_AREATYPE)
at_station = 1
dest.clear_docking_area()
moving = 0
from.move_contents_to(dest)
from.move_contents_to(dest)
//Check whether the shuttle is allowed to move
proc/can_move()
if(moving) return 0
//Check whether the shuttle is allowed to move
/datum/controller/supply_shuttle/proc/can_move()
if(moving) return 0
var/area/shuttle = locate(/area/supply/station)
if(!shuttle) return 0
var/area/shuttle = locate(/area/supply/station)
if(!shuttle) return 0
if(forbidden_atoms_check(shuttle))
return 0
if(forbidden_atoms_check(shuttle))
return 0
return 1
//To stop things being sent to centcom which should not be sent to centcom Recursively checks for these types.
/datum/controller/supply_shuttle/proc/forbidden_atoms_check(atom/A)
if(istype(A,/mob/living))
return 1
if(istype(A,/obj/item/weapon/disk/nuclear))
return 1
if(istype(A,/obj/machinery/nuclearbomb))
return 1
if(istype(A,/obj/item/device/radio/beacon))
return 1
if(istype(A,/obj/effect/blob))
return 1
if(istype(A,/obj/effect/spider/spiderling))
return 1
//To stop things being sent to centcom which should not be sent to centcom Recursively checks for these types.
proc/forbidden_atoms_check(atom/A)
if(istype(A,/mob/living))
return 1
if(istype(A,/obj/item/weapon/disk/nuclear))
return 1
if(istype(A,/obj/machinery/nuclearbomb))
return 1
if(istype(A,/obj/item/device/radio/beacon))
return 1
if(istype(A,/obj/effect/blob))
return 1
if(istype(A,/obj/effect/spider/spiderling))
for(var/i=1, i<=A.contents.len, i++)
var/atom/B = A.contents[i]
if(.(B))
return 1
for(var/i=1, i<=A.contents.len, i++)
var/atom/B = A.contents[i]
if(.(B))
return 1
//Sellin
/datum/controller/supply_shuttle/proc/sell()
var/shuttle_at
if(at_station) shuttle_at = SUPPLY_STATION_AREATYPE
else shuttle_at = SUPPLY_DOCK_AREATYPE
//Sellin
proc/sell()
var/shuttle_at
if(at_station) shuttle_at = SUPPLY_STATION_AREATYPE
else shuttle_at = SUPPLY_DOCK_AREATYPE
var/area/shuttle = locate(shuttle_at)
if(!shuttle) return
var/area/shuttle = locate(shuttle_at)
if(!shuttle) return
var/plasma_count = 0
var/intel_count = 0
var/crate_count = 0
var/plasma_count = 0
var/intel_count = 0
var/crate_count = 0
centcom_message = ""
centcom_message = ""
for(var/atom/movable/MA in shuttle)
if(MA.anchored) continue
for(var/atom/movable/MA in shuttle)
if(MA.anchored) continue
// Must be in a crate (or a critter crate)!
if(istype(MA,/obj/structure/closet/crate) || istype(MA,/obj/structure/closet/critter))
crate_count++
var/find_slip = 1
// Must be in a crate (or a critter crate)!
if(istype(MA,/obj/structure/closet/crate) || istype(MA,/obj/structure/closet/critter))
crate_count++
var/find_slip = 1
for(var/atom in MA)
// Sell manifests
var/atom/A = atom
if(find_slip && istype(A,/obj/item/weapon/paper/manifest))
var/obj/item/weapon/paper/manifest/slip = A
// 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)
points += slip.points-points_per_crate // For now, give a full refund for paying attention (minus the crate cost)
centcom_message += "<font color=green>+[slip.points-points_per_crate]</font>: Station correctly denied package [slip.ordernumber]: "
for(var/atom in MA)
// Sell manifests
var/atom/A = atom
if(find_slip && istype(A,/obj/item/weapon/paper/manifest))
var/obj/item/weapon/paper/manifest/slip = A
// 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)
points += slip.points-points_per_crate // For now, give a full refund for paying attention (minus the crate cost)
centcom_message += "<font color=green>+[slip.points-points_per_crate]</font>: Station correctly denied package [slip.ordernumber]: "
if(slip.erroneous & MANIFEST_ERROR_NAME)
centcom_message += "Destination station incorrect. "
else if(slip.erroneous & MANIFEST_ERROR_COUNT)
centcom_message += "Packages incorrectly counted. "
else if(slip.erroneous & MANIFEST_ERROR_ITEM)
centcom_message += "Package incomplete. "
centcom_message += "Points refunded.<BR>"
else if(!slip.erroneous && !denied) // Approving a proper order awards the relatively tiny points_per_slip
points += points_per_slip
centcom_message += "<font color=green>+1</font>: Package [slip.ordernumber] accorded.<BR>"
else // You done goofed.
if(slip.erroneous)
centcom_message += "<font color=red>+0</font>: Station approved package [slip.ordernumber] despite error: "
if(slip.erroneous & MANIFEST_ERROR_NAME)
centcom_message += "Destination station incorrect. "
centcom_message += "Destination station incorrect."
else if(slip.erroneous & MANIFEST_ERROR_COUNT)
centcom_message += "Packages incorrectly counted. "
centcom_message += "Packages incorrectly counted."
else if(slip.erroneous & MANIFEST_ERROR_ITEM)
centcom_message += "Package incomplete. "
centcom_message += "Points refunded.<BR>"
else if(!slip.erroneous && !denied) // Approving a proper order awards the relatively tiny points_per_slip
points += points_per_slip
centcom_message += "<font color=green>+1</font>: Package [slip.ordernumber] accorded.<BR>"
else // You done goofed.
if(slip.erroneous)
centcom_message += "<font color=red>+0</font>: Station approved package [slip.ordernumber] despite error: "
if(slip.erroneous & MANIFEST_ERROR_NAME)
centcom_message += "Destination station incorrect."
else if(slip.erroneous & MANIFEST_ERROR_COUNT)
centcom_message += "Packages incorrectly counted."
else if(slip.erroneous & MANIFEST_ERROR_ITEM)
centcom_message += "We found unshipped items on our dock."
centcom_message += " Be more vigilant.<BR>"
else
points -= slip.points-points_per_crate
centcom_message += "<font color=red>-[slip.points-points_per_crate]</font>: Station denied package [slip.ordernumber]. Our records show no fault on our part.<BR>"
find_slip = 0
continue
centcom_message += "We found unshipped items on our dock."
centcom_message += " Be more vigilant.<BR>"
else
points -= slip.points-points_per_crate
centcom_message += "<font color=red>-[slip.points-points_per_crate]</font>: Station denied package [slip.ordernumber]. Our records show no fault on our part.<BR>"
find_slip = 0
continue
// Sell plasma
if(istype(A, /obj/item/stack/sheet/mineral/plasma))
var/obj/item/stack/sheet/mineral/plasma/P = A
plasma_count += P.amount
// Sell plasma
if(istype(A, /obj/item/stack/sheet/mineral/plasma))
var/obj/item/stack/sheet/mineral/plasma/P = A
plasma_count += P.amount
// Sell syndicate intel
if(istype(A, /obj/item/documents/syndicate))
intel_count += 1
// Sell syndicate intel
if(istype(A, /obj/item/documents/syndicate))
intel_count += 1
if(istype(A, /obj/item/seeds))
var/obj/item/seeds/S = A
if(S.rarity == 0) // Mundane species
centcom_message += "<font color=red>+0</font>: We don't need samples of mundane species \"[capitalize(S.species)]\".<BR>"
else if(discoveredPlants[S.type]) // This species has already been sent to CentComm
var/potDiff = S.potency - discoveredPlants[S.type] // Compare it to the previous best
if(potDiff > 0) // This sample is better
discoveredPlants[S.type] = S.potency
centcom_message += "<font color=green>+[potDiff]</font>: New sample of \"[capitalize(S.species)]\" is superior. Good work.<BR>"
points += potDiff
else // This sample is worthless
centcom_message += "<font color=red>+0</font>: New sample of \"[capitalize(S.species)]\" is not more potent than existing sample ([discoveredPlants[S.type]] potency).<BR>"
else // This is a new discovery!
if(istype(A, /obj/item/seeds))
var/obj/item/seeds/S = A
if(S.rarity == 0) // Mundane species
centcom_message += "<font color=red>+0</font>: We don't need samples of mundane species \"[capitalize(S.species)]\".<BR>"
else if(discoveredPlants[S.type]) // This species has already been sent to CentComm
var/potDiff = S.potency - discoveredPlants[S.type] // Compare it to the previous best
if(potDiff > 0) // This sample is better
discoveredPlants[S.type] = S.potency
centcom_message += "<font color=green>+[S.rarity]</font>: New species discovered: \"[capitalize(S.species)]\". Excellent work.<BR>"
points += S.rarity // That's right, no bonus for potency. Send a crappy sample first to "show improvement" later
qdel(MA)
centcom_message += "<font color=green>+[potDiff]</font>: New sample of \"[capitalize(S.species)]\" is superior. Good work.<BR>"
points += potDiff
else // This sample is worthless
centcom_message += "<font color=red>+0</font>: New sample of \"[capitalize(S.species)]\" is not more potent than existing sample ([discoveredPlants[S.type]] potency).<BR>"
else // This is a new discovery!
discoveredPlants[S.type] = S.potency
centcom_message += "<font color=green>+[S.rarity]</font>: New species discovered: \"[capitalize(S.species)]\". Excellent work.<BR>"
points += S.rarity // That's right, no bonus for potency. Send a crappy sample first to "show improvement" later
qdel(MA)
if(plasma_count)
centcom_message += "<font color=green>+[round(plasma_count/plasma_per_point)]</font>: Received [plasma_count] unit(s) of exotic material.<BR>"
points += round(plasma_count / plasma_per_point)
if(plasma_count)
centcom_message += "<font color=green>+[round(plasma_count/plasma_per_point)]</font>: Received [plasma_count] unit(s) of exotic material.<BR>"
points += round(plasma_count / plasma_per_point)
if(intel_count)
centcom_message += "<font color=green>+[round(intel_count*points_per_intel)]</font>: Received [intel_count] article(s) of enemy intelligence.<BR>"
points += round(intel_count*points_per_intel)
if(intel_count)
centcom_message += "<font color=green>+[round(intel_count*points_per_intel)]</font>: Received [intel_count] article(s) of enemy intelligence.<BR>"
points += round(intel_count*points_per_intel)
if(crate_count)
centcom_message += "<font color=green>+[round(crate_count*points_per_crate)]</font>: Received [crate_count] crate(s).<BR>"
points += crate_count * points_per_crate
if(crate_count)
centcom_message += "<font color=green>+[round(crate_count*points_per_crate)]</font>: Received [crate_count] crate(s).<BR>"
points += crate_count * points_per_crate
//Buyin
proc/buy()
if(!shoppinglist.len) return
//Buyin
/datum/controller/supply_shuttle/proc/buy()
if(!shoppinglist.len) return
var/shuttle_at
if(at_station) shuttle_at = SUPPLY_STATION_AREATYPE
else shuttle_at = SUPPLY_DOCK_AREATYPE
var/shuttle_at
if(at_station) shuttle_at = SUPPLY_STATION_AREATYPE
else shuttle_at = SUPPLY_DOCK_AREATYPE
var/area/shuttle = locate(shuttle_at)
if(!shuttle) return
var/area/shuttle = locate(shuttle_at)
if(!shuttle) return
var/list/clear_turfs = list()
var/list/clear_turfs = list()
for(var/turf/T in shuttle)
if(T.density || T.contents.len) continue
clear_turfs += T
for(var/turf/T in shuttle)
if(T.density || T.contents.len) continue
clear_turfs += T
for(var/S 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)
for(var/S 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)
var/datum/supply_order/SO = S
var/datum/supply_packs/SP = SO.object
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])":"" ]"
var/atom/A = new SP.containertype(pickedloc)
A.name = "[SP.containername] [SO.comment ? "([SO.comment])":"" ]"
//supply manifest generation begin
//supply manifest generation begin
var/obj/item/weapon/paper/manifest/slip = new /obj/item/weapon/paper/manifest(A)
var/obj/item/weapon/paper/manifest/slip = new /obj/item/weapon/paper/manifest(A)
var printed_station_name = world.name // World name is available in the title bar, station_name can be different based on config.
if(prob(5))
printed_station_name = new_station_name()
slip.erroneous |= MANIFEST_ERROR_NAME // They got our station name wrong. BASTARDS!
// IDEA: Have Centcom accidentally send random low-value crates in large orders, give large bonus for returning them intact.
var printed_packages_amount = supply_shuttle.shoppinglist.len
if(prob(5))
printed_packages_amount += rand(1,2) // I considered rand(-2,2), but that could be zero. Heh.
slip.erroneous |= MANIFEST_ERROR_COUNT // They typoed the number of crates in this shipment. It won't match the other manifests.
var printed_station_name = world.name // World name is available in the title bar, station_name can be different based on config.
if(prob(5))
printed_station_name = new_station_name()
slip.erroneous |= MANIFEST_ERROR_NAME // They got our station name wrong. BASTARDS!
// IDEA: Have Centcom accidentally send random low-value crates in large orders, give large bonus for returning them intact.
var printed_packages_amount = supply_shuttle.shoppinglist.len
if(prob(5))
printed_packages_amount += rand(1,2) // I considered rand(-2,2), but that could be zero. Heh.
slip.erroneous |= MANIFEST_ERROR_COUNT // They typoed the number of crates in this shipment. It won't match the other manifests.
slip.points = SP.cost
slip.ordernumber = SO.ordernum
slip.info = "<h3>[command_name()] Shipping Manifest</h3><hr><br>"
slip.info +="Order #[SO.ordernum]<br>"
slip.info +="Destination: [printed_station_name]<br>"
slip.info +="[printed_packages_amount] PACKAGES IN THIS SHIPMENT<br>"
slip.info +="CONTENTS:<br><ul>"
slip.points = SP.cost
slip.ordernumber = SO.ordernum
slip.info = "<h3>[command_name()] Shipping Manifest</h3><hr><br>"
slip.info +="Order #[SO.ordernum]<br>"
slip.info +="Destination: [printed_station_name]<br>"
slip.info +="[printed_packages_amount] PACKAGES IN THIS SHIPMENT<br>"
slip.info +="CONTENTS:<br><ul>"
//spawn the stuff, finish generating the manifest while you're at it
if(SP.access)
A:req_access = list()
A:req_access += text2num(SP.access)
//spawn the stuff, finish generating the manifest while you're at it
if(SP.access)
A:req_access = list()
A:req_access += text2num(SP.access)
var/list/contains
if(istype(SP,/datum/supply_packs/misc/randomised))
var/datum/supply_packs/misc/randomised/SPR = SP
contains = list()
if(SPR.contains.len)
for(var/j=1,j<=SPR.num_contained,j++)
contains += pick(SPR.contains)
else
contains = SP.contains
var/list/contains
if(istype(SP,/datum/supply_packs/misc/randomised))
var/datum/supply_packs/misc/randomised/SPR = SP
contains = list()
if(SPR.contains.len)
for(var/j=1,j<=SPR.num_contained,j++)
contains += pick(SPR.contains)
else
contains = SP.contains
for(var/typepath in contains)
if(!typepath) continue
var/atom/B2 = new typepath(A)
if(SP.amount && B2:amount) B2:amount = SP.amount
slip.info += "<li>[B2.name]</li>" //add the item to the manifest (even if it was misplaced)
// If it has multiple items, there's a 1% of each going missing... Not for secure crates or those large wooden ones, though.
if(contains.len > 1 && prob(1) && !findtext(SP.containertype,"/secure/") && !findtext(SP.containertype,"/largecrate/"))
slip.erroneous |= MANIFEST_ERROR_ITEM // This item was not included in the shipment!
qdel(B2) // Lost in space... or the loading dock.
for(var/typepath in contains)
if(!typepath) continue
var/atom/B2 = new typepath(A)
if(SP.amount && B2:amount) B2:amount = SP.amount
slip.info += "<li>[B2.name]</li>" //add the item to the manifest (even if it was misplaced)
// If it has multiple items, there's a 1% of each going missing... Not for secure crates or those large wooden ones, though.
if(contains.len > 1 && prob(1) && !findtext(SP.containertype,"/secure/") && !findtext(SP.containertype,"/largecrate/"))
slip.erroneous |= MANIFEST_ERROR_ITEM // This item was not included in the shipment!
qdel(B2) // Lost in space... or the loading dock.
//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.
//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.
supply_shuttle.shoppinglist.Cut()
return
supply_shuttle.shoppinglist.Cut()
return
/obj/item/weapon/paper/manifest
name = "supply manifest"
+239 -239
View File
@@ -1,6 +1,6 @@
var/datum/controller/vote/vote = new()
datum/controller/vote
/datum/controller/vote
var/initiator = null
var/started_timeofday = null
var/time_remaining = 0
@@ -10,253 +10,253 @@ datum/controller/vote
var/list/voted = list()
var/list/voting = list()
New()
if(vote != src)
if(istype(vote))
del(vote)
vote = src
/datum/controller/vote/New()
if(vote != src)
if(istype(vote))
del(vote)
vote = src
proc/process() //called by master_controller
if(mode)
time_remaining = started_timeofday + config.vote_period
if(world.timeofday < started_timeofday)
time_remaining -= 864000
time_remaining = round((time_remaining - world.timeofday)/10)
var/i=1
if(time_remaining < 0)
result()
while(i<=voting.len)
var/client/C = voting[i]
if(C)
C << browse(null,"window=vote;can_close=0")
i++
reset()
else
var/datum/browser/client_popup
while(i<=voting.len)
var/client/C = voting[i]
if(C)
//C << browse(vote.interface(C),"window=vote;can_close=0")
client_popup = new(C, "vote", "Voting Panel")
client_popup.set_window_options("can_close=0")
client_popup.set_content(vote.interface(C))
client_popup.open(0)
i++
else
voting.Cut(i,i+1)
proc/reset()
initiator = null
time_remaining = 0
mode = null
question = null
choices.Cut()
voted.Cut()
voting.Cut()
proc/get_result()
//get the highest number of votes
var/greatest_votes = 0
var/total_votes = 0
for(var/option in choices)
var/votes = choices[option]
total_votes += votes
if(votes > greatest_votes)
greatest_votes = votes
//default-vote for everyone who didn't vote
if(!config.vote_no_default && choices.len)
var/non_voters = (clients.len - total_votes)
if(non_voters > 0)
if(mode == "restart")
choices["Continue Playing"] += non_voters
if(choices["Continue Playing"] >= greatest_votes)
greatest_votes = choices["Continue Playing"]
else if(mode == "gamemode")
if(master_mode in choices)
choices[master_mode] += non_voters
if(choices[master_mode] >= greatest_votes)
greatest_votes = choices[master_mode]
//get all options with that many votes and return them in a list
. = list()
if(greatest_votes)
for(var/option in choices)
if(choices[option] == greatest_votes)
. += option
return .
proc/announce_result()
var/list/winners = get_result()
var/text
if(winners.len > 0)
if(question) text += "<b>[question]</b>"
else text += "<b>[capitalize(mode)] Vote</b>"
for(var/i=1,i<=choices.len,i++)
var/votes = choices[choices[i]]
if(!votes) votes = 0
text += "\n<b>[choices[i]]:</b> [votes]"
if(mode != "custom")
if(winners.len > 1)
text = "\n<b>Vote Tied Between:</b>"
for(var/option in winners)
text += "\n\t[option]"
. = pick(winners)
text += "\n<b>Vote Result: [.]</b>"
else
text += "\n<b>Did not vote:</b> [clients.len-voted.len]"
else
text += "<b>Vote Result: Inconclusive - No Votes!</b>"
log_vote(text)
world << "\n<font color='purple'>[text]</font>"
return .
proc/result()
. = announce_result()
var/restart = 0
if(.)
switch(mode)
if("restart")
if(. == "Restart Round")
restart = 1
if("gamemode")
if(master_mode != .)
world.save_mode(.)
if(ticker && ticker.mode)
restart = 1
else
master_mode = .
if(restart)
world << "World restarting due to vote..."
feedback_set_details("end_error","restart vote")
if(blackbox) blackbox.save_all_data_to_sql()
sleep(50)
log_game("Rebooting due to restart vote")
world.Reboot()
return .
proc/submit_vote(var/vote)
if(mode)
if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder)
return 0
if(!(usr.ckey in voted))
if(vote && 1<=vote && vote<=choices.len)
voted += usr.ckey
choices[choices[vote]]++ //check this
return vote
return 0
proc/initiate_vote(var/vote_type, var/initiator_key)
if(!mode)
if(started_timeofday != null)
var/next_allowed_timeofday = (started_timeofday + config.vote_delay)
if(world.timeofday < started_timeofday)
next_allowed_timeofday -= 864000
if(next_allowed_timeofday > world.timeofday)
return 0
/datum/controller/vote/proc/process() //called by master_controller
if(mode)
time_remaining = started_timeofday + config.vote_period
if(world.timeofday < started_timeofday)
time_remaining -= 864000
time_remaining = round((time_remaining - world.timeofday)/10)
var/i=1
if(time_remaining < 0)
result()
while(i<=voting.len)
var/client/C = voting[i]
if(C)
C << browse(null,"window=vote;can_close=0")
i++
reset()
switch(vote_type)
if("restart") choices.Add("Restart Round","Continue Playing")
if("gamemode") choices.Add(config.votable_modes)
if("custom")
question = html_encode(input(usr,"What is the vote for?") as text|null)
if(!question) return 0
for(var/i=1,i<=10,i++)
var/option = capitalize(html_encode(input(usr,"Please enter an option or hit cancel to finish") as text|null))
if(!option || mode || !usr.client) break
choices.Add(option)
else return 0
mode = vote_type
initiator = initiator_key
started_timeofday = world.timeofday
var/text = "[capitalize(mode)] vote started by [initiator]."
if(mode == "custom")
text += "\n[question]"
log_vote(text)
world << "\n<font color='purple'><b>[text]</b>\nType <b>vote</b> to place your votes.\nYou have [config.vote_period/10] seconds to vote.</font>"
time_remaining = round(config.vote_period/10)
return 1
return 0
proc/interface(var/client/C)
if(!C) return
var/admin = 0
var/trialmin = 0
if(C.holder)
admin = 1
if(check_rights_for(C, R_ADMIN))
trialmin = 1
voting |= C
if(mode)
if(question) . += "<h2>Vote: '[question]'</h2>"
else . += "<h2>Vote: [capitalize(mode)]</h2>"
. += "Time Left: [time_remaining] s<hr><ul>"
for(var/i=1,i<=choices.len,i++)
var/votes = choices[choices[i]]
if(!votes) votes = 0
. += "<li><a href='?src=\ref[src];vote=[i]'>[choices[i]]</a> ([votes] votes)</li>"
. += "</ul><hr>"
if(admin)
. += "(<a href='?src=\ref[src];vote=cancel'>Cancel Vote</a>) "
else
. += "<h2>Start a vote:</h2><hr><ul><li>"
//restart
if(trialmin || config.allow_vote_restart)
. += "<a href='?src=\ref[src];vote=restart'>Restart</a>"
else
. += "<font color='grey'>Restart (Disallowed)</font>"
if(trialmin)
. += "\t(<a href='?src=\ref[src];vote=toggle_restart'>[config.allow_vote_restart?"Allowed":"Disallowed"]</a>)"
. += "</li><li>"
//gamemode
if(trialmin || config.allow_vote_mode)
. += "<a href='?src=\ref[src];vote=gamemode'>GameMode</a>"
else
. += "<font color='grey'>GameMode (Disallowed)</font>"
if(trialmin)
. += "\t(<a href='?src=\ref[src];vote=toggle_gamemode'>[config.allow_vote_mode?"Allowed":"Disallowed"]</a>)"
var/datum/browser/client_popup
while(i<=voting.len)
var/client/C = voting[i]
if(C)
//C << browse(vote.interface(C),"window=vote;can_close=0")
client_popup = new(C, "vote", "Voting Panel")
client_popup.set_window_options("can_close=0")
client_popup.set_content(vote.interface(C))
client_popup.open(0)
. += "</li>"
//custom
if(trialmin)
. += "<li><a href='?src=\ref[src];vote=custom'>Custom</a></li>"
. += "</ul><hr>"
. += "<a href='?src=\ref[src];vote=close' style='position:absolute;right:50px'>Close</a>"
return .
i++
else
voting.Cut(i,i+1)
/datum/controller/vote/proc/reset()
initiator = null
time_remaining = 0
mode = null
question = null
choices.Cut()
voted.Cut()
voting.Cut()
Topic(href,href_list[],hsrc)
if(!usr || !usr.client) return //not necessary but meh...just in-case somebody does something stupid
switch(href_list["vote"])
if("close")
voting -= usr.client
usr << browse(null, "window=vote")
return
if("cancel")
if(usr.client.holder)
reset()
if("toggle_restart")
if(usr.client.holder)
config.allow_vote_restart = !config.allow_vote_restart
if("toggle_gamemode")
if(usr.client.holder)
config.allow_vote_mode = !config.allow_vote_mode
/datum/controller/vote/proc/get_result()
//get the highest number of votes
var/greatest_votes = 0
var/total_votes = 0
for(var/option in choices)
var/votes = choices[option]
total_votes += votes
if(votes > greatest_votes)
greatest_votes = votes
//default-vote for everyone who didn't vote
if(!config.vote_no_default && choices.len)
var/non_voters = (clients.len - total_votes)
if(non_voters > 0)
if(mode == "restart")
choices["Continue Playing"] += non_voters
if(choices["Continue Playing"] >= greatest_votes)
greatest_votes = choices["Continue Playing"]
else if(mode == "gamemode")
if(master_mode in choices)
choices[master_mode] += non_voters
if(choices[master_mode] >= greatest_votes)
greatest_votes = choices[master_mode]
//get all options with that many votes and return them in a list
. = list()
if(greatest_votes)
for(var/option in choices)
if(choices[option] == greatest_votes)
. += option
return .
/datum/controller/vote/proc/announce_result()
var/list/winners = get_result()
var/text
if(winners.len > 0)
if(question) text += "<b>[question]</b>"
else text += "<b>[capitalize(mode)] Vote</b>"
for(var/i=1,i<=choices.len,i++)
var/votes = choices[choices[i]]
if(!votes) votes = 0
text += "\n<b>[choices[i]]:</b> [votes]"
if(mode != "custom")
if(winners.len > 1)
text = "\n<b>Vote Tied Between:</b>"
for(var/option in winners)
text += "\n\t[option]"
. = pick(winners)
text += "\n<b>Vote Result: [.]</b>"
else
text += "\n<b>Did not vote:</b> [clients.len-voted.len]"
else
text += "<b>Vote Result: Inconclusive - No Votes!</b>"
log_vote(text)
world << "\n<font color='purple'>[text]</font>"
return .
/datum/controller/vote/proc/result()
. = announce_result()
var/restart = 0
if(.)
switch(mode)
if("restart")
if(config.allow_vote_restart || usr.client.holder)
initiate_vote("restart",usr.key)
if(. == "Restart Round")
restart = 1
if("gamemode")
if(config.allow_vote_mode || usr.client.holder)
initiate_vote("gamemode",usr.key)
if(master_mode != .)
world.save_mode(.)
if(ticker && ticker.mode)
restart = 1
else
master_mode = .
if(restart)
world << "World restarting due to vote..."
feedback_set_details("end_error","restart vote")
if(blackbox) blackbox.save_all_data_to_sql()
sleep(50)
log_game("Rebooting due to restart vote")
world.Reboot()
return .
/datum/controller/vote/proc/submit_vote(var/vote)
if(mode)
if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder)
return 0
if(!(usr.ckey in voted))
if(vote && 1<=vote && vote<=choices.len)
voted += usr.ckey
choices[choices[vote]]++ //check this
return vote
return 0
/datum/controller/vote/proc/initiate_vote(var/vote_type, var/initiator_key)
if(!mode)
if(started_timeofday != null)
var/next_allowed_timeofday = (started_timeofday + config.vote_delay)
if(world.timeofday < started_timeofday)
next_allowed_timeofday -= 864000
if(next_allowed_timeofday > world.timeofday)
return 0
reset()
switch(vote_type)
if("restart") choices.Add("Restart Round","Continue Playing")
if("gamemode") choices.Add(config.votable_modes)
if("custom")
if(usr.client.holder)
initiate_vote("custom",usr.key)
else
submit_vote(round(text2num(href_list["vote"])))
usr.vote()
question = html_encode(input(usr,"What is the vote for?") as text|null)
if(!question) return 0
for(var/i=1,i<=10,i++)
var/option = capitalize(html_encode(input(usr,"Please enter an option or hit cancel to finish") as text|null))
if(!option || mode || !usr.client) break
choices.Add(option)
else return 0
mode = vote_type
initiator = initiator_key
started_timeofday = world.timeofday
var/text = "[capitalize(mode)] vote started by [initiator]."
if(mode == "custom")
text += "\n[question]"
log_vote(text)
world << "\n<font color='purple'><b>[text]</b>\nType <b>vote</b> to place your votes.\nYou have [config.vote_period/10] seconds to vote.</font>"
time_remaining = round(config.vote_period/10)
return 1
return 0
/datum/controller/vote/proc/interface(var/client/C)
if(!C) return
var/admin = 0
var/trialmin = 0
if(C.holder)
admin = 1
if(check_rights_for(C, R_ADMIN))
trialmin = 1
voting |= C
if(mode)
if(question) . += "<h2>Vote: '[question]'</h2>"
else . += "<h2>Vote: [capitalize(mode)]</h2>"
. += "Time Left: [time_remaining] s<hr><ul>"
for(var/i=1,i<=choices.len,i++)
var/votes = choices[choices[i]]
if(!votes) votes = 0
. += "<li><a href='?src=\ref[src];vote=[i]'>[choices[i]]</a> ([votes] votes)</li>"
. += "</ul><hr>"
if(admin)
. += "(<a href='?src=\ref[src];vote=cancel'>Cancel Vote</a>) "
else
. += "<h2>Start a vote:</h2><hr><ul><li>"
//restart
if(trialmin || config.allow_vote_restart)
. += "<a href='?src=\ref[src];vote=restart'>Restart</a>"
else
. += "<font color='grey'>Restart (Disallowed)</font>"
if(trialmin)
. += "\t(<a href='?src=\ref[src];vote=toggle_restart'>[config.allow_vote_restart?"Allowed":"Disallowed"]</a>)"
. += "</li><li>"
//gamemode
if(trialmin || config.allow_vote_mode)
. += "<a href='?src=\ref[src];vote=gamemode'>GameMode</a>"
else
. += "<font color='grey'>GameMode (Disallowed)</font>"
if(trialmin)
. += "\t(<a href='?src=\ref[src];vote=toggle_gamemode'>[config.allow_vote_mode?"Allowed":"Disallowed"]</a>)"
. += "</li>"
//custom
if(trialmin)
. += "<li><a href='?src=\ref[src];vote=custom'>Custom</a></li>"
. += "</ul><hr>"
. += "<a href='?src=\ref[src];vote=close' style='position:absolute;right:50px'>Close</a>"
return .
/datum/controller/vote/Topic(href,href_list[],hsrc)
if(!usr || !usr.client) return //not necessary but meh...just in-case somebody does something stupid
switch(href_list["vote"])
if("close")
voting -= usr.client
usr << browse(null, "window=vote")
return
if("cancel")
if(usr.client.holder)
reset()
if("toggle_restart")
if(usr.client.holder)
config.allow_vote_restart = !config.allow_vote_restart
if("toggle_gamemode")
if(usr.client.holder)
config.allow_vote_mode = !config.allow_vote_mode
if("restart")
if(config.allow_vote_restart || usr.client.holder)
initiate_vote("restart",usr.key)
if("gamemode")
if(config.allow_vote_mode || usr.client.holder)
initiate_vote("gamemode",usr.key)
if("custom")
if(usr.client.holder)
initiate_vote("custom",usr.key)
else
submit_vote(round(text2num(href_list["vote"])))
usr.vote()
/mob/verb/vote()
@@ -268,4 +268,4 @@ datum/controller/vote
var/datum/browser/popup = new(src, "vote", "Voting Panel")
popup.set_window_options("can_close=0")
popup.set_content(vote.interface(client))
popup.open(0)
popup.open(0)