From 440f784c703558779619e922bb23f0ffa36c7818 Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Fri, 21 Feb 2014 02:11:11 -0600 Subject: [PATCH 01/65] Bugfix: People unable to hear while in certain locations. (And some debug verbs) ...hopefully --- code/__HELPERS/game.dm | 36 ++++++++++------ code/modules/admin/verbs/mapping.dm | 67 +++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 13 deletions(-) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 577c8093390..911b5c6f1eb 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -35,12 +35,17 @@ // Like view but bypasses luminosity check -/proc/hear(var/range, var/atom/source) +/proc/hear(var/range, var/turf/source) + var/Alum = source.loc.luminosity var/lum = source.luminosity + source.loc.luminosity = 6 source.luminosity = 6 - var/list/heard = view(range, source) + var/list/heard = viewers(range, source) //Only lists mobs, but does a better job then view of getting the mobs. + heard |= view(range, source) + + source.loc.luminosity = Alum source.luminosity = lum return heard @@ -174,33 +179,38 @@ var/list/range = hear(R, T) - for(var/mob/M in range) + var/list/clients_minus_checked = clients + + for(var/mob/M in range) //Only looking for living mobs because ghosts are automatically added. hear += M + if(M.client) + clients_minus_checked -= M.client var/list/objects = list() - for(var/obj/O in range) //Get a list of objects in hearing range. We'll check to see if any clients have their "eye" set to the object + for(var/obj/O in range) //Get a list of objects in hearing range. We'll check to see if any clients have their "eye" set to the object objects += O - for(var/client/C in clients) - if(!istype(C) || !C.eye) - continue //I have no idea when this client check would be needed, but if this runtimes people won't hear anything - //So kinda paranoid about runtime avoidance. - if(istype(C.eye, /obj/machinery/camera)) - continue //No microphones in cameras. + var/list/hear_and_objects = (hear|objects) - if(C.mob in hear) + for(var/client/C in clients_minus_checked) + if(!istype(C) || !C.eye || istype(C.mob, /mob/dead)) continue - var/list/hear_and_objects = (hear|objects) //Combined these lists here instead of doing the combine 3 more times. + if(istype(C.eye, /obj/machinery/camera)) + continue //No microphones in cameras. if(C.eye in hear_and_objects) hear += C.mob - + hear_and_objects += C.mob else if(C.mob.loc in hear_and_objects) hear += C.mob + hear_and_objects += C.mob + else if(C.mob.loc.loc in hear_and_objects) hear += C.mob + hear_and_objects += C.mob + return hear diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index 00b9f15ca53..6108ebd7749 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -161,6 +161,9 @@ var/list/debug_verbs = list ( ,/client/proc/hide_debug_verbs ,/client/proc/testZAScolors ,/client/proc/testZAScolors_remove + ,/client/proc/test_viewers + ,/client/proc/test_view + ,/client/proc/test_hear ) @@ -185,6 +188,70 @@ var/list/debug_verbs = list ( feedback_add_details("admin_verb","hDV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/test_viewers() + set category = "Debug" + set name = "Test Viewers" + + var/turf/T = get_turf(usr) + var/lum = T.loc.luminosity + T.loc.luminosity = 1 + + + var/list/inviewers = viewers(7, usr) + T.loc.luminosity = lum + var/list/M = list() + var/list/O = list() + + for(var/obj/OBJ in inviewers) + O += OBJ + for(var/mob/MOB in inviewers) + M += MOB + + usr << "VIEWERS MOB: [list2text(M,", ")]" + usr << "VIEWERS OBJ: [list2text(O,", ")]" + + + +/client/proc/test_view() + set category = "Debug" + set name = "Test View" + + var/list/inview = view(7, usr) + var/list/M = list() + var/list/O = list() + + for(var/obj/OBJ in inview) + O += OBJ + for(var/mob/MOB in inview) + M += MOB + + usr << "VIEW MOB: [list2text(M,", ")]" + usr << "VIEW OBJ: [list2text(O,", ")]" + +/client/proc/test_hear() + set category = "Debug" + set name = "Test Hear" + + var/turf/T = get_turf(usr) + var/list/hearers = hear(7, T) + var/list/M = list() + var/list/O = list() + + for(var/obj/OBJ in hearers) + O += OBJ + for(var/mob/MOB in hearers) + M += MOB + + + usr << "HEAR MOB: [list2text(M,", ")]" + usr << "HEAR OBJ: [list2text(O,", ")]" + + + + + + /client/var/list/testZAScolors_turfs = list() /client/var/list/testZAScolors_zones = list() /client/var/usedZAScolors = 0 From 864e097e917672538c05b2ffc85088fd7223d578 Mon Sep 17 00:00:00 2001 From: Loganbacca Date: Sat, 22 Feb 2014 00:47:08 +1300 Subject: [PATCH 02/65] Chemsmoke rewrite - Complete rewrite of the chemsmoke spawning code (everything that happens after the reaction to create the smoke). - Moved it into it's own file since it's a little longer than the old one code-wise. - Tweaked the smoke sprites; gave chemsmoke directions for more randomization, and tweaked the timing of their animations so they are smooth now. Most of the code is documented, so you should be able to follow what's going on just reading through it. In short though: - Chemsmoke now affects a circular area with a variable range depending on the total amount of chemsmoke created (no more 1-of-each-ingredient smoke grenades - sorry). - The carried reagent volume in the cloud balances itself according to how big the affected area is (larger area, less carried reagent per turf). - The carried reagent has more volume the closer you are to the centre of the cloud. - The visual smoke effect scales with how big the affected area is. --- baystation12.dme | 1 + code/game/objects/effects/chemsmoke.dm | 246 +++++++++++++++++++++ code/game/objects/effects/effect_system.dm | 115 ---------- code/modules/reagents/Chemistry-Recipes.dm | 2 - icons/effects/96x96.dmi | Bin 333307 -> 333302 bytes icons/effects/chemsmoke.dmi | Bin 29342 -> 111533 bytes 6 files changed, 247 insertions(+), 117 deletions(-) create mode 100644 code/game/objects/effects/chemsmoke.dm diff --git a/baystation12.dme b/baystation12.dme index 430d3b1377e..9b952db4565 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -421,6 +421,7 @@ #include "code\game\objects\closets\walllocker.dm" #include "code\game\objects\effects\aliens.dm" #include "code\game\objects\effects\bump_teleporter.dm" +#include "code\game\objects\effects\chemsmoke.dm" #include "code\game\objects\effects\effect_system.dm" #include "code\game\objects\effects\gibs.dm" #include "code\game\objects\effects\glowshroom.dm" diff --git a/code/game/objects/effects/chemsmoke.dm b/code/game/objects/effects/chemsmoke.dm new file mode 100644 index 00000000000..ee78cb5d5bc --- /dev/null +++ b/code/game/objects/effects/chemsmoke.dm @@ -0,0 +1,246 @@ +///////////////////////////////////////////// +// Chem smoke +///////////////////////////////////////////// +/obj/effect/effect/smoke/chem + icon = 'icons/effects/chemsmoke.dmi' + opacity = 0 + time_to_live = 300 + pass_flags = PASSTABLE | PASSGRILLE | PASSGLASS //PASSGLASS is fine here, it's just so the visual effect can "flow" around glass + +/obj/effect/effect/smoke/chem/New() + ..() + var/datum/reagents/R = new/datum/reagents(500) + reagents = R + R.my_atom = src + return + +/datum/effect/effect/system/smoke_spread/chem + smoke_type = /obj/effect/effect/smoke/chem + var/obj/chemholder + var/range + var/list/targetTurfs + var/list/wallList + var/floorArea + + +/datum/effect/effect/system/smoke_spread/chem/New() + ..() + chemholder = new/obj() + var/datum/reagents/R = new/datum/reagents(500) + chemholder.reagents = R + R.my_atom = chemholder + +//------------------------------------------ +//Sets up the chem smoke effect +// +// Calculates the max range smoke can travel, then gets all turfs in that view range. +// Culls the selected turfs to a (roughly) circle shape, then calls smokeFlow() to make +// sure the smoke can actually path to the turfs. This culls any turfs it can't reach. +//------------------------------------------ +/datum/effect/effect/system/smoke_spread/chem/set_up(var/datum/reagents/carry = null, n = 10, c = 0, loca, direct) + range = n * 0.3 + cardinals = c + carry.copy_to(chemholder, carry.total_volume) + + if(istype(loca, /turf/)) + location = loca + else + location = get_turf(loca) + + targetTurfs = new() + + //build affected area list + for(var/turf/T in view(range, location)) + //cull turfs to circle + if(cheap_pythag(T.x - location.x, T.y - location.y) <= range) + targetTurfs += T + + //make secondary list for reagents that affect walls + if(chemholder.reagents.has_reagent("thermite") || chemholder.reagents.has_reagent("plantbgone")) + wallList = new() + + //pathing check + smokeFlow(location, targetTurfs, wallList) + + floorArea = targetTurfs.len + + //Admin messaging + var/contained = "" + for(var/reagent in carry.reagent_list) + contained += " [reagent] " + if(contained) + contained = "\[[contained]\]" + var/area/A = get_area(location) + + var/where = "[A.name] | [location.x], [location.y]" + var/whereLink = "[where]" + + if(carry.my_atom.fingerprintslast) + var/mob/M = get_mob_by_key(carry.my_atom.fingerprintslast) + var/more = "" + if(M) + more = "(?)" + message_admins("A chemical smoke reaction has taken place in ([whereLink])[contained]. Last associated key is [carry.my_atom.fingerprintslast][more].", 0, 1) + log_game("A chemical smoke reaction has taken place in ([where])[contained]. Last associated key is [carry.my_atom.fingerprintslast].") + else + message_admins("A chemical smoke reaction has taken place in ([whereLink]). No associated key.", 0, 1) + log_game("A chemical smoke reaction has taken place in ([where])[contained]. No associated key.") + + +//------------------------------------------ +//Runs the chem smoke effect +// +// Spawns damage over time loop for each reagent held in the cloud. +// Applies reagents to walls that affect walls (only thermite and plant-b-gone at the moment). +// Also calculates target locations to spawn the visual smoke effect on, so the whole area +// is covered fairly evenly. +//------------------------------------------ +/datum/effect/effect/system/smoke_spread/chem/start() + + //reagent application + if(chemholder.reagents.reagent_list.len) + for(var/datum/reagent/R in chemholder.reagents.reagent_list) + var/proba = 100 + var/runs = 5 + + //dilute the reagents according to affected area + R.volume /= floorArea / 4 + chemholder.reagents.update_total() + + //apply wall affecting reagents to walls + if(R.id in list("thermite", "plantbgone")) + for(var/turf/T in wallList) + R.reaction_turf(T, R.volume) + + //reagents that should be applied to turfs in a random pattern + if(R.id == "carbon") + proba = 75 + else if(R.id in list("blood", "radium", "uranium")) + proba = 25 + + spawn(0) + for(var/i = 0, i < runs, i++) + for(var/turf/T in targetTurfs) + if(prob(proba)) + R.reaction_turf(T, R.volume) + for(var/atom/A in T.contents) + if(istype(A, /obj/effect/effect/smoke/chem)) //skip the item if it is chem smoke + continue + else if(istype(A, /mob)) + var/dist = cheap_pythag(T.x - location.x, T.y - location.y) + if(!dist) + dist = 1 + R.reaction_mob(A, volume = R.volume / dist) + else if(istype(A, /obj)) + R.reaction_obj(A, R.volume) + sleep(30) + + + //build smoke icon + var/color = mix_color_from_reagents(chemholder.reagents.reagent_list) + var/icon/I + if(color) + I = icon('icons/effects/chemsmoke.dmi') + I += color + else + I = icon('icons/effects/96x96.dmi', "smoke") + + + //distance between each smoke cloud + var/const/arcLength = 2.3559 + + + //calculate positions for smoke coverage - then spawn smoke + for(var/i = 0, i < range, i++) + var/radius = i * 1.5 + if(!radius) + spawn(0) + spawnSmoke(location, I, 1) + continue + + var/offset = 0 + var/points = round((radius * 2 * PI) / arcLength) + var/angle = round(ToDegrees(arcLength / radius), 1) + + if(!IsInteger(radius)) + offset = 45 //degrees + + for(var/j = 0, j < points, j++) + var/a = (angle * j) + offset + var/x = round(radius * cos(a) + location.x, 1) + var/y = round(radius * sin(a) + location.y, 1) + var/turf/T = locate(x,y,location.z) + if(T in targetTurfs) + var/dist = cheap_pythag(T.x - location.x, T.y - location.y) + if(!dist) + dist = 1 + spawn(0) + spawnSmoke(T, I, dist) + +//------------------------------------------ +// Randomizes and spawns the smoke effect. +// Also handles deleting the smoke once the effect is finished. +//------------------------------------------ +/datum/effect/effect/system/smoke_spread/chem/proc/spawnSmoke(var/turf/T, var/icon/I, var/dist = 1) + var/obj/effect/effect/smoke/chem/smoke = new(location) + chemholder.reagents.copy_to(smoke, chemholder.reagents.total_volume / dist, safety = 1) //copy reagents to the smoke so mob/breathe() can handle inhaling the reagents + smoke.icon = I + smoke.layer = 6 + smoke.dir = pick(cardinal) + smoke.pixel_x = -32 + rand(-8,8) + smoke.pixel_y = -32 + rand(-8,8) + walk_to(smoke, T) + smoke.opacity = 1 //switching opacity on after the smoke has spawned, and then + sleep(150+rand(0,20)) // turning it off before it is deleted results in cleaner + smoke.opacity = 0 // lighting and view range updates + fadeOut(smoke) + smoke.delete() + +//------------------------------------------ +// Fades out the smoke smoothly using it's alpha variable. +//------------------------------------------ +/datum/effect/effect/system/smoke_spread/chem/proc/fadeOut(var/atom/A, var/frames = 16) + var/step = A.alpha / frames + for(var/i = 0, i < frames, i++) + A.alpha -= step + sleep(world.tick_lag) + return + +//------------------------------------------ +// Smoke pathfinder. Uses a flood fill method based on zones to +// quickly check what turfs the smoke (airflow) can actually reach. +//------------------------------------------ +/datum/effect/effect/system/smoke_spread/chem/proc/smokeFlow() + + var/list/pending = new() + var/list/complete = new() + + pending += location + + while(pending.len) + for(var/turf/simulated/current in pending) + for(var/D in cardinal) + var/turf/simulated/target = get_step(current, D) + + if(wallList) + if(istype(target, /turf/simulated/wall)) + if(!(target in wallList)) + wallList += target + continue + if(!target.zone) + continue + if(target in pending) + continue + if(target in complete) + continue + if(!(target in targetTurfs)) + continue + + pending += target + + pending -= current + complete += current + + targetTurfs = complete + + return \ No newline at end of file diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index 159a4266dd2..b2f22ce9089 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -379,121 +379,6 @@ steam.start() -- spawns the effect /datum/effect/effect/system/smoke_spread/mustard smoke_type = /obj/effect/effect/smoke/mustard -///////////////////////////////////////////// -// Chem smoke -///////////////////////////////////////////// -/obj/effect/effect/smoke/chem - icon = 'icons/effects/chemsmoke.dmi' - -/obj/effect/effect/smoke/chem/New() - ..() - var/datum/reagents/R = new/datum/reagents(500) - reagents = R - R.my_atom = src - return - -/obj/effect/effect/smoke/chem/proc/applyReagents() - if(reagents.reagent_list.len) - for(var/atom/A in view(1, src)) - if(!istype(A, src.type)) - if(reagents.has_reagent("radium")||reagents.has_reagent("uranium")||reagents.has_reagent("carbon")||reagents.has_reagent("thermite"))//Prevents unholy radium spam by reducing the number of 'greenglows' down to something reasonable -Sieve - if(prob(5)) - reagents.reaction(A) - else - reagents.reaction(A) - -/obj/effect/effect/smoke/chem/affect(mob/living/carbon/M as mob ) - reagents.reaction(M) - -/datum/effect/effect/system/smoke_spread/chem - smoke_type = /obj/effect/effect/smoke/chem - var/obj/chemholder - - New() - ..() - chemholder = new/obj() - var/datum/reagents/R = new/datum/reagents(500) - chemholder.reagents = R - R.my_atom = chemholder - - set_up(var/datum/reagents/carry = null, n = 5, c = 0, loca, direct) - if(n > 20) - n = 20 - number = n - cardinals = c - carry.copy_to(chemholder, carry.total_volume) - - - if(istype(loca, /turf/)) - location = loca - else - location = get_turf(loca) - if(direct) - direction = direct - - var/contained = "" - for(var/reagent in carry.reagent_list) - contained += " [reagent] " - if(contained) - contained = "\[[contained]\]" - var/area/A = get_area(location) - - var/where = "[A.name] | [location.x], [location.y]" - var/whereLink = "[where]" - - if(carry.my_atom.fingerprintslast) - var/mob/M = get_mob_by_key(carry.my_atom.fingerprintslast) - var/more = "" - if(M) - more = "(?)" - message_admins("A chemical smoke reaction has taken place in ([whereLink])[contained]. Last associated key is [carry.my_atom.fingerprintslast][more].", 0, 1) - log_game("A chemical smoke reaction has taken place in ([where])[contained]. Last associated key is [carry.my_atom.fingerprintslast].") - else - message_admins("A chemical smoke reaction has taken place in ([whereLink]). No associated key.", 0, 1) - log_game("A chemical smoke reaction has taken place in ([where])[contained]. No associated key.") - - start() - var/i = 0 - - var/color = mix_color_from_reagents(chemholder.reagents.reagent_list) - - for(i=0, i 20) - return - spawn(0) - if(holder) - src.location = get_turf(holder) - var/obj/effect/effect/smoke/chem/smoke = new /obj/effect/effect/smoke/chem(src.location) - src.total_smoke++ - var/direction = src.direction - if(!direction) - if(src.cardinals) - direction = pick(cardinal) - else - direction = pick(alldirs) - - if(chemholder.reagents.total_volume != 1) // can't split 1 very well - chemholder.reagents.copy_to(smoke, chemholder.reagents.total_volume / number, safety = 1) // copy reagents to each smoke, divide evenly - - if(color) - smoke.icon += color // give the smoke color, if it has any to begin with - else - // if no color, just use the old smoke icon - smoke.icon = 'icons/effects/96x96.dmi' - smoke.icon_state = "smoke" - - for(i=0, i}>!6YL zRA}6lvvFt9J6Vz?87a>XY0Zex1Nr}ew3nN$yu{ZjEXGe+|9B}GIOCgx0dCI1*8B{~ ozd~q=-LXJ%DCrFYQgfk|A?;~_`-S@fh5G`9`vZmh1f}~06{6mFY5)KL delta 243 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 z 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 Bwod>6 literal 29342 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 From f593232aa5e6107225735b7a0c9a0da56bbc5d02 Mon Sep 17 00:00:00 2001 From: Loganbacca Date: Sat, 22 Feb 2014 00:56:12 +1300 Subject: [PATCH 03/65] Reagent reaction_mob/turf tweaks - Adds an if() check to reaction_mob for catching a very rare runtime related to mobs inhaling smoke reagents from just deleted smoke. - Carbons reaction_turf proc now modifies a single dirt overlay layer, instead of just adding more decal objects to the turf. - Added some checks to the radium and uranium reaction_turf proc so it doesn't stack multiple greenglow decals. - Performed colon removal surgery on thermites reaction_turf proc, also tweaked it's overlay operation to correctly overlay a chemical puddle effect, instead of a melted wall effect. - Removed space_cleaners overlays.Cut() code, since it was removing decals from turfs. --- code/modules/reagents/Chemistry-Reagents.dm | 62 ++++++++++++--------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 72a92061105..85ffdf0d79e 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -35,31 +35,32 @@ datum var/datum/reagent/self = src src = null //of the reagent to the mob on TOUCHING it. - if(!istype(self.holder.my_atom, /obj/effect/effect/smoke/chem)) - // If the chemicals are in a smoke cloud, do not try to let the chemicals "penetrate" into the mob's system (balance station 13) -- Doohl + if(self.holder) //for catching rare runtimes + if(!istype(self.holder.my_atom, /obj/effect/effect/smoke/chem)) + // If the chemicals are in a smoke cloud, do not try to let the chemicals "penetrate" into the mob's system (balance station 13) -- Doohl - if(method == TOUCH) + if(method == TOUCH) - var/chance = 1 - var/block = 0 + var/chance = 1 + var/block = 0 - for(var/obj/item/clothing/C in M.get_equipped_items()) - if(C.permeability_coefficient < chance) chance = C.permeability_coefficient - if(istype(C, /obj/item/clothing/suit/bio_suit)) - // bio suits are just about completely fool-proof - Doohl - // kind of a hacky way of making bio suits more resistant to chemicals but w/e - if(prob(75)) - block = 1 + for(var/obj/item/clothing/C in M.get_equipped_items()) + if(C.permeability_coefficient < chance) chance = C.permeability_coefficient + if(istype(C, /obj/item/clothing/suit/bio_suit)) + // bio suits are just about completely fool-proof - Doohl + // kind of a hacky way of making bio suits more resistant to chemicals but w/e + if(prob(75)) + block = 1 - if(istype(C, /obj/item/clothing/head/bio_hood)) - if(prob(75)) - block = 1 + if(istype(C, /obj/item/clothing/head/bio_hood)) + if(prob(75)) + block = 1 - chance = chance * 100 + chance = chance * 100 - if(prob(chance) && !block) - if(M.reagents) - M.reagents.add_reagent(self.id,self.volume/2) + if(prob(chance) && !block) + if(M.reagents) + M.reagents.add_reagent(self.id,self.volume/2) return 1 reaction_obj(var/obj/O, var/volume) //By default we transfer a small part of the reagent to the object @@ -582,7 +583,12 @@ datum reaction_turf(var/turf/T, var/volume) src = null if(!istype(T, /turf/space)) - new /obj/effect/decal/cleanable/dirt(T) + var/obj/effect/decal/cleanable/dirt/dirtoverlay = locate(/obj/effect/decal/cleanable/dirt, T) + if (!dirtoverlay) + dirtoverlay = new/obj/effect/decal/cleanable/dirt(T) + dirtoverlay.alpha = volume*30 + else + dirtoverlay.alpha = min(dirtoverlay.alpha+volume*30, 255) chlorine name = "Chlorine" @@ -708,7 +714,9 @@ datum src = null if(volume >= 3) if(!istype(T, /turf/space)) - new /obj/effect/decal/cleanable/greenglow(T) + var/obj/effect/decal/cleanable/greenglow/glow = locate(/obj/effect/decal/cleanable/greenglow, T) + if(!glow) + new /obj/effect/decal/cleanable/greenglow(T) return @@ -748,9 +756,9 @@ datum src = null if(volume >= 5) if(istype(T, /turf/simulated/wall)) - T:thermite = 1 - T.overlays.Cut() - T.overlays = image('icons/effects/effects.dmi',icon_state = "thermite") + var/turf/simulated/wall/W = T + W.thermite = 1 + W.overlays += image('icons/effects/effects.dmi',icon_state = "#673910") return on_mob_life(var/mob/living/M as mob) @@ -872,7 +880,10 @@ datum src = null if(volume >= 3) if(!istype(T, /turf/space)) - new /obj/effect/decal/cleanable/greenglow(T) + var/obj/effect/decal/cleanable/greenglow/glow = locate(/obj/effect/decal/cleanable/greenglow, T) + if(!glow) + new /obj/effect/decal/cleanable/greenglow(T) + return aluminum name = "Aluminum" @@ -931,7 +942,6 @@ datum if(istype(T, /turf/simulated)) var/turf/simulated/S = T S.dirt = 0 - T.overlays.Cut() T.clean_blood() for(var/obj/effect/decal/cleanable/C in T.contents) src.reaction_obj(C, volume) From a204a46f4bfdc60e9cdbc791a93c9f4b7dab87e9 Mon Sep 17 00:00:00 2001 From: Loganbacca Date: Sat, 22 Feb 2014 01:07:45 +1300 Subject: [PATCH 04/65] Runtime fix - Fixed a runtime caused by effects bumping disposal chutes. --- code/modules/recycling/sortingmachinery.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index 02289aacf8f..28dad70da25 100755 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -218,7 +218,7 @@ return Bumped(var/atom/movable/AM) //Go straight into the chute - if(istype(AM, /obj/item/projectile)) return + if(istype(AM, /obj/item/projectile) || istype(AM, /obj/effect)) return switch(dir) if(NORTH) if(AM.loc.y != src.loc.y+1) return From 4c27af0bb9cfc2727d4c6c261600ae9d094ab114 Mon Sep 17 00:00:00 2001 From: Aryn Date: Thu, 20 Feb 2014 17:08:13 -0700 Subject: [PATCH 05/65] Added Z-level support. --- code/ZAS/Atom.dm | 21 +++++++++++++++------ code/ZAS/Connection.dm | 23 +++++++++++++++++++++++ code/ZAS/Turf.dm | 8 ++++++++ code/ZAS/_docs.dm | 1 + 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/code/ZAS/Atom.dm b/code/ZAS/Atom.dm index 38e57d6165b..b4d1de20af4 100644 --- a/code/ZAS/Atom.dm +++ b/code/ZAS/Atom.dm @@ -49,9 +49,18 @@ turf/c_airblock(turf/other) #endif if(blocks_air) return BLOCKED - else - var/result = 0 - for(var/atom/movable/M in contents) - result |= M.c_airblock(other) - if(result == BLOCKED) return BLOCKED - return result \ No newline at end of file + + //Z-level handling code. Always block if there isn't an open space. + #ifdef ZLEVELS + if(other.z != src.z) + if(other.z < src.z) + if(!istype(src, /turf/simulated/floor/open)) return BLOCKED + else + if(!istype(other, /turf/simulated/floor/open)) return BLOCKED + #endif + + var/result = 0 + for(var/atom/movable/M in contents) + result |= M.c_airblock(other) + if(result == BLOCKED) return BLOCKED + return result \ No newline at end of file diff --git a/code/ZAS/Connection.dm b/code/ZAS/Connection.dm index e3ce7373a61..a6d62ec2e98 100644 --- a/code/ZAS/Connection.dm +++ b/code/ZAS/Connection.dm @@ -10,6 +10,11 @@ /connection_manager/var/connection/E /connection_manager/var/connection/W +#ifdef ZLEVELS +/connection_manager/var/connection/U +/connection_manager/var/connection/D +#endif + /connection_manager/proc/get(d) switch(d) if(NORTH) @@ -25,6 +30,15 @@ if(check(W)) return W else return null + #ifdef ZLEVELS + if(UP) + if(check(U)) return U + else return null + if(DOWN) + if(check(D)) return D + else return null + #endif + /connection_manager/proc/place(connection/c, d) switch(d) if(NORTH) N = c @@ -32,11 +46,20 @@ if(EAST) E = c if(WEST) W = c + #ifdef ZLEVELS + if(UP) U = c + if(DOWN) D = c + #endif + /connection_manager/proc/update_all() if(check(N)) N.update() if(check(S)) S.update() if(check(E)) E.update() if(check(W)) W.update() + #ifdef ZLEVELS + if(check(U)) U.update() + if(check(D)) D.update() + #endif /connection_manager/proc/check(connection/c) return c && c.valid() diff --git a/code/ZAS/Turf.dm b/code/ZAS/Turf.dm index cb4b9c20f5e..976379c06d2 100644 --- a/code/ZAS/Turf.dm +++ b/code/ZAS/Turf.dm @@ -19,7 +19,11 @@ //dbg(blocked) return 1 + #ifdef ZLEVELS + for(var/d = 1, d < 64, d *= 2) + #else for(var/d = 1, d < 16, d *= 2) + #endif var/turf/unsim = get_step(src, d) block = unsim.c_airblock(src) @@ -59,7 +63,11 @@ open_directions = 0 var/list/postponed + #ifdef ZLEVELS + for(var/d = 1, d < 64, d *= 2) + #else for(var/d = 1, d < 16, d *= 2) + #endif var/turf/unsim = get_step(src, d) var/block = unsim.c_airblock(src) diff --git a/code/ZAS/_docs.dm b/code/ZAS/_docs.dm index 706b6a40d79..b57f751bc54 100644 --- a/code/ZAS/_docs.dm +++ b/code/ZAS/_docs.dm @@ -22,6 +22,7 @@ air_master.mark_for_update(turf) */ //#define ZASDBG +#define ZLEVELS #define AIR_BLOCKED 1 #define ZONE_BLOCKED 2 From bae9fad90b403ec78c23db876ba4747b6beee686 Mon Sep 17 00:00:00 2001 From: Aryn Date: Thu, 20 Feb 2014 17:14:01 -0700 Subject: [PATCH 06/65] Added Z-level support for ZAS, disabled by default to save CPU. - Use #define ZLEVELS or uncomment it in _docs.dm to turn it on. --- code/ZAS/_docs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ZAS/_docs.dm b/code/ZAS/_docs.dm index b57f751bc54..62837615505 100644 --- a/code/ZAS/_docs.dm +++ b/code/ZAS/_docs.dm @@ -22,7 +22,7 @@ air_master.mark_for_update(turf) */ //#define ZASDBG -#define ZLEVELS +//#define ZLEVELS #define AIR_BLOCKED 1 #define ZONE_BLOCKED 2 From f0e4e2782175c132f8190a05b4550f8167b87e05 Mon Sep 17 00:00:00 2001 From: Aryn Date: Fri, 21 Feb 2014 03:46:30 -0700 Subject: [PATCH 07/65] Fixed a special case with simulated turfs being replaced by space. Actually any unsimulated turf, but mostly space. --- baystation12.int | 3 +++ code/game/turfs/turf.dm | 3 +++ 2 files changed, 6 insertions(+) diff --git a/baystation12.int b/baystation12.int index b82874fded5..b9efdebddff 100644 --- a/baystation12.int +++ b/baystation12.int @@ -1,6 +1,9 @@ // BEGIN_INTERNALS /* MAP_ICON_TYPE: 0 +WINDOW: code\ZAS\Turf.dm;code\game\turfs\turf.dm;code\ZAS\Zone.dm +DIR: code code\game code\game\turfs code\ZAS +FILE: code\game\turfs\turf.dm AUTO_FILE_DIR: OFF */ // END_INTERNALS diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index ff47a1fa72a..65231916c8f 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -216,6 +216,9 @@ var/old_lumcount = lighting_lumcount - initial(lighting_lumcount) + if(!ispath(N,/turf/simulated) && istype(src,/turf/simulated)) + src:zone:remove(src) + if(ispath(N, /turf/simulated/floor)) //if the old turf had a zone, connect the new turf to it as well - Cael //Adjusted by SkyMarshal 5/10/13 - The air master will handle the addition of the new turf. From f95d0f9a989863ca53d90686f80753f4c144ee8f Mon Sep 17 00:00:00 2001 From: Aryn Date: Fri, 21 Feb 2014 03:54:45 -0700 Subject: [PATCH 08/65] Fixed some zone.remove() bugs: Turf should be set back to no gas overlays. Debug mode checks if zone actually contains turf (might be useful in turf replacement.) --- code/ZAS/Zone.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/ZAS/Zone.dm b/code/ZAS/Zone.dm index d1cf8ec0af7..cfaba5d082c 100644 --- a/code/ZAS/Zone.dm +++ b/code/ZAS/Zone.dm @@ -33,9 +33,11 @@ ASSERT(!invalid) ASSERT(istype(T)) ASSERT(T.zone == src) + ASSERT(T in contents) #endif contents.Remove(T) T.zone = null + T.set_graphic(0) if(contents.len) air.group_multiplier = contents.len else From 0089ae6282ee932ec66669a03253d1a62e0d25ff Mon Sep 17 00:00:00 2001 From: Aryn Date: Fri, 21 Feb 2014 07:05:11 -0700 Subject: [PATCH 09/65] Fixed some weird bugs concerning space and the creation thereof. --- code/ZAS/Connection.dm | 19 ++++++++++++++----- code/ZAS/ConnectionGroup.dm | 12 +++++++++--- code/ZAS/Controller.dm | 8 ++++++-- code/ZAS/Debug.dm | 3 +++ code/ZAS/Turf.dm | 9 ++++++--- code/ZAS/Zone.dm | 2 +- code/ZAS/_docs.dm | 2 +- code/game/turfs/turf.dm | 10 ++++++++-- 8 files changed, 48 insertions(+), 17 deletions(-) diff --git a/code/ZAS/Connection.dm b/code/ZAS/Connection.dm index a6d62ec2e98..00a676664cd 100644 --- a/code/ZAS/Connection.dm +++ b/code/ZAS/Connection.dm @@ -2,7 +2,7 @@ #define CONNECTION_SPACE 4 #define CONNECTION_INVALID 8 -/turf/simulated/var/tmp/connection_manager/connections = new +/turf/var/tmp/connection_manager/connections /connection_manager/var/connection/N @@ -61,6 +61,16 @@ if(check(D)) D.update() #endif +/connection_manager/proc/erase_all() + if(check(N)) N.erase() + if(check(S)) S.erase() + if(check(E)) E.erase() + if(check(W)) W.erase() + #ifdef ZLEVELS + if(check(U)) U.erase() + if(check(D)) D.erase() + #endif + /connection_manager/proc/check(connection/c) return c && c.valid() @@ -92,14 +102,12 @@ edge.add_connection(src) /connection/proc/mark_direct() - edge.remove_connection(src) state |= CONNECTION_DIRECT - edge.add_connection(src) + //world << "Marked direct." /connection/proc/mark_indirect() - edge.remove_connection(src) state &= ~CONNECTION_DIRECT - edge.add_connection(src) + //world << "Marked indirect." /connection/proc/mark_space() state |= CONNECTION_SPACE @@ -113,6 +121,7 @@ /connection/proc/erase() edge.remove_connection(src) state |= CONNECTION_INVALID + //world << "Connection Erased: [state]" /connection/proc/update() //world << "Updated, \..." diff --git a/code/ZAS/ConnectionGroup.dm b/code/ZAS/ConnectionGroup.dm index 2a4c374f78b..bd100b8fdc0 100644 --- a/code/ZAS/ConnectionGroup.dm +++ b/code/ZAS/ConnectionGroup.dm @@ -11,10 +11,10 @@ /connection_edge/proc/add_connection(connection/c) coefficient++ - //world << "Connection added. Coefficient: [coefficient]" + //world << "Connection added: [type] Coefficient: [coefficient]" /connection_edge/proc/remove_connection(connection/c) - //world << "Connection removed. Coefficient: [coefficient-1]" + //world << "Connection removed: [type] Coefficient: [coefficient-1]" coefficient-- if(coefficient <= 0) erase() @@ -23,7 +23,7 @@ /connection_edge/proc/erase() air_master.remove_edge(src) - //world << "Erased." + //world << "[type] Erased." /connection_edge/proc/tick() @@ -130,9 +130,15 @@ /connection_edge/unsimulated/add_connection(connection/c) . = ..() connecting_turfs.Add(c.B) + air.group_multiplier = coefficient /connection_edge/unsimulated/remove_connection(connection/c) connecting_turfs.Remove(c.B) + air.group_multiplier = coefficient + . = ..() + +/connection_edge/unsimulated/erase() + A.edges.Remove(src) . = ..() /connection_edge/unsimulated/contains_zone(zone/Z) diff --git a/code/ZAS/Controller.dm b/code/ZAS/Controller.dm index 32899b15561..b074358193a 100644 --- a/code/ZAS/Controller.dm +++ b/code/ZAS/Controller.dm @@ -190,15 +190,19 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun a_to_b = get_dir(A,B) b_to_a = get_dir(B,A) + if(!A.connections) A.connections = new + if(!B.connections) B.connections = new + if(A.connections.get(a_to_b)) return + if(B.connections.get(b_to_a)) return if(!space) if(A.zone == B.zone) return - if(B.connections.get(b_to_a)) return + var/connection/c = new /connection(A,B) A.connections.place(c, a_to_b) - if(!space) B.connections.place(c, b_to_a) + B.connections.place(c, b_to_a) if(direct) c.mark_direct() diff --git a/code/ZAS/Debug.dm b/code/ZAS/Debug.dm index e9ac325d53b..62db9d0eb88 100644 --- a/code/ZAS/Debug.dm +++ b/code/ZAS/Debug.dm @@ -14,6 +14,9 @@ var/image/mark = image('icons/Testing/Zone.dmi', icon_state = "mark") overlays += img dbg_img = img +proc/soft_assert(thing,fail) + if(!thing) message_admins(fail) + /turf/simulated/var/verbose = 0 /turf/simulated/verb/Verbose() set src in world diff --git a/code/ZAS/Turf.dm b/code/ZAS/Turf.dm index 976379c06d2..d3d98d720f2 100644 --- a/code/ZAS/Turf.dm +++ b/code/ZAS/Turf.dm @@ -32,6 +32,11 @@ //unsim.dbg(air_blocked, turn(180,d)) continue + var/r_block = c_airblock(unsim) + + if(r_block & AIR_BLOCKED) + continue + if(istype(unsim, /turf/simulated)) var/turf/simulated/sim = unsim @@ -165,9 +170,7 @@ air_master.connect(src, T) /turf/proc/post_update_air_properties() - -/turf/simulated/post_update_air_properties() - connections.update_all() + if(connections) connections.update_all() /turf/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air del(giver) diff --git a/code/ZAS/Zone.dm b/code/ZAS/Zone.dm index cfaba5d082c..4edfb2ecfba 100644 --- a/code/ZAS/Zone.dm +++ b/code/ZAS/Zone.dm @@ -33,7 +33,7 @@ ASSERT(!invalid) ASSERT(istype(T)) ASSERT(T.zone == src) - ASSERT(T in contents) + soft_assert(T in contents, "Lists are weird broseph") #endif contents.Remove(T) T.zone = null diff --git a/code/ZAS/_docs.dm b/code/ZAS/_docs.dm index 62837615505..2f763f2b1ab 100644 --- a/code/ZAS/_docs.dm +++ b/code/ZAS/_docs.dm @@ -21,7 +21,7 @@ air_master.mark_for_update(turf) */ -//#define ZASDBG +#define ZASDBG //#define ZLEVELS #define AIR_BLOCKED 1 diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 65231916c8f..b172024579e 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -216,8 +216,14 @@ var/old_lumcount = lighting_lumcount - initial(lighting_lumcount) - if(!ispath(N,/turf/simulated) && istype(src,/turf/simulated)) - src:zone:remove(src) + //world << "Replacing [src.type] with [N]" + + if(connections) connections.erase_all() + + if(istype(src,/turf/simulated)) + //world << "Removed from zone." + var/turf/simulated/S = src + if(S.zone) S.zone.remove(S) if(ispath(N, /turf/simulated/floor)) //if the old turf had a zone, connect the new turf to it as well - Cael From d0c0315d53d9dca24534491f99ad74b4797a2995 Mon Sep 17 00:00:00 2001 From: Aryn Date: Fri, 21 Feb 2014 08:19:12 -0700 Subject: [PATCH 10/65] Added documentation, split ConnectionManager.dm, removed some unused procs. Added a proc to find the other zone in an edge for future procs. Fixed the stupid .int again. --- baystation12.dme | 1 + baystation12.int | 3 - code/ZAS/Connection.dm | 96 ++++++++++++-------------------- code/ZAS/ConnectionGroup.dm | 64 ++++++++++++++++++++- code/ZAS/ConnectionManager.dm | 102 ++++++++++++++++++++++++++++++++++ code/ZAS/Controller.dm | 66 +++++++++++++++++++++- code/ZAS/Zone.dm | 47 ++++++++++++++-- code/ZAS/_docs.dm | 6 ++ 8 files changed, 311 insertions(+), 74 deletions(-) create mode 100644 code/ZAS/ConnectionManager.dm diff --git a/baystation12.dme b/baystation12.dme index 430d3b1377e..3e1ea6b03f5 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1331,6 +1331,7 @@ #include "code\ZAS\Atom.dm" #include "code\ZAS\Connection.dm" #include "code\ZAS\ConnectionGroup.dm" +#include "code\ZAS\ConnectionManager.dm" #include "code\ZAS\Controller.dm" #include "code\ZAS\Debug.dm" #include "code\ZAS\Diagnostic.dm" diff --git a/baystation12.int b/baystation12.int index b9efdebddff..b82874fded5 100644 --- a/baystation12.int +++ b/baystation12.int @@ -1,9 +1,6 @@ // BEGIN_INTERNALS /* MAP_ICON_TYPE: 0 -WINDOW: code\ZAS\Turf.dm;code\game\turfs\turf.dm;code\ZAS\Zone.dm -DIR: code code\game code\game\turfs code\ZAS -FILE: code\game\turfs\turf.dm AUTO_FILE_DIR: OFF */ // END_INTERNALS diff --git a/code/ZAS/Connection.dm b/code/ZAS/Connection.dm index 00a676664cd..b9cf2278a18 100644 --- a/code/ZAS/Connection.dm +++ b/code/ZAS/Connection.dm @@ -2,78 +2,52 @@ #define CONNECTION_SPACE 4 #define CONNECTION_INVALID 8 -/turf/var/tmp/connection_manager/connections +/* +Overview: + Connections are made between turfs by air_master.connect(). They represent a single point where two zones converge. -/connection_manager/var/connection/N -/connection_manager/var/connection/S -/connection_manager/var/connection/E -/connection_manager/var/connection/W +Class Vars: + A - Always a simulated turf. + B - A simulated or unsimulated turf. -#ifdef ZLEVELS -/connection_manager/var/connection/U -/connection_manager/var/connection/D -#endif + zoneA - The archived zone of A. Used to check that the zone hasn't changed. + zoneB - The archived zone of B. May be null in case of unsimulated connections. -/connection_manager/proc/get(d) - switch(d) - if(NORTH) - if(check(N)) return N - else return null - if(SOUTH) - if(check(S)) return S - else return null - if(EAST) - if(check(E)) return E - else return null - if(WEST) - if(check(W)) return W - else return null + edge - Stores the edge this connection is in. Can reference an edge that is no longer processed + after this connection is removed, so make sure to check edge.coefficient > 0 before re-adding it. - #ifdef ZLEVELS - if(UP) - if(check(U)) return U - else return null - if(DOWN) - if(check(D)) return D - else return null - #endif +Class Procs: -/connection_manager/proc/place(connection/c, d) - switch(d) - if(NORTH) N = c - if(SOUTH) S = c - if(EAST) E = c - if(WEST) W = c + mark_direct() + Marks this connection as direct. Does not update the edge. + Called when the connection is made and there are no doors between A and B. + Also called by update() as a correction. - #ifdef ZLEVELS - if(UP) U = c - if(DOWN) D = c - #endif + mark_indirect() + Unmarks this connection as direct. Does not update the edge. + Called by update() as a correction. -/connection_manager/proc/update_all() - if(check(N)) N.update() - if(check(S)) S.update() - if(check(E)) E.update() - if(check(W)) W.update() - #ifdef ZLEVELS - if(check(U)) U.update() - if(check(D)) D.update() - #endif + mark_space() + Marks this connection as unsimulated. Updating the connection will check the validity of this. + Called when the connection is made. + This will not be called as a correction, any connections failing a check against this mark are erased and rebuilt. -/connection_manager/proc/erase_all() - if(check(N)) N.erase() - if(check(S)) S.erase() - if(check(E)) E.erase() - if(check(W)) W.erase() - #ifdef ZLEVELS - if(check(U)) U.erase() - if(check(D)) D.erase() - #endif + direct() + Returns 1 if no doors are in between A and B. -/connection_manager/proc/check(connection/c) - return c && c.valid() + valid() + Returns 1 if the connection has not been erased. + erase() + Called by update() and connection_manager/erase_all(). + Marks the connection as erased and removes it from its edge. + + update() + Called by connection_manager/update_all(). + Makes numerous checks to decide whether the connection is still valid. Erases it automatically if not. + +*/ /connection/var/turf/simulated/A /connection/var/turf/simulated/B diff --git a/code/ZAS/ConnectionGroup.dm b/code/ZAS/ConnectionGroup.dm index bd100b8fdc0..2c7e4373c03 100644 --- a/code/ZAS/ConnectionGroup.dm +++ b/code/ZAS/ConnectionGroup.dm @@ -1,10 +1,68 @@ +/* + +Overview: + These are what handle gas transfers between zones and into space. + They are found in a zone's edges list and in air_master.edges. + Each edge updates every air tick due to their role in gas transfer. + They come in two flavors, /connection_edge/zone and /connection_edge/unsimulated. + As the type names might suggest, they handle inter-zone and spacelike connections respectively. + +Class Vars: + + A - This always holds a zone. In unsimulated edges, it holds the only zone. + + connecting_turfs - This holds a list of connected turfs, mainly for the sake of airflow. + + coefficent - This is a marker for how many connections are on this edge. Used to determine the ratio of flow. + + connection_edge/zone + + B - This holds the second zone with which the first zone equalizes. + + direct - This counts the number of direct (i.e. with no doors) connections on this edge. + Any value of this is sufficient to make the zones mergeable. + + connection_edge/unsimulated + + B - This holds an unsimulated turf which has the gas values this edge is mimicing. + + air - Retrieved from B on creation and used as an argument for the legacy ShareSpace() proc. + +Class Procs: + + add_connection(connection/c) + Adds a connection to this edge. Usually increments the coefficient and adds a turf to connecting_turfs. + + remove_connection(connection/c) + Removes a connection from this edge. This works even if c is not in the edge, so be careful. + If the coefficient reaches zero as a result, the edge is erased. + + contains_zone(zone/Z) + Returns true if either A or B is equal to Z. Unsimulated connections return true only on A. + + erase() + Removes this connection from processing and zone edge lists. + + tick() + Called every air tick on edges in the processing list. Equalizes gas. + + flow(list/movable, differential, repelled) + Airflow proc causing all objects in movable to be checked against a pressure differential. + If repelled is true, the objects move away from any turf in connecting_turfs, otherwise they approach. + A check against vsc.lightest_airflow_pressure should generally be performed before calling this. + + get_connected_zone(zone/from) + Helper proc that allows getting the other zone of an edge given one of them. + Only on /connection_edge/zone, otherwise use A. + +*/ + /connection_edge/var/zone/A /connection_edge/var/list/connecting_turfs = list() /connection_edge/var/coefficient = 0 -/connection_edge/var/id /connection_edge/New() CRASH("Cannot make connection edge without specifications.") @@ -115,6 +173,10 @@ flow(attracted, abs(differential), 0) flow(repelled, abs(differential), 1) +//Helper proc to get connections for a zone. +/connection_edge/zone/proc/get_connected_zone(zone/from) + if(A == from) return B + else return A /connection_edge/unsimulated/var/turf/B /connection_edge/unsimulated/var/datum/gas_mixture/air diff --git a/code/ZAS/ConnectionManager.dm b/code/ZAS/ConnectionManager.dm new file mode 100644 index 00000000000..1c101f4b45a --- /dev/null +++ b/code/ZAS/ConnectionManager.dm @@ -0,0 +1,102 @@ +/* + +Overview: + The connection_manager class stores connections in each cardinal direction on a turf. + It isn't always present if a turf has no connections, check if(connections) before using. + Contains procs for mass manipulation of connection data. + +Class Vars: + + NSEWUD - Connections to this turf in each cardinal direction. + +Class Procs: + + get(d) + Returns the connection (if any) in this direction. + Preferable to accessing the connection directly because it checks validity. + + place(connection/c, d) + Called by air_master.connect(). Sets the connection in the specified direction to c. + + update_all() + Called after turf/update_air_properties(). Updates the validity of all connections on this turf. + + erase_all() + Called when the turf is changed with ChangeTurf(). Erases all existing connections. + + check(connection/c) + Checks for connection validity. It's possible to have a reference to a connection that has been erased. + + +*/ + +/turf/var/tmp/connection_manager/connections + +/connection_manager/var/connection/N +/connection_manager/var/connection/S +/connection_manager/var/connection/E +/connection_manager/var/connection/W + +#ifdef ZLEVELS +/connection_manager/var/connection/U +/connection_manager/var/connection/D +#endif + +/connection_manager/proc/get(d) + switch(d) + if(NORTH) + if(check(N)) return N + else return null + if(SOUTH) + if(check(S)) return S + else return null + if(EAST) + if(check(E)) return E + else return null + if(WEST) + if(check(W)) return W + else return null + + #ifdef ZLEVELS + if(UP) + if(check(U)) return U + else return null + if(DOWN) + if(check(D)) return D + else return null + #endif + +/connection_manager/proc/place(connection/c, d) + switch(d) + if(NORTH) N = c + if(SOUTH) S = c + if(EAST) E = c + if(WEST) W = c + + #ifdef ZLEVELS + if(UP) U = c + if(DOWN) D = c + #endif + +/connection_manager/proc/update_all() + if(check(N)) N.update() + if(check(S)) S.update() + if(check(E)) E.update() + if(check(W)) W.update() + #ifdef ZLEVELS + if(check(U)) U.update() + if(check(D)) D.update() + #endif + +/connection_manager/proc/erase_all() + if(check(N)) N.erase() + if(check(S)) S.erase() + if(check(E)) E.erase() + if(check(W)) W.erase() + #ifdef ZLEVELS + if(check(U)) U.erase() + if(check(D)) D.erase() + #endif + +/connection_manager/proc/check(connection/c) + return c && c.valid() \ No newline at end of file diff --git a/code/ZAS/Controller.dm b/code/ZAS/Controller.dm index b074358193a..429906a6495 100644 --- a/code/ZAS/Controller.dm +++ b/code/ZAS/Controller.dm @@ -2,6 +2,69 @@ var/datum/controller/air_system/air_master var/tick_multiplier = 2 +/* + +Overview: + The air controller does everything. There are tons of procs in here. + +Class Vars: + zones - All zones currently holding one or more turfs. + edges - All processing edges. + + tiles_to_update - Tiles scheduled to update next tick. + zones_to_update - Zones which have had their air changed and need air archival. + active_hotspots - All processing fire objects. + + active_zones - The number of zones which were archived last tick. Used in debug verbs. + next_id - The next UID to be applied to a zone. Mostly useful for debugging purposes as zones do not need UIDs to function. + +Class Procs: + + mark_for_update(turf/T) + Adds the turf to the update list. When updated, update_air_properties() will be called. + When stuff changes that might affect airflow, call this. It's basically the only thing you need. + + add_zone(zone/Z) and remove_zone(zone/Z) + Adds zones to the zones list. Does not mark them for update. + + air_blocked(turf/A, turf/B) + Returns a bitflag consisting of: + AIR_BLOCKED - The connection between turfs is physically blocked. No air can pass. + ZONE_BLOCKED - There is a door between the turfs, so zones cannot cross. Air may or may not be permeable. + + has_valid_zone(turf/T) + Checks the presence and validity of T's zone. + May be called on unsimulated turfs, returning 0. + + merge(zone/A, zone/B) + Called when zones have a direct connection and equivalent pressure and temperature. + Merges the zones to create a single zone. + + connect(turf/simulated/A, turf/B) + Called by turf/update_air_properties(). The first argument must be simulated. + Creates a connection between A and B. + + mark_zone_update(zone/Z) + Adds zone to the update list. Unlike mark_for_update(), this one is called automatically whenever + air is returned from a simulated turf. + + equivalent_pressure(zone/A, zone/B) + Currently identical to A.air.compare(B.air). Returns 1 when directly connected zones are ready to be merged. + + get_edge(zone/A, zone/B) + get_edge(zone/A, turf/B) + Gets a valid connection_edge between A and B, creating a new one if necessary. + + has_same_air(turf/A, turf/B) + Used to determine if an unsimulated edge represents a specific turf. + Simulated edges use connection_edge/contains_zone() for the same purpose. + Returns 1 if A has identical gases and temperature to B. + + remove_edge(connection_edge/edge) + Called when an edge is erased. Removes it from processing. + +*/ + //Geometry lists /datum/controller/air_system/var/list/zones = list() @@ -228,9 +291,6 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun /datum/controller/air_system/proc/equivalent_pressure(zone/A, zone/B) return A.air.compare(B.air) -/datum/controller/air_system/proc/active_zones() - return active_zones - /datum/controller/air_system/proc/get_edge(zone/A, zone/B) if(istype(B)) diff --git a/code/ZAS/Zone.dm b/code/ZAS/Zone.dm index 4edfb2ecfba..8373771ae26 100644 --- a/code/ZAS/Zone.dm +++ b/code/ZAS/Zone.dm @@ -1,3 +1,44 @@ +/* + +Overview: + Each zone is a self-contained area where gas values would be the same if tile-based equalization were run indefinitely. + If you're unfamiliar with ZAS, FEA's air groups would have similar functionality if they didn't break in a stiff breeze. + +Class Vars: + name - A name of the format "Zone [#]", used for debugging. + invalid - True if the zone has been erased and is no longer eligible for processing. + needs_update - True if the zone has been added to the update list. + edges - A list of edges that connect to this zone. + air - The gas mixture that any turfs in this zone will return. Values are per-tile with a group multiplier. + +Class Procs: + add(turf/simulated/T) + Adds a turf to the contents, sets its zone and merges its air. + + remove(turf/simulated/T) + Removes a turf, sets its zone to null and erases any gas graphics. + Invalidates the zone if it has no more tiles. + + c_merge(zone/into) + Invalidates this zone and adds all its former contents to into. + + c_invalidate() + Marks this zone as invalid and removes it from processing. + + rebuild() + Invalidates the zone and marks all its former tiles for updates. + + add_tile_air(turf/simulated/T) + Adds the air contained in T.air to the zone's air supply. Called when adding a turf. + + tick() + Called only when the gas content is changed. Archives values and changes gas graphics. + + dbg_data(mob/M) + Sends M a printout of important figures for the zone. + +*/ + /zone/var/name /zone/var/invalid = 0 @@ -86,12 +127,6 @@ for(var/turf/simulated/T in contents) T.set_graphic(air.graphic) -/zone/proc/remove_connection(connection/c) - return - -/zone/proc/add_connection(connection/c) - return - /zone/proc/dbg_data(mob/M) M << name M << "O2: [air.oxygen] N2: [air.nitrogen] CO2: [air.carbon_dioxide] P: [air.toxins]" diff --git a/code/ZAS/_docs.dm b/code/ZAS/_docs.dm index 2f763f2b1ab..26bb4d3b215 100644 --- a/code/ZAS/_docs.dm +++ b/code/ZAS/_docs.dm @@ -19,6 +19,12 @@ air_master.mark_for_update(turf) When stuff happens, call this. It works on everything. You basically don't need to worry about any other functions besides CanPass(). +Notes for people who used ZAS before: + There is no connected_zones anymore. + To get the zones that are connected to a zone, use this loop: + for(var/connection_edge/zone/edge in zone.edges) + var/zone/connected_zone = edge.get_connected_zone(zone) + */ #define ZASDBG From f511ac20c20c822ef41b78cf77edd457170a066f Mon Sep 17 00:00:00 2001 From: Aryn Date: Fri, 21 Feb 2014 08:46:56 -0700 Subject: [PATCH 11/65] Fixed some debug verbs, removed ZASDBG define. --- baystation12.int | 5 +++ code/ZAS/_docs.dm | 2 +- code/modules/admin/verbs/mapping.dm | 51 +++++++++++++++-------------- 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/baystation12.int b/baystation12.int index b82874fded5..fd01a6c5944 100644 --- a/baystation12.int +++ b/baystation12.int @@ -1,6 +1,11 @@ // BEGIN_INTERNALS /* MAP_ICON_TYPE: 0 +LAST_COMPILE_VERSION: 503.1224 +WINDOW: code\modules\admin\verbs\mapping.dm;code\ZAS\ConnectionGroup.dm;code\ZAS\Debug.dm;code\ZAS\_docs.dm +DIR: code code\modules code\modules\admin code\modules\admin\verbs code\ZAS +FILE: code\ZAS\_docs.dm +LAST_COMPILE_TIME: 1392997541 AUTO_FILE_DIR: OFF */ // END_INTERNALS diff --git a/code/ZAS/_docs.dm b/code/ZAS/_docs.dm index 26bb4d3b215..8d084dc4c95 100644 --- a/code/ZAS/_docs.dm +++ b/code/ZAS/_docs.dm @@ -27,7 +27,7 @@ Notes for people who used ZAS before: */ -#define ZASDBG +//#define ZASDBG //#define ZLEVELS #define AIR_BLOCKED 1 diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index f984e174475..ab7ef30e915 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -125,20 +125,20 @@ var/intercom_range_display_status = 0 feedback_add_details("admin_verb","mIRD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! var/list/debug_verbs = list ( - /client/proc/do_not_use_these - ,/client/proc/camera_view + /client/proc/do_not_use_these + ,/client/proc/camera_view ,/client/proc/sec_camera_report - ,/client/proc/intercom_view - ,/client/proc/air_status - ,/client/proc/Cell - ,/client/proc/atmosscan - ,/client/proc/powerdebug + ,/client/proc/intercom_view + ,/client/proc/air_status + ,/client/proc/Cell + ,/client/proc/atmosscan + ,/client/proc/powerdebug ,/client/proc/count_objects_on_z_level ,/client/proc/count_objects_all ,/client/proc/cmd_assume_direct_control ,/client/proc/jump_to_dead_group ,/client/proc/startSinglo - ,/client/proc/ticklag + ,/client/proc/ticklag ,/client/proc/cmd_admin_grantfullaccess ,/client/proc/kaboom ,/client/proc/splash @@ -158,8 +158,8 @@ var/list/debug_verbs = list ( ,/client/proc/Test_ZAS_Connection ,/client/proc/ZoneTick ,/client/proc/hide_debug_verbs - ,/client/proc/testZAScolors - ,/client/proc/testZAScolors_remove + ,/client/proc/testZAScolors + ,/client/proc/testZAScolors_remove ) @@ -193,16 +193,17 @@ var/list/debug_verbs = list ( testZAScolors_zones += Z if(recurse_level > 10) return - var/icon/yellow = new('icons/misc/debug_group.dmi', "yellow") + var/icon/yellow = new('icons/misc/debug_group.dmi', "yellow") for(var/turf/T in Z.contents) images += image(yellow, T, "zasdebug", TURF_LAYER) testZAScolors_turfs += T - for(var/zone/connected in Z.connected_zones) + for(var/connection_edge/zone/edge in Z.edges) + var/zone/connected = edge.get_connected_zone(Z) if(connected in testZAScolors_zones) continue recurse_zone(connected,recurse_level+1) - + /client/proc/testZAScolors() set category = "ZAS" @@ -211,17 +212,17 @@ var/list/debug_verbs = list ( if(!check_rights(R_DEBUG)) return testZAScolors_remove() - var/turf/location = get_turf(usr) - - if(!istype(location, /turf/simulated)) // We're in space, let's not cause runtimes. - usr << "\red this debug tool cannot be used from space" - return + var/turf/simulated/location = get_turf(usr) + + if(!istype(location, /turf/simulated)) // We're in space, let's not cause runtimes. + usr << "\red this debug tool cannot be used from space" + return var/icon/red = new('icons/misc/debug_group.dmi', "red") //created here so we don't have to make thousands of these. - var/icon/green = new('icons/misc/debug_group.dmi', "green") - var/icon/blue = new('icons/misc/debug_group.dmi', "blue") + var/icon/green = new('icons/misc/debug_group.dmi', "green") + var/icon/blue = new('icons/misc/debug_group.dmi', "blue") - if(!usedZAScolors) + if(!usedZAScolors) usr << "ZAS Test Colors" usr << "Green = Zone you are standing in" usr << "Blue = Connected zone to the zone you are standing in" @@ -233,12 +234,14 @@ var/list/debug_verbs = list ( for(var/turf/T in location.zone.contents) images += image(green, T,"zasdebug", TURF_LAYER) testZAScolors_turfs += T - for(var/zone/Z in location.zone.connected_zones) - testZAScolors_zones += Z + for(var/connection_edge/zone/edge in location.zone.edges) + var/zone/Z = edge.get_connected_zone(location.zone) + testZAScolors_zones += Z for(var/turf/T in Z.contents) images += image(blue, T,"zasdebug",TURF_LAYER) testZAScolors_turfs += T - for(var/zone/connected in Z.connected_zones) + for(var/connection_edge/zone/z_edge in Z.edges) + var/zone/connected = z_edge.get_connected_zone(Z) if(connected in testZAScolors_zones) continue recurse_zone(connected,1) From 2689a508df9529e2ff28a1e440971608243a663e Mon Sep 17 00:00:00 2001 From: Aryn Date: Fri, 21 Feb 2014 08:53:09 -0700 Subject: [PATCH 12/65] baystation12.int is the worst thing to happen to version control --- baystation12.int | 5 ----- 1 file changed, 5 deletions(-) diff --git a/baystation12.int b/baystation12.int index fd01a6c5944..b82874fded5 100644 --- a/baystation12.int +++ b/baystation12.int @@ -1,11 +1,6 @@ // BEGIN_INTERNALS /* MAP_ICON_TYPE: 0 -LAST_COMPILE_VERSION: 503.1224 -WINDOW: code\modules\admin\verbs\mapping.dm;code\ZAS\ConnectionGroup.dm;code\ZAS\Debug.dm;code\ZAS\_docs.dm -DIR: code code\modules code\modules\admin code\modules\admin\verbs code\ZAS -FILE: code\ZAS\_docs.dm -LAST_COMPILE_TIME: 1392997541 AUTO_FILE_DIR: OFF */ // END_INTERNALS From 6dc330a3988d531466d010e45b58c624431afb19 Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Fri, 21 Feb 2014 21:29:34 -0600 Subject: [PATCH 13/65] Bugfix: get_mobs_in_view won't allow AIeyes to hear chat. Also: Added a client check to saycode for now that stops runtimes when you have a dead body with no client and removed colons from it. herp derp. --- code/__HELPERS/game.dm | 29 ++++++++++++++++++----------- code/modules/mob/living/say.dm | 27 ++++++++++++++------------- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 911b5c6f1eb..a9b7f23072e 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -42,7 +42,7 @@ source.loc.luminosity = 6 source.luminosity = 6 - var/list/heard = viewers(range, source) //Only lists mobs, but does a better job then view of getting the mobs. + var/list/heard = hearers(range, source) //Only lists mobs, but does a better job then view of getting the mobs. heard |= view(range, source) source.loc.luminosity = Alum @@ -178,23 +178,30 @@ return hear var/list/range = hear(R, T) - + var/list/objects = list() var/list/clients_minus_checked = clients - for(var/mob/M in range) //Only looking for living mobs because ghosts are automatically added. - hear += M - if(M.client) - clients_minus_checked -= M.client - - var/list/objects = list() + for(var/I in range) + if(istype(I, /mob)) + var/mob/M = I + if(istype(M, /mob/living)) + hear += M + else if(istype(M, /mob/dead)) + hear += M + else + objects += M //We still need to check if they contain entities that can hear + continue - for(var/obj/O in range) //Get a list of objects in hearing range. We'll check to see if any clients have their "eye" set to the object - objects += O + if(M.client) + clients_minus_checked -= M.client + + else + objects += I var/list/hear_and_objects = (hear|objects) for(var/client/C in clients_minus_checked) - if(!istype(C) || !C.eye || istype(C.mob, /mob/dead)) + if(!istype(C) || !C.eye || istype(C.mob, /mob/dead) || istype(C.eye, /mob/aiEye)) continue if(istype(C.eye, /obj/machinery/camera)) diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 93369793586..554ec38afae 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -384,19 +384,20 @@ var/list/department_radio_keys = list( rendered = "[GetVoice()][alt_name] [message_a]" var/rendered_ghost = "[GetVoice()][alt_name] [message_ghost]" for (var/mob/M in heard_a) - if(hascall(M,"show_message")) - var/deaf_message = "" - var/deaf_type = 1 - if(M != src) - deaf_message = "[name][alt_name] talks but you cannot hear them." - else - deaf_message = "You cannot hear yourself!" - deaf_type = 2 // Since you should be able to hear yourself without looking - if (M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTEARS) && M in onscreen) - M:show_message(rendered_ghost, 2, deaf_message, deaf_type) - else - M:show_message(rendered, 2, deaf_message, deaf_type) - M << speech_bubble + if(M.client) //Runtime fix. + if(hascall(M,"show_message")) + var/deaf_message = "" + var/deaf_type = 1 + if(M != src) + deaf_message = "[name][alt_name] talks but you cannot hear them." + else + deaf_message = "You cannot hear yourself!" + deaf_type = 2 // Since you should be able to hear yourself without looking + if (M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTEARS) && M in onscreen) + M.show_message(rendered_ghost, 2, deaf_message, deaf_type) + else + M.show_message(rendered, 2, deaf_message, deaf_type) + M << speech_bubble if (length(heard_b)) From c6d39deac0a34cf30ace6ca063a377f0502e57be Mon Sep 17 00:00:00 2001 From: Segrain Date: Sat, 22 Feb 2014 06:49:57 +0300 Subject: [PATCH 14/65] Fix for #4445. --- code/_onclick/ai.dm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 112c3431e52..d6918b1f7e0 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -32,6 +32,9 @@ build_click(src, client.buildmode, params, A) return + if(control_disabled || stat) + return + var/list/modifiers = params2list(params) if(modifiers["middle"]) MiddleClickOn(A) @@ -46,7 +49,8 @@ CtrlClickOn(A) return - if(control_disabled || stat || world.time <= next_move) return + if(world.time <= next_move) + return next_move = world.time + 9 /* @@ -123,4 +127,4 @@ else // disable/6 is not in Topic; disable/5 disables both temporary and permenant shock Topic("aiDisable=5", list("aiDisable"="5"), 1) - return + return \ No newline at end of file From ef3b565f6413ccc44c9b185662a148eae3f5288c Mon Sep 17 00:00:00 2001 From: Segrain Date: Sat, 22 Feb 2014 06:53:37 +0300 Subject: [PATCH 15/65] Fix for #4458. --- code/game/objects/structures/watercloset.dm | 4 +++- code/modules/mob/living/carbon/human/human.dm | 10 ++++++---- code/modules/mob/living/silicon/robot/robot.dm | 2 +- code/modules/reagents/Chemistry-Reagents.dm | 5 ++++- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 0a9dc69bacd..237ee6c92f1 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -268,10 +268,12 @@ if(H.belt) if(H.belt.clean_blood()) H.update_inv_belt(0) + H.clean_blood(washshoes) else if(M.wear_mask) //if the mob is not human, it cleans the mask without asking for bitflags if(M.wear_mask.clean_blood()) M.update_inv_wear_mask(0) + M.clean_blood() else O.clean_blood() @@ -413,4 +415,4 @@ /obj/structure/sink/puddle/attackby(obj/item/O as obj, mob/user as mob) icon_state = "puddle-splash" ..() - icon_state = "puddle" + icon_state = "puddle" \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 97a6987ad9e..998b4f80144 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -47,7 +47,7 @@ if(!dna) dna = new /datum/dna(null) - dna.species=species.name + dna.species=species.name for(var/i=0;i<7;i++) // 2 for medHUDs and 5 for secHUDs hud_list += image('icons/mob/hud.dmi', src, "hudunknown") @@ -1113,10 +1113,12 @@ verbs += /mob/living/carbon/human/proc/bloody_doodle return 1 //we applied blood to the item -/mob/living/carbon/human/clean_blood() +/mob/living/carbon/human/clean_blood(var/clean_feet) .=..() - if(istype(feet_blood_DNA, /list) && feet_blood_DNA.len) + if(clean_feet && !shoes && istype(feet_blood_DNA, /list) && feet_blood_DNA.len) + feet_blood_color = null del(feet_blood_DNA) + update_inv_shoes(1) return 1 /mob/living/carbon/human/get_visible_implants(var/class = 0) @@ -1193,7 +1195,7 @@ if(!new_species) new_species = dna.species else - dna.species = new_species + dna.species = new_species if(species && (species.name && species.name == new_species)) return diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 2e03b9ffd04..5b417e40247 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1189,7 +1189,7 @@ if(cleaned_human.shoes) cleaned_human.shoes.clean_blood() cleaned_human.update_inv_shoes(0) - cleaned_human.clean_blood() + cleaned_human.clean_blood(1) cleaned_human << "\red [src] cleans your face!" return diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index c9666d98f00..b48b96d3095 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -962,6 +962,9 @@ datum if(H.shoes) if(H.shoes.clean_blood()) H.update_inv_shoes(0) + else + H.clean_blood(1) + return M.clean_blood() leporazine @@ -3696,4 +3699,4 @@ datum return // Undefine the alias for REAGENTS_EFFECT_MULTIPLER -#undef REM +#undef REM \ No newline at end of file From b04d00ff7b19e53d497a8f4c52829b8058cf593a Mon Sep 17 00:00:00 2001 From: Segrain Date: Sat, 22 Feb 2014 06:54:11 +0300 Subject: [PATCH 16/65] Typo fix. --- code/modules/economy/cash.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/economy/cash.dm b/code/modules/economy/cash.dm index c352caa88d4..356015c6c06 100644 --- a/code/modules/economy/cash.dm +++ b/code/modules/economy/cash.dm @@ -17,7 +17,7 @@ var/worth = 0 /obj/item/weapon/spacecash/c1 - name = "1 credip chip" + name = "1 credit chip" icon_state = "spacecash" desc = "It's worth 1 credit." worth = 1 From fd738a5767ef808c862c932e943fcd1234630d95 Mon Sep 17 00:00:00 2001 From: Segrain Date: Sat, 22 Feb 2014 06:54:48 +0300 Subject: [PATCH 17/65] Smallfix. --- code/modules/client/preferences.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index ab55f29f50e..2be354860ed 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -248,9 +248,9 @@ datum/preferences dat += "-Alpha(transparence): [UI_style_alpha]
" dat += "Play admin midis: [(toggles & SOUND_MIDI) ? "Yes" : "No"]
" dat += "Play lobby music: [(toggles & SOUND_LOBBY) ? "Yes" : "No"]
" - dat += "Ghost ears: [(toggles & CHAT_GHOSTEARS) ? "Nearest Creatures" : "All Speech"]
" - dat += "Ghost sight: [(toggles & CHAT_GHOSTSIGHT) ? "Nearest Creatures" : "All Emotes"]
" - dat += "Ghost radio: [(toggles & CHAT_GHOSTRADIO) ? "Nearest Speakers" : "All Chatter"]
" + dat += "Ghost ears: [(toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]
" + dat += "Ghost sight: [(toggles & CHAT_GHOSTSIGHT) ? "All Emotes" : "Nearest Creatures"]
" + dat += "Ghost radio: [(toggles & CHAT_GHOSTRADIO) ? "All Chatter" : "Nearest Speakers"]
" if(config.allow_Metadata) dat += "OOC Notes: Edit
" From 2b9842c113231ebb396ff77835c9eca67d66d520 Mon Sep 17 00:00:00 2001 From: Segrain Date: Sat, 22 Feb 2014 06:56:12 +0300 Subject: [PATCH 18/65] Smallfix. --- .../objects/items/weapons/cigs_lighters.dm | 26 +++++++++++-------- .../objects/items/weapons/storage/boxes.dm | 4 ++- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index ac80658f27c..2dd706649d9 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -21,6 +21,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM icon = 'icons/obj/cigarettes.dmi' icon_state = "match_unlit" var/lit = 0 + var/burnt = 0 var/smoketime = 5 w_class = 1.0 origin_tech = "materials=1" @@ -30,24 +31,27 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/turf/location = get_turf(src) smoketime-- if(smoketime < 1) - icon_state = "match_burnt" - lit = -1 - processing_objects.Remove(src) + burn_out() return if(location) location.hotspot_expose(700, 5) return /obj/item/weapon/match/dropped(mob/user as mob) - if(lit == 1) - lit = -1 - damtype = "brute" - icon_state = "match_burnt" - item_state = "cigoff" - name = "burnt match" - desc = "A match. This one has seen better days." + if(lit) + burn_out() return ..() +/obj/item/weapon/match/proc/burn_out() + lit = 0 + burnt = 1 + damtype = "brute" + icon_state = "match_burnt" + item_state = "cigoff" + name = "burnt match" + desc = "A match. This one has seen better days." + processing_objects.Remove(src) + ////////////////// //FINE SMOKABLES// ////////////////// @@ -419,4 +423,4 @@ CIGARETTE PACKETS ARE IN FANCY.DM if(lit) user.SetLuminosity(user.luminosity-2) SetLuminosity(2) - return + return \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 91c68bd1e74..83189aafd6b 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -418,6 +418,7 @@ w_class = 1 flags = TABLEPASS slot_flags = SLOT_BELT + can_hold = list("/obj/item/weapon/match") New() ..() @@ -425,8 +426,9 @@ new /obj/item/weapon/match(src) attackby(obj/item/weapon/match/W as obj, mob/user as mob) - if(istype(W, /obj/item/weapon/match) && W.lit == 0) + if(istype(W) && !W.lit && !W.burnt) W.lit = 1 + W.damtype = "burn" W.icon_state = "match_lit" processing_objects.Add(W) W.update_icon() From 05c82c970b2f3a7284c4e1f39c49e107b52212b9 Mon Sep 17 00:00:00 2001 From: Segrain Date: Sat, 22 Feb 2014 06:56:51 +0300 Subject: [PATCH 19/65] Tiny fix. --- code/game/objects/items/weapons/storage/fancy.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index 119d2d2c22e..5766fd27e45 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -173,7 +173,6 @@ /obj/item/weapon/storage/fancy/cigarettes/update_icon() icon_state = "[initial(icon_state)][contents.len]" - desc = "There are [contents.len] cig\s left!" return /obj/item/weapon/storage/fancy/cigarettes/remove_from_storage(obj/item/W as obj, atom/new_location) @@ -253,5 +252,4 @@ /obj/item/weapon/storage/lockbox/vials/attackby(obj/item/weapon/W as obj, mob/user as mob) ..() - update_icon() - + update_icon() \ No newline at end of file From 86c73e242b24aec51c2779aae2fa0b1a336617e1 Mon Sep 17 00:00:00 2001 From: Segrain Date: Sat, 22 Feb 2014 10:16:55 +0300 Subject: [PATCH 20/65] Fix for embedding. --- code/modules/projectiles/projectile/force.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/projectiles/projectile/force.dm b/code/modules/projectiles/projectile/force.dm index 2fab1a4da18..364ad53370b 100644 --- a/code/modules/projectiles/projectile/force.dm +++ b/code/modules/projectiles/projectile/force.dm @@ -4,7 +4,6 @@ icon_state = "ice_1" damage = 20 flag = "energy" - embed = 1 /obj/item/projectile/forcebolt/strong name = "force bolt" From d95caffecb62ce0d50d811aabbf0eb7ef25e5588 Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Sat, 22 Feb 2014 01:45:43 -0600 Subject: [PATCH 21/65] DEV EMPOWERMENT Gives people with R_DEBUG access to runtimelogs. Also moves make_everyone_random to R_FUN where it belongs, gets rid of that dumb panel from my awesome dev screen. --- code/modules/admin/admin_verbs.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 664b70bcff2..0258ddb50ae 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -29,7 +29,6 @@ var/list/admin_verbs_admin = list( /client/proc/cmd_admin_check_contents, /*displays the contents of an instance*/ /datum/admins/proc/access_news_network, /*allows access of newscasters*/ /client/proc/giveruntimelog, /*allows us to give access to runtime logs to somebody*/ - /client/proc/getruntimelog, /*allows us to access runtime logs to somebody*/ /client/proc/getserverlog, /*allows us to fetch server logs (diary) for other days*/ /client/proc/jumptocoord, /*we ghost and jump to a coordinate*/ /client/proc/Getmob, /*teleports a mob to our location*/ @@ -89,6 +88,7 @@ var/list/admin_verbs_fun = list( /client/proc/cmd_admin_dress, /client/proc/cmd_admin_gib_self, /client/proc/drop_bomb, + /client/proc/everyone_random, /client/proc/cinematic, /client/proc/one_click_antag, /datum/admins/proc/toggle_aliens, @@ -127,6 +127,7 @@ var/list/admin_verbs_server = list( /client/proc/check_customitem_activity ) var/list/admin_verbs_debug = list( + /client/proc/getruntimelog, /*allows us to access runtime logs to somebody*/ /client/proc/cmd_admin_list_open_jobs, /client/proc/Debug2, /client/proc/kill_air, From 92e0c601260471d5b82d9d91e52fb668b05c26fc Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Sat, 22 Feb 2014 02:50:49 -0600 Subject: [PATCH 22/65] Remove clients removal derp. --- code/__HELPERS/game.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index a9b7f23072e..e5a4ab8de94 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -179,7 +179,8 @@ var/list/range = hear(R, T) var/list/objects = list() - var/list/clients_minus_checked = clients + var/list/clients_minus_checked = list() + clients_minus_checked |= clients for(var/I in range) if(istype(I, /mob)) From 8ef2e1023722882956d86ccb8734b7f2ae579815 Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Sat, 22 Feb 2014 03:43:37 -0600 Subject: [PATCH 23/65] This reverts commit all the say code changes over the last couple of days. Except for the removal of the redundant get_mobs_in_view used for bolding ghosts text. --- code/__HELPERS/game.dm | 57 +++++------------------- code/modules/admin/verbs/mapping.dm | 67 ----------------------------- code/modules/mob/emote.dm | 6 +-- code/modules/mob/living/say.dm | 27 ++++++------ 4 files changed, 26 insertions(+), 131 deletions(-) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index e5a4ab8de94..e2c04299f1c 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -35,17 +35,12 @@ // Like view but bypasses luminosity check -/proc/hear(var/range, var/turf/source) +/proc/hear(var/range, var/atom/source) - var/Alum = source.loc.luminosity var/lum = source.luminosity - source.loc.luminosity = 6 source.luminosity = 6 - var/list/heard = hearers(range, source) //Only lists mobs, but does a better job then view of getting the mobs. - heard |= view(range, source) - - source.loc.luminosity = Alum + var/list/heard = view(range, source) source.luminosity = lum return heard @@ -166,8 +161,6 @@ // The old system would loop through lists for a total of 5000 per function call, in an empty server. // This new system will loop at around 1000 in an empty server. -// SCREW THAT SHIT, we're not recursing. - /proc/get_mobs_in_view(var/R, var/atom/source) // Returns a list of mobs in range of R from source. Used in radio and say code. @@ -178,46 +171,18 @@ return hear var/list/range = hear(R, T) - var/list/objects = list() - var/list/clients_minus_checked = list() - clients_minus_checked |= clients - - for(var/I in range) - if(istype(I, /mob)) - var/mob/M = I - if(istype(M, /mob/living)) - hear += M - else if(istype(M, /mob/dead)) - hear += M - else - objects += M //We still need to check if they contain entities that can hear - continue + for(var/atom/A in range) + if(ismob(A)) + var/mob/M = A if(M.client) - clients_minus_checked -= M.client + hear += M + //world.log << "Start = [M] - [get_turf(M)] - ([M.x], [M.y], [M.z])" + else if(istype(A, /obj/item/device/radio)) + hear += A - else - objects += I - - var/list/hear_and_objects = (hear|objects) - - for(var/client/C in clients_minus_checked) - if(!istype(C) || !C.eye || istype(C.mob, /mob/dead) || istype(C.eye, /mob/aiEye)) - continue - - if(istype(C.eye, /obj/machinery/camera)) - continue //No microphones in cameras. - - if(C.eye in hear_and_objects) - hear += C.mob - hear_and_objects += C.mob - else if(C.mob.loc in hear_and_objects) - hear += C.mob - hear_and_objects += C.mob - - else if(C.mob.loc.loc in hear_and_objects) - hear += C.mob - hear_and_objects += C.mob + if(isobj(A) || ismob(A)) + hear |= recursive_mob_check(A, hear, 3, 1, 0, 1) return hear diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index 6108ebd7749..00b9f15ca53 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -161,9 +161,6 @@ var/list/debug_verbs = list ( ,/client/proc/hide_debug_verbs ,/client/proc/testZAScolors ,/client/proc/testZAScolors_remove - ,/client/proc/test_viewers - ,/client/proc/test_view - ,/client/proc/test_hear ) @@ -188,70 +185,6 @@ var/list/debug_verbs = list ( feedback_add_details("admin_verb","hDV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/test_viewers() - set category = "Debug" - set name = "Test Viewers" - - var/turf/T = get_turf(usr) - var/lum = T.loc.luminosity - T.loc.luminosity = 1 - - - var/list/inviewers = viewers(7, usr) - T.loc.luminosity = lum - var/list/M = list() - var/list/O = list() - - for(var/obj/OBJ in inviewers) - O += OBJ - for(var/mob/MOB in inviewers) - M += MOB - - usr << "VIEWERS MOB: [list2text(M,", ")]" - usr << "VIEWERS OBJ: [list2text(O,", ")]" - - - -/client/proc/test_view() - set category = "Debug" - set name = "Test View" - - var/list/inview = view(7, usr) - var/list/M = list() - var/list/O = list() - - for(var/obj/OBJ in inview) - O += OBJ - for(var/mob/MOB in inview) - M += MOB - - usr << "VIEW MOB: [list2text(M,", ")]" - usr << "VIEW OBJ: [list2text(O,", ")]" - -/client/proc/test_hear() - set category = "Debug" - set name = "Test Hear" - - var/turf/T = get_turf(usr) - var/list/hearers = hear(7, T) - var/list/M = list() - var/list/O = list() - - for(var/obj/OBJ in hearers) - O += OBJ - for(var/mob/MOB in hearers) - M += MOB - - - usr << "HEAR MOB: [list2text(M,", ")]" - usr << "HEAR OBJ: [list2text(O,", ")]" - - - - - - /client/var/list/testZAScolors_turfs = list() /client/var/list/testZAScolors_zones = list() /client/var/usedZAScolors = 0 diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm index c33732ed133..e2125ada66c 100644 --- a/code/modules/mob/emote.dm +++ b/code/modules/mob/emote.dm @@ -38,15 +38,13 @@ // Type 1 (Visual) emotes are sent to anyone in view of the item if (m_type & 1) - var/list/can_see = get_mobs_in_view(1,src) //Allows silicon & mmi mobs carried around to see the emotes of the person carrying them around. - can_see |= viewers(src,null) - for (var/mob/O in can_see) + for (var/mob/O in viewers(src, null)) O.show_message(message, m_type) // Type 2 (Audible) emotes are sent to anyone in hear range // of the *LOCATION* -- this is important for pAIs to be heard else if (m_type & 2) - for (var/mob/O in get_mobs_in_view(7,src)) + for (var/mob/O in hearers(get_turf(src), null)) O.show_message(message, m_type) /mob/proc/emote_dead(var/message) diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 554ec38afae..93369793586 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -384,20 +384,19 @@ var/list/department_radio_keys = list( rendered = "[GetVoice()][alt_name] [message_a]" var/rendered_ghost = "[GetVoice()][alt_name] [message_ghost]" for (var/mob/M in heard_a) - if(M.client) //Runtime fix. - if(hascall(M,"show_message")) - var/deaf_message = "" - var/deaf_type = 1 - if(M != src) - deaf_message = "[name][alt_name] talks but you cannot hear them." - else - deaf_message = "You cannot hear yourself!" - deaf_type = 2 // Since you should be able to hear yourself without looking - if (M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTEARS) && M in onscreen) - M.show_message(rendered_ghost, 2, deaf_message, deaf_type) - else - M.show_message(rendered, 2, deaf_message, deaf_type) - M << speech_bubble + if(hascall(M,"show_message")) + var/deaf_message = "" + var/deaf_type = 1 + if(M != src) + deaf_message = "[name][alt_name] talks but you cannot hear them." + else + deaf_message = "You cannot hear yourself!" + deaf_type = 2 // Since you should be able to hear yourself without looking + if (M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTEARS) && M in onscreen) + M:show_message(rendered_ghost, 2, deaf_message, deaf_type) + else + M:show_message(rendered, 2, deaf_message, deaf_type) + M << speech_bubble if (length(heard_b)) From e72c584ac86818f0954e36d21f8cf7a423ae679c Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Sat, 22 Feb 2014 03:47:46 -0600 Subject: [PATCH 24/65] Reapplys this runtime fix when dead /mob/living would not have a client. --- code/modules/mob/living/say.dm | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 93369793586..3f7bd7c02dd 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -384,19 +384,20 @@ var/list/department_radio_keys = list( rendered = "[GetVoice()][alt_name] [message_a]" var/rendered_ghost = "[GetVoice()][alt_name] [message_ghost]" for (var/mob/M in heard_a) - if(hascall(M,"show_message")) - var/deaf_message = "" - var/deaf_type = 1 - if(M != src) - deaf_message = "[name][alt_name] talks but you cannot hear them." - else - deaf_message = "You cannot hear yourself!" - deaf_type = 2 // Since you should be able to hear yourself without looking - if (M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTEARS) && M in onscreen) - M:show_message(rendered_ghost, 2, deaf_message, deaf_type) - else - M:show_message(rendered, 2, deaf_message, deaf_type) - M << speech_bubble + if(M.client) + if(hascall(M,"show_message")) + var/deaf_message = "" + var/deaf_type = 1 + if(M != src) + deaf_message = "[name][alt_name] talks but you cannot hear them." + else + deaf_message = "You cannot hear yourself!" + deaf_type = 2 // Since you should be able to hear yourself without looking + if (M.stat == DEAD && (M.client.prefs.toggles & CHAT_GHOSTEARS) && M in onscreen) + M:show_message(rendered_ghost, 2, deaf_message, deaf_type) + else + M:show_message(rendered, 2, deaf_message, deaf_type) + M << speech_bubble if (length(heard_b)) From dcc7ad33c912b4a95ce0146aa4b50dc2f3c3b613 Mon Sep 17 00:00:00 2001 From: Aryn Date: Sat, 22 Feb 2014 08:02:10 -0700 Subject: [PATCH 25/65] Zones didn't split when a full window was placed. --- code/ZAS/Turf.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ZAS/Turf.dm b/code/ZAS/Turf.dm index d3d98d720f2..fece782aa71 100644 --- a/code/ZAS/Turf.dm +++ b/code/ZAS/Turf.dm @@ -57,7 +57,7 @@ #endif if(zone) var/zone/z = zone - if(s_block & ZONE_BLOCKED) + if(locate(/obj/machinery/door/airlock) in src) //Hacky, but prevents normal airlocks from rebuilding zones all the time z.remove(src) else z.rebuild() From d6b275ca7381440f2f4f8fbb10778f07c3b3176f Mon Sep 17 00:00:00 2001 From: Aryn Date: Sat, 22 Feb 2014 08:16:35 -0700 Subject: [PATCH 26/65] Fixed walls not splitting zones. --- code/ZAS/Zone.dm | 1 + code/ZAS/_docs.dm | 2 +- code/game/turfs/turf.dm | 6 ++++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/code/ZAS/Zone.dm b/code/ZAS/Zone.dm index 8373771ae26..17d6097cdaf 100644 --- a/code/ZAS/Zone.dm +++ b/code/ZAS/Zone.dm @@ -107,6 +107,7 @@ Class Procs: #endif /zone/proc/rebuild() + if(invalid) return //Short circuit for explosions where rebuild is called many times over. c_invalidate() for(var/turf/simulated/T in contents) //T.dbg(invalid_zone) diff --git a/code/ZAS/_docs.dm b/code/ZAS/_docs.dm index 8d084dc4c95..26bb4d3b215 100644 --- a/code/ZAS/_docs.dm +++ b/code/ZAS/_docs.dm @@ -27,7 +27,7 @@ Notes for people who used ZAS before: */ -//#define ZASDBG +#define ZASDBG //#define ZLEVELS #define AIR_BLOCKED 1 diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index b172024579e..57e9aab94cb 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -221,9 +221,11 @@ if(connections) connections.erase_all() if(istype(src,/turf/simulated)) - //world << "Removed from zone." + //Yeah, we're just going to rebuild the whole thing. + //Despite this being called a bunch during explosions, + //the zone will only really do heavy lifting once. var/turf/simulated/S = src - if(S.zone) S.zone.remove(S) + if(S.zone) S.zone.rebuild() if(ispath(N, /turf/simulated/floor)) //if the old turf had a zone, connect the new turf to it as well - Cael From 6c91d220b81686ea9b10b228d9049445d9ea1637 Mon Sep 17 00:00:00 2001 From: Aryn Date: Sat, 22 Feb 2014 08:45:31 -0700 Subject: [PATCH 27/65] Added code protecting against obscure merges of invalid zones. - Usually happened when welding fuel tanks caused secondary explosions. --- code/ZAS/ConnectionGroup.dm | 6 ++++++ code/ZAS/Controller.dm | 3 +++ 2 files changed, 9 insertions(+) diff --git a/code/ZAS/ConnectionGroup.dm b/code/ZAS/ConnectionGroup.dm index 2c7e4373c03..1486f5088b6 100644 --- a/code/ZAS/ConnectionGroup.dm +++ b/code/ZAS/ConnectionGroup.dm @@ -143,6 +143,9 @@ Class Procs: . = ..() /connection_edge/zone/tick() + if(A.invalid || B.invalid) + erase() + return //world << "[id]: Tick [air_master.current_cycle]: \..." if(direct) if(air_master.equivalent_pressure(A, B)) @@ -207,6 +210,9 @@ Class Procs: return A == Z /connection_edge/unsimulated/tick() + if(A.invalid) + erase() + return //world << "[id]: Tick [air_master.current_cycle]: To [B]!" //A.air.mimic(B, coefficient) ShareSpace(A.air,air) diff --git a/code/ZAS/Controller.dm b/code/ZAS/Controller.dm index 429906a6495..83b4bf3f3b4 100644 --- a/code/ZAS/Controller.dm +++ b/code/ZAS/Controller.dm @@ -220,6 +220,8 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun #ifdef ZASDBG ASSERT(istype(A)) ASSERT(istype(B)) + ASSERT(!A.invalid) + ASSERT(!B.invalid) ASSERT(A != B) #endif if(A.contents.len < B.contents.len) @@ -234,6 +236,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun ASSERT(istype(A)) ASSERT(isturf(B)) ASSERT(A.zone) + ASSERT(!A.zone.invalid) //ASSERT(B.zone) ASSERT(A != B) #endif From e3b87b4c4d01b55b37c91efdb266a54f1b72ea12 Mon Sep 17 00:00:00 2001 From: Aryn Date: Sat, 22 Feb 2014 08:47:54 -0700 Subject: [PATCH 28/65] Removed a leftover generally-accessible debug verb. --- code/ZAS/Debug.dm | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/code/ZAS/Debug.dm b/code/ZAS/Debug.dm index 62db9d0eb88..b27056f2384 100644 --- a/code/ZAS/Debug.dm +++ b/code/ZAS/Debug.dm @@ -15,9 +15,4 @@ var/image/mark = image('icons/Testing/Zone.dmi', icon_state = "mark") dbg_img = img proc/soft_assert(thing,fail) - if(!thing) message_admins(fail) - -/turf/simulated/var/verbose = 0 -/turf/simulated/verb/Verbose() - set src in world - verbose = !verbose \ No newline at end of file + if(!thing) message_admins(fail) \ No newline at end of file From bb6f030f84feea4c652f88a3e60d18cba118cd0e Mon Sep 17 00:00:00 2001 From: Aryn Date: Sat, 22 Feb 2014 09:09:48 -0700 Subject: [PATCH 29/65] Added Reboot ZAS as a debug verb. Replaces the air controller, marks all old zones invalid, and adds every turf to the update list. Results are the same as on a server start. --- code/ZAS/_docs.dm | 2 +- code/modules/admin/verbs/mapping.dm | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/code/ZAS/_docs.dm b/code/ZAS/_docs.dm index 26bb4d3b215..8d084dc4c95 100644 --- a/code/ZAS/_docs.dm +++ b/code/ZAS/_docs.dm @@ -27,7 +27,7 @@ Notes for people who used ZAS before: */ -#define ZASDBG +//#define ZASDBG //#define ZLEVELS #define AIR_BLOCKED 1 diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index ab7ef30e915..2e092689c3d 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -157,6 +157,7 @@ var/list/debug_verbs = list ( ,/client/proc/Zone_Info ,/client/proc/Test_ZAS_Connection ,/client/proc/ZoneTick + ,/client/proc/rebootAirMaster ,/client/proc/hide_debug_verbs ,/client/proc/testZAScolors ,/client/proc/testZAScolors_remove @@ -266,6 +267,19 @@ var/list/debug_verbs = list ( if(i.icon_state == "zasdebug") images.Remove(i) +/client/proc/rebootAirMaster() + set category = "ZAS" + set name = "Reboot ZAS" + + if(alert("This will destroy and remake all zone geometry on the whole map.","Reboot ZAS","Reboot ZAS","Nevermind") == "Reboot ZAS") + var/datum/controller/air_system/old_air = air_master + for(var/zone/zone in old_air.zones) + zone.c_invalidate() + del old_air + air_master = new + air_master.Setup() + spawn air_master.Start() + /client/proc/count_objects_on_z_level() set category = "Mapping" From 32de00eed82c0c834a017c067373579afe9a9531 Mon Sep 17 00:00:00 2001 From: suethecake Date: Sat, 22 Feb 2014 21:50:21 -0600 Subject: [PATCH 30/65] Fix to cloned gun issue - now your holster is located on your tactical armor. --- .../objects/items/weapons/storage/belt.dm | 40 +------------------ code/modules/clothing/suits/armor.dm | 35 +++++++++++++++- 2 files changed, 36 insertions(+), 39 deletions(-) diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 8798cb699c1..3ad8b79e49a 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -173,7 +173,6 @@ desc = "Can hold security gear like handcuffs and flashes, with more pouches for more storage." icon_state = "swatbelt" item_state = "swatbelt" - var/obj/item/weapon/gun/holstered = null storage_slots = 9 max_w_class = 3 max_combined_w_class = 21 @@ -195,40 +194,5 @@ "/obj/item/device/flashlight", "/obj/item/device/pda", "/obj/item/device/radio/headset", - "/obj/item/weapon/melee", - "/obj/item/taperoll/police", - "/obj/item/weapon/gun/energy/taser" - ) - - - /obj/item/weapon/storage/belt/security/tactical/verb/holster() - set name = "Holster" - set category = "Object" - set src in usr - if(!istype(usr, /mob/living)) return - if(usr.stat) return - - if(!holstered) - if(!istype(usr.get_active_hand(), /obj/item/weapon/gun)) - usr << "\blue You need your gun equiped to holster it." - return - var/obj/item/weapon/gun/W = usr.get_active_hand() - if (!W.isHandgun()) - usr << "\red This gun won't fit in \the belt!" - return - holstered = usr.get_active_hand() - usr.drop_item() - holstered.loc = src - usr.visible_message("\blue \The [usr] holsters \the [holstered].", "You holster \the [holstered].") - else - if(istype(usr.get_active_hand(),/obj) && istype(usr.get_inactive_hand(),/obj)) - usr << "\red You need an empty hand to draw the gun!" - else - if(usr.a_intent == "hurt") - usr.visible_message("\red \The [usr] draws \the [holstered], ready to shoot!", \ - "\red You draw \the [holstered], ready to shoot!") - else - usr.visible_message("\blue \The [usr] draws \the [holstered], pointing it at the ground.", \ - "\blue You draw \the [holstered], pointing it at the ground.") - usr.put_in_hands(holstered) - holstered = null \ No newline at end of file + "/obj/item/weapon/melee" + ) \ No newline at end of file diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index c58ec18be0f..7299516c9cd 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -190,7 +190,40 @@ desc = "A suit of armor most often used by Special Weapons and Tactics squads. Includes padded vest with pockets along with shoulder and kneeguards." icon_state = "swatarmor" item_state = "armor" + var/obj/item/weapon/gun/holstered = null body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|ARMS slowdown = 1 armor = list(melee = 60, bullet = 60, laser = 60, energy = 40, bomb = 20, bio = 0, rad = 0) - siemens_coefficient = 0.7 \ No newline at end of file + siemens_coefficient = 0.7 + + /obj/item/clothing/suit/armor/tactical/verb/holster() + set name = "Holster" + set category = "Object" + set src in usr + if(!istype(usr, /mob/living)) return + if(usr.stat) return + + if(!holstered) + if(!istype(usr.get_active_hand(), /obj/item/weapon/gun)) + usr << "\blue You need your gun equiped to holster it." + return + var/obj/item/weapon/gun/W = usr.get_active_hand() + if (!W.isHandgun()) + usr << "\red This gun won't fit in \the belt!" + return + holstered = usr.get_active_hand() + usr.drop_item() + holstered.loc = src + usr.visible_message("\blue \The [usr] holsters \the [holstered].", "You holster \the [holstered].") + else + if(istype(usr.get_active_hand(),/obj) && istype(usr.get_inactive_hand(),/obj)) + usr << "\red You need an empty hand to draw the gun!" + else + if(usr.a_intent == "hurt") + usr.visible_message("\red \The [usr] draws \the [holstered], ready to shoot!", \ + "\red You draw \the [holstered], ready to shoot!") + else + usr.visible_message("\blue \The [usr] draws \the [holstered], pointing it at the ground.", \ + "\blue You draw \the [holstered], pointing it at the ground.") + usr.put_in_hands(holstered) + holstered = null \ No newline at end of file From cea151813e72e5ac6b01cc2a48659622bfce093d Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Mon, 24 Feb 2014 00:44:00 -0600 Subject: [PATCH 31/65] Runtime fix: Dirt in SPAAAAACCEEEEEEE ndefined variable /turf/space/var/dirt proc name: reaction turf (/datum/reagent/space_cleaner/reaction_turf) source file: Chemistry-Reagents.dm,939 --- code/modules/reagents/Chemistry-Reagents.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index c9666d98f00..73c500403f8 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -935,8 +935,9 @@ datum for(var/mob/living/carbon/slime/M in T) M.adjustToxLoss(rand(5,10)) reaction_turf(var/turf/simulated/S, var/volume) - if(volume >= 1) - S.dirt = 0 + if(istype(S) + if(volume >= 1) + S.dirt = 0 reaction_mob(var/mob/M, var/method=TOUCH, var/volume) if(iscarbon(M)) From 1eb66f1f78d7cc8261a3d488ec90e961f3d60ae2 Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Mon, 24 Feb 2014 00:47:55 -0600 Subject: [PATCH 32/65] Runtime fix blood_DNA length checks when it's possibly null. runtime error: Cannot read null.len proc name: attack self (/obj/item/weapon/melee/telebaton/attack_self) source file: swords_axes_etc.dm,156 --- code/game/objects/items/weapons/swords_axes_etc.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/weapons/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm index 8b9d914bc24..7ee3499c1cd 100644 --- a/code/game/objects/items/weapons/swords_axes_etc.dm +++ b/code/game/objects/items/weapons/swords_axes_etc.dm @@ -153,7 +153,7 @@ playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1) add_fingerprint(user) - if(blood_overlay && (blood_DNA.len >= 1)) //updates blood overlay, if any + if(blood_overlay && blood_DNA && (blood_DNA.len >= 1)) //updates blood overlay, if any overlays.Cut()//this might delete other item overlays as well but eeeeeeeh var/icon/I = new /icon(src.icon, src.icon_state) @@ -265,4 +265,4 @@ H.update_inv_r_hand() add_fingerprint(user) - return \ No newline at end of file + return From 0bcd89360a26223820d5b7ef0b89baf4de7fc5eb Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Mon, 24 Feb 2014 00:51:57 -0600 Subject: [PATCH 33/65] Runtime fix: I have no UI, and I must close it. runtime error: Cannot execute null.close(). proc name: Topic (/obj/item/device/pda/Topic) source file: PDA.dm,485 usr: Garry Myers (/mob/living/carbon/human) src: PDA-Garry Myers (Station Engin... (/obj/item/device/pda/engineering) call stack: PDA-Garry Myers (Station Engin... (/obj/item/device/pda/engineering): Topic("src=\[0x2003e95];choice=Messag...", /list (/list)) NeroHarry (/client): Topic("src=\[0x2003e95];choice=Messag...", /list (/list), PDA-Garry Myers (Station Engin... (/obj/item/device/pda/engineering)) NeroHarry (/client): Topic("src=\[0x2003e95];choice=Messag...", /list (/list), PDA-Garry Myers (Station Engin... (/obj/item/device/pda/engineering)) --- code/game/objects/items/devices/PDA/PDA.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 5a0bdf4af30..df04ddfcfe7 100755 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -482,7 +482,8 @@ var/global/list/obj/item/device/pda/PDAs = list() return 0 if(!can_use()) //Why reinvent the wheel? There's a proc that does exactly that. U.unset_machine() - ui.close() + if(ui) + ui.close() return 0 add_fingerprint(U) From 75116bfd53602c49da55fc477cbfe004ff2addc0 Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Mon, 24 Feb 2014 01:16:19 -0600 Subject: [PATCH 34/65] Runtime fix: Someone using a gas mask with no tank...IN SPACE runtime error: Cannot read null.oxygen proc name: copy from (/datum/gas_mixture/proc/copy_from) source file: FEA_gas_mixture.dm,480 usr: null src: /datum/gas_mixture (/datum/gas_mixture) call stack: /datum/gas_mixture (/datum/gas_mixture): copy from(null) Basileus (/mob/living/carbon/human): breathe() Basileus (/mob/living/carbon/human): Life() /datum/controller/game_control... (/datum/controller/game_controller): process mobs() /datum/controller/game_control... (/datum/controller/game_controller): process() runtime error: Cannot read null.toxins proc name: breathe (/mob/living/carbon/human/proc/breathe) source file: life.dm,339 usr: null src: Basileus (/mob/living/carbon/human) call stack: Basileus (/mob/living/carbon/human): breathe() Basileus (/mob/living/carbon/human): Life() /datum/controller/game_control... (/datum/controller/game_controller): process mobs() /datum/controller/game_control... (/datum/controller/game_controller): process() --- code/modules/mob/living/carbon/human/life.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 00368c2debd..8470095cde0 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -325,7 +325,7 @@ breath = loc.remove_air(breath_moles) - if(istype(wear_mask, /obj/item/clothing/mask/gas)) + if(istype(wear_mask, /obj/item/clothing/mask/gas) && breath) var/obj/item/clothing/mask/gas/G = wear_mask var/datum/gas_mixture/filtered = new From d5951781fdeaf675508fa5d67bb44e130dde63df Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Mon, 24 Feb 2014 01:27:04 -0600 Subject: [PATCH 35/65] Runtime fix: Alarms keep trying to heat up space. runtime error: Cannot execute null.heat capacity(). proc name: process (/obj/machinery/alarm/process) source file: alarm.dm,186 runtime error: Cannot execute null.heat capacity(). proc name: process (/obj/machinery/alarm/process) source file: alarm.dm,186 over and over and over. --- code/game/machinery/alarm.dm | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index f2a069c4543..c781bb20c99 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -183,24 +183,25 @@ var/datum/gas_mixture/gas gas = location.remove_air(0.25*environment.total_moles) - var/heat_capacity = gas.heat_capacity() - var/energy_used = min( abs( heat_capacity*(gas.temperature - target_temperature) ), MAX_ENERGY_CHANGE) + if(gas) + var/heat_capacity = gas.heat_capacity() + var/energy_used = min( abs( heat_capacity*(gas.temperature - target_temperature) ), MAX_ENERGY_CHANGE) - //Use power. Assuming that each power unit represents 1000 watts.... - use_power(energy_used/1000, ENVIRON) + //Use power. Assuming that each power unit represents 1000 watts.... + use_power(energy_used/1000, ENVIRON) - //We need to cool ourselves. - if(environment.temperature > target_temperature) - gas.temperature -= energy_used/heat_capacity - else - gas.temperature += energy_used/heat_capacity + //We need to cool ourselves. + if(environment.temperature > target_temperature) + gas.temperature -= energy_used/heat_capacity + else + gas.temperature += energy_used/heat_capacity - environment.merge(gas) + environment.merge(gas) - if(abs(environment.temperature - target_temperature) <= 0.5) - regulating_temperature = 0 - visible_message("\The [src] clicks quietly as it stops [environment.temperature > target_temperature ? "cooling" : "heating"] the room.",\ - "You hear a click as a faint electronic humming stops.") + if(abs(environment.temperature - target_temperature) <= 0.5) + regulating_temperature = 0 + visible_message("\The [src] clicks quietly as it stops [environment.temperature > target_temperature ? "cooling" : "heating"] the room.",\ + "You hear a click as a faint electronic humming stops.") var/old_level = danger_level danger_level = overall_danger_level() @@ -1683,4 +1684,4 @@ Code shamelessly copied from apc_frame else usr << browse(null, "window=partyalarm") return - return \ No newline at end of file + return From 3d8899812320df31b5dab37f9d0472370b70dc37 Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Mon, 24 Feb 2014 01:35:04 -0600 Subject: [PATCH 36/65] Runtime fix: usr = 0??? runtime error: Cannot read 0.item_use_icon proc name: remove gun icons (/client/proc/remove_gun_icons) source file: targeting.dm,273 usr: 0 src: Vivalas (/client) call stack: Vivalas (/client): remove gun icons() the taser gun (/obj/item/weapon/gun/energy/taser): dropped(Jonathon Sommer (/mob/living/carbon/human)) Jonathon Sommer (/mob/living/carbon/human): drop r hand(null) Jonathon Sommer (/mob/living/carbon/human): update canmove() Jonathon Sommer (/mob/living/carbon/human): Weaken(5) Jonathon Sommer (/mob/living/carbon/human): Weaken(5) Jonathon Sommer (/mob/living/carbon/human): apply effect(5, "weaken", 0) Jonathon Sommer (/mob/living/carbon/human): apply effects(0, 5, 0, 0, 0, 0, 0, 0, 0) --- code/modules/projectiles/targeting.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/projectiles/targeting.dm b/code/modules/projectiles/targeting.dm index 06f25a7e18b..d627a5c7713 100644 --- a/code/modules/projectiles/targeting.dm +++ b/code/modules/projectiles/targeting.dm @@ -269,7 +269,7 @@ client/proc/add_gun_icons() screen += usr.gun_run_icon client/proc/remove_gun_icons() - if(isnull(usr)) return 1 // Runtime prevention on N00k agents spawning with SMG + if(!usr) return 1 // Runtime prevention on N00k agents spawning with SMG screen -= usr.item_use_icon screen -= usr.gun_move_icon if (target_can_move) From f071421552188fa08ac19f042d244ef2777dc706 Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Mon, 24 Feb 2014 01:39:25 -0600 Subject: [PATCH 37/65] Runtime fix: Null isn't really that sharp. runtime error: Cannot read null.sharp proc name: is sharp (/proc/is_sharp) source file: unsorted.dm,1270 usr: Arthur Ward (/mob/living/carbon/human) src: null call stack: is sharp(null) the police tape (/obj/item/tape/police): breaktape(null, Arthur Ward (/mob/living/carbon/human)) the police tape (/obj/item/tape/police): attack hand(Arthur Ward (/mob/living/carbon/human)) Arthur Ward (/mob/living/carbon/human): UnarmedAttack(the police tape (/obj/item/tape/police), 1) Arthur Ward (/mob/living/carbon/human): ClickOn(the police tape (/obj/item/tape/police), "icon-x=16;icon-y=10;left=1;scr...") the police tape (/obj/item/tape/police): Click(the floor (172,128,1) (/turf/simulated/floor), "mapwindow.map", "icon-x=16;icon-y=10;left=1;scr...") --- code/__HELPERS/unsorted.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index f9c2c90dd57..c5ec1748419 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1267,6 +1267,7 @@ proc/is_hot(obj/item/W as obj) //Is this even used for anything besides balloons? Yes I took out the W:lit stuff because : really shouldnt be used. /proc/is_sharp(obj/item/W as obj) // For the record, WHAT THE HELL IS THIS METHOD OF DOING IT? + if(!W) return 0 if(W.sharp) return 1 return ( \ W.sharp || \ @@ -1374,4 +1375,4 @@ var/list/WALLITEMS = list( return 0 /proc/format_text(text) - return replacetext(replacetext(text,"\proper ",""),"\improper ","") \ No newline at end of file + return replacetext(replacetext(text,"\proper ",""),"\improper ","") From 0f538a9b2faae56f86eb630298ba0234cce92bb6 Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Mon, 24 Feb 2014 01:50:44 -0600 Subject: [PATCH 38/65] Typo fix. Screw typechecks and their need for closing parens :*( --- code/modules/reagents/Chemistry-Reagents.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 73c500403f8..8a6f6a74f99 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -935,7 +935,7 @@ datum for(var/mob/living/carbon/slime/M in T) M.adjustToxLoss(rand(5,10)) reaction_turf(var/turf/simulated/S, var/volume) - if(istype(S) + if(istype(S)) if(volume >= 1) S.dirt = 0 From 8a3b99aa6800fb90fe088a3420dea3559d08dbae Mon Sep 17 00:00:00 2001 From: Aryn Date: Sun, 23 Feb 2014 01:40:51 -0700 Subject: [PATCH 39/65] Added lighting code, didn't include it yet. --- .../Aryn/Lighting/Controller.dm | 115 ++++++++++++ code/WorkInProgress/Aryn/Lighting/Engine.dm | 176 ++++++++++++++++++ code/WorkInProgress/Aryn/Lighting/Light.dm | 70 +++++++ .../Aryn/Lighting/Lightpoint.dm | 60 ++++++ code/WorkInProgress/Aryn/Lighting/Math.dm | 22 +++ icons/effects/ArynLights.dmi | Bin 0 -> 81489 bytes 6 files changed, 443 insertions(+) create mode 100644 code/WorkInProgress/Aryn/Lighting/Controller.dm create mode 100644 code/WorkInProgress/Aryn/Lighting/Engine.dm create mode 100644 code/WorkInProgress/Aryn/Lighting/Light.dm create mode 100644 code/WorkInProgress/Aryn/Lighting/Lightpoint.dm create mode 100644 code/WorkInProgress/Aryn/Lighting/Math.dm create mode 100644 icons/effects/ArynLights.dmi diff --git a/code/WorkInProgress/Aryn/Lighting/Controller.dm b/code/WorkInProgress/Aryn/Lighting/Controller.dm new file mode 100644 index 00000000000..aaeb9ce17f8 --- /dev/null +++ b/code/WorkInProgress/Aryn/Lighting/Controller.dm @@ -0,0 +1,115 @@ +/* + +Overview: + Unlike the previous lighting controller, this is mostly here to hold global lighting procs and vars. + It does not process every tick, because not even DAL did something so stupid. + +Global Vars: + initial_lights - This holds all lights formed before the lighting controller started up. It becomes null on initialization. + +Class Vars: + starlight - The light value of space. + + icon_updates - The list of turfs which need an update to their overlays. + + light_border - Space turfs which are adjacent to non-space turfs. + +Class Procs: + Initialize() + Starts the lighting system, creating all light points and turf overlays. + + StarLight(n) + Sets the light produced by space. If a solar eclipse suddenly happens, it'll probably lag. + + MarkIconUpdate(turf/T) + Called when a turf needs an update to its light icon. Ensures that it only gets calculated once per turf. + + FlushIconUpdates() + Called when a light is done marking icon updates. Updates every marked turf. + + AddBorder(turf/T) & RemoveBorder(turf/T) + Called by turf/CheckForOpaqueObjects() to modify the light_border list. + + +*/ + +var/datum/controller/lighting/lighting_controller +var/list/initial_lights = list() +var/all_lightpoints_made = 0 + +/datum/controller/lighting + + var/starlight = 4 + var/list/icon_updates = list() + + var/list/light_border = list() + + //var/icon/border = icon('Icons/Test.dmi', "border") + +/datum/controller/lighting/New() + lighting_controller = src + +/datum/controller/lighting/proc/Initialize() + + var/start_time = world.timeofday + world << "Processing lights..." + + var/turfs_updated = 0 + + for(var/z = 1, z <= world.maxz, z++) + for(var/y = 0, y <= world.maxy, y++) + for(var/x = 0, x <= world.maxx, x++) + if(x > 0 && y > 0) + var/turf/T = locate(x,y,z) + if(!T.light_overlay) + T.light_overlay = new(T) + T.CheckForOpaqueObjects() + turfs_updated++ + if(!all_lightpoints_made) new/lightpoint(x+0.5,y+0.5,z) + + all_lightpoints_made = 1 + + for(var/atom/movable/M in initial_lights) + if(!M.light) + M.SetLight(M.luminosity,M.luminosity) + else + M.light.Reset() + + StarLight(starlight) + initial_lights = null + + world << "Lighting initialization took [(world.timeofday-start_time)/world.fps] seconds." + world << "Updated [turfs_updated] turfs." + +/datum/controller/lighting/proc/StarLight(n) + starlight = n + for(var/turf/T in light_border) + T.SetLight(5,n-1) + + for(var/turf/T) + if(T.is_outside) + T.ResetValue() + + FlushIconUpdates() + +/datum/controller/lighting/proc/MarkIconUpdate(turf/T) + if(!T.needs_light_update) + icon_updates.Add(T) + T.needs_light_update = 1 + +/datum/controller/lighting/proc/FlushIconUpdates() + for(var/turf/T in icon_updates) + T.UpdateLight() + T.needs_light_update = 0 + icon_updates = list() + +/datum/controller/lighting/proc/AddBorder(turf/T) + if(!T.is_border) + light_border.Add(T) + T.is_border = 1 + //T.overlays.Add(border) + +/datum/controller/lighting/proc/RemoveBorder(turf/T) + if(T.is_border) + light_border.Remove(T) + T.is_border = 0 diff --git a/code/WorkInProgress/Aryn/Lighting/Engine.dm b/code/WorkInProgress/Aryn/Lighting/Engine.dm new file mode 100644 index 00000000000..9c7dcfa713e --- /dev/null +++ b/code/WorkInProgress/Aryn/Lighting/Engine.dm @@ -0,0 +1,176 @@ +/* + +Overview: + Procs given to atom and turf by the lighting engine, as well as the lighting overlay object. + +Atom Vars: + light - Contains the light object this atom is currently shining with. + +Turf Vars: + light_overlay - Contains an object showing the lighting icon over this turf. + + lit_value - Stores how brightly lit the turf is. + + has_opaque - A cached value updated by CheckForOpaqueObjects() + + is_outside - Any turf with this set to true will be considered as bright as space. + + needs_light_update - Turf is marked for icon updates when true. + + lightNE, lightSE, lightNW, lightSW - Hold the lightpoints on the four corners of this turf. See Lightpoint.dm + + lit_by - A list of lights that are lighting this turf. + +Atom Procs: + SetLight(intensity, radius) + A more versatile SetLuminosity() that allows independent control of intensity and radius. + Called behind the scenes of SetLuminosity(). + + SetOpacity(opacity) + Does the same thing as DAL. + +Turf Procs: + UpdateLight() + Called by the lighting controller. It is advisable not to call this manually due to the cost of lightpoint/max_value() + + AddLight(light/light) + Called by light/Reset() to light this turf with a particular light. + + RemoveLight(light/light) + Called by light/Off() to unlight turfs that were lit by it. + + ResetValue() + Called when lights are reset or starlight is changed. + + ResetCachedValues() + Resets cached values of all four light points. Called by ResetValue(). + + CheckForOpaqueObjects() + Called by lighting_controller.Initialize(), SetOpacity() or when a turf might change opacity. + Resets the opacity cache and looks for opaque objects. Also responsible for adding and removing borders to space. +*/ + + +#define LIGHTCLAMP(x) ( max(0,min(3,round(x,1))) ) + +obj/effect/lighting_overlay + //anchored = 1 + layer = 9 + mouse_opacity = 0 + icon = 'icons/effects/ArynLights.dmi' + icon_state = "0000" + +atom/var/light/light + +turf/var/obj/effect/lighting_overlay/light_overlay + +turf/var/lit_value = 0 +turf/var/has_opaque = 0 +turf/var/is_outside = 0 +turf/var/is_border = 0 +turf/var/needs_light_update = 0 + +turf/var/lightpoint/lightNE +turf/var/lightpoint/lightNW +turf/var/lightpoint/lightSE +turf/var/lightpoint/lightSW +turf/var/list/lit_by + +atom/New() + . = ..() + if(luminosity || light) + if(!lighting_controller) + initial_lights.Add(src) + else + if(!light) + SetLight(luminosity,luminosity) + else + light.Reset() + if(lighting_controller) + if(opacity) + opacity = 0 + SetOpacity(1) + +atom/movable/Move() + var/o = opacity + if(o) SetOpacity(0) + . = ..() + if(.) + if(o) SetOpacity(1) + if(light) + light.Reset() + lighting_controller.FlushIconUpdates() + +atom/proc/SetLight(intensity, radius) + if(!light) light = new(src) + light.radius = min(radius,15) + light.intensity = intensity + light.Reset() + lighting_controller.FlushIconUpdates() + +atom/proc/SetOpacity(o) + if(o == opacity) return + opacity = o + var/turf/T = loc + if(isturf(T)) + for(var/light/A in T.lit_by) + A.Reset() + lighting_controller.FlushIconUpdates() + +turf/proc/UpdateLight() + if(light_overlay) + light_overlay.icon_state = "[lightSE.max_value()][lightSW.max_value()][lightNW.max_value()][lightNE.max_value()]" + +turf/proc/AddLight(light/light) + if(!lit_by) lit_by = list() + lit_by.Add(light) + if(!has_opaque) + var/brightness = light.CalculateBrightness(src) + if(brightness > lit_value) + lit_value = LIGHTCLAMP(brightness) + ResetCachedValues() + for(var/turf/T in range(1,src)) + lighting_controller.MarkIconUpdate(T) + +turf/proc/RemoveLight(light/light) + lit_by.Remove(light) + ResetValue() + if(!lit_by.len) lit_by = null + +turf/proc/ResetValue() + CheckForOpaqueObjects() + if(has_opaque) + lit_value = 0 + else + var/max_brightness = (is_outside?(lighting_controller.starlight):0) + for(var/light/light in lit_by) + var/brightness = light.CalculateBrightness(src) + if(brightness > max_brightness) + max_brightness = brightness + lit_value = LIGHTCLAMP(max_brightness) + ResetCachedValues() + for(var/turf/T in range(1,src)) + lighting_controller.MarkIconUpdate(T) + +turf/proc/ResetCachedValues() + lightNE.cached_value = -1 + lightNW.cached_value = -1 + lightSE.cached_value = -1 + lightSW.cached_value = -1 + +turf/proc/CheckForOpaqueObjects() + has_opaque = opacity + if(!opacity) + for(var/atom/movable/M in contents) + if(M.opacity) + has_opaque = 1 + break + if(is_outside) + for(var/d = 1, d < 16, d*=2) + var/turf/T = get_step(src,d) + if(T && !T.is_outside) + lighting_controller.AddBorder(src) + return + if(is_border) lighting_controller.RemoveBorder(src) + +#undef LIGHTCLAMP \ No newline at end of file diff --git a/code/WorkInProgress/Aryn/Lighting/Light.dm b/code/WorkInProgress/Aryn/Lighting/Light.dm new file mode 100644 index 00000000000..40cf88120d4 --- /dev/null +++ b/code/WorkInProgress/Aryn/Lighting/Light.dm @@ -0,0 +1,70 @@ +/* + +Overview: + This object functions similarly to /tg/'s /light. It is responsible for calculating what turfs are lit by it. + +Class Vars: + radius - Set by atom/SetLight(). This stores how far out turfs will be lit up. + intensity - Set by atom/SetLight(). Stores the amount of light generated at the center. + lit_turfs - A list of turfs being lit by this light. + atom - The atom this light is attached to. + +Class Procs: + Reset() + This is called whenever the light changes, or the underlying atom changes position. + + Off() + A quick way to turn off a light. Removes the light from all turfs in lit_turfs. + + CalculateBrightness(turf/T) + Returns the brightness that should be displayed by this light on a specific turf. + +*/ + + +light/var/radius = 0 +light/var/intensity = 0 +light/var/list/lit_turfs +light/var/atom/atom + +light/New(atom/atom) + src.atom = atom + +light/proc/Reset() + Off() + + lit_turfs = list() + + if(intensity > 0) + for(var/turf/T in view(atom,radius+1)) + T.AddLight(src) + lit_turfs.Add(T) + +light/proc/Off() + for(var/turf/T in lit_turfs) + T.RemoveLight(src) + +light/proc/CalculateBrightness(turf/T) + var/square = get_square_dist(atom.x,atom.y,atom.z,T.x,T.y,T.z) + if(square > (radius+2)*(radius+2)) return 0 + //+2 offset gives an ambient light effect. + + var/value = ((radius)/(2*fsqrt(square) + 1)) * intensity - 0.48 + /* + lightRadius + ---------------- * lightValue - 0.48 + 2 * distance + 1 + + The light decreases by twice the distance, starting from the radius. + The + 1 causes the graph to shift to the left one unit so that division by zero is prevented on the source tile. + + This is then multiplied by the light value to give the final result. + The -0.48 offset causes the value to be near zero at the radius. + + This gives a result which is likely close to the inverse-square law in two dimensions instead of three. + */ + + + return max(min( value , intensity), 0) //Ensure the value never goes above the maximum light value or below zero. + + //return cos(90 * sqrt(square) / max(1,lightRadius)) * lightValue \ No newline at end of file diff --git a/code/WorkInProgress/Aryn/Lighting/Lightpoint.dm b/code/WorkInProgress/Aryn/Lighting/Lightpoint.dm new file mode 100644 index 00000000000..dfca9db4fd2 --- /dev/null +++ b/code/WorkInProgress/Aryn/Lighting/Lightpoint.dm @@ -0,0 +1,60 @@ +/* + +Overview: + Perhaps the most cryptic datum in the lighting engine, there are four of these at the corners of every turf. + Any two turfs that share a corner will also have the same lightpoint. Because of the nature of the icons used, + light is shown at the corner of the turf rather than in the middle, necessitating some way to keep track of what + icon state to use. + +Class Vars: + x, y, z - The position of the lightpoint. x and y will usually be expressed in terms of 0.5 due to its location on the corner. + + NE, NW, SE, SW - The turfs that are in these directions relative to the lightpoint. + + cached_value - A cached value of max_value(). + +Class Procs: + max_value() + The maximum of the light amounts on the four turfs of this light point. + +*/ + +lightpoint + var/x + var/y + var/z + + var/turf/NE + var/turf/NW + var/turf/SW + var/turf/SE + + var/cached_value = -1 + + New(x,y,z) + var/turf/T = locate(x+0.5,y+0.5,z) + if(T) + NE = T + T.lightSW = src + T = locate(x-0.5,y+0.5,z) + if(T) + NW = T + T.lightSE = src + T = locate(x-0.5,y-0.5,z) + if(T) + SW = T + T.lightNE = src + T = locate(x+0.5,y-0.5,z) + if(T) + SE = T + T.lightNW = src + + proc/max_value() + if(cached_value < 0) + var + valueA = (NW?(NW.lit_value):0) + valueB = (NE?(NE.lit_value):0) + valueC = (SW?(SW.lit_value):0) + valueD = (SE?(SE.lit_value):0) + cached_value = max(valueA,valueB,valueC,valueD) + return cached_value \ No newline at end of file diff --git a/code/WorkInProgress/Aryn/Lighting/Math.dm b/code/WorkInProgress/Aryn/Lighting/Math.dm new file mode 100644 index 00000000000..cd8716373be --- /dev/null +++ b/code/WorkInProgress/Aryn/Lighting/Math.dm @@ -0,0 +1,22 @@ +/* + +Some math procs used by lighting, including ul's fastroot. + +*/ + +var/list/fastroot = list(0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7) + +proc/get_square_dist(Ax,Ay,Az,Bx,By,Bz) + var/X = (Ax - Bx) + var/Y = (Ay - By) + var/Z = (Az - Bz) + return (X * X + Y * Y + Z * Z) + +proc/fsqrt(n) + if (n > fastroot.len) + //world << "Adding [n-fastroot.len] entries to root table." + for(var/i = fastroot.len, i <= n, i++) + fastroot += round(sqrt(i)) + return fastroot[n + 1] \ No newline at end of file diff --git a/icons/effects/ArynLights.dmi b/icons/effects/ArynLights.dmi new file mode 100644 index 0000000000000000000000000000000000000000..f3d21402a33087a25d547faee4dfa8777169777c GIT binary patch literal 81489 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 literal 0 HcmV?d00001 From ca7d4026b83db7214e9e8eb44a72374e4c648987 Mon Sep 17 00:00:00 2001 From: Aryn Date: Sun, 23 Feb 2014 07:50:58 -0700 Subject: [PATCH 40/65] Lighting system is too buggy to continue until I know wtf is going on --- baystation12.dme | 8 +- .../Aryn/Lighting/Compatibility.dm | 41 ++++++++ .../Aryn/Lighting/Controller.dm | 54 ++++++----- code/WorkInProgress/Aryn/Lighting/Engine.dm | 97 ++++++++++++------- code/WorkInProgress/Aryn/Lighting/Light.dm | 5 +- code/ZAS/Zone.dm | 1 + code/controllers/failsafe.dm | 5 +- code/controllers/master_controller.dm | 1 + code/controllers/verbs.dm | 2 +- code/game/area/areas.dm | 6 +- code/game/gamemodes/gameticker.dm | 2 +- code/game/objects/items/blueprints.dm | 3 - code/game/turfs/turf.dm | 17 ++-- code/modules/mob/living/carbon/human/life.dm | 8 +- code/modules/mob/living/carbon/monkey/life.dm | 2 +- code/modules/power/lighting.dm | 4 +- 16 files changed, 163 insertions(+), 93 deletions(-) create mode 100644 code/WorkInProgress/Aryn/Lighting/Compatibility.dm diff --git a/baystation12.dme b/baystation12.dme index d2f2026b508..f61266ba9b6 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -74,13 +74,11 @@ #include "code\ATMOSPHERICS\components\unary\unary_base.dm" #include "code\ATMOSPHERICS\components\unary\vent_pump.dm" #include "code\ATMOSPHERICS\components\unary\vent_scrubber.dm" -#include "code\controllers\_DynamicAreaLighting_TG.dm" #include "code\controllers\autotransfer.dm" #include "code\controllers\configuration.dm" #include "code\controllers\failsafe.dm" #include "code\controllers\hooks-defs.dm" #include "code\controllers\hooks.dm" -#include "code\controllers\lighting_controller.dm" #include "code\controllers\master_controller.dm" #include "code\controllers\shuttle_controller.dm" #include "code\controllers\verbs.dm" @@ -1285,6 +1283,12 @@ #include "code\WorkInProgress\explosion_particles.dm" #include "code\WorkInProgress\periodic_news.dm" #include "code\WorkInProgress\Apples\artifacts.dm" +#include "code\WorkInProgress\Aryn\Lighting\Compatibility.dm" +#include "code\WorkInProgress\Aryn\Lighting\Controller.dm" +#include "code\WorkInProgress\Aryn\Lighting\Engine.dm" +#include "code\WorkInProgress\Aryn\Lighting\Light.dm" +#include "code\WorkInProgress\Aryn\Lighting\Lightpoint.dm" +#include "code\WorkInProgress\Aryn\Lighting\Math.dm" #include "code\WorkInProgress\Cael_Aislinn\Jungle\falsewall.dm" #include "code\WorkInProgress\Cael_Aislinn\Jungle\jungle.dm" #include "code\WorkInProgress\Cael_Aislinn\Jungle\jungle_animals.dm" diff --git a/code/WorkInProgress/Aryn/Lighting/Compatibility.dm b/code/WorkInProgress/Aryn/Lighting/Compatibility.dm new file mode 100644 index 00000000000..e9109bc67f4 --- /dev/null +++ b/code/WorkInProgress/Aryn/Lighting/Compatibility.dm @@ -0,0 +1,41 @@ +area/var/lighting_use_dynamic + +turf/space/is_outside = 1 + +/datum/controller/lighting/var/processing = 1 +/datum/controller/lighting/var/iteration = 0 + +//Because so many objects jump the gun. +proc/lighting_ready() + return lighting_controller && lighting_controller.started + +turf_light_data + var/light_overlay + var/lightNW + var/lightSW + var/lightNE + var/lightSE + var/lit_by + +turf_light_data/proc/copy_from(turf/T) + light_overlay = T.light_overlay + lightNW = T.lightNW + lightSW = T.lightSW + lightNE = T.lightNE + lightSE = T.lightSE + lit_by = T.lit_by + +turf_light_data/proc/copy_to(turf/T) + T.light_overlay = light_overlay + T.lightNW = lightNW + T.lightSW = lightSW + T.lightNE = lightNE + T.lightSE = lightSE + T.lit_by = lit_by + //T.ResetValue() + +atom/proc/SetLuminosity(n) + n = min(n,10) //Caelcode. + SetLight(n>>1,n) + luminosity = n + //else lighting_controller.initial_lights.Add(src) \ No newline at end of file diff --git a/code/WorkInProgress/Aryn/Lighting/Controller.dm b/code/WorkInProgress/Aryn/Lighting/Controller.dm index aaeb9ce17f8..7f93107dd5c 100644 --- a/code/WorkInProgress/Aryn/Lighting/Controller.dm +++ b/code/WorkInProgress/Aryn/Lighting/Controller.dm @@ -34,9 +34,11 @@ Class Procs: */ var/datum/controller/lighting/lighting_controller -var/list/initial_lights = list() + var/all_lightpoints_made = 0 +var/list/lit_z_levels = list(1,5) + /datum/controller/lighting var/starlight = 4 @@ -44,6 +46,8 @@ var/all_lightpoints_made = 0 var/list/light_border = list() + var/started = 0 + //var/icon/border = icon('Icons/Test.dmi', "border") /datum/controller/lighting/New() @@ -51,47 +55,45 @@ var/all_lightpoints_made = 0 /datum/controller/lighting/proc/Initialize() + set background = 1 + var/start_time = world.timeofday world << "Processing lights..." - var/turfs_updated = 0 + sleep(1) - for(var/z = 1, z <= world.maxz, z++) + var/turfs_updated = 0 + var/total_turfs = world.maxx*world.maxy*lit_z_levels.len + + for(var/z in lit_z_levels) for(var/y = 0, y <= world.maxy, y++) for(var/x = 0, x <= world.maxx, x++) if(x > 0 && y > 0) - var/turf/T = locate(x,y,z) - if(!T.light_overlay) - T.light_overlay = new(T) - T.CheckForOpaqueObjects() + turfs_updated++ + if((turfs_updated % 5000) == 0) + sleep(1) + world << "Progress: [round((turfs_updated/total_turfs)*100, 0.01)]% ([turfs_updated]/[total_turfs])" + + var/turf/T = locate(x,y,z) + if(!T.light_overlay && !T.is_outside) + T.light_overlay = new(T) + T.ResetValue() if(!all_lightpoints_made) new/lightpoint(x+0.5,y+0.5,z) + + + //world << "[x],[y],[z]" + all_lightpoints_made = 1 + started = 1 - for(var/atom/movable/M in initial_lights) - if(!M.light) - M.SetLight(M.luminosity,M.luminosity) - else - M.light.Reset() - - StarLight(starlight) - initial_lights = null + for(var/turf/T) + if(!T.is_outside) T.UpdateLight() world << "Lighting initialization took [(world.timeofday-start_time)/world.fps] seconds." world << "Updated [turfs_updated] turfs." -/datum/controller/lighting/proc/StarLight(n) - starlight = n - for(var/turf/T in light_border) - T.SetLight(5,n-1) - - for(var/turf/T) - if(T.is_outside) - T.ResetValue() - - FlushIconUpdates() - /datum/controller/lighting/proc/MarkIconUpdate(turf/T) if(!T.needs_light_update) icon_updates.Add(T) diff --git a/code/WorkInProgress/Aryn/Lighting/Engine.dm b/code/WorkInProgress/Aryn/Lighting/Engine.dm index 9c7dcfa713e..7b3458b29a3 100644 --- a/code/WorkInProgress/Aryn/Lighting/Engine.dm +++ b/code/WorkInProgress/Aryn/Lighting/Engine.dm @@ -65,6 +65,7 @@ atom/var/light/light turf/var/obj/effect/lighting_overlay/light_overlay turf/var/lit_value = 0 +turf/var/max_brightness = 0 turf/var/has_opaque = 0 turf/var/is_outside = 0 turf/var/is_border = 0 @@ -78,16 +79,13 @@ turf/var/list/lit_by atom/New() . = ..() - if(luminosity || light) - if(!lighting_controller) - initial_lights.Add(src) + if(luminosity) + if(!light) + SetLight(luminosity,luminosity) else - if(!light) - SetLight(luminosity,luminosity) - else - light.Reset() - if(lighting_controller) - if(opacity) + light.Reset() + if(opacity) + if(lighting_ready()) opacity = 0 SetOpacity(1) @@ -102,11 +100,18 @@ atom/movable/Move() lighting_controller.FlushIconUpdates() atom/proc/SetLight(intensity, radius) + if(!intensity) + if(!light) return + light.Off() + light = null + if(lighting_ready()) lighting_controller.FlushIconUpdates() + return if(!light) light = new(src) + if(light.intensity == intensity) return light.radius = min(radius,15) light.intensity = intensity light.Reset() - lighting_controller.FlushIconUpdates() + if(lighting_ready()) lighting_controller.FlushIconUpdates() atom/proc/SetOpacity(o) if(o == opacity) return @@ -122,41 +127,72 @@ turf/proc/UpdateLight() light_overlay.icon_state = "[lightSE.max_value()][lightSW.max_value()][lightNW.max_value()][lightNE.max_value()]" turf/proc/AddLight(light/light) + if(is_outside) return + if(has_opaque) return + if(!lit_by) lit_by = list() lit_by.Add(light) - if(!has_opaque) - var/brightness = light.CalculateBrightness(src) - if(brightness > lit_value) + + var/brightness = light.CalculateBrightness(src) + lit_by[light] = brightness + + if(!has_opaque && lighting_ready()) + if(brightness > max_brightness) lit_value = LIGHTCLAMP(brightness) + max_brightness = brightness ResetCachedValues() - for(var/turf/T in range(1,src)) - lighting_controller.MarkIconUpdate(T) + for(var/turf/T in range(1,src)) + lighting_controller.MarkIconUpdate(T) turf/proc/RemoveLight(light/light) - lit_by.Remove(light) - ResetValue() - if(!lit_by.len) lit_by = null + if(has_opaque) return + if(lit_by) + var/brightness = lit_by[light] + lit_by.Remove(light) + if(brightness == max_brightness) + ResetValue() + if(!lit_by.len) lit_by = null turf/proc/ResetValue() + if(is_outside) + max_brightness = lighting_controller.starlight + lit_value = LIGHTCLAMP(lighting_controller.starlight) + return + + var/old_value = lit_value + CheckForOpaqueObjects() if(has_opaque) lit_value = 0 else - var/max_brightness = (is_outside?(lighting_controller.starlight):0) + the_part_where_I_calculate_brightness() + + if(lighting_ready() && lit_value != old_value) + the_part_where_I_use_range() + +turf/proc + the_part_where_I_calculate_brightness() + max_brightness = 0 for(var/light/light in lit_by) - var/brightness = light.CalculateBrightness(src) + var/brightness = lit_by[light]//light.CalculateBrightness(src) if(brightness > max_brightness) max_brightness = brightness lit_value = LIGHTCLAMP(max_brightness) - ResetCachedValues() - for(var/turf/T in range(1,src)) - lighting_controller.MarkIconUpdate(T) + + the_part_where_I_use_range() + ResetCachedValues() + for(var/turf/T in range(1,src)) + lighting_controller.MarkIconUpdate(T) turf/proc/ResetCachedValues() - lightNE.cached_value = -1 - lightNW.cached_value = -1 - lightSE.cached_value = -1 - lightSW.cached_value = -1 + if(lightNE) + lightNE.cached_value = -1 + if(lightNW) + lightNW.cached_value = -1 + if(lightSE) + lightSE.cached_value = -1 + if(lightSW) + lightSW.cached_value = -1 turf/proc/CheckForOpaqueObjects() has_opaque = opacity @@ -165,12 +201,5 @@ turf/proc/CheckForOpaqueObjects() if(M.opacity) has_opaque = 1 break - if(is_outside) - for(var/d = 1, d < 16, d*=2) - var/turf/T = get_step(src,d) - if(T && !T.is_outside) - lighting_controller.AddBorder(src) - return - if(is_border) lighting_controller.RemoveBorder(src) #undef LIGHTCLAMP \ No newline at end of file diff --git a/code/WorkInProgress/Aryn/Lighting/Light.dm b/code/WorkInProgress/Aryn/Lighting/Light.dm index 40cf88120d4..0fd824eca14 100644 --- a/code/WorkInProgress/Aryn/Lighting/Light.dm +++ b/code/WorkInProgress/Aryn/Lighting/Light.dm @@ -37,8 +37,9 @@ light/proc/Reset() if(intensity > 0) for(var/turf/T in view(atom,radius+1)) - T.AddLight(src) - lit_turfs.Add(T) + if(!T.is_outside) + T.AddLight(src) + lit_turfs.Add(T) light/proc/Off() for(var/turf/T in lit_turfs) diff --git a/code/ZAS/Zone.dm b/code/ZAS/Zone.dm index 17d6097cdaf..2d3346ab053 100644 --- a/code/ZAS/Zone.dm +++ b/code/ZAS/Zone.dm @@ -108,6 +108,7 @@ Class Procs: /zone/proc/rebuild() if(invalid) return //Short circuit for explosions where rebuild is called many times over. + if(air_master.current_cycle == 0) return //Why would you rebuild when you're building? c_invalidate() for(var/turf/simulated/T in contents) //T.dbg(invalid_zone) diff --git a/code/controllers/failsafe.dm b/code/controllers/failsafe.dm index 91449e10c89..bfc0b08fd96 100644 --- a/code/controllers/failsafe.dm +++ b/code/controllers/failsafe.dm @@ -45,7 +45,8 @@ var/datum/controller/failsafe/Failsafe MC_defcon = 0 MC_iteration = controller_iteration - if(lighting_controller.processing) + //Lighting controller now neither processes nor iterates. + /*if(lighting_controller.processing) if(lighting_iteration == lighting_controller.iteration) //master_controller hasn't finished processing in the defined interval switch(lighting_defcon) if(0 to 3) @@ -60,7 +61,7 @@ var/datum/controller/failsafe/Failsafe lighting_defcon = 0 else lighting_defcon = 0 - lighting_iteration = lighting_controller.iteration + lighting_iteration = lighting_controller.iteration*/ else MC_defcon = 0 lighting_defcon = 0 diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index e0bd38086aa..e5970e40fbc 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -77,6 +77,7 @@ datum/controller/game_controller/proc/setup() if(ticker) ticker.pregame() + new/datum/controller/lighting() lighting_controller.Initialize() diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index 3faa6e4c809..ace54c03a70 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -19,7 +19,7 @@ feedback_add_details("admin_verb","RFailsafe") if("Lighting") new /datum/controller/lighting() - lighting_controller.process() + //lighting_controller.process() feedback_add_details("admin_verb","RLighting") if("Supply Shuttle") supply_shuttle.process() diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index f69b2a35e3f..9161ac9570d 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -24,20 +24,16 @@ // lighting_state = 4 //has_gravity = 0 // Space has gravity. Because.. because. - if(requires_power) - luminosity = 0 - else + if(!requires_power) 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) diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index 371db0de19e..f0361f2245c 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -148,7 +148,7 @@ var/global/datum/controller/gameticker/ticker supply_shuttle.process() //Start the supply shuttle regenerating points -- TLE master_controller.process() //Start master_controller.process() - lighting_controller.process() //Start processing DynamicAreaLighting updates + //lighting_controller.process() //Start processing DynamicAreaLighting updates for(var/obj/multiz/ladder/L in world) L.connect() //Lazy hackfix for ladders. TODO: move this to an actual controller. ~ Z diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm index 5c5b1b6fd81..92ed4e92447 100644 --- a/code/game/objects/items/blueprints.dm +++ b/code/game/objects/items/blueprints.dm @@ -133,9 +133,6 @@ move an amendment to the drawing.

move_turfs_to_area(turfs, A) A.always_unpowered = 0 - for(var/turf/T in A.contents) - T.lighting_changed = 1 - lighting_controller.changed_turfs += T spawn(5) //ma = A.master ? "[A.master]" : "(null)" diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 57e9aab94cb..04aa40318cf 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -195,6 +195,8 @@ if(L) del L +var/turf_light_data/old_lights = new + //Creates a new turf /turf/proc/ChangeTurf(var/turf/N) if (!N) @@ -214,10 +216,10 @@ return W ///// Z-Level Stuff - var/old_lumcount = lighting_lumcount - initial(lighting_lumcount) - //world << "Replacing [src.type] with [N]" + old_lights.copy_from(src) + if(connections) connections.erase_all() if(istype(src,/turf/simulated)) @@ -238,10 +240,7 @@ var/turf/simulated/W = new N( locate(src.x, src.y, src.z) ) //W.Assimilate_Air() - W.lighting_lumcount += old_lumcount - if(old_lumcount != W.lighting_lumcount) - W.lighting_changed = 1 - lighting_controller.changed_turfs += W + old_lights.copy_to(W) if (istype(W,/turf/simulated/floor)) W.RemoveLattice() @@ -259,10 +258,8 @@ // zone.SetStatus(ZONE_ACTIVE) var/turf/W = new N( locate(src.x, src.y, src.z) ) - W.lighting_lumcount += old_lumcount - if(old_lumcount != W.lighting_lumcount) - W.lighting_changed = 1 - lighting_controller.changed_turfs += W + + old_lights.copy_to(W) if(air_master) air_master.mark_for_update(src) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index a9680785f6a..26fa2378e62 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -897,7 +897,7 @@ var/turf/T = loc var/area/A = T.loc if(A) - if(A.lighting_use_dynamic) light_amount = min(10,T.lighting_lumcount) - 5 //hardcapped so it's not abused by having a ton of flashlights + if(A.lighting_use_dynamic) light_amount = min(10,T.lit_value) - 5 //hardcapped so it's not abused by having a ton of flashlights else light_amount = 5 nutrition += light_amount traumatic_shock -= light_amount @@ -917,7 +917,7 @@ var/turf/T = loc var/area/A = T.loc if(A) - if(A.lighting_use_dynamic) light_amount = T.lighting_lumcount + if(A.lighting_use_dynamic) light_amount = T.lit_value else light_amount = 10 if(light_amount > 2) //if there's enough light, start dying take_overall_damage(1,1) @@ -1072,7 +1072,7 @@ E = get_visible_implants(0) if(!E.len) embedded_flag = 0 - + //Eyes if(sdisabilities & BLIND) //disabled-blind, doesn't get better on its own @@ -1393,7 +1393,7 @@ //0.1% chance of playing a scary sound to someone who's in complete darkness if(isturf(loc) && rand(1,1000) == 1) var/turf/currentTurf = loc - if(!currentTurf.lighting_lumcount) + if(!currentTurf.lit_value) playsound_local(src,pick(scarySounds),50, 1, -1) proc/handle_virus_updates() diff --git a/code/modules/mob/living/carbon/monkey/life.dm b/code/modules/mob/living/carbon/monkey/life.dm index 4ec4d413062..30cd98d4441 100644 --- a/code/modules/mob/living/carbon/monkey/life.dm +++ b/code/modules/mob/living/carbon/monkey/life.dm @@ -446,7 +446,7 @@ var/turf/T = loc var/area/A = T.loc if(A) - if(A.lighting_use_dynamic) light_amount = min(10,T.lighting_lumcount) - 5 //hardcapped so it's not abused by having a ton of flashlights + if(A.lighting_use_dynamic) light_amount = min(10,T.lit_value) - 5 //hardcapped so it's not abused by having a ton of flashlights else light_amount = 5 nutrition += light_amount diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 0a3a4d37943..76f486e4c4d 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -604,8 +604,8 @@ #define LIGHTING_POWER_FACTOR 20 //20W per unit luminosity /obj/machinery/light/process()//TODO: remove/add this from machines to save on processing as needed ~Carn PRIORITY - if(on) - use_power(luminosity * LIGHTING_POWER_FACTOR, LIGHT) + if(on && light) + use_power(light.radius * LIGHTING_POWER_FACTOR, LIGHT) // called when area power state changes /obj/machinery/light/power_change() From 7f4c4715e73fd46f9d4c0be4e9ce06a2ba28da98 Mon Sep 17 00:00:00 2001 From: Aryn Date: Sun, 23 Feb 2014 22:51:47 -0700 Subject: [PATCH 41/65] Lighting seems to be working now. --- .../Aryn/Lighting/Compatibility.dm | 6 +++- .../Aryn/Lighting/Controller.dm | 4 ++- code/WorkInProgress/Aryn/Lighting/Engine.dm | 31 ++++++++++------- code/WorkInProgress/Aryn/Lighting/Light.dm | 10 +++--- code/WorkInProgress/Aryn/Lighting/Verbs.dm | 33 +++++++++++++++++++ code/game/turfs/turf.dm | 8 +++++ code/modules/power/lighting.dm | 2 +- 7 files changed, 75 insertions(+), 19 deletions(-) create mode 100644 code/WorkInProgress/Aryn/Lighting/Verbs.dm diff --git a/code/WorkInProgress/Aryn/Lighting/Compatibility.dm b/code/WorkInProgress/Aryn/Lighting/Compatibility.dm index e9109bc67f4..9c98f5f6c9c 100644 --- a/code/WorkInProgress/Aryn/Lighting/Compatibility.dm +++ b/code/WorkInProgress/Aryn/Lighting/Compatibility.dm @@ -1,6 +1,7 @@ area/var/lighting_use_dynamic turf/space/is_outside = 1 +turf/simulated/shuttle/is_outside = 1 /datum/controller/lighting/var/processing = 1 /datum/controller/lighting/var/iteration = 0 @@ -36,6 +37,9 @@ turf_light_data/proc/copy_to(turf/T) atom/proc/SetLuminosity(n) n = min(n,10) //Caelcode. - SetLight(n>>1,n) + if(n > 0) + SetLight(max(1,n>>1),n) + else + SetLight(0,0) luminosity = n //else lighting_controller.initial_lights.Add(src) \ No newline at end of file diff --git a/code/WorkInProgress/Aryn/Lighting/Controller.dm b/code/WorkInProgress/Aryn/Lighting/Controller.dm index 7f93107dd5c..da2c32128cc 100644 --- a/code/WorkInProgress/Aryn/Lighting/Controller.dm +++ b/code/WorkInProgress/Aryn/Lighting/Controller.dm @@ -89,7 +89,9 @@ var/list/lit_z_levels = list(1,5) started = 1 for(var/turf/T) - if(!T.is_outside) T.UpdateLight() + if(!T.is_outside) + if(!T.lit_value) T.ResetValue() + T.UpdateLight() world << "Lighting initialization took [(world.timeofday-start_time)/world.fps] seconds." world << "Updated [turfs_updated] turfs." diff --git a/code/WorkInProgress/Aryn/Lighting/Engine.dm b/code/WorkInProgress/Aryn/Lighting/Engine.dm index 7b3458b29a3..53033235727 100644 --- a/code/WorkInProgress/Aryn/Lighting/Engine.dm +++ b/code/WorkInProgress/Aryn/Lighting/Engine.dm @@ -77,7 +77,7 @@ turf/var/lightpoint/lightSE turf/var/lightpoint/lightSW turf/var/list/lit_by -atom/New() +atom/movable/New() . = ..() if(luminosity) if(!light) @@ -97,17 +97,25 @@ atom/movable/Move() if(o) SetOpacity(1) if(light) light.Reset() - lighting_controller.FlushIconUpdates() + if(lighting_ready()) lighting_controller.FlushIconUpdates() atom/proc/SetLight(intensity, radius) + if(lights_verbose) world << "SetLight([intensity],[radius])" if(!intensity) - if(!light) return + if(!light || !light.intensity) + if(lights_verbose) world << "Still off." + return + if(lights_verbose) world << "Shut off light with [light.lit_turfs.len] turfs lit." light.Off() - light = null + light.intensity = 0 if(lighting_ready()) lighting_controller.FlushIconUpdates() return - if(!light) light = new(src) - if(light.intensity == intensity) return + if(!light) + if(lights_verbose) world << "New light." + light = new(src) + if(light.intensity == intensity) + if(lights_verbose) world << "Same intensity." + return light.radius = min(radius,15) light.intensity = intensity light.Reset() @@ -128,12 +136,14 @@ turf/proc/UpdateLight() turf/proc/AddLight(light/light) if(is_outside) return - if(has_opaque) return + + var/brightness = light.CalculateBrightness(src) + if(brightness <= 0) return if(!lit_by) lit_by = list() lit_by.Add(light) - var/brightness = light.CalculateBrightness(src) + lit_by[light] = brightness if(!has_opaque && lighting_ready()) @@ -145,7 +155,6 @@ turf/proc/AddLight(light/light) lighting_controller.MarkIconUpdate(T) turf/proc/RemoveLight(light/light) - if(has_opaque) return if(lit_by) var/brightness = lit_by[light] lit_by.Remove(light) @@ -159,15 +168,13 @@ turf/proc/ResetValue() lit_value = LIGHTCLAMP(lighting_controller.starlight) return - var/old_value = lit_value - CheckForOpaqueObjects() if(has_opaque) lit_value = 0 else the_part_where_I_calculate_brightness() - if(lighting_ready() && lit_value != old_value) + if(lighting_ready()) the_part_where_I_use_range() turf/proc diff --git a/code/WorkInProgress/Aryn/Lighting/Light.dm b/code/WorkInProgress/Aryn/Lighting/Light.dm index 0fd824eca14..9e6113169a6 100644 --- a/code/WorkInProgress/Aryn/Lighting/Light.dm +++ b/code/WorkInProgress/Aryn/Lighting/Light.dm @@ -31,19 +31,21 @@ light/New(atom/atom) src.atom = atom light/proc/Reset() + if(atom.lights_verbose) world << "light.Reset()" Off() - - lit_turfs = list() - if(intensity > 0) - for(var/turf/T in view(atom,radius+1)) + if(atom.lights_verbose) world << "Restoring light." + for(var/turf/T in view(get_turf(atom),radius+1)) if(!T.is_outside) T.AddLight(src) lit_turfs.Add(T) + if(atom.lights_verbose) world << "[lit_turfs.len] turfs added." light/proc/Off() + if(atom.lights_verbose) world << "light.Off()" for(var/turf/T in lit_turfs) T.RemoveLight(src) + lit_turfs = list() light/proc/CalculateBrightness(turf/T) var/square = get_square_dist(atom.x,atom.y,atom.z,T.x,T.y,T.z) diff --git a/code/WorkInProgress/Aryn/Lighting/Verbs.dm b/code/WorkInProgress/Aryn/Lighting/Verbs.dm new file mode 100644 index 00000000000..bf1b40f1ba1 --- /dev/null +++ b/code/WorkInProgress/Aryn/Lighting/Verbs.dm @@ -0,0 +1,33 @@ +var/icon/lighting_dbg = icon('icons/Testing/Zone.dmi', "created") + +atom/var/lights_verbose = 0 + +obj/machinery/light/verb/ShowInfluence() + set src in world + + lights_verbose = 1 + usr << "[src]" + if(light) + usr << "Intensity: [light.intensity]" + usr << "Radius: [light.radius]" + + for(var/turf/T in light.lit_turfs) + T.overlays += lighting_dbg + spawn(50) + for(var/turf/T in light.lit_turfs) + T.overlays -= lighting_dbg + +turf/verb/ShowData() + set src in world + + usr << "[src]" + usr << "Lit Value: [lit_value]" + usr << "Max Brightness: [max_brightness]" + + usr << "Lit By: " + for(var/light/light in lit_by) + usr << " - [light.atom] \[[lit_by[light]]\][(lit_by[light] == max_brightness ? "(MAX)" : "")]" + light.atom.overlays += lighting_dbg + spawn(50) + for(var/light/light in lit_by) + light.atom.overlays -= lighting_dbg \ No newline at end of file diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 04aa40318cf..5747bfdcfd2 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -218,6 +218,8 @@ var/turf_light_data/old_lights = new //world << "Replacing [src.type] with [N]" + var/old_opacity = opacity + old_lights.copy_from(src) if(connections) connections.erase_all() @@ -241,6 +243,11 @@ var/turf_light_data/old_lights = new //W.Assimilate_Air() old_lights.copy_to(W) + W.ResetValue() + + if(old_opacity) + W.opacity = 1 + W.SetOpacity(0) if (istype(W,/turf/simulated/floor)) W.RemoveLattice() @@ -260,6 +267,7 @@ var/turf_light_data/old_lights = new var/turf/W = new N( locate(src.x, src.y, src.z) ) old_lights.copy_to(W) + W.ResetValue() if(air_master) air_master.mark_for_update(src) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 76f486e4c4d..076a1b28e89 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -605,7 +605,7 @@ /obj/machinery/light/process()//TODO: remove/add this from machines to save on processing as needed ~Carn PRIORITY if(on && light) - use_power(light.radius * LIGHTING_POWER_FACTOR, LIGHT) + use_power(luminosity * LIGHTING_POWER_FACTOR, LIGHT) // called when area power state changes /obj/machinery/light/power_change() From 3c2e65cf5d64b1999e06aac980b7c0c21f612490 Mon Sep 17 00:00:00 2001 From: Aryn Date: Mon, 24 Feb 2014 03:35:07 -0700 Subject: [PATCH 42/65] Lighting code complete. --- code/WorkInProgress/Aryn/Lighting/Controller.dm | 2 +- code/WorkInProgress/Aryn/Lighting/Engine.dm | 10 +++++----- code/WorkInProgress/Aryn/Lighting/Light.dm | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/code/WorkInProgress/Aryn/Lighting/Controller.dm b/code/WorkInProgress/Aryn/Lighting/Controller.dm index da2c32128cc..92085eb9c39 100644 --- a/code/WorkInProgress/Aryn/Lighting/Controller.dm +++ b/code/WorkInProgress/Aryn/Lighting/Controller.dm @@ -71,7 +71,7 @@ var/list/lit_z_levels = list(1,5) if(x > 0 && y > 0) turfs_updated++ - if((turfs_updated % 5000) == 0) + if((turfs_updated % (total_turfs>>2)) == 0) sleep(1) world << "Progress: [round((turfs_updated/total_turfs)*100, 0.01)]% ([turfs_updated]/[total_turfs])" diff --git a/code/WorkInProgress/Aryn/Lighting/Engine.dm b/code/WorkInProgress/Aryn/Lighting/Engine.dm index 53033235727..498e84aa4fd 100644 --- a/code/WorkInProgress/Aryn/Lighting/Engine.dm +++ b/code/WorkInProgress/Aryn/Lighting/Engine.dm @@ -100,21 +100,21 @@ atom/movable/Move() if(lighting_ready()) lighting_controller.FlushIconUpdates() atom/proc/SetLight(intensity, radius) - if(lights_verbose) world << "SetLight([intensity],[radius])" + //if(lights_verbose) world << "SetLight([intensity],[radius])" if(!intensity) if(!light || !light.intensity) - if(lights_verbose) world << "Still off." + //if(lights_verbose) world << "Still off." return - if(lights_verbose) world << "Shut off light with [light.lit_turfs.len] turfs lit." + //if(lights_verbose) world << "Shut off light with [light.lit_turfs.len] turfs lit." light.Off() light.intensity = 0 if(lighting_ready()) lighting_controller.FlushIconUpdates() return if(!light) - if(lights_verbose) world << "New light." + //if(lights_verbose) world << "New light." light = new(src) if(light.intensity == intensity) - if(lights_verbose) world << "Same intensity." + //if(lights_verbose) world << "Same intensity." return light.radius = min(radius,15) light.intensity = intensity diff --git a/code/WorkInProgress/Aryn/Lighting/Light.dm b/code/WorkInProgress/Aryn/Lighting/Light.dm index 9e6113169a6..28eb733a271 100644 --- a/code/WorkInProgress/Aryn/Lighting/Light.dm +++ b/code/WorkInProgress/Aryn/Lighting/Light.dm @@ -31,18 +31,18 @@ light/New(atom/atom) src.atom = atom light/proc/Reset() - if(atom.lights_verbose) world << "light.Reset()" + //if(atom.lights_verbose) world << "light.Reset()" Off() if(intensity > 0) - if(atom.lights_verbose) world << "Restoring light." + //if(atom.lights_verbose) world << "Restoring light." for(var/turf/T in view(get_turf(atom),radius+1)) if(!T.is_outside) T.AddLight(src) lit_turfs.Add(T) - if(atom.lights_verbose) world << "[lit_turfs.len] turfs added." + //if(atom.lights_verbose) world << "[lit_turfs.len] turfs added." light/proc/Off() - if(atom.lights_verbose) world << "light.Off()" + //if(atom.lights_verbose) world << "light.Off()" for(var/turf/T in lit_turfs) T.RemoveLight(src) lit_turfs = list() From e32066cd3f05de3cc0174513db7dd646c5301fa9 Mon Sep 17 00:00:00 2001 From: Aryn Date: Mon, 24 Feb 2014 05:54:06 -0700 Subject: [PATCH 43/65] Modified the way lighting initializes to fix light glitches in engineering. --- code/WorkInProgress/Aryn/Lighting/Controller.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/WorkInProgress/Aryn/Lighting/Controller.dm b/code/WorkInProgress/Aryn/Lighting/Controller.dm index 92085eb9c39..5c668d62c7b 100644 --- a/code/WorkInProgress/Aryn/Lighting/Controller.dm +++ b/code/WorkInProgress/Aryn/Lighting/Controller.dm @@ -78,7 +78,7 @@ var/list/lit_z_levels = list(1,5) var/turf/T = locate(x,y,z) if(!T.light_overlay && !T.is_outside) T.light_overlay = new(T) - T.ResetValue() + //T.ResetValue() if(!all_lightpoints_made) new/lightpoint(x+0.5,y+0.5,z) @@ -89,8 +89,8 @@ var/list/lit_z_levels = list(1,5) started = 1 for(var/turf/T) - if(!T.is_outside) - if(!T.lit_value) T.ResetValue() + if(T.light_overlay) + T.ResetValue() T.UpdateLight() world << "Lighting initialization took [(world.timeofday-start_time)/world.fps] seconds." From 130f58a41c26d34b7a1cbb3d61ecd99fb08292eb Mon Sep 17 00:00:00 2001 From: Aryn Date: Mon, 24 Feb 2014 06:39:50 -0700 Subject: [PATCH 44/65] ChangeTurf()... We meet again... --- code/WorkInProgress/Aryn/Lighting/Engine.dm | 5 +++++ code/game/turfs/turf.dm | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/code/WorkInProgress/Aryn/Lighting/Engine.dm b/code/WorkInProgress/Aryn/Lighting/Engine.dm index 498e84aa4fd..5092f726bf5 100644 --- a/code/WorkInProgress/Aryn/Lighting/Engine.dm +++ b/code/WorkInProgress/Aryn/Lighting/Engine.dm @@ -162,6 +162,11 @@ turf/proc/RemoveLight(light/light) ResetValue() if(!lit_by.len) lit_by = null +//Only called by ChangeTurf, because it really needs it. +turf/proc/ResetAllLights() + for(var/light/light in lit_by) + light.Reset() + turf/proc/ResetValue() if(is_outside) max_brightness = lighting_controller.starlight diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 5747bfdcfd2..1302f65bdbe 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -243,7 +243,7 @@ var/turf_light_data/old_lights = new //W.Assimilate_Air() old_lights.copy_to(W) - W.ResetValue() + W.ResetAllLights() if(old_opacity) W.opacity = 1 @@ -267,7 +267,7 @@ var/turf_light_data/old_lights = new var/turf/W = new N( locate(src.x, src.y, src.z) ) old_lights.copy_to(W) - W.ResetValue() + W.ResetAllLights() if(air_master) air_master.mark_for_update(src) From 1ae892d732c774d1df02454c77f91f0e58797165 Mon Sep 17 00:00:00 2001 From: Aryn Date: Mon, 24 Feb 2014 06:43:07 -0700 Subject: [PATCH 45/65] Updated the changelog. --- html/changelog.html | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/html/changelog.html b/html/changelog.html index 4ae2b5a0a25..865faf12fe8 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,14 @@ should be listed in the changelog upon commit though. Thanks. --> +
+

24 February 2014

+

Aryn updated:

+
    +
  • New lighting system! Credit goes to Forum_account for the code that generated the icons it uses.
  • +
+
+

19 February 2014

Aryn updated:

From 9f92792d7476d96ec435db12ed82d8c0ec01960e Mon Sep 17 00:00:00 2001 From: Aryn Date: Mon, 24 Feb 2014 07:12:40 -0700 Subject: [PATCH 46/65] Fixed ghosts' lighting toggle. Mesons still look weird. --- code/WorkInProgress/Aryn/Lighting/Engine.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/WorkInProgress/Aryn/Lighting/Engine.dm b/code/WorkInProgress/Aryn/Lighting/Engine.dm index 5092f726bf5..82a4324ba8f 100644 --- a/code/WorkInProgress/Aryn/Lighting/Engine.dm +++ b/code/WorkInProgress/Aryn/Lighting/Engine.dm @@ -59,6 +59,7 @@ obj/effect/lighting_overlay mouse_opacity = 0 icon = 'icons/effects/ArynLights.dmi' icon_state = "0000" + invisibility = INVISIBILITY_LIGHTING atom/var/light/light From 84f02ae47c1ea01d49b872e446ca78bc87bcacfd Mon Sep 17 00:00:00 2001 From: Aryn Date: Mon, 24 Feb 2014 07:55:36 -0700 Subject: [PATCH 47/65] Reverted unrelated ZAS modification and unnecessary check. --- code/ZAS/Zone.dm | 1 - code/modules/power/lighting.dm | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/code/ZAS/Zone.dm b/code/ZAS/Zone.dm index 2d3346ab053..17d6097cdaf 100644 --- a/code/ZAS/Zone.dm +++ b/code/ZAS/Zone.dm @@ -108,7 +108,6 @@ Class Procs: /zone/proc/rebuild() if(invalid) return //Short circuit for explosions where rebuild is called many times over. - if(air_master.current_cycle == 0) return //Why would you rebuild when you're building? c_invalidate() for(var/turf/simulated/T in contents) //T.dbg(invalid_zone) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 076a1b28e89..0a3a4d37943 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -604,7 +604,7 @@ #define LIGHTING_POWER_FACTOR 20 //20W per unit luminosity /obj/machinery/light/process()//TODO: remove/add this from machines to save on processing as needed ~Carn PRIORITY - if(on && light) + if(on) use_power(luminosity * LIGHTING_POWER_FACTOR, LIGHT) // called when area power state changes From fa2061a249dd783698e963a2797ce371d5341f26 Mon Sep 17 00:00:00 2001 From: Mloc Date: Tue, 25 Feb 2014 00:11:07 +0000 Subject: [PATCH 48/65] Fix for ban queries. --- code/modules/admin/IsBanned.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index 178384f5f6c..4f0c356dc57 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -51,7 +51,7 @@ world/IsBanned(key,address,computer_id) failedcid = 0 cidquery = " OR computerid = '[computer_id]' " - var/DBQuery/query = dbcon.NewQuery("SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM erro_Ban WHERE (ckey = '[ckeytext]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)") + var/DBQuery/query = dbcon.NewQuery("SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype FROM erro_ban WHERE (ckey = '[ckeytext]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR (bantype = 'TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)") query.Execute() From bd5585052c67e0adc9f6e905d79860d460d45ea8 Mon Sep 17 00:00:00 2001 From: Segrain Date: Tue, 25 Feb 2014 03:33:18 +0300 Subject: [PATCH 49/65] Fix for #4479. --- code/modules/reagents/Chemistry-Recipes.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index c06117a08bb..63ab84432f2 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -485,7 +485,7 @@ datum name = "Potassium Chlorophoride" id = "potassium_chlorophoride" result = "potassium_chlorophoride" - required_reagents = list("potassium_chloride" = 1, "plasma" = 1, "chloral_hydrate" = 1) + required_reagents = list("potassium_chloride" = 1, "plasma" = 1, "chloralhydrate" = 1) result_amount = 4 stoxin From e098746209559582d846eac5cf24a18e75cea63f Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Tue, 25 Feb 2014 00:20:44 -0600 Subject: [PATCH 50/65] Runtime fix: RP_Revolution's auto_add_rev_head loves that null. runtime error: Cannot read null.client proc name: process (/datum/game_mode/revolution/rp_revolution/process) source file: rp_revolution.dm,198 runtime error: Cannot read null.client proc name: process (/datum/game_mode/revolution/rp_revolution/process) source file: rp_revolution.dm,198 runtime error: Cannot read null.client proc name: process (/datum/game_mode/revolution/rp_revolution/process) source file: rp_revolution.dm,198 runtime error: Cannot read null.client proc name: process (/datum/game_mode/revolution/rp_revolution/process) source file: rp_revolution.dm,198 runtime error: Cannot read null.client proc name: process (/datum/game_mode/revolution/rp_revolution/process) source file: rp_revolution.dm,198 runtime error: Cannot read null.client proc name: process (/datum/game_mode/revolution/rp_revolution/process) source file: rp_revolution.dm,198 --- code/game/gamemodes/revolution/rp_revolution.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/revolution/rp_revolution.dm b/code/game/gamemodes/revolution/rp_revolution.dm index 98f97cf4600..f9a3e9f2c27 100644 --- a/code/game/gamemodes/revolution/rp_revolution.dm +++ b/code/game/gamemodes/revolution/rp_revolution.dm @@ -195,7 +195,7 @@ tried_to_add_revheads = world.time+50 var/active_revs = 0 for(var/datum/mind/rev_mind in head_revolutionaries) - if(rev_mind.current.client && rev_mind.current.client.inactivity <= 10*60*20) // 20 minutes inactivity are OK + if(rev_mind.current && rev_mind.current.client && rev_mind.current.client.inactivity <= 10*60*20) // 20 minutes inactivity are OK active_revs++ if(active_revs == 0) From ceb220f7055dea16a5253b1068467a54fa13d52d Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Tue, 25 Feb 2014 00:21:41 -0600 Subject: [PATCH 51/65] Runtime fix: OH GOD NOT THE BEEs WON'T SOMEONE CALM THEM DOWN? Other then NULL? runtime error: Cannot read null.type proc name: Life (/mob/living/simple_animal/bee/Life) source file: bees.dm,91 runtime error: Cannot read null.type proc name: Life (/mob/living/simple_animal/bee/Life) source file: bees.dm,91 runtime error: Cannot read null.type proc name: Life (/mob/living/simple_animal/bee/Life) source file: bees.dm,91 runtime error: Cannot read null.type proc name: Life (/mob/living/simple_animal/bee/Life) source file: bees.dm,91 runtime error: Cannot read null.type proc name: Life (/mob/living/simple_animal/bee/Life) source file: bees.dm,91 runtime error: Cannot read null.type proc name: Life (/mob/living/simple_animal/bee/Life) source file: bees.dm,91 runtime error: Cannot read null.type proc name: Life (/mob/living/simple_animal/bee/Life) source file: bees.dm,91 runtime error: Cannot read null.type proc name: Life (/mob/living/simple_animal/bee/Life) source file: bees.dm,91 --- code/modules/mob/living/simple_animal/bees.dm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/living/simple_animal/bees.dm b/code/modules/mob/living/simple_animal/bees.dm index e78e818eccd..1fa531070c2 100644 --- a/code/modules/mob/living/simple_animal/bees.dm +++ b/code/modules/mob/living/simple_animal/bees.dm @@ -88,9 +88,10 @@ for(var/this_type in calmers) var/mob/living/simple_animal/check_effect = locate() in src.loc - if(check_effect.type == this_type) - calming = 1 - break + if(istype(check_effect)) + if(check_effect.type == this_type) + calming = 1 + break if(calming) if(feral > 0) From 3ab7e8438a2aa07335f34be7b2913ce437d7ca2e Mon Sep 17 00:00:00 2001 From: Ccomp5950 Date: Tue, 25 Feb 2014 00:28:00 -0600 Subject: [PATCH 52/65] Runtime fix: Sparks trying to delete that which does not exist. runtime error: Cannot execute null.delete(). proc name: start (/datum/effect/effect/system/spark_spread/start) source file: effect_system.dm,204 usr: Mark Hoover (/mob/living/carbon/human) src: /datum/effect/effect/system/sp... (/datum/effect/effect/system/spark_spread) call stack: /datum/effect/effect/system/sp... (/datum/effect/effect/system/spark_spread): start() runtime error: Cannot execute null.delete(). proc name: start (/datum/effect/effect/system/spark_spread/start) source file: effect_system.dm,204 usr: Mark Hoover (/mob/living/carbon/human) src: /datum/effect/effect/system/sp... (/datum/effect/effect/system/spark_spread) call stack: /datum/effect/effect/system/sp... (/datum/effect/effect/system/spark_spread): start() --- code/game/objects/effects/effect_system.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index 8d2d69a654f..09600d09ed6 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -201,7 +201,8 @@ steam.start() -- spawns the effect sleep(5) step(sparks,direction) spawn(20) - sparks.delete() + if(sparks) + sparks.delete() src.total_sparks-- From 72eba68bd8dfbd9429bcad57aaf1d9ad000e74dd Mon Sep 17 00:00:00 2001 From: ZekeSulastin Date: Mon, 24 Feb 2014 17:37:19 -0500 Subject: [PATCH 53/65] Added laser scalpel items --- .../objects/items/weapons/surgery_tools.dm | 31 +++++++++++++++++- icons/obj/surgery.dmi | Bin 8407 -> 10466 bytes 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm index 7af5304887b..4bd89f7d43b 100644 --- a/code/game/objects/items/weapons/surgery_tools.dm +++ b/code/game/objects/items/weapons/surgery_tools.dm @@ -620,6 +620,35 @@ LOOK FOR SURGERY.DM*/ return */ +/* + * Researchable Scalpels + */ +/obj/item/weapon/scalpel/laser1 + name = "laser scalpel" + desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks basic and could be improved." + icon_state = "scalpel_laser1_on" + damtype = "fire" + +/obj/item/weapon/scalpel/laser2 + name = "laser scalpel" + desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks somewhat advanced." + icon_state = "scalpel_laser2_on" + damtype = "fire" + force = 12.0 + +/obj/item/weapon/scalpel/laser3 + name = "laser scalpel" + desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks to be the pinnacle of precision energy cutlery!" + icon_state = "scalpel_laser3_on" + damtype = "fire" + force = 15.0 + +/obj/item/weapon/scalpel/manager + name = "incision management system" + desc = "A true extension of the surgeon's body, this marvel instantly and completely prepares an incision allowing for the immediate commencement of therapeutic steps." + icon_state = "scalpel_manager_on" + force = 7.5 + /* * Circular Saw */ @@ -819,4 +848,4 @@ LOOK FOR SURGERY.DM*/ throw_speed = 3 throw_range = 5 w_class = 2.0 - attack_verb = list("attacked", "hit", "bludgeoned") \ No newline at end of file + attack_verb = list("attacked", "hit", "bludgeoned") diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index c39b4a6214eb3ee179a86560d19de6ac793c8fce..a5c7e0c7cdded57a409504f7390a1cb3adc6af7a 100644 GIT binary patch literal 10466 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 From f5ab084eaccce49ea0bfc1f5c866944300063b16 Mon Sep 17 00:00:00 2001 From: Mloc-Argent Date: Tue, 25 Feb 2014 20:36:46 +0000 Subject: [PATCH 54/65] Fixes admin attack logs to show up in-game as well as in the logfiles. Signed-off-by: Mloc-Argent --- code/_onclick/item_attack.dm | 2 +- code/game/machinery/kitchen/gibber.dm | 2 +- code/game/objects/items/weapons/gift_wrappaper.dm | 2 +- code/game/objects/items/weapons/handcuffs.dm | 2 +- code/game/objects/items/weapons/stunbaton.dm | 4 ++-- code/game/objects/items/weapons/swords_axes_etc.dm | 2 +- code/modules/mob/living/carbon/human/human_attackhand.dm | 4 ++-- code/modules/mob/mob_grab.dm | 4 ++-- code/modules/reagents/reagent_containers/food/cans.dm | 2 +- code/modules/reagents/reagent_containers/food/drinks.dm | 2 +- code/modules/reagents/reagent_containers/food/snacks.dm | 2 +- 11 files changed, 14 insertions(+), 14 deletions(-) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 1dbaeb1a3f6..90a68b02b68 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -39,7 +39,7 @@ user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" - log_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" ) + msg_admin_attack("[key_name(user)] attacked [key_name(M)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])" ) //spawn(1800) // this wont work right // M.lastattacker = null diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm index 219581d5b3d..b0861395f52 100644 --- a/code/game/machinery/kitchen/gibber.dm +++ b/code/game/machinery/kitchen/gibber.dm @@ -203,7 +203,7 @@ if(src.occupant.client) // Gibbed a cow with a client in it? log that shit src.occupant.attack_log += "\[[time_stamp()]\] Was gibbed by [user]/[user.ckey]" user.attack_log += "\[[time_stamp()]\] Gibbed [src.occupant]/[src.occupant.ckey]" - log_attack("\[[time_stamp()]\] [user]/[user.ckey] gibbed [src.occupant]/[src.occupant.ckey]") + msg_admin_attack("\[[time_stamp()]\] [key_name(user)] gibbed [key_name(src.occupant)]") src.occupant.death(1) src.occupant.ghostize() diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index afd63497073..9e876154471 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -185,7 +185,7 @@ H.attack_log += text("\[[time_stamp()]\] Has been wrapped with [src.name] by [user.name] ([user.ckey])") user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to wrap [H.name] ([H.ckey])") - log_attack("[user.name] ([user.ckey]) used the [src.name] to wrap [H.name] ([H.ckey])") + msg_admin_attack("[key_name(user)] used [src] to wrap [key_name(H)]") else user << "\blue You need more paper." diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index 80b3403a9be..c3e5b6a88d0 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -54,7 +54,7 @@ C.attack_log += text("\[[time_stamp()]\] Has been handcuffed (attempt) by [user.name] ([user.ckey])") user.attack_log += text("\[[time_stamp()]\] Attempted to handcuff [C.name] ([C.ckey])") - log_attack("[user.name] ([user.ckey]) Attempted to handcuff [C.name] ([C.ckey])") + msg_admin_attack("[key_name(user)] attempted to handcuff [key_name(C)]") var/obj/effect/equip_e/human/O = new /obj/effect/equip_e/human( ) O.source = user diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 5637f47f983..9f439b2b376 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -88,7 +88,7 @@ user.attack_log += "\[[time_stamp()]\] Stunned [H.name] ([H.ckey]) with [src.name]" H.attack_log += "\[[time_stamp()]\] Stunned by [user.name] ([user.ckey]) with [src.name]" - log_attack("[user.name] ([user.ckey]) stunned [H.name] ([H.ckey]) with [src.name]") + msg_admin_attack("[key_name(user)] stunned [key_name(H)] with [src.name]") playsound(src.loc, 'sound/weapons/Egloves.ogg', 50, 1, -1) if(charges < 1) @@ -115,7 +115,7 @@ H.visible_message("[src], thrown by [foundmob.name], strikes [H] and stuns them!") H.attack_log += "\[[time_stamp()]\] Stunned by thrown [src.name] last touched by ([src.fingerprintslast])" - log_attack("Flying [src.name], last touched by ([src.fingerprintslast]) stunned [H.name] ([H.ckey])" ) + msg_admin_attack("Flying [src.name], last touched by ([src.fingerprintslast]) stunned [key_name(H)]" ) /obj/item/weapon/melee/baton/emp_act(severity) switch(severity) diff --git a/code/game/objects/items/weapons/swords_axes_etc.dm b/code/game/objects/items/weapons/swords_axes_etc.dm index 7ee3499c1cd..bbfb940ec9c 100644 --- a/code/game/objects/items/weapons/swords_axes_etc.dm +++ b/code/game/objects/items/weapons/swords_axes_etc.dm @@ -104,7 +104,7 @@ M.Weaken(5) M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])") user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])") - log_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])") + msg_admin_attack("[key_name(user)] attacked [key_name(user)] with [src.name] (INTENT: [uppertext(user.a_intent)])") src.add_fingerprint(user) for(var/mob/O in viewers(M)) diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index a085a88b34f..2620a20964d 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -114,7 +114,7 @@ M.attack_log += text("\[[time_stamp()]\] [M.species.attack_verb]ed [src.name] ([src.ckey])") src.attack_log += text("\[[time_stamp()]\] Has been [M.species.attack_verb]ed by [M.name] ([M.ckey])") - log_attack("[M.name] ([M.ckey]) [M.species.attack_verb]ed [src.name] ([src.ckey])") + msg_admin_attack("[key_name(M)] [M.species.attack_verb]ed [key_name(src)]") var/damage = rand(0, 5)//BS12 EDIT if(!damage) @@ -153,7 +153,7 @@ M.attack_log += text("\[[time_stamp()]\] Disarmed [src.name] ([src.ckey])") src.attack_log += text("\[[time_stamp()]\] Has been disarmed by [M.name] ([M.ckey])") - log_attack("[M.name] ([M.ckey]) disarmed [src.name] ([src.ckey])") + msg_admin_attack("[key_name(M)] disarmed [src.name] ([src.ckey])") if(w_uniform) w_uniform.add_fingerprint(M) diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 13bf68005ee..a95f8612c1b 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -137,7 +137,7 @@ affecting.loc = assailant.loc affecting.attack_log += "\[[time_stamp()]\] Has had their neck grabbed by [assailant.name] ([assailant.ckey])" assailant.attack_log += "\[[time_stamp()]\] Grabbed the neck of [affecting.name] ([affecting.ckey])" - log_attack("[assailant.name] ([assailant.ckey]) grabbed the neck of [affecting.name] ([affecting.ckey])") + msg_admin_attack("[key_name(assailant)] grabbed the neck of [key_name(affecting)]") hud.icon_state = "disarm/kill" hud.name = "disarm/kill" else @@ -158,7 +158,7 @@ assailant.visible_message("[assailant] has tightened \his grip on [affecting]'s neck!") affecting.attack_log += "\[[time_stamp()]\] Has been strangled (kill intent) by [assailant.name] ([assailant.ckey])" assailant.attack_log += "\[[time_stamp()]\] Strangled (kill intent) [affecting.name] ([affecting.ckey])" - log_attack("[assailant.name] ([assailant.ckey]) Strangled (kill intent) [affecting.name] ([affecting.ckey])") + msg_admin_attack("[key_name(assailant)] strangled (kill intent) [key_name(affecting)]") assailant.next_move = world.time + 10 affecting.losebreath += 1 diff --git a/code/modules/reagents/reagent_containers/food/cans.dm b/code/modules/reagents/reagent_containers/food/cans.dm index 6f3b3f3901d..ec9f457b67c 100644 --- a/code/modules/reagents/reagent_containers/food/cans.dm +++ b/code/modules/reagents/reagent_containers/food/cans.dm @@ -39,7 +39,7 @@ M.attack_log += text("\[[time_stamp()]\] Has been fed [src.name] by [user.name] ([user.ckey]) Reagents: [reagentlist(src)]") user.attack_log += text("\[[time_stamp()]\] Fed [M.name] by [M.name] ([M.ckey]) Reagents: [reagentlist(src)]") - log_attack("[user.name] ([user.ckey]) fed [M.name] ([M.ckey]) with [src.name] Reagents: [reagentlist(src)] (INTENT: [uppertext(user.a_intent)]) (JMP)") + msg_admin_attack("[key_name(user)] fed [key_name(M)] with [src.name] Reagents: [reagentlist(src)] (INTENT: [uppertext(user.a_intent)]) (JMP)") if(reagents.total_volume) reagents.reaction(M, INGEST) diff --git a/code/modules/reagents/reagent_containers/food/drinks.dm b/code/modules/reagents/reagent_containers/food/drinks.dm index fe49ad0262a..837e54a6d0c 100644 --- a/code/modules/reagents/reagent_containers/food/drinks.dm +++ b/code/modules/reagents/reagent_containers/food/drinks.dm @@ -45,7 +45,7 @@ M.attack_log += text("\[[time_stamp()]\] Has been fed [src.name] by [user.name] ([user.ckey]) Reagents: [reagentlist(src)]") user.attack_log += text("\[[time_stamp()]\] Fed [M.name] by [M.name] ([M.ckey]) Reagents: [reagentlist(src)]") - log_attack("[user.name] ([user.ckey]) fed [M.name] ([M.ckey]) with [src.name] Reagents: [reagentlist(src)] (INTENT: [uppertext(user.a_intent)]) (JMP)") + msg_admin_attack("[key_name(user)] fed [key_name(M)] with [src.name] Reagents: [reagentlist(src)] (INTENT: [uppertext(user.a_intent)]) (JMP)") if(reagents.total_volume) reagents.reaction(M, INGEST) diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index 4476eb6d4f1..6142f023f2a 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -66,7 +66,7 @@ M.attack_log += text("\[[time_stamp()]\] Has been fed [src.name] by [user.name] ([user.ckey]) Reagents: [reagentlist(src)]") user.attack_log += text("\[[time_stamp()]\] Fed [src.name] by [M.name] ([M.ckey]) Reagents: [reagentlist(src)]") - log_attack("[user.name] ([user.ckey]) fed [M.name] ([M.ckey]) with [src.name] Reagents: [reagentlist(src)] (INTENT: [uppertext(user.a_intent)])") + msg_admin_attack("[key_name(user)] fed [key_name(M)] with [src.name] Reagents: [reagentlist(src)] (INTENT: [uppertext(user.a_intent)])") for(var/mob/O in viewers(world.view, user)) O.show_message("\red [user] feeds [M] [src].", 1) From 2b3c2064da04954fcd9343cfd562006246f50448 Mon Sep 17 00:00:00 2001 From: ZekeSulastin Date: Tue, 25 Feb 2014 15:10:28 -0500 Subject: [PATCH 55/65] Initial run of surgery steps for laser scalpels --- code/modules/surgery/generic.dm | 82 ++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index 9ebf546d449..4de37a05397 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -19,6 +19,86 @@ return 0 return 1 +/datum/surgery_step/generic/cut_with_laser + allowed_tools = list( + /obj/item/weapon/scalpel/laser3 = 95, \ + /obj/item/weapon/scalpel/laser2 = 85, \ + /obj/item/weapon/scalpel/laser1 = 75, \ + /obj/item/weapon/melee/energy/sword = 5 + ) + + min_duration = 90 + max_duration = 110 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/datum/organ/external/affected = target.get_organ(target_zone) + return ..() && affected.open == 0 && target_zone != "mouth" + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/datum/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts the bloodless incision on [target]'s [affected.display_name] with \the [tool].", \ + "You start the bloodless incision on [target]'s [affected.display_name] with \the [tool].") + target.custom_pain("You feel a horrible, searing pain in your [affected.display_name]!",1) + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/datum/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] has made a bloodless incision on [target]'s [affected.display_name] with \the [tool].", \ + "\blue You have made a bloodless incision on [target]'s [affected.display_name] with \the [tool].",) + //Could be cleaner ... + affected.open = 1 + affected.status |= ORGAN_BLEEDING + affected.createwound(CUT, 1) + affected.clamp() + spread_germs_to_organ(affected, user) + if (target_zone == "head") + target.brain_op_stage = 1 + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/datum/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand slips as the blade sputters, searing a long gash in [target]'s [affected.display_name] with \the [tool]!", \ + "\red Your hand slips as the blade sputters, searing a long gash in [target]'s [affected.display_name] with \the [tool]!") + affected.createwound(CUT, 7.5) + affected.createwound(BURN, 12.5) + +/datum/surgery_step/generic/incision_manager + allowed_tools = list( + /obj/item/weapon/scalpel/manager = 100 + ) + + min_duration = 80 + max_duration = 120 + + can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/datum/organ/external/affected = target.get_organ(target_zone) + return ..() && affected.open == 0 && target_zone != "mouth" + + begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/datum/organ/external/affected = target.get_organ(target_zone) + user.visible_message("[user] starts to construct a prepared incision on and within [target]'s [affected.display_name] with \the [tool].", \ + "You start to construct a prepared incision on and within [target]'s [affected.display_name] with \the [tool].") + target.custom_pain("You feel a horrible, searing pain in your [affected.display_name] as it is pushed apart!",1) + ..() + + end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/datum/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\blue [user] has constructed a prepared incision on and within [target]'s [affected.display_name] with \the [tool].", \ + "\blue You have constructed a prepared incision on and within [target]'s [affected.display_name] with \the [tool].",) + affected.open = 1 + affected.status |= ORGAN_BLEEDING + affected.createwound(CUT, 1) + affected.clamp() + affected.open = 2 + if (target_zone == "head") + target.brain_op_stage = 1 + + fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) + var/datum/organ/external/affected = target.get_organ(target_zone) + user.visible_message("\red [user]'s hand jolts as the system sparks, ripping a gruesome hole in [target]'s [affected.display_name] with \the [tool]!", \ + "\red Your hand jolts as the system sparks, ripping a gruesome hole in [target]'s [affected.display_name] with \the [tool]!") + affected.createwound(CUT, 20) + affected.createwound(BURN, 15) + /datum/surgery_step/generic/cut_open allowed_tools = list( /obj/item/weapon/scalpel = 100, \ @@ -219,4 +299,4 @@ user.visible_message("\red [user]'s hand slips, sawwing through the bone in [target]'s [affected.display_name] with \the [tool]!", \ "\red Your hand slips, sawwing through the bone in [target]'s [affected.display_name] with \the [tool]!") affected.createwound(CUT, 30) - affected.fracture() \ No newline at end of file + affected.fracture() From 53b338060c8c8b4c83aed6aa2149d9fef5abde2d Mon Sep 17 00:00:00 2001 From: Loganbacca Date: Thu, 27 Feb 2014 00:59:01 +1300 Subject: [PATCH 56/65] Chemsmoke tweaks and bug fixes - Renamed the variable for the smoke density mechanic to density. Also clamped it to a minimum of 1 so it cant multiply reagents. - Added some checks so the chemsmoke effect doesn't run if it's in nullspace. - Removed an unnecessary distance calculation. - Added a null turf check to prevent runtimes if a really big smoke grenade goes off at the edge of the map. - Added a check so the reagent copy code doesn't run if there's no reagents to run it on. --- code/game/objects/effects/chemsmoke.dm | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/code/game/objects/effects/chemsmoke.dm b/code/game/objects/effects/chemsmoke.dm index ee78cb5d5bc..4c245b78cc2 100644 --- a/code/game/objects/effects/chemsmoke.dm +++ b/code/game/objects/effects/chemsmoke.dm @@ -20,7 +20,7 @@ var/range var/list/targetTurfs var/list/wallList - var/floorArea + var/density /datum/effect/effect/system/smoke_spread/chem/New() @@ -46,6 +46,8 @@ location = loca else location = get_turf(loca) + if(!location) + return targetTurfs = new() @@ -62,7 +64,8 @@ //pathing check smokeFlow(location, targetTurfs, wallList) - floorArea = targetTurfs.len + //set the density of the cloud - for diluting reagents + density = max(1, targetTurfs.len / 4) //clamp the cloud density minimum to 1 so it cant multiply the reagents //Admin messaging var/contained = "" @@ -97,14 +100,17 @@ //------------------------------------------ /datum/effect/effect/system/smoke_spread/chem/start() - //reagent application + if(!location) //kill grenade if it somehow ends up in nullspace + return + + //reagent application - only run if there are extra reagents in the smoke if(chemholder.reagents.reagent_list.len) for(var/datum/reagent/R in chemholder.reagents.reagent_list) var/proba = 100 var/runs = 5 - //dilute the reagents according to affected area - R.volume /= floorArea / 4 + //dilute the reagents according to cloud density + R.volume /= density chemholder.reagents.update_total() //apply wall affecting reagents to walls @@ -170,12 +176,11 @@ var/x = round(radius * cos(a) + location.x, 1) var/y = round(radius * sin(a) + location.y, 1) var/turf/T = locate(x,y,location.z) + if(!T) + continue if(T in targetTurfs) - var/dist = cheap_pythag(T.x - location.x, T.y - location.y) - if(!dist) - dist = 1 spawn(0) - spawnSmoke(T, I, dist) + spawnSmoke(T, I, range) //------------------------------------------ // Randomizes and spawns the smoke effect. @@ -183,7 +188,8 @@ //------------------------------------------ /datum/effect/effect/system/smoke_spread/chem/proc/spawnSmoke(var/turf/T, var/icon/I, var/dist = 1) var/obj/effect/effect/smoke/chem/smoke = new(location) - chemholder.reagents.copy_to(smoke, chemholder.reagents.total_volume / dist, safety = 1) //copy reagents to the smoke so mob/breathe() can handle inhaling the reagents + if(chemholder.reagents.reagent_list.len) + chemholder.reagents.copy_to(smoke, chemholder.reagents.total_volume / dist, safety = 1) //copy reagents to the smoke so mob/breathe() can handle inhaling the reagents smoke.icon = I smoke.layer = 6 smoke.dir = pick(cardinal) From c4f6a66d3def27644acee8f45bdeace28c3d1b78 Mon Sep 17 00:00:00 2001 From: Aryn Date: Wed, 26 Feb 2014 08:16:52 -0700 Subject: [PATCH 57/65] Fixed nuke shuttle being a swirly vortex of death. This bug was actually in legacy ShareSpace code, I'm surprised it wasn't noticeable in the old ZAS. --- code/ZAS/ConnectionGroup.dm | 21 +++++++++++++++------ code/ZAS/Debug.dm | 2 ++ code/ZAS/Diagnostic.dm | 3 +++ code/ZAS/Zone.dm | 1 + 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/code/ZAS/ConnectionGroup.dm b/code/ZAS/ConnectionGroup.dm index 1486f5088b6..c31dbf9a034 100644 --- a/code/ZAS/ConnectionGroup.dm +++ b/code/ZAS/ConnectionGroup.dm @@ -190,7 +190,7 @@ Class Procs: A.edges.Add(src) air = B.return_air() //id = 52*A.id - //world << "New edge from [A.id] to [B]." + //world << "New edge from [A] to [B]." /connection_edge/unsimulated/add_connection(connection/c) . = ..() @@ -215,7 +215,7 @@ Class Procs: return //world << "[id]: Tick [air_master.current_cycle]: To [B]!" //A.air.mimic(B, coefficient) - ShareSpace(A.air,air) + ShareSpace(A.air,air,dbg_out) air_master.mark_zone_update(A) var/differential = A.air.return_pressure() - air.return_pressure() @@ -333,6 +333,9 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output) share_size = max(1, max(size + 3, 1) + avg_unsim.group_multiplier) tileslen = avg_unsim.group_multiplier + if(dbg_output) + world << "O2: [unsim_oxygen] N2: [unsim_nitrogen] Size: [share_size] Tiles: [tileslen]" + else if(istype(unsimulated_tiles, /list)) if(!unsimulated_tiles.len) return 0 @@ -376,10 +379,10 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output) full_heat_capacity = A.heat_capacity() * size - oxy_avg = (full_oxy + unsim_oxygen) / (size + share_size) - nit_avg = (full_nitro + unsim_nitrogen) / (size + share_size) - co2_avg = (full_co2 + unsim_co2) / (size + share_size) - plasma_avg = (full_plasma + unsim_plasma) / (size + share_size) + oxy_avg = (full_oxy + unsim_oxygen*share_size) / (size + share_size) + nit_avg = (full_nitro + unsim_nitrogen*share_size) / (size + share_size) + co2_avg = (full_co2 + unsim_co2*share_size) / (size + share_size) + plasma_avg = (full_plasma + unsim_plasma*share_size) / (size + share_size) temp_avg = 0 @@ -389,6 +392,10 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output) if(sharing_lookup_table.len >= tileslen) //6 or more interconnecting tiles will max at 42% of air moved per tick. ratio = sharing_lookup_table[tileslen] + if(dbg_output) + world << "Ratio: [ratio]" + world << "Avg O2: [oxy_avg] N2: [nit_avg]" + A.oxygen = max(0, (A.oxygen - oxy_avg) * (1 - ratio) + oxy_avg ) A.nitrogen = max(0, (A.nitrogen - nit_avg) * (1 - ratio) + nit_avg ) A.carbon_dioxide = max(0, (A.carbon_dioxide - co2_avg) * (1 - ratio) + co2_avg ) @@ -402,6 +409,8 @@ proc/ShareSpace(datum/gas_mixture/A, list/unsimulated_tiles, dbg_output) A.update_values() + if(dbg_output) world << "Result: [abs(old_pressure - A.return_pressure())] kPa" + return abs(old_pressure - A.return_pressure()) diff --git a/code/ZAS/Debug.dm b/code/ZAS/Debug.dm index b27056f2384..6f0a67fd3eb 100644 --- a/code/ZAS/Debug.dm +++ b/code/ZAS/Debug.dm @@ -7,6 +7,8 @@ var/image/zone_blocked = image('icons/Testing/Zone.dmi', icon_state = "zoneblock var/image/blocked = image('icons/Testing/Zone.dmi', icon_state = "fullblock") var/image/mark = image('icons/Testing/Zone.dmi', icon_state = "mark") +/connection_edge/var/dbg_out = 0 + /turf/var/tmp/dbg_img /turf/proc/dbg(image/img, d = 0) if(d > 0) img.dir = d diff --git a/code/ZAS/Diagnostic.dm b/code/ZAS/Diagnostic.dm index 07f06a5514d..eb5d72788e2 100644 --- a/code/ZAS/Diagnostic.dm +++ b/code/ZAS/Diagnostic.dm @@ -17,6 +17,9 @@ client/proc/Zone_Info(turf/T as null|turf) T:zone:dbg_data(src) else mob << "No zone here." + var/datum/gas_mixture/mix = T.return_air() + mob << "[mix.return_pressure()] kPa [mix.temperature]C" + mob << "O2: [mix.oxygen] N2: [mix.nitrogen] CO2: [mix.carbon_dioxide] TX: [mix.toxins]" else if(zone_debug_images) for(var/zone in zone_debug_images) diff --git a/code/ZAS/Zone.dm b/code/ZAS/Zone.dm index 17d6097cdaf..349d0e0582f 100644 --- a/code/ZAS/Zone.dm +++ b/code/ZAS/Zone.dm @@ -145,6 +145,7 @@ Class Procs: else space_edges++ space_coefficient += E.coefficient + M << "[E:air:return_pressure()]kPa" M << "Zone Edges: [zone_edges]" M << "Space Edges: [space_edges] ([space_coefficient] connections)" From d4cce9be6661bc4276af2055e02c660fc84fe052 Mon Sep 17 00:00:00 2001 From: ZekeSulastin Date: Wed, 26 Feb 2014 15:23:08 -0500 Subject: [PATCH 58/65] Laser scalpels are now producable --- code/modules/research/designs.dm | 37 ++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index bcd33b2a792..53b45fcbe55 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -1398,6 +1398,43 @@ datum/design/noreactbeaker reliability_base = 76 build_path = "/obj/item/weapon/reagent_containers/glass/beaker/noreact" category = "Misc" + +datum/design/scalpel_laser1 + name = "Basic Laser Scalpel" + desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks basic and could be improved." + id = "scalpel_laser1" + req_tech = list("biotech" = 2, "materials" = 2, "magnets" = 2) + build_type = PROTOLATHE + materials = list("$metal" = 12500, "$glass" = 7500) + build_path = "/obj/item/weapon/scalpel/laser1" + +datum/design/scalpel_laser2 + name = "Improved Laser Scalpel" + desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks somewhat advanced." + id = "scalpel_laser2" + req_tech = list("biotech" = 3, "materials" = 4, "magnets" = 4) + build_type = PROTOLATHE + materials = list("$metal" = 12500, "$glass" = 7500, "$silver" = 2500) + build_path = "/obj/item/weapon/scalpel/laser2" + +datum/design/scalpel_laser3 + name = "Advanced Laser Scalpel" + desc = "A scalpel augmented with a directed laser, for more precise cutting without blood entering the field. This one looks to be the pinnacle of precision energy cutlery!" + id = "scalpel_laser3" + req_tech = list("biotech" = 4, "materials" = 6, "magnets" = 5) + build_type = PROTOLATHE + materials = list("$metal" = 12500, "$glass" = 7500, "$silver" = 2000, "$gold" = 1500) + build_path = "/obj/item/weapon/scalpel/laser3" + +datum/design/scalpel_manager + name = "Incision Management System" + desc = "A true extension of the surgeon's body, this marvel instantly and completely prepares an incision allowing for the immediate commencement of therapeutic steps." + id = "scalpel_manager" + req_tech = list("biotech" = 4, "materials" = 7, "magnets" = 5, "programming" = 4) + build_type = PROTOLATHE + materials = list ("$metal" = 12500, "$glass" = 7500, "$silver" = 1500, "$gold" = 1500, "$diamond" = 750) + build_path = "/obj/item/weapon/scalpel/manager" + ///////////////////////////////////////// /////////////////Weapons///////////////// ///////////////////////////////////////// From ac8f5451e8d74db2ea1f452651c1532093578593 Mon Sep 17 00:00:00 2001 From: Loganbacca Date: Thu, 27 Feb 2014 14:09:47 +1300 Subject: [PATCH 59/65] Chemgrenade fix - If check to handle grenades detonating in a mobs hand correctly. --- code/game/objects/items/weapons/grenades/chem_grenade.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index 29814b14acc..2f24667049d 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -161,6 +161,10 @@ if( A == src ) continue src.reagents.reaction(A, 1, 10) + if(istype(loc, /mob/living/carbon)) //drop dat grenade if it goes off in your hand + var/mob/living/carbon/C = loc + C.drop_from_inventory(src) + C.throw_mode_off() invisibility = INVISIBILITY_MAXIMUM //Why am i doing this? spawn(50) //To make sure all reagents can work From 61fe10fe3d8452a09f436b38abe7c0d5a47dfa63 Mon Sep 17 00:00:00 2001 From: ZomgPonies Date: Sat, 1 Mar 2014 00:41:18 -0500 Subject: [PATCH 60/65] Efficiency: Joblist Conflicts: code/__HELPERS/global_lists.dm --- code/__HELPERS/global_lists.dm | 6 ++++++ code/__HELPERS/names.dm | 6 +++--- code/datums/mind.dm | 2 +- code/game/gamemodes/intercept_report.dm | 4 ++-- code/game/jobs/access.dm | 6 +++--- code/game/machinery/computer/card.dm | 2 +- code/game/machinery/computer/security.dm | 4 ++-- code/game/machinery/computer/skills.dm | 4 ++-- 8 files changed, 20 insertions(+), 14 deletions(-) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 22e6376836e..531dbeb0dba 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -17,6 +17,7 @@ var/global/list/landmarks_list = list() //list of all landmarks created var/global/list/surgery_steps = list() //list of all surgery steps |BS12 var/global/list/side_effects = list() //list of all medical sideeffects types by thier names |BS12 var/global/list/mechas_list = list() //list of all mechs. Used by hostile mobs target tracking. +var/global/list/joblist = list() //list of all jobstypes, minus borg and AI //Languages/species/whitelist. var/global/list/all_species[0] @@ -85,6 +86,11 @@ var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Al var/datum/medical_effect/M = new T side_effects[M.name] = T + //List of job. I can't believe this was calculated multiple times per tick! + paths = typesof(/datum/job) -list(/datum/job,/datum/job/ai,/datum/job/cyborg) + for(var/T in paths) + var/datum/job/J = new T + joblist[J.title] = J //Languages and species. paths = typesof(/datum/language)-/datum/language diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm index 7dd535a2fe9..ca682b42611 100644 --- a/code/__HELPERS/names.dm +++ b/code/__HELPERS/names.dm @@ -200,7 +200,7 @@ var/syndicate_code_response//Code response for traitors. code_phrase += " " code_phrase += pick(last_names) if(2) - code_phrase += pick(get_all_jobs())//Returns a job. + code_phrase += pick(joblist)//Returns a job. safety -= 1 if(2) switch(rand(1,2))//Places or things. @@ -270,7 +270,7 @@ var/syndicate_code_response//Code response for traitors. if(5) syndicate_code_phrase += pick("Do we have","Is there","Where is","Where's","Who's") syndicate_code_phrase += " " - syndicate_code_phrase += "[pick(get_all_jobs())]" + syndicate_code_phrase += "[pick(joblist)]" syndicate_code_phrase += "?" switch(choice) @@ -299,7 +299,7 @@ var/syndicate_code_response//Code response for traitors. syndicate_code_response += pick(last_names) else syndicate_code_response += " the " - syndicate_code_response += "[pic(get_all_jobs())]" + syndicate_code_response += "[pic(joblist)]" syndicate_code_response += "." else syndicate_code_response += pick("*shrug*","*smile*","*blink*","*sigh*","*laugh*","*nod*","*giggle*") diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 8d2a926c8ea..6a8bddf55cd 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -357,7 +357,7 @@ datum/mind if(!check_rights(R_ADMIN)) return if (href_list["role_edit"]) - var/new_role = input("Select new role", "Assigned role", assigned_role) as null|anything in get_all_jobs() + var/new_role = input("Select new role", "Assigned role", assigned_role) as null|anything in joblist if (!new_role) return assigned_role = new_role diff --git a/code/game/gamemodes/intercept_report.dm b/code/game/gamemodes/intercept_report.dm index 54c1ac6b079..2ee0fe7d919 100644 --- a/code/game/gamemodes/intercept_report.dm +++ b/code/game/gamemodes/intercept_report.dm @@ -213,11 +213,11 @@ if(prob(prob_right_job)) if(correct_person) if(correct_person:assigned_role=="MODE") - changeling_job = pick(get_all_jobs()) + changeling_job = pick(joblist) else changeling_job = correct_person:assigned_role else - changeling_job = pick(get_all_jobs()) + changeling_job = pick(joblist) if(prob(prob_right_dude) && ticker.mode == "changeling") if(correct_person:assigned_role=="MODE") changeling_name = correct_person:current diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index 22037996ce3..32ae991d06c 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -440,10 +440,10 @@ rank = src:rank assignment = src:assignment - if( rank in get_all_jobs() ) + if( rank in joblist ) return rank - if( assignment in get_all_jobs() ) + if( assignment in joblist ) return assignment return "Unknown" @@ -496,7 +496,7 @@ proc/FindNameFromID(var/mob/living/carbon/human/H) return ID.registered_name proc/get_all_job_icons() //For all existing HUD icons - return get_all_jobs() + list("Prisoner") + return joblist + list("Prisoner") /obj/proc/GetJobName() //Used in secHUD icon generation if (!istype(src, /obj/item/device/pda) && !istype(src,/obj/item/weapon/card/id)) diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index 911ccace956..1d724b83cd9 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -108,7 +108,7 @@ header += "
" var/jobs_all = "" - var/list/alljobs = (istype(src,/obj/machinery/computer/card/centcom)? get_all_centcom_jobs() : get_all_jobs()) + "Custom" + var/list/alljobs = (istype(src,/obj/machinery/computer/card/centcom)? get_all_centcom_jobs() : joblist) + "Custom" for(var/job in alljobs) jobs_all += "[replacetext(job, " ", " ")] " //make sure there isn't a line break in the middle of a job diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 479633ff100..a772ff88f16 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -501,7 +501,7 @@ What a mess.*/ if ((istype(active1, /datum/data/record) && L.Find(rank))) temp = "
Rank:
" temp += "
    " - for(var/rank in get_all_jobs()) + for(var/rank in joblist) temp += "
  • [rank]
  • " temp += "
" else @@ -520,7 +520,7 @@ What a mess.*/ if ("Change Rank") if (active1) active1.fields["rank"] = href_list["rank"] - if(href_list["rank"] in get_all_jobs()) + if(href_list["rank"] in joblist) active1.fields["real_rank"] = href_list["real_rank"] if ("Change Criminal Status") diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm index 7613d711ce6..307ff5f662f 100644 --- a/code/game/machinery/computer/skills.dm +++ b/code/game/machinery/computer/skills.dm @@ -354,7 +354,7 @@ What a mess.*/ if ((istype(active1, /datum/data/record) && L.Find(rank))) temp = "
Rank:
" temp += "
    " - for(var/rank in get_all_jobs()) + for(var/rank in joblist) temp += "
  • [rank]
  • " temp += "
" else @@ -373,7 +373,7 @@ What a mess.*/ if ("Change Rank") if (active1) active1.fields["rank"] = href_list["rank"] - if(href_list["rank"] in get_all_jobs()) + if(href_list["rank"] in joblist) active1.fields["real_rank"] = href_list["real_rank"] if ("Delete Record (ALL) Execute") From 4025ccbee5d34b93cebfb01cd90ae3553bd9aacb Mon Sep 17 00:00:00 2001 From: Jeremy Liberman Date: Sat, 1 Mar 2014 22:53:23 -0600 Subject: [PATCH 61/65] Fractures and severed limbs cause cuffs to fall off. Deranged spessmen can chew their own wrists to break free. --- code/game/objects/items/weapons/handcuffs.dm | 24 +++++++++++++++- code/modules/organs/organ_external.dm | 30 +++++++++++++++++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index 5546a0db02e..9508341c041 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -92,6 +92,28 @@ return return +var/last_chew = 0 +/mob/living/carbon/human/RestrainedClickOn(var/atom/A) + if (A != src) return ..() + if (last_chew + 26 > world.time) return + + var/mob/living/carbon/human/H = A + if (H.a_intent != "hurt") return + if (H.zone_sel.selecting != "mouth") return + + var/datum/organ/external/O = H.organs_by_name[H.hand?"l_hand":"r_hand"] + if (!O) return + + var/s = "\red [H.name] chews on \his [O.display_name]!" + H.visible_message(s, "\red You chew on your [O.display_name]!") + H.attack_log += text("\[[time_stamp()]\] [s] ([H.ckey])") + log_attack("[s] ([H.ckey])") + + if(O.take_damage(3,0,1,"teeth marks")) + H:UpdateDamageIcon() + + last_chew = world.time + /obj/item/weapon/handcuffs/cable name = "cable restraints" desc = "Looks like some cables tied together. Could be used to tie something up." @@ -123,4 +145,4 @@ color = "#FFFFFF" /obj/item/weapon/handcuffs/cyborg - dispenser = 1 \ No newline at end of file + dispenser = 1 diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 8ba5c0939a9..466986b0085 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -570,11 +570,32 @@ This function completely restores a damaged organ to perfect condition. owner.update_body(1) + // OK so maybe your limb just flew off, but if it was attached to a pair of cuffs then hooray! Freedom! + release_restraints() /**************************************************** HELPERS ****************************************************/ +/datum/organ/external/proc/release_restraints() + if (owner.handcuffed && body_part in list(ARM_LEFT, ARM_RIGHT, HAND_LEFT, HAND_RIGHT)) + owner.visible_message(\ + "\The [owner.handcuffed.name] falls off of [owner.name].",\ + "\The [owner.handcuffed.name] falls off you.") + + owner.handcuffed.loc = owner.loc + owner.handcuffed = null + owner.update_inv_handcuffed() + + if (owner.legcuffed && body_part in list(FOOT_LEFT, FOOT_RIGHT, LEG_LEFT, LEG_RIGHT)) + owner.visible_message(\ + "\The [owner.legcuffed.name] falls off of [owner.name].",\ + "\The [owner.legcuffed.name] falls off you.") + + owner.legcuffed.loc = owner.loc + owner.legcuffed = null + owner.update_inv_legcuffed() + /datum/organ/external/proc/bandage() var/rval = 0 src.status &= ~ORGAN_BLEEDING @@ -603,7 +624,10 @@ This function completely restores a damaged organ to perfect condition. /datum/organ/external/proc/fracture() if(status & ORGAN_BROKEN) return - owner.visible_message("\red You hear a loud cracking sound coming from \the [owner].","\red Something feels like it shattered in your [display_name]!","You hear a sickening crack.") + owner.visible_message(\ + "\red You hear a loud cracking sound coming from \the [owner].",\ + "\red Something feels like it shattered in your [display_name]!",\ + "You hear a sickening crack.") if(owner.species && !(owner.species.flags & NO_PAIN)) owner.emote("scream") @@ -612,6 +636,10 @@ This function completely restores a damaged organ to perfect condition. broken_description = pick("broken","fracture","hairline fracture") perma_injury = brute_dam + // Fractures have a chance of getting you out of restraints + if (prob(25)) + release_restraints() + /datum/organ/external/proc/robotize() src.status &= ~ORGAN_BROKEN src.status &= ~ORGAN_BLEEDING From 787ea323609771f71f186d80a99282cb55727840 Mon Sep 17 00:00:00 2001 From: Joey Haas Date: Sun, 2 Mar 2014 21:31:46 +0100 Subject: [PATCH 62/65] Added 3D glasses to Dormitory --- code/modules/clothing/glasses/glasses.dm | 6 ++++++ icons/mob/eyes.dmi | Bin 6577 -> 6707 bytes icons/obj/clothing/glasses.dmi | Bin 6555 -> 6674 bytes maps/tgstation2.dmm | 5 +++-- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 7ee835da35e..8ac25dc9b09 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -70,6 +70,12 @@ icon_state = "hipster_glasses" item_state = "hipster_glasses" +/obj/item/clothing/glasses/threedglasses + desc = "A long time ago, people used these glasses to makes images from screens threedimensional." + name = "3D glasses" + icon_state = "3d" + item_state = "3d" + /obj/item/clothing/glasses/gglasses name = "Green Glasses" desc = "Forest green glasses, like the kind you'd wear when hatching a nasty scheme." diff --git a/icons/mob/eyes.dmi b/icons/mob/eyes.dmi index b33224f4264aafe8b62e68ba3f853d373873a230..272f79fc8d1db716c4ba4e0f2e3aa992ca2789a2 100644 GIT binary patch literal 6707 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 literal 6577 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 diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi index 7db3c3ee819b313e76fde9bb1c7d2a7300e4e74b..4c32803e21f8e11dbd30aef732da3045c34fa341 100644 GIT binary patch literal 6674 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 literal 6555 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 U=`2oQf4Tsgs=6vQO4ecj1u(8@ Date: Sun, 2 Mar 2014 21:35:10 +0100 Subject: [PATCH 63/65] Added '50 Wooden Planks' to shipments --- code/datums/supplypacks.dm | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 0c677cc83e7..71b7bab0410 100755 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -390,6 +390,15 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee containername = "Glass sheets crate" group = "Engineering" +/datum/supply_packs/wood50 + name = "50 Wooden Planks" + contains = list(/obj/item/stack/sheet/wood) + amount = 50 + cost = 10 + containertype = /obj/structure/closet/crate + containername = "Wooden planks crate" + group = "Engineering" + /datum/supply_packs/electrical name = "Electrical maintenance crate" contains = list(/obj/item/weapon/storage/toolbox/electrical, From d41d3b2b9e27d3beb5f3ce1acb8355ca9eda57b1 Mon Sep 17 00:00:00 2001 From: Jeremy Liberman Date: Sun, 2 Mar 2014 15:08:55 -0600 Subject: [PATCH 64/65] Fixes UI glitch when losing cuffs from fractures, resisting, or cult magic --- code/game/gamemodes/cult/runes.dm | 8 ++------ code/modules/mob/living/living.dm | 11 ++++++++--- code/modules/organs/organ_external.dm | 8 ++------ 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 8c373aa1a78..fdc669a0c40 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -775,13 +775,9 @@ var/list/sacrificed = list() return cultist.buckled = null if (cultist.handcuffed) - cultist.handcuffed.loc = cultist.loc - cultist.handcuffed = null - cultist.update_inv_handcuffed() + cultist.drop_from_inventory(cultist.handcuffed) if (cultist.legcuffed) - cultist.legcuffed.loc = cultist.loc - cultist.legcuffed = null - cultist.update_inv_legcuffed() + cultist.drop_from_inventory(cultist.legcuffed) if (istype(cultist.wear_mask, /obj/item/clothing/mask/muzzle)) cultist.u_equip(cultist.wear_mask) if(istype(cultist.loc, /obj/structure/closet)&&cultist.loc:welded) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 57bb02ce5c3..97e04597dcb 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -256,8 +256,15 @@ buckled = initial(src.buckled) if(iscarbon(src)) var/mob/living/carbon/C = src + + if (C.handcuffed && !initial(C.handcuffed)) + C.drop_from_inventory(C.handcuffed) C.handcuffed = initial(C.handcuffed) + if (C.legcuffed && !initial(C.legcuffed)) + C.drop_from_inventory(C.legcuffed) + C.legcuffed = initial(C.legcuffed) + /mob/living/proc/rejuvenate() // shut down various types of badness @@ -627,8 +634,6 @@ O.show_message("\red [CM] manages to remove the handcuffs!", 1) CM << "\blue You successfully remove \the [CM.handcuffed]." CM.drop_from_inventory(CM.handcuffed) - CM.handcuffed = null - CM.update_inv_handcuffed() else if(CM.legcuffed && CM.canmove && (CM.last_special <= world.time)) CM.next_move = world.time + 100 @@ -766,4 +771,4 @@ loc = target_vent.loc var/area/new_area = get_area(loc) if(new_area) - new_area.Entered(src) \ No newline at end of file + new_area.Entered(src) diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 466986b0085..fb6ed08dc56 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -583,18 +583,14 @@ This function completely restores a damaged organ to perfect condition. "\The [owner.handcuffed.name] falls off of [owner.name].",\ "\The [owner.handcuffed.name] falls off you.") - owner.handcuffed.loc = owner.loc - owner.handcuffed = null - owner.update_inv_handcuffed() + owner.drop_from_inventory(owner.handcuffed) if (owner.legcuffed && body_part in list(FOOT_LEFT, FOOT_RIGHT, LEG_LEFT, LEG_RIGHT)) owner.visible_message(\ "\The [owner.legcuffed.name] falls off of [owner.name].",\ "\The [owner.legcuffed.name] falls off you.") - owner.legcuffed.loc = owner.loc - owner.legcuffed = null - owner.update_inv_legcuffed() + owner.drop_from_inventory(owner.legcuffed) /datum/organ/external/proc/bandage() var/rval = 0 From c5261a2796bab8e2abb99d7b48b8c8a8ecd128cd Mon Sep 17 00:00:00 2001 From: Jeremy Liberman Date: Mon, 3 Mar 2014 20:24:09 -0600 Subject: [PATCH 65/65] Wearing masks or straight jackets blocks chewing on your wrists --- code/game/objects/items/weapons/handcuffs.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm index 9508341c041..58a0713ecc9 100644 --- a/code/game/objects/items/weapons/handcuffs.dm +++ b/code/game/objects/items/weapons/handcuffs.dm @@ -98,8 +98,11 @@ var/last_chew = 0 if (last_chew + 26 > world.time) return var/mob/living/carbon/human/H = A + if (!H.handcuffed) return if (H.a_intent != "hurt") return if (H.zone_sel.selecting != "mouth") return + if (H.wear_mask) return + if (istype(H.wear_suit, /obj/item/clothing/suit/straight_jacket)) return var/datum/organ/external/O = H.organs_by_name[H.hand?"l_hand":"r_hand"] if (!O) return