From b1feb2c215737d41ce2c559a2a40bb7340d95cf6 Mon Sep 17 00:00:00 2001 From: Firecage Date: Sat, 16 Aug 2014 12:57:18 +0200 Subject: [PATCH] Absolute paths for the files in the Controllers folder --- code/controllers/_DynamicAreaLighting_TG.dm | 216 ++++----- code/controllers/lighting_controller.dm | 10 +- code/controllers/master_controller.dm | 28 +- code/controllers/shuttle_controller.dm | 315 +++++++------ code/controllers/supply_shuttle.dm | 450 +++++++++--------- code/controllers/voting.dm | 478 ++++++++++---------- 6 files changed, 748 insertions(+), 749 deletions(-) diff --git a/code/controllers/_DynamicAreaLighting_TG.dm b/code/controllers/_DynamicAreaLighting_TG.dm index e7c71a59423..d40e9a10bf7 100644 --- a/code/controllers/_DynamicAreaLighting_TG.dm +++ b/code/controllers/_DynamicAreaLighting_TG.dm @@ -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 \ No newline at end of file +#undef LIGHTING_MAX_LUMINOSITY_TURF diff --git a/code/controllers/lighting_controller.dm b/code/controllers/lighting_controller.dm index 7814d21753d..d4f46b104fe 100644 --- a/code/controllers/lighting_controller.dm +++ b/code/controllers/lighting_controller.dm @@ -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)) diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index da3b635c434..564304b2dfd 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -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) diff --git a/code/controllers/shuttle_controller.dm b/code/controllers/shuttle_controller.dm index 6e1c9a0a078..83fbd2c883a 100644 --- a/code/controllers/shuttle_controller.dm +++ b/code/controllers/shuttle_controller.dm @@ -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) diff --git a/code/controllers/supply_shuttle.dm b/code/controllers/supply_shuttle.dm index 5bc835af74c..3f6af30ac58 100644 --- a/code/controllers/supply_shuttle.dm +++ b/code/controllers/supply_shuttle.dm @@ -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 += "+[slip.points-points_per_crate]: 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 += "+[slip.points-points_per_crate]: 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.
" + else if(!slip.erroneous && !denied) // Approving a proper order awards the relatively tiny points_per_slip + points += points_per_slip + centcom_message += "+1: Package [slip.ordernumber] accorded.
" + else // You done goofed. + if(slip.erroneous) + centcom_message += "+0: 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.
" - else if(!slip.erroneous && !denied) // Approving a proper order awards the relatively tiny points_per_slip - points += points_per_slip - centcom_message += "+1: Package [slip.ordernumber] accorded.
" - else // You done goofed. - if(slip.erroneous) - centcom_message += "+0: 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.
" - else - points -= slip.points-points_per_crate - centcom_message += "-[slip.points-points_per_crate]: Station denied package [slip.ordernumber]. Our records show no fault on our part.
" - find_slip = 0 - continue + centcom_message += "We found unshipped items on our dock." + centcom_message += " Be more vigilant.
" + else + points -= slip.points-points_per_crate + centcom_message += "-[slip.points-points_per_crate]: Station denied package [slip.ordernumber]. Our records show no fault on our part.
" + 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 += "+0: We don't need samples of mundane species \"[capitalize(S.species)]\".
" - 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 += "+[potDiff]: New sample of \"[capitalize(S.species)]\" is superior. Good work.
" - points += potDiff - else // This sample is worthless - centcom_message += "+0: New sample of \"[capitalize(S.species)]\" is not more potent than existing sample ([discoveredPlants[S.type]] potency).
" - 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 += "+0: We don't need samples of mundane species \"[capitalize(S.species)]\".
" + 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 += "+[S.rarity]: New species discovered: \"[capitalize(S.species)]\". Excellent work.
" - points += S.rarity // That's right, no bonus for potency. Send a crappy sample first to "show improvement" later - qdel(MA) + centcom_message += "+[potDiff]: New sample of \"[capitalize(S.species)]\" is superior. Good work.
" + points += potDiff + else // This sample is worthless + centcom_message += "+0: New sample of \"[capitalize(S.species)]\" is not more potent than existing sample ([discoveredPlants[S.type]] potency).
" + else // This is a new discovery! + discoveredPlants[S.type] = S.potency + centcom_message += "+[S.rarity]: New species discovered: \"[capitalize(S.species)]\". Excellent work.
" + 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 += "+[round(plasma_count/plasma_per_point)]: Received [plasma_count] unit(s) of exotic material.
" - points += round(plasma_count / plasma_per_point) + if(plasma_count) + centcom_message += "+[round(plasma_count/plasma_per_point)]: Received [plasma_count] unit(s) of exotic material.
" + points += round(plasma_count / plasma_per_point) - if(intel_count) - centcom_message += "+[round(intel_count*points_per_intel)]: Received [intel_count] article(s) of enemy intelligence.
" - points += round(intel_count*points_per_intel) + if(intel_count) + centcom_message += "+[round(intel_count*points_per_intel)]: Received [intel_count] article(s) of enemy intelligence.
" + points += round(intel_count*points_per_intel) - if(crate_count) - centcom_message += "+[round(crate_count*points_per_crate)]: Received [crate_count] crate(s).
" - points += crate_count * points_per_crate + if(crate_count) + centcom_message += "+[round(crate_count*points_per_crate)]: Received [crate_count] crate(s).
" + 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 = "

