// Areas.dm // === /area var/global/global_uid = 0 var/uid /area/New() icon_state = "" layer = 10 master = src //moved outside the spawn(1) to avoid runtimes in lighting.dm when it references loc.loc.master ~Carn uid = ++global_uid related = list(src) all_areas += src if(requires_power) luminosity = 0 else power_light = 0 //rastaf0 power_equip = 0 //rastaf0 power_environ = 0 //rastaf0 luminosity = 1 lighting_use_dynamic = 0 ..() // spawn(15) power_change() // all machines set to current power level, also updates lighting icon InitializeLighting() /area/proc/poweralert(var/state, var/obj/source as obj) if (state != poweralm) poweralm = state if(istype(source)) //Only report power alarms on the z-level where the source is located. var/list/cameras = list() for (var/area/RA in related) for (var/obj/machinery/camera/C in RA) cameras += C if(state == 1) C.network.Remove("Power Alarms") else C.network.Add("Power Alarms") for (var/mob/living/silicon/aiPlayer in player_list) if(aiPlayer.z == source.z) if (state == 1) aiPlayer.cancelAlarm("Power", src, source) else aiPlayer.triggerAlarm("Power", src, cameras, source) for(var/obj/machinery/computer/station_alert/a in machines) if(a.z == source.z) if(state == 1) a.cancelAlarm("Power", src, source) else a.triggerAlarm("Power", src, cameras, source) return /area/proc/atmosalert(danger_level) // if(type==/area) //No atmos alarms in space // return 0 //redudant //Check all the alarms before lowering atmosalm. Raising is perfectly fine. for (var/area/RA in related) for (var/obj/machinery/alarm/AA in RA) if (!(AA.stat & (NOPOWER|BROKEN)) && !AA.shorted && AA.report_danger_level) danger_level = max(danger_level, AA.danger_level) if(danger_level != atmosalm) if (danger_level < 1 && atmosalm >= 1) //closing the doors on red and opening on green provides a bit of hysteresis that will hopefully prevent fire doors from opening and closing repeatedly due to noise air_doors_open() if (danger_level < 2 && atmosalm >= 2) for(var/area/RA in related) for(var/obj/machinery/camera/C in RA) C.network.Remove("Atmosphere Alarms") for(var/mob/living/silicon/aiPlayer in player_list) aiPlayer.cancelAlarm("Atmosphere", src, src) for(var/obj/machinery/computer/station_alert/a in machines) a.cancelAlarm("Atmosphere", src, src) if (danger_level >= 2 && atmosalm < 2) var/list/cameras = list() for(var/area/RA in related) //updateicon() for(var/obj/machinery/camera/C in RA) cameras += C C.network.Add("Atmosphere Alarms") for(var/mob/living/silicon/aiPlayer in player_list) aiPlayer.triggerAlarm("Atmosphere", src, cameras, src) for(var/obj/machinery/computer/station_alert/a in machines) a.triggerAlarm("Atmosphere", src, cameras, src) air_doors_close() atmosalm = danger_level for(var/area/RA in related) for (var/obj/machinery/alarm/AA in RA) AA.update_icon() return 1 return 0 /area/proc/air_doors_close() if(!src.master.air_doors_activated) src.master.air_doors_activated = 1 for(var/obj/machinery/door/firedoor/E in src.master.all_doors) if(!E:blocked) if(E.operating) E:nextstate = CLOSED else if(!E.density) spawn(0) E.close() /area/proc/air_doors_open() if(src.master.air_doors_activated) src.master.air_doors_activated = 0 for(var/obj/machinery/door/firedoor/E in src.master.all_doors) if(!E:blocked) if(E.operating) E:nextstate = OPEN else if(E.density) spawn(0) E.open() /area/proc/firealert() if(name == "Space") //no fire alarms in space return if( !fire ) fire = 1 master.fire = 1 //used for firedoor checks updateicon() mouse_opacity = 0 for(var/obj/machinery/door/firedoor/D in all_doors) if(!D.blocked) if(D.operating) D.nextstate = CLOSED else if(!D.density) spawn() D.close() var/list/cameras = list() for(var/area/RA in related) for (var/obj/machinery/camera/C in RA) cameras.Add(C) C.network.Add("Fire Alarms") for (var/mob/living/silicon/ai/aiPlayer in player_list) aiPlayer.triggerAlarm("Fire", src, cameras, src) for (var/obj/machinery/computer/station_alert/a in machines) a.triggerAlarm("Fire", src, cameras, src) /area/proc/firereset() if (fire) fire = 0 master.fire = 0 //used for firedoor checks mouse_opacity = 0 updateicon() for(var/obj/machinery/door/firedoor/D in all_doors) if(!D.blocked) if(D.operating) D.nextstate = OPEN else if(D.density) spawn(0) D.open() for(var/area/RA in related) for (var/obj/machinery/camera/C in RA) C.network.Remove("Fire Alarms") for (var/mob/living/silicon/ai/aiPlayer in player_list) aiPlayer.cancelAlarm("Fire", src, src) for (var/obj/machinery/computer/station_alert/a in machines) a.cancelAlarm("Fire", src, src) /area/proc/readyalert() if(!eject) eject = 1 updateicon() return /area/proc/readyreset() if(eject) eject = 0 updateicon() return /area/proc/partyalert() if (!( party )) party = 1 updateicon() mouse_opacity = 0 return /area/proc/partyreset() if (party) party = 0 mouse_opacity = 0 updateicon() for(var/obj/machinery/door/firedoor/D in src) if(!D.blocked) if(D.operating) D.nextstate = OPEN else if(D.density) spawn(0) D.open() return /area/proc/updateicon() if ((fire || eject || party) && (!requires_power||power_environ) && !lighting_space)//If it doesn't require power, can still activate this proc. if(fire && !eject && !party) icon_state = "blue" /*else if(atmosalm && !fire && !eject && !party) icon_state = "bluenew"*/ else if(!fire && eject && !party) icon_state = "red" else if(party && !fire && !eject) icon_state = "party" else icon_state = "blue-red" else // new lighting behaviour with obj lights icon_state = null /* #define EQUIP 1 #define LIGHT 2 #define ENVIRON 3 */ /area/proc/powered(var/chan) // return true if the area has power to given channel if(!master.requires_power) return 1 if(master.always_unpowered) return 0 if(src.lighting_space) return 0 // Nope sorry switch(chan) if(EQUIP) return master.power_equip if(LIGHT) return master.power_light if(ENVIRON) return master.power_environ return 0 // called when power status changes /area/proc/power_change() for(var/area/RA in related) for(var/obj/machinery/M in RA) // for each machine in the area M.power_change() // reverify power status (to update icons etc.) if (fire || eject || party) RA.updateicon() /area/proc/usage(var/chan) var/used = 0 switch(chan) if(LIGHT) used += master.used_light if(EQUIP) used += master.used_equip if(ENVIRON) used += master.used_environ if(TOTAL) used += master.used_light + master.used_equip + master.used_environ return used /area/proc/clear_usage() master.used_equip = 0 master.used_light = 0 master.used_environ = 0 /area/proc/use_power(var/amount, var/chan) switch(chan) if(EQUIP) master.used_equip += amount if(LIGHT) master.used_light += amount if(ENVIRON) master.used_environ += amount var/list/mob/living/forced_ambiance_list = new /area/Entered(A) if(!istype(A,/mob/living)) return var/mob/living/L = A if(!L.ckey) return if(!L.lastarea) L.lastarea = get_area(L.loc) var/area/newarea = get_area(L.loc) var/area/oldarea = L.lastarea if((oldarea.has_gravity == 0) && (newarea.has_gravity == 1) && (L.m_intent == "run")) // Being ready when you change areas gives you a chance to avoid falling all together. thunk(L) L.make_floating(0) L.lastarea = newarea play_ambience(L) /area/proc/play_ambience(var/mob/living/L) // Ambience goes down here -- make sure to list each area seperately for ease of adding things in later, thanks! Note: areas adjacent to each other should have the same sounds to prevent cutoff when possible.- LastyScratch if(!(L && L.client && (L.client.prefs.toggles & SOUND_AMBIENCE))) return // If we previously were in an area with force-played ambiance, stop it. if(L in forced_ambiance_list) L << sound(null, channel = 1) forced_ambiance_list -= L if(!L.client.ambience_playing) L.client.ambience_playing = 1 L << sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = 2) if(forced_ambience) forced_ambiance_list += L L << forced_ambience else if(src.ambience.len && prob(35)) if((world.time >= L.client.played + 600)) var/musVolume = 25 var/sound = pick(ambience) L << sound(sound, repeat = 0, wait = 0, volume = musVolume, channel = 1) L.client.played = world.time /area/proc/gravitychange(var/gravitystate = 0, var/area/A) A.has_gravity = gravitystate for(var/area/SubA in A.related) SubA.has_gravity = gravitystate if(gravitystate) for(var/mob/living/carbon/human/M in SubA) thunk(M) for(var/mob/M1 in SubA) M1.make_floating(0) else for(var/mob/M in SubA) if(M.Check_Dense_Object() && istype(src,/mob/living/carbon/human/)) var/mob/living/carbon/human/H = src if(istype(H.shoes, /obj/item/clothing/shoes/magboots) && (H.shoes.flags & NOSLIP)) //magboots + dense_object = no floaty effect H.make_floating(0) else H.make_floating(1) else M.make_floating(1) /area/proc/thunk(mob) if(istype(mob,/mob/living/carbon/human/)) // Only humans can wear magboots, so we give them a chance to. if((istype(mob:shoes, /obj/item/clothing/shoes/magboots) && (mob:shoes.flags & NOSLIP))) return if(istype(get_turf(mob), /turf/space)) // Can't fall onto nothing. return if((istype(mob,/mob/living/carbon/human/)) && (mob:m_intent == "run")) // Only clumbsy humans can fall on their asses. mob:AdjustStunned(5) mob:AdjustWeakened(5) else if (istype(mob,/mob/living/carbon/human/)) mob:AdjustStunned(2) mob:AdjustWeakened(2) mob << "Gravity!"