[command_name()] Shipping Manifest



" - slip.info +="Order #[SO.ordernum]
" - slip.info +="Destination: [printed_station_name]
" - slip.info +="[printed_packages_amount] PACKAGES IN THIS SHIPMENT
" - slip.info +="CONTENTS:

" + slip.info += "CHECK CONTENTS AND STAMP BELOW THE LINE TO CONFIRM RECEIPT OF GOODS
" // And now this is actually meaningful. - supply_shuttle.shoppinglist.Cut() - return + supply_shuttle.shoppinglist.Cut() + return /obj/item/weapon/paper/manifest name = "supply manifest" diff --git a/code/controllers/voting.dm b/code/controllers/voting.dm index 97bc448a4c2..1af635b5d18 100644 --- a/code/controllers/voting.dm +++ b/code/controllers/voting.dm @@ -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 += "[question]" - else text += "[capitalize(mode)] Vote" - for(var/i=1,i<=choices.len,i++) - var/votes = choices[choices[i]] - if(!votes) votes = 0 - text += "\n[choices[i]]: [votes]" - if(mode != "custom") - if(winners.len > 1) - text = "\nVote Tied Between:" - for(var/option in winners) - text += "\n\t[option]" - . = pick(winners) - text += "\nVote Result: [.]" - else - text += "\nDid not vote: [clients.len-voted.len]" - else - text += "Vote Result: Inconclusive - No Votes!" - log_vote(text) - world << "\n[text]" - 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[text]\nType vote to place your votes.\nYou have [config.vote_period/10] seconds to vote." - 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) . += "

Vote: '[question]'

" - else . += "

Vote: [capitalize(mode)]

" - . += "Time Left: [time_remaining] s

" - if(admin) - . += "(Cancel Vote) " else - . += "

Start a vote:



" - . += "Close" - 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 += "[question]" + else text += "[capitalize(mode)] Vote" + for(var/i=1,i<=choices.len,i++) + var/votes = choices[choices[i]] + if(!votes) votes = 0 + text += "\n[choices[i]]: [votes]" + if(mode != "custom") + if(winners.len > 1) + text = "\nVote Tied Between:" + for(var/option in winners) + text += "\n\t[option]" + . = pick(winners) + text += "\nVote Result: [.]" + else + text += "\nDid not vote: [clients.len-voted.len]" + else + text += "Vote Result: Inconclusive - No Votes!" + log_vote(text) + world << "\n[text]" + 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[text]\nType vote to place your votes.\nYou have [config.vote_period/10] seconds to vote." + 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) . += "

Vote: '[question]'

" + else . += "

Vote: [capitalize(mode)]

" + . += "Time Left: [time_remaining] s

" + if(admin) + . += "(Cancel Vote) " + else + . += "

Start a vote:



" + . += "Close" + 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) \ No newline at end of file + popup.open(0)