diff --git a/baystation12.dme b/baystation12.dme
index d14983d796..58da258540 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -139,7 +139,6 @@
#include "code\datums\diseases\advance\symptoms\weight.dm"
#include "code\datums\helper_datums\construction_datum.dm"
#include "code\datums\helper_datums\events.dm"
-#include "code\datums\helper_datums\getrev.dm"
#include "code\datums\helper_datums\global_iterator.dm"
#include "code\datums\helper_datums\teleport.dm"
#include "code\datums\helper_datums\topic_input.dm"
@@ -488,6 +487,7 @@
#include "code\game\objects\items\devices\pipe_painter.dm"
#include "code\game\objects\items\devices\powersink.dm"
#include "code\game\objects\items\devices\scanners.dm"
+#include "code\game\objects\items\devices\suit_cooling.dm"
#include "code\game\objects\items\devices\taperecorder.dm"
#include "code\game\objects\items\devices\traitordevices.dm"
#include "code\game\objects\items\devices\transfer_valve.dm"
@@ -1215,6 +1215,7 @@
#include "code\modules\research\xenoarchaeology\chemistry.dm"
#include "code\modules\research\xenoarchaeology\geosample.dm"
#include "code\modules\research\xenoarchaeology\manuals.dm"
+#include "code\modules\research\xenoarchaeology\master_controller.dm"
#include "code\modules\research\xenoarchaeology\misc.dm"
#include "code\modules\research\xenoarchaeology\artifact\artifact.dm"
#include "code\modules\research\xenoarchaeology\artifact\artifact_autocloner.dm"
@@ -1250,7 +1251,11 @@
#include "code\modules\research\xenoarchaeology\finds\finds_defines.dm"
#include "code\modules\research\xenoarchaeology\finds\finds_fossils.dm"
#include "code\modules\research\xenoarchaeology\finds\finds_misc.dm"
+#include "code\modules\research\xenoarchaeology\finds\finds_special.dm"
#include "code\modules\research\xenoarchaeology\finds\finds_talkingitem.dm"
+#include "code\modules\research\xenoarchaeology\genetics\prehistoric_animals.dm"
+#include "code\modules\research\xenoarchaeology\genetics\prehistoric_plants.dm"
+#include "code\modules\research\xenoarchaeology\genetics\reconstitutor.dm"
#include "code\modules\research\xenoarchaeology\machinery\artifact_analyser.dm"
#include "code\modules\research\xenoarchaeology\machinery\artifact_harvester.dm"
#include "code\modules\research\xenoarchaeology\machinery\artifact_scanner.dm"
diff --git a/code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi
index 13cd5e7739..f27897881c 100644
Binary files a/code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi and b/code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi differ
diff --git a/code/WorkInProgress/Susan/susan_desert_turfs.dm b/code/WorkInProgress/Susan/susan_desert_turfs.dm
index 947f6b6788..a52f90a4bc 100644
--- a/code/WorkInProgress/Susan/susan_desert_turfs.dm
+++ b/code/WorkInProgress/Susan/susan_desert_turfs.dm
@@ -227,7 +227,7 @@ Alien plants should do something if theres a lot of poison
del(src)
-/obj/effect/alien/flesh/weeds/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/effect/alien/flesh/weeds/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
health -= 5
healthcheck()
diff --git a/code/WorkInProgress/buildmode.dm b/code/WorkInProgress/buildmode.dm
index ceb1954a5d..d93d45fec5 100644
--- a/code/WorkInProgress/buildmode.dm
+++ b/code/WorkInProgress/buildmode.dm
@@ -259,7 +259,8 @@
if(4)
if(pa.Find("left"))
- holder.throw_atom = object
+ if(istype(object, /atom/movable))
+ holder.throw_atom = object
if(pa.Find("right"))
if(holder.throw_atom)
holder.throw_atom.throw_at(object, 10, 1)
diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm
index 8b692c5b13..33161b8214 100644
--- a/code/ZAS/Fire.dm
+++ b/code/ZAS/Fire.dm
@@ -50,7 +50,7 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
icon = 'icons/effects/fire.dmi'
icon_state = "1"
-
+ l_color = "#ED9200"
layer = TURF_LAYER
var/firelevel = 10000 //Calculated by gas_mixture.calculate_firelevel()
@@ -84,7 +84,7 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
air_contents.trace_gases.Remove(fuel)
//check if there is something to combust
- if(!air_contents.check_recombustability(liquid))
+ if(!air_contents.check_combustability(liquid))
//del src
RemoveFire()
@@ -116,7 +116,7 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
var/datum/gas_mixture/acs = enemy_tile.return_air()
var/obj/effect/decal/cleanable/liquid_fuel/liq = locate() in enemy_tile
if(!acs) continue
- if(!acs.check_recombustability(liq)) continue
+ if(!acs.check_combustability(liq)) continue
//If extinguisher mist passed over the turf it's trying to spread to, don't spread and
//reduce firelevel.
if(enemy_tile.fire_protection > world.time-30)
@@ -134,16 +134,8 @@ turf/simulated/hotspot_expose(exposed_temperature, exposed_volume, soh)
///////////////////////////////// FLOW HAS BEEN CREATED /// DONT DELETE THE FIRE UNTIL IT IS MERGED BACK OR YOU WILL DELETE AIR ///////////////////////////////////////////////
if(flow)
-
- if(flow.check_recombustability(liquid))
- //Ensure flow temperature is higher than minimum fire temperatures.
- //this creates some energy ex nihilo but is necessary to get a fire started
- //lets just pretend this energy comes from the ignition source and dont mention this again
- //flow.temperature = max(PHORON_MINIMUM_BURN_TEMPERATURE+0.1,flow.temperature)
-
- //burn baby burn!
-
- flow.zburn(liquid,1)
+ //burn baby burn!
+ flow.zburn(liquid,1)
//merge the air back
S.assume_air(flow)
@@ -275,9 +267,9 @@ datum/gas_mixture/proc/check_combustability(obj/effect/decal/cleanable/liquid_fu
if(oxygen && (phoron || fuel || liquid))
if(liquid)
return 1
- if (phoron >= 0.1)
+ if(QUANTIZE(phoron * vsc.fire_consuption_rate) >= 0.1)
return 1
- if(fuel && fuel.moles >= 0.1)
+ if(fuel && QUANTIZE(fuel.moles * vsc.fire_consuption_rate) >= 0.1)
return 1
return 0
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index e2c04299f1..77ed7f308e 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -366,3 +366,36 @@ datum/projectile_data
var/dest_y = src_y + distance*cos(rotation);
return new /datum/projectile_data(src_x, src_y, time, distance, power_x, power_y, dest_x, dest_y)
+
+/proc/GetRedPart(const/hexa)
+ return hex2num(copytext(hexa,2,4))
+
+/proc/GetGreenPart(const/hexa)
+ return hex2num(copytext(hexa,4,6))
+
+/proc/GetBluePart(const/hexa)
+ return hex2num(copytext(hexa,6,8))
+
+/proc/GetHexColors(const/hexa)
+ return list(
+ GetRedPart(hexa),
+ GetGreenPart(hexa),
+ GetBluePart(hexa)
+ )
+
+/proc/MixColors(const/list/colors)
+ var/list/reds = list()
+ var/list/blues = list()
+ var/list/greens = list()
+ var/list/weights = list()
+
+ for (var/i = 0, ++i <= colors.len)
+ reds.Add(GetRedPart(colors[i]))
+ blues.Add(GetBluePart(colors[i]))
+ greens.Add(GetGreenPart(colors[i]))
+ weights.Add(1)
+
+ var/r = mixOneColor(weights, reds)
+ var/g = mixOneColor(weights, greens)
+ var/b = mixOneColor(weights, blues)
+ return rgb(r,g,b)
\ No newline at end of file
diff --git a/code/__HELPERS/logging.dm b/code/__HELPERS/logging.dm
index b551d86c75..69d01e3d35 100644
--- a/code/__HELPERS/logging.dm
+++ b/code/__HELPERS/logging.dm
@@ -6,11 +6,12 @@
// in the logs. ascii character 13 = CR
/var/global/log_end= world.system_type == UNIX ? ascii2text(13) : ""
-
+
/proc/error(msg)
world.log << "## ERROR: [msg][log_end]"
+#define WARNING(MSG) warning("[MSG] in [__FILE__] at line [__LINE__] src: [src] usr: [usr].")
//print a warning message to world.log
/proc/warning(msg)
world.log << "## WARNING: [msg][log_end]"
@@ -79,4 +80,4 @@
diary << "\[[time_stamp()]]PDA: [text][log_end]"
/proc/log_misc(text)
- diary << "\[[time_stamp()]]MISC: [text][log_end]"
+ diary << "\[[time_stamp()]]MISC: [text][log_end]"
diff --git a/code/__HELPERS/maths.dm b/code/__HELPERS/maths.dm
index b174147d58..d36551f1d6 100644
--- a/code/__HELPERS/maths.dm
+++ b/code/__HELPERS/maths.dm
@@ -3,6 +3,11 @@
var/const/E = 2.71828183
var/const/Sqrt2 = 1.41421356
+// List of square roots for the numbers 1-100.
+var/list/sqrtTable = list(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, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10)
/proc/Atan2(x, y)
if(!x && !y) return 0
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index 093899c5c4..147d790919 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -16,9 +16,11 @@
Note that this proc can be overridden, and is in the case of screen objects.
*/
/atom/Click(location,control,params)
- usr.ClickOn(src, params)
+ if(src)
+ usr.ClickOn(src, params)
/atom/DblClick(location,control,params)
- usr.DblClickOn(src,params)
+ if(src)
+ usr.DblClickOn(src,params)
/*
Standard mob ClickOn()
diff --git a/code/controllers/_DynamicAreaLighting_TG.dm b/code/controllers/_DynamicAreaLighting_TG.dm
index 5f87620780..c11bda0f0c 100644
--- a/code/controllers/_DynamicAreaLighting_TG.dm
+++ b/code/controllers/_DynamicAreaLighting_TG.dm
@@ -5,9 +5,10 @@
ShadowDarke's respective lighting libraries. Credits, where due, to them.
Like sd_DAL (what we used to use), it changes the shading overlays of areas by splitting each type of area into sub-areas
- by using the var/tag variable and moving turfs into the contents list of the correct sub-area.
+ by using the var/tag variable and moving turfs into the contents list of the correct sub-area. This method is
+ much less costly than using overlays or objects.
- Unlike sd_DAL however it uses a queueing system. Everytime we call a change to opacity or luminosity
+ Unlike sd_DAL however it uses a queueing system. Everytime we call a change to opacity or luminosity
(through SetOpacity() or SetLuminosity()) we are simply updating variables and scheduling certain lights/turfs for an
update. Actual updates are handled periodically by the lighting_controller. This carries additional overheads, however it
means that each thing is changed only once per lighting_controller.processing_interval ticks. Allowing for greater control
@@ -15,50 +16,40 @@
setting lighting_controller.processing = 0 at say, the start of a large explosion, waiting for it to finish, and then
turning it back on with lighting_controller.processing = 1.
- Unlike our old system there is a hardcoded maximum luminosity. This is to discourage coders using large luminosity values
- for dynamic lighting, as the cost of lighting grows rapidly at large luminosity levels (especially when changing opacity
- at runtime)
+ Unlike our old system there are hardcoded maximum luminositys (different for certain atoms).
+ This is to cap the cost of creating lighting effects.
+ (without this, an atom with luminosity of 20 would have to update 41^2 turfs!) :s
Also, in order for the queueing system to work, each light remembers the effect it casts on each turf. This is going to
- have larger memory requirements than our previous system but hopefully it's worth the hassle for the greater control we
- gain. Besides, there are far far worse uses of needless lists in the game, it'd be worth pruning some of them to offset
- costs.
+ have larger memory requirements than our previous system but it's easily worth the hassle for the greater control we
+ gain. It also reduces cost of removing lighting effects by a lot!
Known Issues/TODO:
- admin-spawned turfs will have broken lumcounts. Not willing to fix it at this moment
- mob luminosity will be lower than expected when one of multiple light sources is dropped after exceeding the maximum luminosity
Shuttles still do not have support for dynamic lighting (I hope to fix this at some point)
- No directional lighting support. Fairly easy to add this and the code is ready.
+ No directional lighting support. (prototype looked ugly)
*/
-#define LIGHTING_MAX_LUMINOSITY 12 //Hard maximum luminosity to prevet lag which could be caused by coders making mini-suns
-#define LIGHTING_MAX_LUMINOSITY_MOB 7 //Mobs get their own max because 60-odd human suns running around would be pretty silly
-#define LIGHTING_LAYER 10 //Drawing layer for lighting overlays
-#define LIGHTING_ICON 'icons/effects/ss13_dark_alpha7.dmi' //Icon used for lighting shading effects
+#define LIGHTING_CIRCULAR 1 //comment this out to use old square lighting effects.
+#define LIGHTING_LAYER 10 //Drawing layer for lighting overlays
+#define LIGHTING_ICON 'icons/effects/ss13_dark_alpha6.dmi' //Icon used for lighting shading effects
datum/light_source
var/atom/owner
var/changed = 1
- var/mobile = 1
var/list/effect = list()
-
var/__x = 0 //x coordinate at last update
var/__y = 0 //y coordinate at last update
+ var/l_color
New(atom/A)
if(!istype(A))
CRASH("The first argument to the light object's constructor must be the atom that is the light source. Expected atom, received '[A]' instead.")
-
..()
owner = A
-
- if(istype(owner, /atom/movable)) mobile = 1 //apparantly this is faster than type-checking
- else mobile = 0 //Perhaps removing support for luminous turfs would be a good idea.
-
+ l_color = owner.l_color
__x = owner.x
__y = owner.y
-
// the lighting object maintains a list of all light sources
lighting_controller.lights += src
@@ -69,12 +60,14 @@ datum/light_source
remove_effect()
return 1 //causes it to be removed from our list of lights. The garbage collector will then destroy it.
- if(mobile)
- // check to see if we've moved since last update
- if(owner.x != __x || owner.y != __y)
- __x = owner.x
- __y = owner.y
- changed = 1
+ // check to see if we've moved since last update
+ if(owner.x != __x || owner.y != __y)
+ __x = owner.x
+ __y = owner.y
+ changed = 1
+
+ if (owner.l_color != l_color)
+ changed = 1
if(changed)
changed = 0
@@ -85,197 +78,264 @@ datum/light_source
proc/remove_effect()
// before we apply the effect we remove the light's current effect.
- if(effect.len)
- for(var/turf in effect) // negate the effect of this light source
- var/turf/T = turf
- T.update_lumcount(-effect[T])
- effect.Cut() // clear the effect list
+ for(var/turf/T in effect) // negate the effect of this light source
+ T.update_lumcount(-effect[T], l_color, 1)
+ effect.Cut() // clear the effect list
proc/add_effect()
// only do this if the light is turned on and is on the map
if(owner.loc && owner.luminosity > 0)
- effect = new_effect() // identify the effects of this light source
- for(var/turf in effect)
- var/turf/T = turf
- T.update_lumcount(effect[T]) // apply the effect
+ l_color = owner.l_color
+ effect = list()
+ for(var/turf/T in view(owner.get_light_range(),owner))
+ var/delta_lumen = lum(T)
+ if(delta_lumen > 0)
+ effect[T] = delta_lumen
+ T.update_lumcount(delta_lumen, l_color, 0)
+
return 0
else
owner.light = null
return 1 //cause the light to be removed from the lights list and garbage collected once it's no
//longer referenced by the queue
- proc/new_effect()
- . = list()
-
- for(var/turf/T in view(owner.luminosity, owner))
-// var/area/A = T.loc
-// if(!A) continue
- var/change_in_lumcount = lum(T)
- if(change_in_lumcount > 0)
- .[T] = change_in_lumcount
-
- return .
-
-
proc/lum(turf/A)
- return owner.luminosity - max(abs(A.x-__x),abs(A.y-__y))
-// var/dist = cheap_hypotenuse(A.x,A.y,__x,__y) //fetches the pythagorean distance between A and the light
-// if(owner.luminosity < dist) //if the turf is outside the radius the light doesn't illuminate it
-// return 0
-// return round(owner.luminosity - (dist/2),0.1)
+ if (owner.trueLuminosity < 1)
+ return 0
+ var/dist
+ if(!A)
+ dist = 0
+ else
+#ifdef LIGHTING_CIRCULAR
+ dist = cheap_hypotenuse(A.x, A.y, __x, __y)
+#else
+ dist = max(abs(A.x - __x), abs(A.y - __y))
+#endif
+ if (owner.trueLuminosity > 100) // This will never happen... right?
+ return sqrt(owner.trueLuminosity) - dist
+ else
+ return sqrtTable[owner.trueLuminosity] - dist
atom
var/datum/light_source/light
+ var/trueLuminosity = 0 // Typically 'luminosity' squared. The builtin luminosity must remain linear.
+ // We may read it, but NEVER set it directly.
+ var/l_color
//Turfs with opacity when they are constructed will trigger nearby lights to update
-//Turfs atoms with luminosity when they are constructed will create a light_source automatically
-//TODO: lag reduction
+//Turfs and atoms with luminosity when they are constructed will create a light_source automatically
turf/New()
..()
- if(opacity)
- UpdateAffectingLights()
if(luminosity)
- world.log << "[type] has luminosity at New()"
- if(light) world.log << "## WARNING: [type] - Don't set lights up manually during New(), We do it automatically."
+ if(light) WARNING("[type] - Don't set lights up manually during New(), We do it automatically.")
+ trueLuminosity = luminosity * luminosity
light = new(src)
//Movable atoms with opacity when they are constructed will trigger nearby lights to update
//Movable atoms with luminosity when they are constructed will create a light_source automatically
-//TODO: lag reduction
atom/movable/New()
..()
if(opacity)
- UpdateAffectingLights()
+ if(isturf(loc))
+ if(loc:lighting_lumcount > 1)
+ UpdateAffectingLights()
if(luminosity)
- if(light) world.log << "## WARNING: [type] - Don't set lights up manually during New(), We do it automatically."
+ if(light) WARNING("[type] - Don't set lights up manually during New(), We do it automatically.")
+ trueLuminosity = luminosity * luminosity
light = new(src)
-//Turfs with opacity will trigger nearby lights to update at next lighting process.
-//TODO: is this really necessary? Removing it could help reduce lag during singulo-mayhem somewhat
-turf/Del()
- if(opacity)
- UpdateAffectingLights()
- ..()
-
//Objects with opacity will trigger nearby lights to update at next lighting process.
atom/movable/Del()
if(opacity)
- UpdateAffectingLights()
+ if(isturf(loc))
+ if(loc:lighting_lumcount > 1)
+ UpdateAffectingLights()
+
..()
-//Sets our luminosity. Enforces a hardcoded maximum luminosity by default. This maximum can be overridden but it is extremely
-//unwise to do so.
+//Sets our luminosity.
//If we have no light it will create one.
-//If we are setting luminosity to 0 the light will be cleaned up and delted once all its queues are complete
-//if we have a light already it is merely updated
-atom/proc/SetLuminosity(new_luminosity, max_luminosity = LIGHTING_MAX_LUMINOSITY)
+//If we are setting luminosity to 0 the light will be cleaned up by the controller and garbage collected once all its
+//queues are complete.
+//if we have a light already it is merely updated, rather than making a new one.
+atom/proc/SetLuminosity(new_luminosity, trueLum = FALSE)
if(new_luminosity < 0)
new_luminosity = 0
-// world.log << "## WARNING: [type] - luminosity cannot be negative"
- else if(max_luminosity < new_luminosity)
- new_luminosity = max_luminosity
-// if(luminosity != new_luminosity)
-// world.log << "## WARNING: [type] - LIGHT_MAX_LUMINOSITY exceeded"
+ if(!trueLum)
+ new_luminosity *= new_luminosity
+ if(light)
+ if(trueLuminosity != new_luminosity) //non-luminous lights are removed from the lights list in add_effect()
+ light.changed = 1
+ else
+ if(new_luminosity)
+ light = new(src)
+ trueLuminosity = new_luminosity
+ if (trueLuminosity < 1)
+ luminosity = 0
+ else if (trueLuminosity <= 100)
+ luminosity = sqrtTable[trueLuminosity]
+ else
+ luminosity = sqrt(trueLuminosity)
- if(isturf(loc))
- if(light)
- if(luminosity != new_luminosity) //TODO: remove lights from the light list when they're not luminous? DONE in add_effect
- light.changed = 1
- else
- if(new_luminosity)
- light = new(src)
+atom/proc/AddLuminosity(delta_luminosity)
+ if(delta_luminosity > 0)
+ SetLuminosity(trueLuminosity + delta_luminosity*delta_luminosity, TRUE)
+ else if(delta_luminosity < 0)
+ SetLuminosity(trueLuminosity - delta_luminosity*delta_luminosity, TRUE)
- luminosity = new_luminosity
+area/SetLuminosity(new_luminosity) //we don't want dynamic lighting for areas
+ luminosity = !!new_luminosity
+ trueLuminosity = luminosity
-//Snowflake code to prevent mobs becoming suns (lag-prevention)
-mob/SetLuminosity(new_luminosity)
- ..(new_luminosity,LIGHTING_MAX_LUMINOSITY_MOB)
//change our opacity (defaults to toggle), and then update all lights that affect us.
-atom/proc/SetOpacity(var/new_opacity)
- if(new_opacity == null) new_opacity = !opacity
- else if(opacity == new_opacity) return
- opacity = new_opacity
+atom/proc/SetOpacity(new_opacity)
+ if(new_opacity == null)
+ new_opacity = !opacity //default = toggle opacity
+ else if(opacity == new_opacity)
+ return 0 //opacity hasn't changed! don't bother doing anything
+ opacity = new_opacity //update opacity, the below procs now call light updates.
+ return 1
- UpdateAffectingLights()
+turf/SetOpacity(new_opacity)
+ if(..()==1) //only bother if opacity changed
+ if(lighting_lumcount) //only bother with an update if our turf is currently affected by a light
+ UpdateAffectingLights()
-//set the changed status of all lights which could have possibly lit this atom.
-//We don't need to worry about lights which lit us but moved away, since they will have change status set already
-atom/proc/UpdateAffectingLights()
- var/turf/T = src
- if(!isturf(T))
- T = loc
- if(!isturf(T)) return
- for(var/atom in range(LIGHTING_MAX_LUMINOSITY,T)) //TODO: this will probably not work very well :(
- var/atom/A = atom
- if(A.light && A.luminosity)
- A.light.changed = 1 //force it to update at next process()
+/atom/movable/SetOpacity(new_opacity)
+ if(..()==1) //only bother if opacity changed
+ if(isturf(loc)) //only bother with an update if we're on a turf
+ var/turf/T = loc
+ if(T.lighting_lumcount) //only bother with an update if our turf is currently affected by a light
+ UpdateAffectingLights()
-// for(var/light in lighting_controller.lights) //TODO: this will probably laaaaaag
-// var/datum/light_source/L = light
-// if(L.changed) continue
-// if(!L.owner) continue
-// if(!L.owner.luminosity) continue
-// if(src in L.effect)
-// L.changed = 1
turf
var/lighting_lumcount = 0
var/lighting_changed = 0
+ var/color_lighting_lumcount = 0
+ var/list/colors = list()
turf/space
lighting_lumcount = 4 //starlight
-turf/proc/update_lumcount(amount)
+turf/proc/update_lumcount(amount, _lcolor, removing = 0)
lighting_lumcount += amount
-// if(lighting_lumcount < 0 || lighting_lumcount > 100)
-// world.log << "## WARNING: [type] ([src]) lighting_lumcount = [lighting_lumcount]"
+ var/blended
+
+ if (_lcolor)
+ if (removing)
+ colors.Remove(_lcolor) // Remove the color that's leaving us from our list.
+
+ if (colors && !colors.len)
+ l_color = null // All our color is gone, no color for us.
+ else if (colors && colors.len > 1)
+ var/maxdepth = 3 // Will blend 3 colors, anymore than that and it looks bad or we will get lag on every tile update.
+ var/currentblended = colors
+ if (colors.len > maxdepth)
+ currentblended = MixColors(colors.Copy(1,maxdepth+1))
+
+ if (currentblended)
+ //world << "Ended up with [currentblended]"
+ l_color = currentblended // blended the remaining colors so apply it.
+ else
+ l_color = null // Something went wrong, no color for you.
+ else
+ l_color = colors[colors.len]
+ else // we added a color.
+ colors.Add(_lcolor) // Add the base color to the list.
+ if (l_color && _lcolor && l_color != _lcolor) // Blend colors.
+ blended = MixColors(list(l_color,_lcolor))
+
+ if (blended)
+ l_color = blended // If we had a blended color, this is what we get otherwise.
+ else
+ l_color = _lcolor // Basecolor is our color.
+
+ // if ((l_color != LIGHT_WHITE && l_color != "#FFF") || removing)
+ color_lighting_lumcount = max(color_lighting_lumcount + amount, 0) // Minimum of 0.
+
if(!lighting_changed)
lighting_controller.changed_turfs += src
lighting_changed = 1
+turf/proc/lighting_tag(const/level)
+ var/area/A = loc
+ return A.tagbase + "sd_L[level]"
+
+turf/proc/build_lighting_area(const/tag, const/level, const/color_light)
+ var/area/Area = loc
+ var/area/A = new Area.type() // create area if it wasn't found
+ // replicate vars
+ for(var/V in Area.vars)
+ switch(V)
+ if ("contents","lighting_overlay", "color_overlay", "overlays")
+ continue
+ else
+ if(issaved(Area.vars[V])) A.vars[V] = Area.vars[V]
+
+ A.tag = tag
+ A.lighting_subarea = 1
+ A.lighting_space = 0 // in case it was copied from a space subarea
+
+ if (l_color != A.l_color)
+ A.l_color = l_color
+ //color_light = min(max(round(color_lighting_lumcount, 1), 0), lighting_controller.lighting_states)
+ //world << "[color_light] [color_lighting_lumcount]"
+
+ A.SetLightLevel(level, color_light)
+ Area.related += A
+ return A
+
turf/proc/shift_to_subarea()
lighting_changed = 0
var/area/Area = loc
if(!istype(Area) || !Area.lighting_use_dynamic) return
- // change the turf's area depending on its brightness
- // restrict light to valid levels
- var/light = min(max(round(lighting_lumcount,1),0),lighting_controller.lighting_states)
+ var/level = min(max(round(lighting_lumcount,1),0),lighting_controller.lighting_states)
+ var/new_tag = lighting_tag(level)
- var/find = findtextEx(Area.tag, "sd_L")
- var/new_tag = copytext(Area.tag, 1, find)
- new_tag += "sd_L[light]"
+ // pomf - If we have a lighting color that is not null, apply the new tag to seperate the areas.
+ if (l_color)
+ new_tag += "[l_color][color_lighting_lumcount]" // pomf - We append the color lighting lumcount so we can have colored lights.
if(Area.tag!=new_tag) //skip if already in this area
-
var/area/A = locate(new_tag) // find an appropriate area
+ var/color_light = min(max(round(color_lighting_lumcount,1),0),lighting_controller.lighting_states)
- if(!A)
-
- A = new Area.type() // create area if it wasn't found
- // replicate vars
- for(var/V in Area.vars)
- switch(V)
- if("contents","lighting_overlay","overlays") continue
- else
- if(issaved(Area.vars[V])) A.vars[V] = Area.vars[V]
-
- A.tag = new_tag
- A.lighting_subarea = 1
- A.SetLightLevel(light)
-
- Area.related += A
+ if (!A)
+ A = build_lighting_area(new_tag, level, color_light)
+ else if (l_color != A.l_color)
+ A.l_color = l_color
+ //color_light = min(max(round(color_lighting_lumcount, 1), 0), lighting_controller.lighting_states)
+ A.SetLightLevel(level, color_light)
A.contents += src // move the turf into the area
+// Dedicated lighting sublevel for space turfs
+// helps us depower things in space, remove space fire alarms,
+// and evens out space lighting
+turf/space/lighting_tag(var/level)
+ var/area/A = loc
+ return A.tagbase + "sd_L_space"
+turf/space/build_lighting_area(var/tag,var/level)
+ var/area/A = ..(tag,4)
+ A.lighting_space = 1
+ A.SetLightLevel(4)
+ A.icon_state = null
+ return A
+
+
area
var/lighting_use_dynamic = 1 //Turn this flag off to prevent sd_DynamicAreaLighting from affecting this area
var/image/lighting_overlay //tracks the darkness image of the area for easy removal
var/lighting_subarea = 0 //tracks whether we're a lighting sub-area
+ var/lighting_space = 0 // true for space-only lighting subareas
+ var/tagbase
+ var/image/color_overlay //Tracks the color image.
- proc/SetLightLevel(light)
+ proc/SetLightLevel(light, color_light = 0)
if(!src) return
if(light <= 0)
light = 0
@@ -291,17 +351,97 @@ area
else
lighting_overlay = image(LIGHTING_ICON,,num2text(light),LIGHTING_LAYER)
- overlays += lighting_overlay
+ if (color_overlay)
+ overlays.Remove(color_overlay)
+ color_overlay.icon_state = "5"
+ else
+ if (l_color)
+ color_overlay = image('icons/effects/effects.dmi', ,"5", 10.1)
+ //color_overlay = image('icons/effects/effects.dmi', ,"white", 10.1)
+
+ if (istype(color_overlay))
+ color_overlay.color = l_color
+
+
+ switch (color_light)
+ if (6)
+ color_overlay.icon_state = "5"
+ //color_overlay.alpha = 180
+ if (5)
+ color_overlay.icon_state = "4"
+ //color_overlay.alpha = 150
+ if (4)
+ color_overlay.icon_state = "3"
+ //color_overlay.alpha = 120
+ if (3)
+ color_overlay.icon_state = "2"
+ //color_overlay.alpha = 90
+ if (2)
+ color_overlay.icon_state = "1"
+ //color_overlay.alpha = 60
+ if (1)
+ color_overlay.icon_state = "1"
+ color_overlay.alpha = 200
+ //color_overlay.alpha = 30
+ if (-INFINITY to 0)
+ //world << "Zero or below, [color_light]."
+ color_overlay.alpha = 0
+ else
+ //world << "Setting the alpha to max... color_light [color_light]."
+ color_overlay.alpha = 180
+
+ color_overlay.blend_mode = BLEND_ADD
+ if (color_overlay.color)
+ overlays.Add(color_overlay)
+
+ if (isnull(color_overlay))
+ overlays.Add(lighting_overlay)
+ else if (light < 6)
+ overlays.Add(lighting_overlay)
+
+ proc/SetDynamicLighting()
+
+ src.lighting_use_dynamic = 1
+ for(var/turf/T in src.contents)
+ T.update_lumcount(0)
proc/InitializeLighting() //TODO: could probably improve this bit ~Carn
- if(!tag) tag = "[type]"
+ tagbase = "[type]"
+ if(!tag) tag = tagbase
if(!lighting_use_dynamic)
if(!lighting_subarea) // see if this is a lighting subarea already
//show the dark overlay so areas, not yet in a lighting subarea, won't be bright as day and look silly.
SetLightLevel(4)
+//#undef LIGHTING_LAYER
+#undef LIGHTING_CIRCULAR
+//#undef LIGHTING_ICON
-#undef LIGHTING_MAX_LUMINOSITY
-#undef LIGHTING_MAX_LUMINOSITY_MOB
-#undef LIGHTING_LAYER
-//#undef LIGHTING_ICON
\ No newline at end of file
+#define LIGHTING_MAX_LUMINOSITY_STATIC 8 //Maximum luminosity to reduce lag.
+#define LIGHTING_MAX_LUMINOSITY_MOBILE 5 //Moving objects have a lower max luminosity since these update more often. (lag reduction)
+#define LIGHTING_MAX_LUMINOSITY_TURF 1 //turfs have a severely shortened range to protect from inevitable floor-lighttile spam.
+
+//set the changed status of all lights which could have possibly lit this atom.
+//We don't need to worry about lights which lit us but moved away, since they will have change status set already
+//This proc can cause lots of lights to be updated. :(
+atom/proc/UpdateAffectingLights()
+ for(var/atom/A in oview(LIGHTING_MAX_LUMINOSITY_STATIC-1,src))
+ if(A.light)
+ A.light.changed = 1 //force it to update at next process()
+
+//caps luminosity effects max-range based on what type the light's owner is.
+atom/proc/get_light_range()
+ return min(luminosity, LIGHTING_MAX_LUMINOSITY_STATIC)
+
+atom/movable/get_light_range()
+ return min(luminosity, LIGHTING_MAX_LUMINOSITY_MOBILE)
+
+obj/machinery/light/get_light_range()
+ return min(luminosity, LIGHTING_MAX_LUMINOSITY_STATIC)
+
+turf/get_light_range()
+ return min(luminosity, LIGHTING_MAX_LUMINOSITY_TURF)
+
+#undef LIGHTING_MAX_LUMINOSITY_STATIC
+#undef LIGHTING_MAX_LUMINOSITY_MOBILE
+#undef LIGHTING_MAX_LUMINOSITY_TURF
\ No newline at end of file
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index c51528eb6e..6d578e585e 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -146,6 +146,11 @@ proc/get_id_photo(var/mob/living/carbon/human/H)
if(E.status & ORGAN_ROBOT)
temp.MapColors(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0))
preview_icon.Blend(temp, ICON_OVERLAY)
+
+ //Tail
+ if(H.species.tail && H.species.flags & HAS_TAIL)
+ temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[H.species.tail]_s")
+ preview_icon.Blend(temp, ICON_OVERLAY)
// Skin tone
if(H.species.flags & HAS_SKIN_TONE)
diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm
deleted file mode 100644
index 6d81631890..0000000000
--- a/code/datums/helper_datums/getrev.dm
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * This datum gets revision info from local svn 'entries' file
- * Path to the directory containing it should be in 'config/svndir.txt' file
- *
- */
-
-var/global/datum/getrev/revdata = new("config/svndir.txt")
-
-//Oh yeah, I'm an OOP fag, lalala
-/datum/getrev
- var/revision
- var/commiter
- var/svndirpath
- var/revhref
-
- proc/abort()
- spawn()
- del src
-
- New(filename)
- ..()
- var/list/Lines = file2list(filename)
- if(!Lines.len) return abort()
- for(var/t in Lines)
- if(!t) continue
- t = trim(t)
- if (length(t) == 0)
- continue
- else if (copytext(t, 1, 2) == "#")
- continue
- var/pos = findtext(t, " ")
- var/name = null
- var/value = null
- if (pos)
- name = lowertext(copytext(t, 1, pos))
- value = copytext(t, pos + 1)
- else
- name = lowertext(t)
- if(!name)
- continue
- switch(name)
- if("svndir")
- svndirpath = value
- if("revhref")
- revhref = value
-
- if(svndirpath && fexists(svndirpath) && fexists("[svndirpath]/entries") && isfile(file("[svndirpath]/entries")))
- var/list/filelist = file2list("[svndirpath]/entries")
- var/s_archive = "" //Stores the previous line so the revision owner can be assigned.
-
- //This thing doesn't count blank lines, so doing filelist[4] isn't working.
- for(var/s in filelist)
- if(!commiter)
- if(s == "has-props")//The line before this is the committer.
- commiter = s_archive
- if(!revision)
- var/n = text2num(s)
- if(isnum(n))
- if(n > 5000 && n < 99999) //Do you think we'll still be up and running at r100000? :) ~Errorage
- revision = s
- if(revision && commiter)
- break
- s_archive = s
- if(!revision)
- abort()
- log_misc("Revision info loaded succesfully")
- return
- return abort()
-
- proc/getRevisionText()
- var/output
- if(revhref)
- output = {"[revision]"}
- else
- output = revision
- return output
-
- proc/showInfo()
- return {"
-
-
-
- Server Revision: [getRevisionText()]
- Author: [commiter]
-
- "}
-
-client/verb/showrevinfo()
- set category = "OOC"
- set name = "Show Server Revision"
- var/output = "Sorry, the revision info is unavailable."
- output = file2text("/home/bay12/live/data/gitcommit")
- output += "Current Infomational Settings:
"
- output += "Protect Authority Roles From Traitor: [config.protect_roles_from_antagonist]
"
- usr << browse(output,"window=revdata");
- return
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 351216b8bf..3253f272d0 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -10,7 +10,7 @@
var/last_bumped = 0
var/pass_flags = 0
var/throwpass = 0
- var/germ_level = 0 // The higher the germ level, the more germ on the atom.
+ var/germ_level = GERM_LEVEL_AMBIENT // The higher the germ level, the more germ on the atom.
///Chemistry.
var/datum/reagents/reagents = null
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 1326e65e5e..41da5ea7c8 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -15,8 +15,8 @@
/atom/movable/Move()
var/atom/A = src.loc
. = ..()
- src.move_speed = world.timeofday - src.l_move_time
- src.l_move_time = world.timeofday
+ src.move_speed = world.time - src.l_move_time
+ src.l_move_time = world.time
src.m_flag = 1
if ((A != src.loc && A && A.z == src.z))
src.last_move = get_dir(A, src.loc)
diff --git a/code/game/dna/dna2_domutcheck.dm b/code/game/dna/dna2_domutcheck.dm
index 954c86f2a6..02495bbc49 100644
--- a/code/game/dna/dna2_domutcheck.dm
+++ b/code/game/dna/dna2_domutcheck.dm
@@ -6,7 +6,7 @@
#define MUTCHK_FORCED 1
/proc/domutcheck(var/mob/living/M, var/connected=null, var/flags=0)
for(var/datum/dna/gene/gene in dna_genes)
- if(!M)
+ if(!M || !M.dna)
return
if(!gene.block)
continue
diff --git a/code/game/gamemodes/autotraitor/autotraitor.dm b/code/game/gamemodes/autotraitor/autotraitor.dm
index 43dea8c32f..882f161842 100644
--- a/code/game/gamemodes/autotraitor/autotraitor.dm
+++ b/code/game/gamemodes/autotraitor/autotraitor.dm
@@ -188,7 +188,8 @@
//message_admins("The probability of a new traitor is [traitor_prob]%")
if(prob(traitor_prob))
message_admins("New traitor roll passed. Making a new Traitor.")
- forge_traitor_objectives(character.mind)
+ if (!config.objectives_disabled)
+ forge_traitor_objectives(character.mind)
equip_traitor(character)
traitors += character.mind
character << "\red You are the traitor."
diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm
index 4508c15ba0..51b321528e 100644
--- a/code/game/gamemodes/blob/theblob.dm
+++ b/code/game/gamemodes/blob/theblob.dm
@@ -87,7 +87,7 @@
return 1
return 0
-/* temperature_expose(datum/gas_mixture/air, temperature, volume) Blob is currently fireproof
+/* fire_act(datum/gas_mixture/air, temperature, volume) Blob is currently fireproof
if(temperature > T0C+200)
health -= 0.01 * temperature
update()
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index 8a3b7d075e..03780adf36 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -88,6 +88,9 @@ var/list/possible_changeling_IDs = list("Alpha","Beta","Gamma","Delta","Epsilon"
//No escape alone because changelings aren't suited for it and it'd probably just lead to rampant robusting
//If it seems like they'd be able to do it in play, add a 10% chance to have to escape alone
+ if (config.objectives_disabled)
+ return
+
var/datum/objective/absorb/absorb_objective = new
absorb_objective.owner = changeling
absorb_objective.gen_amount_goal(2, 3)
diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm
index 4e38f4fe44..d55417c5f5 100644
--- a/code/game/gamemodes/cult/cult_items.dm
+++ b/code/game/gamemodes/cult/cult_items.dm
@@ -98,7 +98,7 @@
item_state = "cult_armour"
desc = "A bulky suit of armour, bristling with spikes. It looks space proof."
w_class = 3
- allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade,/obj/item/weapon/tank/emergency_oxygen)
+ allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade,/obj/item/weapon/tank/emergency_oxygen,/obj/item/device/suit_cooling_unit)
slowdown = 1
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
siemens_coefficient = 0
\ No newline at end of file
diff --git a/code/game/gamemodes/events/biomass.dm b/code/game/gamemodes/events/biomass.dm
index d1508221f7..3b48b971f0 100644
--- a/code/game/gamemodes/events/biomass.dm
+++ b/code/game/gamemodes/events/biomass.dm
@@ -154,7 +154,7 @@
return
return
-/obj/effect/biomass/temperature_expose(null, temp, volume) //hotspots kill biomass
+/obj/effect/biomass/fire_act(null, temp, volume) //hotspots kill biomass
del src
diff --git a/code/game/gamemodes/events/ninja_equipment.dm b/code/game/gamemodes/events/ninja_equipment.dm
index d9f3801902..2a7d35b4a5 100644
--- a/code/game/gamemodes/events/ninja_equipment.dm
+++ b/code/game/gamemodes/events/ninja_equipment.dm
@@ -1367,17 +1367,20 @@ It is possible to destroy the net by the occupant or someone else.
playsound(M.loc, 'sound/effects/sparks4.ogg', 50, 1)
anim(M.loc,M,'icons/mob/mob.dmi',,"phaseout",,M.dir)
- M.loc = pick(holdingfacility)//Throw mob in to the holding facility.
- M << "\red You appear in a strange place!"
+ if(holdingfacility.len)
+ M.loc = pick(holdingfacility)//Throw mob in to the holding facility.
+ spawn(0)
+ var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
+ spark_system.set_up(5, 0, M.loc)
+ spark_system.start()
+ playsound(M.loc, 'sound/effects/phasein.ogg', 25, 1)
+ playsound(M.loc, 'sound/effects/sparks2.ogg', 50, 1)
+ anim(M.loc,M,'icons/mob/mob.dmi',,"phasein",,M.dir)
+ del(src)//Wait for everything to finish, delete the net. Else it will stop everything once net is deleted, including the spawn(0).
+ else
+ M.loc = null
- spawn(0)
- var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
- spark_system.set_up(5, 0, M.loc)
- spark_system.start()
- playsound(M.loc, 'sound/effects/phasein.ogg', 25, 1)
- playsound(M.loc, 'sound/effects/sparks2.ogg', 50, 1)
- anim(M.loc,M,'icons/mob/mob.dmi',,"phasein",,M.dir)
- del(src)//Wait for everything to finish, delete the net. Else it will stop everything once net is deleted, including the spawn(0).
+ M << "\red You appear in a strange place!"
for(var/mob/O in viewers(src, 3))
O.show_message(text("[] vanished!", M), 1, text("You hear sparks flying!"), 2)
diff --git a/code/game/gamemodes/events/spacevines.dm b/code/game/gamemodes/events/spacevines.dm
index 3ff70acbdf..b3af8195ca 100644
--- a/code/game/gamemodes/events/spacevines.dm
+++ b/code/game/gamemodes/events/spacevines.dm
@@ -239,7 +239,7 @@
return
return
-/obj/effect/spacevine/temperature_expose(null, temp, volume) //hotspots kill vines
+/obj/effect/spacevine/fire_act(null, temp, volume) //hotspots kill vines
del src
//Carn: Spacevines random event.
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index dd483fc07f..415d1362be 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -112,8 +112,6 @@ Implants;
feedback_set_details("round_start","[time2text(world.realtime)]")
if(ticker && ticker.mode)
feedback_set_details("game_mode","[ticker.mode]")
- if(revdata)
- feedback_set_details("revision","[revdata.revision]")
feedback_set_details("server_ip","[world.internet_address]:[world.port]")
return 1
diff --git a/code/game/gamemodes/meme/meme.dm b/code/game/gamemodes/meme/meme.dm
index 0f9bb44bab..71781c48e8 100644
--- a/code/game/gamemodes/meme/meme.dm
+++ b/code/game/gamemodes/meme/meme.dm
@@ -108,6 +108,9 @@
/datum/game_mode/proc/forge_meme_objectives(var/datum/mind/meme, var/datum/mind/first_host)
+ if (config.objectives_disabled)
+ return
+
// meme always needs to attune X hosts
var/datum/objective/meme_attune/attune_objective = new
attune_objective.owner = meme
diff --git a/code/game/gamemodes/ninja/ninja.dm b/code/game/gamemodes/ninja/ninja.dm
index 42f5b69d7f..33810a2e5b 100644
--- a/code/game/gamemodes/ninja/ninja.dm
+++ b/code/game/gamemodes/ninja/ninja.dm
@@ -85,6 +85,8 @@
return 1
/datum/game_mode/ninja/proc/forge_ninja_objectives(var/datum/mind/ninja)
+ if (config.objectives_disabled)
+ return
var/objective_list = list(1,2,3,4,5)
for(var/i=rand(2,4),i>0,i--)
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index 1677f27222..80f2f3a4dd 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -186,6 +186,8 @@
/datum/game_mode/proc/forge_syndicate_objectives(var/datum/mind/syndicate)
+ if (config.objectives_disabled)
+ return
var/datum/objective/nuclear/syndobj = new
syndobj.owner = syndicate
syndicate.objectives += syndobj
diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm
index 6da8a8ab8d..71076aaf28 100644
--- a/code/game/gamemodes/traitor/traitor.dm
+++ b/code/game/gamemodes/traitor/traitor.dm
@@ -78,6 +78,9 @@
/datum/game_mode/proc/forge_traitor_objectives(var/datum/mind/traitor)
+ if (config.objectives_disabled)
+ return
+
if(istype(traitor.current, /mob/living/silicon))
var/datum/objective/assassinate/kill_objective = new
kill_objective.owner = traitor
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index 751092f388..d28238e28f 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -64,6 +64,9 @@
/datum/game_mode/proc/forge_wizard_objectives(var/datum/mind/wizard)
+ if (config.objectives_disabled)
+ return
+
switch(rand(1,100))
if(1 to 30)
diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm
index d8192c5096..2ed73f8a9d 100644
--- a/code/game/jobs/job/civilian.dm
+++ b/code/game/jobs/job/civilian.dm
@@ -91,12 +91,12 @@
H.equip_to_slot_or_del(new /obj/item/clothing/suit/apron(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/device/analyzer/plant_analyzer(H), slot_s_store)
H.equip_to_slot_or_del(new /obj/item/device/pda/botanist(H), slot_belt)
- if(H.backbag == 3)
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_hyd(H), slot_back)
- else if(H.backbag == 1)
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
- else
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
+ switch(H.backbag)
+ if(1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
+ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
+ if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_hyd(H), slot_back)
+ if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
return 1
diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm
index d8a60f7b12..0eccf03f3c 100644
--- a/code/game/jobs/job/medical.dm
+++ b/code/game/jobs/job/medical.dm
@@ -71,8 +71,12 @@
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/virologist(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/virologist(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/mask/surgical(H), slot_wear_mask)
- if(H.backbag == 3)
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_vir(H), slot_back)
+ switch(H.backbag)
+ if(1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
+ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
+ if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
+ if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
if("Medical Doctor")
H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit)
@@ -122,12 +126,12 @@
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/device/pda/chemist(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/chemist(H), slot_wear_suit)
- if(H.backbag == 3)
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_chem(H), slot_back)
- else if(H.backbag == 1)
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
- else
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
+ switch(H.backbag)
+ if(1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
+ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
+ if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_chem(H), slot_back)
+ if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
return 1
@@ -153,12 +157,12 @@
H.equip_to_slot_or_del(new /obj/item/device/pda/geneticist(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/genetics(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/device/flashlight/pen(H), slot_s_store)
- if(H.backbag == 3)
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_gen(H), slot_back)
- else if(H.backbag == 1)
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
- else
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
+ switch(H.backbag)
+ if(1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
+ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
+ if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_gen(H), slot_back)
+ if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
return 1
/*/datum/job/virologist
diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm
index 385b3fadbc..60e30c085d 100644
--- a/code/game/jobs/job/science.dm
+++ b/code/game/jobs/job/science.dm
@@ -27,12 +27,12 @@
H.equip_to_slot_or_del(new /obj/item/device/pda/heads/rd(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/weapon/clipboard(H), slot_l_hand)
- if(H.backbag == 3)
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
- else if(H.backbag == 1)
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
- else
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
+ switch(H.backbag)
+ if(1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
+ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
+ if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
+ if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
return 1
@@ -57,12 +57,12 @@
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/device/pda/science(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/science(H), slot_wear_suit)
- if(H.backbag == 3)
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
- else if(H.backbag == 1)
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
- else
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
+ switch(H.backbag)
+ if(1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
+ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
+ if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
+ if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
return 1
@@ -86,12 +86,12 @@
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/white(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/device/pda/science(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/labcoat/science(H), slot_wear_suit)
- if(H.backbag == 3)
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
- else if(H.backbag == 1)
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
- else
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
+ switch(H.backbag)
+ if(1) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
+ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back)
+ if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_tox(H), slot_back)
+ if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
return 1
diff --git a/code/game/jobs/whitelist.dm b/code/game/jobs/whitelist.dm
index 2aaad4bde6..f8f3ee80a2 100644
--- a/code/game/jobs/whitelist.dm
+++ b/code/game/jobs/whitelist.dm
@@ -36,8 +36,6 @@ var/list/whitelist = list()
return 1
if(species == "human" || species == "Human")
return 1
- if(species == "machine" || species == "Machine")
- return 1
if(check_rights(R_ADMIN, 0))
return 1
if(!alien_whitelist)
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index c400185a45..ec5529c80c 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -308,6 +308,13 @@
robot = "Prosthetic:"
if(e.open)
open = "Open:"
+ switch (e.germ_level)
+ if (INFECTION_LEVEL_ONE + 50 to INFECTION_LEVEL_TWO)
+ infected = "Mild Infection:"
+ if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_THREE)
+ infected = "Acute Infection:"
+ if (INFECTION_LEVEL_THREE to INFINITY)
+ infected = "Septic:"
var/unknown_body = 0
for(var/I in e.implants)
@@ -332,8 +339,16 @@
mech = "Assisted:"
if(i.robotic == 2)
mech = "Mechanical:"
+
+ var/infection = "None"
+ switch (i.germ_level)
+ if (1 to INFECTION_LEVEL_TWO)
+ infection = "Mild Infection:"
+ if (INFECTION_LEVEL_TWO to INFINITY)
+ infection = "Acute Infection:"
+
dat += ""
- dat += "| [i.name] | N/A | [i.damage] | None:[mech] | | "
+ dat += "[i.name] | N/A | [i.damage] | [infection]:[mech] | | "
dat += "
"
dat += ""
if(occupant.sdisabilities & BLIND)
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index 33592d0bdf..c788dc6430 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -1325,7 +1325,7 @@ FIRE ALARM
else
icon_state = "fire0"
-/obj/machinery/firealarm/temperature_expose(datum/gas_mixture/air, temperature, volume)
+/obj/machinery/firealarm/fire_act(datum/gas_mixture/air, temperature, volume)
if(src.detecting)
if(temperature > T0C+200)
src.alarm() // added check of detector status here
diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm
index 64dcbe0c2f..3557f1f655 100644
--- a/code/game/machinery/atmoalter/canister.dm
+++ b/code/game/machinery/atmoalter/canister.dm
@@ -110,7 +110,7 @@ update_flag
overlays += "can-o3"
return
-/obj/machinery/portable_atmospherics/canister/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/machinery/portable_atmospherics/canister/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > temperature_resistance)
health -= 5
healthcheck()
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index d84e3271e1..ee06823cae 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -304,6 +304,21 @@
user.drop_item()
del(W)
return
+ else if (istype(W, /obj/item/weapon/wrench))
+ if(src.locked && (src.anchored || src.occupant))
+ user << "\red Can not do that while [src] is in use."
+ else
+ if(src.anchored)
+ src.anchored = 0
+ connected.pod1 = null
+ connected = null
+ else
+ src.anchored = 1
+ playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
+ if(anchored)
+ user.visible_message("[user] secures [src] to the floor.", "You secure [src] to the floor.")
+ else
+ user.visible_message("[user] unsecures [src] from the floor.", "You unsecure [src] from the floor.")
else
..()
diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm
index bb8d5fd997..528815ad07 100644
--- a/code/game/machinery/computer/crew.dm
+++ b/code/game/machinery/computer/crew.dm
@@ -108,13 +108,9 @@
/obj/machinery/computer/crew/proc/scan()
- for(var/obj/item/clothing/under/C in world)
- if((C.has_sensor) && (istype(C.loc, /mob/living/carbon/human)))
- var/check = 0
- for(var/O in src.tracked)
- if(O == C)
- check = 1
- break
- if(!check)
- src.tracked.Add(C)
+ for(var/mob/living/carbon/human/H in mob_list)
+ if(istype(H.w_uniform, /obj/item/clothing/under))
+ var/obj/item/clothing/under/C = H.w_uniform
+ if (C.has_sensor)
+ tracked |= C
return 1
\ No newline at end of file
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 37a57e7a99..cbc1cb00cf 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -277,7 +277,7 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }.
icon = 'icons/obj/doors/Doorphoron.dmi'
mineral = "phoron"
-/obj/machinery/door/airlock/phoron/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/machinery/door/airlock/phoron/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
PhoronBurn(exposed_temperature)
diff --git a/code/game/machinery/kitchen/microwave.dm b/code/game/machinery/kitchen/microwave.dm
index 0c45afb409..8113cf5985 100644
--- a/code/game/machinery/kitchen/microwave.dm
+++ b/code/game/machinery/kitchen/microwave.dm
@@ -26,7 +26,7 @@
********************/
/obj/machinery/microwave/New()
- //..() //do not need this
+ ..()
reagents = new/datum/reagents(100)
reagents.my_atom = src
if (!available_recipes)
diff --git a/code/game/machinery/podmen.dm b/code/game/machinery/podmen.dm
index 86c6b33f8e..5acd792942 100644
--- a/code/game/machinery/podmen.dm
+++ b/code/game/machinery/podmen.dm
@@ -92,7 +92,7 @@ Growing it to term with nothing injected will grab a ghost from the observers. *
/obj/item/seeds/replicapod/proc/request_player()
for(var/mob/dead/observer/O in player_list)
- if(jobban_isbanned(O, "Dionaea"))
+ if(jobban_isbanned(O, "Dionaea") || (!is_alien_whitelisted(src, "Diona") && config.usealienwhitelist))
continue
if(O.client)
if(O.client.prefs.be_special & BE_PLANT)
@@ -101,7 +101,7 @@ Growing it to term with nothing injected will grab a ghost from the observers. *
/obj/item/seeds/replicapod/proc/question(var/client/C)
spawn(0)
if(!C) return
- var/response = alert(C, "Someone is harvesting a replica pod. Would you like to play as a Dionaea?", "Replica pod harvest", "Yes", "No", "Never for this round.")
+ var/response = alert(C, "Someone is harvesting a diona pod. Would you like to play as a diona?", "Dionaea harvest", "Yes", "No", "Never for this round.")
if(!C || ckey)
return
if(response == "Yes")
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 53bf77ce57..e3465c3b7c 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -618,7 +618,7 @@
check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT),1)
return
-/obj/mecha/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/mecha/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature>src.max_temperature)
src.log_message("Exposed to dangerous temperature.",1)
src.take_damage(5,"fire")
diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm
index da510025e3..5e3ba542bf 100644
--- a/code/game/objects/effects/aliens.dm
+++ b/code/game/objects/effects/aliens.dm
@@ -287,7 +287,7 @@ Alien plants should do something if theres a lot of poison
del(src)
-/obj/effect/alien/weeds/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/effect/alien/weeds/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
health -= 5
healthcheck()
@@ -469,7 +469,7 @@ Alien plants should do something if theres a lot of poison
if(health <= 0)
Burst()
-/obj/effect/alien/egg/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/effect/alien/egg/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 500)
health -= 5
healthcheck()
diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm
index 5585c033c1..dd5ee1f8b3 100644
--- a/code/game/objects/effects/effect_system.dm
+++ b/code/game/objects/effects/effect_system.dm
@@ -27,24 +27,6 @@ would spawn and follow the beaker, even if it is carried or thrown.
reagents.delete()
return
-
-/obj/effect/effect/water/New()
- ..()
- //var/turf/T = src.loc
- //if (istype(T, /turf))
- // T.firelevel = 0 //TODO: FIX
- spawn( 70 )
- delete()
- return
- return
-
-/obj/effect/effect/water/Del()
- //var/turf/T = src.loc
- //if (istype(T, /turf))
- // T.firelevel = 0 //TODO: FIX
- ..()
- return
-
/obj/effect/effect/water/Move(turf/newloc)
//var/turf/T = src.loc
//if (istype(T, /turf))
@@ -559,7 +541,7 @@ steam.start() -- spawns the effect
// foam disolves when heated
// except metal foams
-/obj/effect/effect/foam/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/effect/effect/foam/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(!metal && prob(max(0, exposed_temperature - 475)))
flick("[icon_state]-disolve", src)
diff --git a/code/game/objects/effects/glowshroom.dm b/code/game/objects/effects/glowshroom.dm
index 425034ba48..39533b0483 100644
--- a/code/game/objects/effects/glowshroom.dm
+++ b/code/game/objects/effects/glowshroom.dm
@@ -154,7 +154,7 @@
else
return
-/obj/effect/glowshroom/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/effect/glowshroom/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
endurance -= 5
CheckEndurance()
diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm
index 522ff35af1..be54a95ba1 100644
--- a/code/game/objects/effects/spiders.dm
+++ b/code/game/objects/effects/spiders.dm
@@ -47,7 +47,7 @@
if(health <= 0)
del(src)
-/obj/effect/spider/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/effect/spider/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
health -= 5
healthcheck()
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index c0b230b4a7..22caeb2090 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -92,6 +92,17 @@ REAGENT SCANNER
usr << "\red You don't have the dexterity to do this!"
return
user.visible_message(" [user] has analyzed [M]'s vitals."," You have analyzed [M]'s vitals.")
+
+ if (!istype(M, /mob/living/carbon) || (ishuman(M) && (M:species.flags & IS_SYNTHETIC)))
+ //these sensors are designed for organic life
+ user.show_message("\blue Analyzing Results for ERROR:\n\t Overall Status: ERROR")
+ user.show_message("\t Key: Suffocation/Toxin/Burns/Brute", 1)
+ user.show_message("\t Damage Specifics: ? - ? - ? - ?")
+ user.show_message("\blue Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1)
+ user.show_message("\red Warning: Blood Level ERROR: --% --cl.\blue Type: ERROR")
+ user.show_message("\blue Subject's pulse: -- bpm.")
+ return
+
var/fake_oxy = max(rand(1,40), M.getOxyLoss(), (300 - (M.getToxLoss() + M.getFireLoss() + M.getBruteLoss())))
var/OX = M.getOxyLoss() > 50 ? "[M.getOxyLoss()]" : M.getOxyLoss()
var/TX = M.getToxLoss() > 50 ? "[M.getToxLoss()]" : M.getToxLoss()
@@ -161,7 +172,7 @@ REAGENT SCANNER
if(e.status & ORGAN_BROKEN)
if(((e.name == "l_arm") || (e.name == "r_arm") || (e.name == "l_leg") || (e.name == "r_leg")) && (!(e.status & ORGAN_SPLINTED)))
user << "\red Unsecured fracture in subject [limb]. Splinting recommended for transport."
- if(e.is_infected())
+ if(e.has_infected_wound())
user << "\red Infected wound detected in subject [limb]. Disinfection recommended."
for(var/name in H.organs_by_name)
diff --git a/code/game/objects/items/devices/suit_cooling.dm b/code/game/objects/items/devices/suit_cooling.dm
new file mode 100644
index 0000000000..f7f893ebbe
--- /dev/null
+++ b/code/game/objects/items/devices/suit_cooling.dm
@@ -0,0 +1,177 @@
+/obj/item/device/suit_cooling_unit
+ name = "portable suit cooling unit"
+ desc = "A portable heat sink and liquid cooled radiator that can be hooked up to a space suit's existing temperature controls to provide industrial levels of cooling."
+ w_class = 4
+ icon = 'icons/obj/device.dmi' //temporary, I hope
+ icon_state = "suitcooler0"
+ slot_flags = SLOT_BACK //you can carry it on your back if you want, but it won't do anything unless attached to suit storage
+
+ var/on = 0 //is it turned on?
+ var/cover_open = 0 //is the cover open?
+ var/obj/item/weapon/cell/cell
+ var/max_cooling = 12 //in degrees per second - probably don't need to mess with heat capacity here
+ var/charge_consumption = 16.6 //charge per second at max_cooling
+ var/thermostat = T20C
+
+ //TODO: make it heat up the surroundings when not in space
+
+/obj/item/device/suit_cooling_unit/New()
+ processing_objects |= src
+
+ cell = new/obj/item/weapon/cell() //comes with the crappy default power cell - high-capacity ones shouldn't be hard to find
+ cell.loc = src
+
+/obj/item/device/suit_cooling_unit/process()
+ if (!on || !cell)
+ return
+
+ if (!ismob(loc))
+ return
+
+ if (!attached_to_suit(loc)) //make sure they have a suit and we are attached to it
+ return
+
+ var/mob/living/carbon/human/H = loc
+
+ var/efficiency = H.get_pressure_protection() //you need to have a good seal for effective cooling
+ var/env_temp = get_environment_temperature() //wont save you from a fire
+ var/temp_adj = min(H.bodytemperature - max(thermostat, env_temp), max_cooling)
+
+ if (temp_adj < 0.5) //only cools, doesn't heat, also we don't need extreme precision
+ return
+
+ var/charge_usage = (temp_adj/max_cooling)*charge_consumption
+
+ H.bodytemperature -= temp_adj*efficiency
+
+ cell.use(charge_usage)
+
+ if(cell.charge <= 0)
+ turn_off()
+
+/obj/item/device/suit_cooling_unit/proc/get_environment_temperature()
+ if (ishuman(loc))
+ var/mob/living/carbon/human/H = loc
+ if(istype(H.loc, /obj/mecha))
+ var/obj/mecha/M = loc
+ return M.return_temperature()
+ else if(istype(H.loc, /obj/machinery/atmospherics/unary/cryo_cell))
+ return H.loc:air_contents.temperature
+
+ var/turf/T = get_turf(src)
+ if(istype(T, /turf/space))
+ return 0 //space has no temperature, this just makes sure the cooling unit works in space
+
+ var/datum/gas_mixture/environment = T.return_air()
+ if (!environment)
+ return 0
+
+ return environment.temperature
+
+/obj/item/device/suit_cooling_unit/proc/attached_to_suit(mob/M)
+ if (!ishuman(M))
+ return 0
+
+ var/mob/living/carbon/human/H = M
+
+ if (!H.wear_suit || H.s_store != src)
+ return 0
+
+ return 1
+
+/obj/item/device/suit_cooling_unit/proc/turn_on()
+ if(!cell)
+ return
+ if(cell.charge <= 0)
+ return
+
+ on = 1
+ updateicon()
+
+/obj/item/device/suit_cooling_unit/proc/turn_off()
+ if (ismob(src.loc))
+ var/mob/M = src.loc
+ M.show_message("\The [src] clicks and whines as it powers down.", 2) //let them know in case it's run out of power.
+ on = 0
+ updateicon()
+
+/obj/item/device/suit_cooling_unit/attack_self(mob/user as mob)
+ if(cover_open && cell)
+ if(ishuman(user))
+ user.put_in_hands(cell)
+ else
+ cell.loc = get_turf(loc)
+
+ cell.add_fingerprint(user)
+ cell.updateicon()
+
+ user << "You remove the [src.cell]."
+ src.cell = null
+ updateicon()
+ return
+
+ //TODO use a UI like the air tanks
+ if(on)
+ turn_off()
+ else
+ turn_on()
+ if (on)
+ user << "You switch on the [src]."
+
+/obj/item/device/suit_cooling_unit/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if (istype(W, /obj/item/weapon/screwdriver))
+ if(cover_open)
+ cover_open = 0
+ user << "You screw the panel into place."
+ else
+ cover_open = 1
+ user << "You unscrew the panel."
+ updateicon()
+ return
+
+ if (istype(W, /obj/item/weapon/cell))
+ if(cover_open)
+ if(cell)
+ user << "There is a [cell] already installed here."
+ else
+ user.drop_item()
+ W.loc = src
+ cell = W
+ user << "You insert the [cell]."
+ updateicon()
+ return
+
+ return ..()
+
+/obj/item/device/suit_cooling_unit/proc/updateicon()
+ if (cover_open)
+ if (cell)
+ icon_state = "suitcooler1"
+ else
+ icon_state = "suitcooler2"
+ else
+ icon_state = "suitcooler0"
+
+/obj/item/device/suit_cooling_unit/examine()
+ set src in view(1)
+
+ ..()
+
+ if (on)
+ if (attached_to_suit(src.loc))
+ usr << "It's switched on and running."
+ else
+ usr << "It's switched on, but not attached to anything."
+ else
+ usr << "It is switched off."
+
+ if (cover_open)
+ if(cell)
+ usr << "The panel is open, exposing the [cell]."
+ else
+ usr << "The panel is open."
+
+ if (cell)
+ usr << "The charge meter reads [round(cell.percent())]%."
+ else
+ usr << "It doesn't have a power cell installed."
\ No newline at end of file
diff --git a/code/game/objects/items/latexballoon.dm b/code/game/objects/items/latexballoon.dm
index 9b6895e0d9..a923de6183 100644
--- a/code/game/objects/items/latexballoon.dm
+++ b/code/game/objects/items/latexballoon.dm
@@ -38,7 +38,7 @@
/obj/item/latexballon/bullet_act()
burst()
-/obj/item/latexballon/temperature_expose(datum/gas_mixture/air, temperature, volume)
+/obj/item/latexballon/fire_act(datum/gas_mixture/air, temperature, volume)
if(temperature > T0C+100)
burst()
return
diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm
index 8ba8879636..72339452e7 100644
--- a/code/game/objects/items/stacks/sheets/leather.dm
+++ b/code/game/objects/items/stacks/sheets/leather.dm
@@ -117,7 +117,7 @@
//Step two - washing..... it's actually in washing machine code.
//Step three - drying
-/obj/item/stack/sheet/wetleather/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/item/stack/sheet/wetleather/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
..()
if(exposed_temperature >= drying_threshold_temperature)
wetness--
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 301f01aeb5..c89b115071 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -1,14 +1,18 @@
/* Toys!
- * ContainsL
+ * Contains:
* Balloons
* Fake telebeacon
* Fake singularity
* Toy gun
* Toy crossbow
* Toy swords
+ * Toy mechs
* Crayons
* Snap pops
* Water flower
+ * Therapy dolls
+ * Toddler doll
+ * Inflatable duck
*/
@@ -579,6 +583,55 @@
w_class = 3
attack_verb = list("attacked", "slashed", "stabbed", "sliced")
+/obj/item/toy/therapy_red
+ name = "red therapy doll"
+ desc = "A toy for therapeutic and recreational purposes. This one is red."
+ icon = 'icons/obj/weapons.dmi'
+ icon_state = "therapyred"
+ item_state = "egg4" // It's the red egg in items_left/righthand
+ w_class = 1
+
+/obj/item/toy/therapy_purple
+ name = "purple therapy doll"
+ desc = "A toy for therapeutic and recreational purposes. This one is purple."
+ icon = 'icons/obj/weapons.dmi'
+ icon_state = "therapypurple"
+ item_state = "egg1" // It's the magenta egg in items_left/righthand
+ w_class = 1
+
+/obj/item/toy/therapy_blue
+ name = "blue therapy doll"
+ desc = "A toy for therapeutic and recreational purposes. This one is blue."
+ icon = 'icons/obj/weapons.dmi'
+ icon_state = "therapyblue"
+ item_state = "egg2" // It's the blue egg in items_left/righthand
+ w_class = 1
+
+/obj/item/toy/therapy_yellow
+ name = "yellow therapy doll"
+ desc = "A toy for therapeutic and recreational purposes. This one is yellow."
+ icon = 'icons/obj/weapons.dmi'
+ icon_state = "therapyyellow"
+ item_state = "egg5" // It's the yellow egg in items_left/righthand
+ w_class = 1
+
+/obj/item/toy/therapy_orange
+ name = "orange therapy doll"
+ desc = "A toy for therapeutic and recreational purposes. This one is orange."
+ icon = 'icons/obj/weapons.dmi'
+ icon_state = "therapyorange"
+ item_state = "egg4" // It's the red one again, lacking an orange item_state and making a new one is pointless
+ w_class = 1
+
+/obj/item/toy/therapy_green
+ name = "green therapy doll"
+ desc = "A toy for therapeutic and recreational purposes. This one is green."
+ icon = 'icons/obj/weapons.dmi'
+ icon_state = "therapygreen"
+ item_state = "egg3" // It's the green egg in items_left/righthand
+ w_class = 1
+
+
/* NYET.
/obj/item/weapon/toddler
icon_state = "toddler"
@@ -590,6 +643,7 @@
*/
//This should really be somewhere else but I don't know where. w/e
+
/obj/item/weapon/inflatable_duck
name = "inflatable duck"
desc = "No bother to sink or swim when you can just float!"
diff --git a/code/game/objects/items/weapons/extinguisher.dm b/code/game/objects/items/weapons/extinguisher.dm
index 513d2e3a3a..219843e68b 100644
--- a/code/game/objects/items/weapons/extinguisher.dm
+++ b/code/game/objects/items/weapons/extinguisher.dm
@@ -127,6 +127,7 @@
W.reagents.reaction(atm)
if(W.loc == my_target) break
sleep(2)
+ W.delete()
if((istype(usr.loc, /turf/space)) || (usr.lastarea.has_gravity == 0))
user.inertia_dir = get_dir(target, user)
diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm
index 4024e5275e..2716719fda 100644
--- a/code/game/objects/items/weapons/grenades/flashbang.dm
+++ b/code/game/objects/items/weapons/grenades/flashbang.dm
@@ -7,19 +7,21 @@
prime()
..()
- for(var/obj/structure/closet/L in view(get_turf(src), null))
+ for(var/obj/structure/closet/L in hear(7, get_turf(src)))
if(locate(/mob/living/carbon/, L))
for(var/mob/living/carbon/M in L)
bang(get_turf(src), M)
- for(var/mob/living/carbon/M in viewers(get_turf(src), null))
+ for(var/mob/living/carbon/M in hear(7, get_turf(src)))
bang(get_turf(src), M)
- for(var/obj/effect/blob/B in view(8,get_turf(src))) //Blob damage here
+ for(var/obj/effect/blob/B in hear(8,get_turf(src))) //Blob damage here
var/damage = round(30/(get_dist(B,get_turf(src))+1))
B.health -= damage
B.update_icon()
+
+ new/obj/effect/effect/smoke/flashbang(src.loc)
del(src)
return
@@ -30,7 +32,7 @@
S.icon_state = "shield0"
M << "\red BANG"
- playsound(src.loc, 'sound/effects/bang.ogg', 25, 1)
+ playsound(src.loc, 'sound/effects/bang.ogg', 50, 1, 5)
//Checking for protections
var/eye_safety = 0
@@ -98,6 +100,15 @@
M << "\red Your ears start to ring!"
M.update_icons()
+/obj/effect/effect/smoke/flashbang
+ name = "illumination"
+ time_to_live = 10
+ opacity = 0
+ icon_state = "sparks"
+
+/obj/effect/effect/smoke/flashbang/New()
+ ..()
+ SetLuminosity(15)
/obj/item/weapon/grenade/flashbang/clusterbang//Created by Polymorph, fixed by Sieve
desc = "Use of this weapon may constiute a war crime in your area, consult your local captain."
diff --git a/code/game/objects/items/weapons/kitchen.dm b/code/game/objects/items/weapons/kitchen.dm
index 2d1cf24098..7244d45520 100644
--- a/code/game/objects/items/weapons/kitchen.dm
+++ b/code/game/objects/items/weapons/kitchen.dm
@@ -25,86 +25,65 @@
flags = FPRINT | TABLEPASS | CONDUCT
origin_tech = "materials=1"
attack_verb = list("attacked", "stabbed", "poked")
+ sharp = 0
+
+ var/loaded //Descriptive string for currently loaded food object.
/obj/item/weapon/kitchen/utensil/New()
if (prob(60))
src.pixel_y = rand(0, 4)
return
-/*
- * Spoons
- */
-/obj/item/weapon/kitchen/utensil/spoon
- name = "spoon"
- desc = "SPOON!"
- icon_state = "spoon"
- attack_verb = list("attacked", "poked")
+ create_reagents(5)
-/obj/item/weapon/kitchen/utensil/pspoon
- name = "plastic spoon"
- desc = "Super dull action!"
- icon_state = "pspoon"
- attack_verb = list("attacked", "poked")
-
-/*
- * Forks
- */
-/obj/item/weapon/kitchen/utensil/fork
- name = "fork"
- desc = "Pointy."
- icon_state = "fork"
- sharp = 1
-
-/obj/item/weapon/kitchen/utensil/fork/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
+/obj/item/weapon/kitchen/utensil/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
if(!istype(M))
return ..()
- if(user.zone_sel.selecting != "eyes" && user.zone_sel.selecting != "head")
- return ..()
+ if(user.a_intent != "help")
+ if(user.zone_sel.selecting == "head" || user.zone_sel.selecting == "eyes")
+ if((CLUMSY in user.mutations) && prob(50))
+ M = user
+ return eyestab(M,user)
+ else
+ return ..()
- if (src.icon_state == "forkloaded") //This is a poor way of handling it, but a proper rewrite of the fork to allow for a more varied foodening can happen when I'm in the mood. --NEO
+ if (reagents.total_volume > 0)
+ reagents.trans_to_ingest(M, reagents.total_volume)
if(M == user)
for(var/mob/O in viewers(M, null))
- O.show_message(text("\blue [] eats a delicious forkful of omelette!", user), 1)
+ O.show_message(text("\blue [] eats some [] from \the [].", user, loaded, src), 1)
M.reagents.add_reagent("nutriment", 1)
else
for(var/mob/O in viewers(M, null))
- O.show_message(text("\blue [] feeds [] a delicious forkful of omelette!", user, M), 1)
+ O.show_message(text("\blue [] feeds [] some [] from \the []", user, M, loaded, src), 1)
M.reagents.add_reagent("nutriment", 1)
- src.icon_state = "fork"
+
+ overlays.Cut()
return
- else
- if((CLUMSY in user.mutations) && prob(50))
- M = user
- return eyestab(M,user)
+
+/obj/item/weapon/kitchen/utensil/fork
+ name = "fork"
+ desc = "It's a fork. Sure is pointy."
+ icon_state = "fork"
+ sharp = 1
/obj/item/weapon/kitchen/utensil/pfork
name = "plastic fork"
desc = "Yay, no washing up to do."
icon_state = "pfork"
-/obj/item/weapon/kitchen/utensil/pfork/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob)
- if(!istype(M))
- return ..()
+/obj/item/weapon/kitchen/utensil/spoon
+ name = "spoon"
+ desc = "It's a spoon. You can see your own upside-down face in it."
+ icon_state = "spoon"
+ attack_verb = list("attacked", "poked")
- if(user.zone_sel.selecting != "eyes" && user.zone_sel.selecting != "head")
- return ..()
-
- if (src.icon_state == "forkloaded") //This is a poor way of handling it, but a proper rewrite of the fork to allow for a more varied foodening can happen when I'm in the mood. --NEO
- if(M == user)
- for(var/mob/O in viewers(M, null))
- O.show_message(text("\blue [] eats a delicious forkful of omelette!", user), 1)
- M.reagents.add_reagent("nutriment", 1)
- else
- for(var/mob/O in viewers(M, null))
- O.show_message(text("\blue [] feeds [] a delicious forkful of omelette!", user, M), 1)
- M.reagents.add_reagent("nutriment", 1)
- src.icon_state = "fork"
- return
- else
- if((CLUMSY in user.mutations) && prob(50))
- M = user
- return eyestab(M,user)
+/obj/item/weapon/kitchen/utensil/pspoon
+ name = "plastic spoon"
+ desc = "It's a plastic spoon. How dull."
+ icon_state = "pspoon"
+ attack_verb = list("attacked", "poked")
/*
* Knives
@@ -477,49 +456,4 @@
for(var/i = 1, i <= rand(1,2), i++)
if(I)
step(I, pick(NORTH,SOUTH,EAST,WEST))
- sleep(rand(2,4))
-
-
-
-
-
-/////////////////////////////////////////////////////////////////////////////////////////
-//Enough with the violent stuff, here's what happens if you try putting food on it
-/////////////////////////////////////////////////////////////////////////////////////////////
-
-
-
-/*/obj/item/weapon/tray/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if(istype(W,/obj/item/weapon/kitchen/utensil/fork))
- if (W.icon_state == "forkloaded")
- user << "\red You already have omelette on your fork."
- return
- W.icon = 'icons/obj/kitchen.dmi'
- W.icon_state = "forkloaded"
- viewers(3,user) << "[user] takes a piece of omelette with his fork!"
- reagents.remove_reagent("nutriment", 1)
- if (reagents.total_volume <= 0)
- del(src)*/
-
-
-/* if (prob(33))
- var/turf/location = H.loc
- if (istype(location, /turf/simulated))
- location.add_blood(H)
- if (H.wear_mask)
- H.wear_mask.add_blood(H)
- if (H.head)
- H.head.add_blood(H)
- if (H.glasses && prob(33))
- H.glasses.add_blood(H)
- if (istype(user, /mob/living/carbon/human))
- var/mob/living/carbon/human/user2 = user
- if (user2.gloves)
- user2.gloves.add_blood(H)
- else
- user2.add_blood(H)
- if (prob(15))
- if (user2.wear_suit)
- user2.wear_suit.add_blood(H)
- else if (user2.w_uniform)
- user2.w_uniform.add_blood(H)*/
\ No newline at end of file
+ sleep(rand(2,4))
diff --git a/code/game/objects/items/weapons/paint.dm b/code/game/objects/items/weapons/paint.dm
index 96e66d7bee..2c0e1d812d 100644
--- a/code/game/objects/items/weapons/paint.dm
+++ b/code/game/objects/items/weapons/paint.dm
@@ -182,16 +182,12 @@ datum/reagent/paint
reaction_turf(var/turf/T, var/volume)
if(!istype(T) || istype(T, /turf/space))
return
- var/ind = "[initial(T.icon)][color]"
- if(!cached_icons[ind])
- var/icon/overlay = new/icon(initial(T.icon))
- overlay.Blend(color,ICON_MULTIPLY)
- overlay.SetIntensity(1.4)
- T.icon = overlay
- cached_icons[ind] = T.icon
- else
- T.icon = cached_icons[ind]
- return
+ T.color = color
+
+ reaction_obj(var/obj/O, var/volume)
+ ..()
+ if(istype(O,/obj/item/weapon/light))
+ O.color = color
red
name = "Red Paint"
diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm
index 06f1270f96..86bbd13651 100644
--- a/code/game/objects/items/weapons/storage/boxes.dm
+++ b/code/game/objects/items/weapons/storage/boxes.dm
@@ -48,6 +48,8 @@
/obj/item/weapon/storage/box/gloves
name = "box of latex gloves"
desc = "Contains white gloves."
+ icon_state = "latex"
+
New()
..()
new /obj/item/clothing/gloves/latex(src)
diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm
index 6623c99cb3..8b883f818a 100644
--- a/code/game/objects/items/weapons/tanks/tanks.dm
+++ b/code/game/objects/items/weapons/tanks/tanks.dm
@@ -6,6 +6,7 @@
icon = 'icons/obj/tank.dmi'
flags = FPRINT | TABLEPASS | CONDUCT
slot_flags = SLOT_BACK
+ w_class = 3
pressure_resistance = ONE_ATMOSPHERE*5
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index fdbb5195f5..b489a69b56 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -121,6 +121,8 @@
/obj/proc/hear_talk(mob/M as mob, text)
+ if(talking_atom)
+ talking_atom.catchMessage(text, M)
/*
var/mob/mo = locate(/mob) in src
if(mo)
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index 97d7657d36..bb50f1d63d 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -216,7 +216,7 @@
return 0
return 0
-/obj/structure/grille/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/grille/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(!destroyed)
if(exposed_temperature > T0C + 1500)
health -= 1
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index 38f0563897..fdb8444370 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -82,6 +82,7 @@
state = 1
update_icon()
isSwitchingStates = 0
+ update_nearby_tiles()
proc/Close()
isSwitchingStates = 1
@@ -93,6 +94,7 @@
state = 0
update_icon()
isSwitchingStates = 0
+ update_nearby_tiles()
update_icon()
if(state)
@@ -198,7 +200,7 @@
TemperatureAct(100)
..()
- temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+ fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
TemperatureAct(exposed_temperature)
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 8812b1ed4f..2c9b755f56 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -361,7 +361,7 @@
return
-/obj/structure/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/window/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > T0C + 800)
hit(round(exposed_volume / 100), 0)
..()
@@ -381,7 +381,7 @@
shardtype = /obj/item/weapon/shard/phoron
health = 120
-/obj/structure/window/phoronbasic/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/window/phoronbasic/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > T0C + 32000)
hit(round(exposed_volume / 1000), 0)
..()
@@ -395,7 +395,7 @@
reinf = 1
health = 160
-/obj/structure/window/phoronreinforced/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/structure/window/phoronreinforced/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return
/obj/structure/window/reinforced
diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm
index dd70ad37ea..b62c32b81a 100644
--- a/code/game/turfs/simulated.dm
+++ b/code/game/turfs/simulated.dm
@@ -144,8 +144,11 @@
for(var/obj/effect/decal/cleanable/blood/B in contents)
if(!B.blood_DNA[M.dna.unique_enzymes])
B.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
+ B.virus2 = virus_copylist(M.virus2)
return 1 //we bloodied the floor
+
+
//if there isn't a blood decal already, make one.
var/obj/effect/decal/cleanable/blood/newblood = new /obj/effect/decal/cleanable/blood(src)
@@ -156,6 +159,7 @@
newblood.basecolor = "#A10808"
newblood.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
+ newblood.virus2 = virus_copylist(M.virus2)
newblood.update_icon()
return 1 //we bloodied the floor
diff --git a/code/game/turfs/simulated/walls_mineral.dm b/code/game/turfs/simulated/walls_mineral.dm
index b600b11dcd..8834a7770b 100644
--- a/code/game/turfs/simulated/walls_mineral.dm
+++ b/code/game/turfs/simulated/walls_mineral.dm
@@ -104,7 +104,7 @@
for(var/obj/machinery/door/airlock/phoron/D in range(3,src))
D.ignite(temperature/4)
-/turf/simulated/wall/mineral/phoron/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)//Doesn't fucking work because walls don't interact with air :(
+/turf/simulated/wall/mineral/phoron/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)//Doesn't fucking work because walls don't interact with air :(
if(exposed_temperature > 300)
PhoronBurn(exposed_temperature)
diff --git a/code/global.dm b/code/global.dm
index ef34efdf15..1eb82f08cd 100644
--- a/code/global.dm
+++ b/code/global.dm
@@ -252,3 +252,6 @@ var/DBConnection/dbcon_old = new() //Tgstation database (Old database) - See the
// Reference list for disposal sort junctions. Filled up by sorting junction's New()
/var/list/tagger_locations = list()
+
+//added for Xenoarchaeology, might be useful for other stuff
+var/global/list/alphabet_uppercase = list("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z")
diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm
index efea3d1609..bdc93347ff 100644
--- a/code/modules/admin/verbs/adminpm.dm
+++ b/code/modules/admin/verbs/adminpm.dm
@@ -114,7 +114,7 @@
//play the recieving admin the adminhelp sound (if they have them enabled)
//non-admins shouldn't be able to disable this
- if(C.prefs.toggles & SOUND_ADMINHELP)
+ if(C.prefs && C.prefs.toggles & SOUND_ADMINHELP)
C << 'sound/effects/adminhelp.ogg'
log_admin("PM: [key_name(src)]->[key_name(C)]: [msg]")
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 84acdb6aca..76e4bb01d2 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -220,7 +220,7 @@ BLIND // can't see anything
permeability_coefficient = 0.02
flags = FPRINT | TABLEPASS | STOPSPRESSUREDMAGE | THICKMATERIAL
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
- allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen)
+ allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen,/obj/item/device/suit_cooling_unit)
slowdown = 3
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 50)
flags_inv = HIDEGLOVES|HIDESHOES|HIDEJUMPSUIT|HIDETAIL
diff --git a/code/modules/clothing/spacesuits/ninja.dm b/code/modules/clothing/spacesuits/ninja.dm
index c146bb21a5..c51594e0e6 100644
--- a/code/modules/clothing/spacesuits/ninja.dm
+++ b/code/modules/clothing/spacesuits/ninja.dm
@@ -13,7 +13,7 @@
desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins."
icon_state = "s-ninja"
item_state = "s-ninja_suit"
- allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank,/obj/item/weapon/cell)
+ allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/handcuffs,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/cell)
slowdown = 0
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
siemens_coefficient = 0.2
diff --git a/code/modules/clothing/spacesuits/rig.dm b/code/modules/clothing/spacesuits/rig.dm
index ab3f723674..995e116717 100644
--- a/code/modules/clothing/spacesuits/rig.dm
+++ b/code/modules/clothing/spacesuits/rig.dm
@@ -55,7 +55,7 @@
item_state = "eng_hardsuit"
slowdown = 1
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 80)
- allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd)
+ allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd)
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
@@ -359,7 +359,7 @@
slowdown = 1
w_class = 3
armor = list(melee = 60, bullet = 50, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 60)
- allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs)
+ allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs)
siemens_coefficient = 0.6
species_restricted = list("exclude","Unathi","Tajaran","Skrell","Vox")
@@ -402,7 +402,7 @@
name = "medical hardsuit"
desc = "A special suit that protects against hazardous, low pressure environments. Has minor radiation shielding."
item_state = "medical_hardsuit"
- allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical)
+ allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical)
armor = list(melee = 30, bullet = 5, laser = 20,energy = 5, bomb = 25, bio = 100, rad = 50)
//Security
@@ -421,7 +421,7 @@
desc = "A special suit that protects against hazardous, low pressure environments. Has an additional layer of armor."
item_state = "sec_hardsuit"
armor = list(melee = 60, bullet = 10, laser = 30, energy = 5, bomb = 45, bio = 100, rad = 10)
- allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/weapon/melee/baton)
+ allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/melee/baton)
siemens_coefficient = 0.7
diff --git a/code/modules/customitems/item_spawning.dm b/code/modules/customitems/item_spawning.dm
index 8682f6f69e..38f50bf742 100644
--- a/code/modules/customitems/item_spawning.dm
+++ b/code/modules/customitems/item_spawning.dm
@@ -4,12 +4,15 @@
//for multiple items just add mutliple entries, unless i change it to be a listlistlist
//yes, it has to be an item, you can't pick up nonitems
-/proc/EquipCustomItems(mob/living/carbon/human/M)
- // load lines
- var/file = file2text("config/custom_items.txt")
- var/lines = text2list(file, "\n")
+/var/list/custom_items = list()
- for(var/line in lines)
+/hook/startup/proc/loadCustomItems()
+ var/custom_items_file = file2text("config/custom_items.txt")
+ custom_items = text2list(custom_items_file, "\n")
+ return 1
+
+/proc/EquipCustomItems(mob/living/carbon/human/M)
+ for(var/line in custom_items)
// split & clean up
var/list/Entry = text2list(line, ":")
for(var/i = 1 to Entry.len)
@@ -24,6 +27,8 @@
var/ok = 0 // 1 if the item was placed successfully
P = trim(P)
var/path = text2path(P)
+ if(!path) continue
+
var/obj/item/Item = new path()
if(istype(Item,/obj/item/weapon/card/id))
//id card needs to replace the original ID
diff --git a/code/modules/events/organ_failure.dm b/code/modules/events/organ_failure.dm
index 80e7f807dd..1499afcb45 100644
--- a/code/modules/events/organ_failure.dm
+++ b/code/modules/events/organ_failure.dm
@@ -21,9 +21,25 @@ datum/event/organ_failure/start()
while(severity > 0 && candidates.len)
var/mob/living/carbon/human/C = candidates[1]
- // Bruise one of their organs
- var/O = pick(C.internal_organs)
- var/datum/organ/internal/I = C.internal_organs[O]
- I.damage = I.min_bruised_damage
- candidates.Remove(C)
- severity--
\ No newline at end of file
+ var/acute = prob(15)
+ if (prob(75))
+ //internal organ infection
+ var/O = pick(C.internal_organs)
+ var/datum/organ/internal/I = C.internal_organs[O]
+
+ if (acute)
+ I.germ_level = max(INFECTION_LEVEL_TWO, I.germ_level)
+ else
+ I.germ_level = max(rand(INFECTION_LEVEL_ONE,INFECTION_LEVEL_ONE*2), I.germ_level)
+ else
+ //external organ infection
+ var/datum/organ/external/O = pick(C.organs)
+
+ if (acute)
+ O.germ_level = max(INFECTION_LEVEL_TWO, O.germ_level)
+ else
+ O.germ_level = max(rand(INFECTION_LEVEL_ONE,INFECTION_LEVEL_ONE*2), O.germ_level)
+
+ C.bad_external_organs |= O
+
+ severity--
diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm
index e359196946..3489854b98 100644
--- a/code/modules/mining/mine_turfs.dm
+++ b/code/modules/mining/mine_turfs.dm
@@ -1,9 +1,6 @@
/**********************Mineral deposits**************************/
-datum/controller/game_controller/var/list/artifact_spawning_turfs = list()
-var/list/artifact_spawn = list() // Runtime fix for geometry loading before controller is instantiated.
-
/turf/simulated/mineral //wall piece
name = "Rock"
icon = 'icons/turf/walls.dmi'
@@ -39,19 +36,19 @@ var/list/artifact_spawn = list() // Runtime fix for geometry loading before cont
if((istype(get_step(src, NORTH), /turf/simulated/floor)) || (istype(get_step(src, NORTH), /turf/space)) || (istype(get_step(src, NORTH), /turf/simulated/shuttle/floor)))
T = get_step(src, NORTH)
if (T)
- T.overlays += image('icons/turf/walls.dmi', "rock_side_s")
+ T.overlays += image('icons/turf/walls.dmi', "rock_side_s", layer=2)
if((istype(get_step(src, SOUTH), /turf/simulated/floor)) || (istype(get_step(src, SOUTH), /turf/space)) || (istype(get_step(src, SOUTH), /turf/simulated/shuttle/floor)))
T = get_step(src, SOUTH)
if (T)
- T.overlays += image('icons/turf/walls.dmi', "rock_side_n", layer=6)
+ T.overlays += image('icons/turf/walls.dmi', "rock_side_n", layer=2)
if((istype(get_step(src, EAST), /turf/simulated/floor)) || (istype(get_step(src, EAST), /turf/space)) || (istype(get_step(src, EAST), /turf/simulated/shuttle/floor)))
T = get_step(src, EAST)
if (T)
- T.overlays += image('icons/turf/walls.dmi', "rock_side_w", layer=6)
+ T.overlays += image('icons/turf/walls.dmi', "rock_side_w", layer=2)
if((istype(get_step(src, WEST), /turf/simulated/floor)) || (istype(get_step(src, WEST), /turf/space)) || (istype(get_step(src, WEST), /turf/simulated/shuttle/floor)))
T = get_step(src, WEST)
if (T)
- T.overlays += image('icons/turf/walls.dmi', "rock_side_e", layer=6)
+ T.overlays += image('icons/turf/walls.dmi', "rock_side_e", layer=2)
ex_act(severity)
@@ -480,6 +477,12 @@ var/list/artifact_spawn = list() // Runtime fix for geometry loading before cont
for(var/obj/item/weapon/ore/O in contents)
O.attackby(W,user)
return
+ else if(istype(W,/obj/item/weapon/storage/bag/fossils))
+ var/obj/item/weapon/storage/bag/fossils/S = W
+ if(S.collection_mode)
+ for(var/obj/item/weapon/fossil/F in contents)
+ F.attackby(W,user)
+ return
else
..(W,user)
diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm
index f156134438..4edcbd3dc7 100644
--- a/code/modules/mob/living/carbon/alien/special/facehugger.dm
+++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm
@@ -72,7 +72,7 @@ var/const/MAX_ACTIVE_TIME = 400
Die()
return
-/obj/item/clothing/mask/facehugger/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/item/clothing/mask/facehugger/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
Die()
return
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 0e6d130a56..64e70e05b9 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -1,3 +1,10 @@
+/mob/living/carbon/Life()
+ ..()
+
+ // Increase germ_level regularly
+ if(germ_level < GERM_LEVEL_AMBIENT && prob(80)) //if you're just standing there, you shouldn't get more germs beyond an ambient level
+ germ_level++
+
/mob/living/carbon/Move(NewLoc, direct)
. = ..()
if(.)
@@ -7,6 +14,10 @@
src.nutrition -= HUNGER_FACTOR/10
if((FAT in src.mutations) && src.m_intent == "run" && src.bodytemperature <= 360)
src.bodytemperature += 2
+
+ // Moving around increases germ_level faster
+ if(germ_level < GERM_LEVEL_MOVE_CAP && prob(8))
+ germ_level++
/mob/living/carbon/relaymove(var/mob/user, direction)
if(user in src.stomach_contents)
@@ -252,11 +263,13 @@
/mob/living/carbon/proc/throw_mode_off()
src.in_throw_mode = 0
- src.throw_icon.icon_state = "act_throw_off"
+ if(src.throw_icon) //in case we don't have the HUD and we use the hotkey
+ src.throw_icon.icon_state = "act_throw_off"
/mob/living/carbon/proc/throw_mode_on()
src.in_throw_mode = 1
- src.throw_icon.icon_state = "act_throw_on"
+ if(src.throw_icon)
+ src.throw_icon.icon_state = "act_throw_on"
/mob/proc/throw_item(atom/target)
return
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 9cc0e22dfc..6ce436e12a 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -243,7 +243,7 @@
msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
if(!key && brain_op_stage != 4 && stat != DEAD)
- msg += "[t_He] [t_is] totally catatonic. The stresses of life in deep-space must have been too much for [t_him]. Any recovery is unlikely\n"
+ msg += "[t_He] [t_is] fast asleep. It doesn't look like they are waking up anytime soon.\n"
else if(!client && brain_op_stage != 4 && stat != DEAD)
msg += "[t_He] [t_has] suddenly fallen asleep.\n"
@@ -262,7 +262,7 @@
wound_flavor_text["[temp.display_name]"] = "[t_He] has a robot [temp.display_name]!\n"
continue
else
- wound_flavor_text["[temp.display_name]"] = "[t_He] has a robot [temp.display_name], it has"
+ wound_flavor_text["[temp.display_name]"] = "[t_He] has a robot [temp.display_name]. It has"
if(temp.brute_dam) switch(temp.brute_dam)
if(0 to 20)
wound_flavor_text["[temp.display_name]"] += " some dents"
@@ -284,8 +284,8 @@
var/this_wound_desc = W.desc
if(W.bleeding()) this_wound_desc = "bleeding [this_wound_desc]"
else if(W.bandaged) this_wound_desc = "bandaged [this_wound_desc]"
- if(W.germ_level > 1000) this_wound_desc = "badly infected [this_wound_desc]"
- else if(W.germ_level > 100) this_wound_desc = "lightly infected [this_wound_desc]"
+ if(W.germ_level > 600) this_wound_desc = "badly infected [this_wound_desc]"
+ else if(W.germ_level > 330) this_wound_desc = "lightly infected [this_wound_desc]"
if(this_wound_desc in wound_descriptors)
wound_descriptors[this_wound_desc] += W.amount
continue
@@ -389,7 +389,7 @@
msg += "[src] has blood running from under [t_his] gloves!\n"
for(var/implant in get_visible_implants(1))
- msg += "[src] has \a [implant] sticking out of their flesh!\n"
+ msg += "[src] has \a [implant] sticking out of [t_his] flesh!\n"
if(digitalcamo)
msg += "[t_He] [t_is] repulsively uncanny!\n"
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 7cdcfca052..7f668cf2f1 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1220,7 +1220,7 @@
return
usr << "Don't move until counting is finished."
- var/time = world.timeofday
+ var/time = world.time
sleep(60)
if(usr.l_move_time >= time) //checks if our mob has moved during the sleep()
usr << "You moved while counting. Try again."
diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm
index 0688f13428..086b098999 100644
--- a/code/modules/mob/living/carbon/human/human_damage.dm
+++ b/code/modules/mob/living/carbon/human/human_damage.dm
@@ -65,13 +65,13 @@
if (organ_name in organs_by_name)
var/datum/organ/external/O = get_organ(organ_name)
-
+
if(amount > 0)
O.take_damage(amount, 0, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
else
//if you don't want to heal robot organs, they you will have to check that yourself before using this proc.
O.heal_damage(-amount, 0, internal=0, robo_repair=(O.status & ORGAN_ROBOT))
-
+
hud_updateflag |= 1 << HEALTH_HUD
/mob/living/carbon/human/proc/adjustFireLossByPart(var/amount, var/organ_name, var/obj/damage_source = null)
@@ -80,13 +80,13 @@
if (organ_name in organs_by_name)
var/datum/organ/external/O = get_organ(organ_name)
-
+
if(amount > 0)
O.take_damage(0, amount, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
else
//if you don't want to heal robot organs, they you will have to check that yourself before using this proc.
O.heal_damage(0, -amount, internal=0, robo_repair=(O.status & ORGAN_ROBOT))
-
+
hud_updateflag |= 1 << HEALTH_HUD
/mob/living/carbon/human/Stun(amount)
@@ -302,14 +302,6 @@ This function restores all organs.
if(istype(used_weapon,/obj/item/weapon))
var/obj/item/weapon/W = used_weapon //Sharp objects will always embed if they do enough damage.
if( (damage > (10*W.w_class)) && ( (sharp && !ismob(W.loc)) || prob(damage/W.w_class) ) )
- organ.implants += W
- visible_message("\The [W] sticks in the wound!")
- embedded_flag = 1
- src.verbs += /mob/proc/yank_out_object
- W.add_blood(src)
- if(ismob(W.loc))
- var/mob/living/H = W.loc
- H.drop_item()
- W.loc = src
+ organ.embed(W)
return 1
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index a98955d0c8..baa1ebb145 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -98,11 +98,7 @@ emp_act
(SP.name) = "[P.name] shrapnel"
(SP.desc) = "[SP.desc] It looks like it was fired from [P.shot_from]."
(SP.loc) = organ
- organ.implants += SP
- visible_message("The projectile sticks in the wound!")
- embedded_flag = 1
- src.verbs += /mob/proc/yank_out_object
- SP.add_blood(src)
+ organ.embed(SP)
return (..(P , def_zone))
@@ -236,7 +232,7 @@ emp_act
if ((weapon_sharp || weapon_edge) && prob(getarmor(def_zone, "melee")))
weapon_sharp = 0
weapon_edge = 0
-
+
if(armor >= 2) return 0
if(!I.force) return 0
@@ -314,4 +310,4 @@ emp_act
var/obj/item/clothing/suit/space/SS = wear_suit
var/penetrated_dam = max(0,(damage - max(0,(SS.breach_threshold - SS.damage))))
- if(penetrated_dam) SS.create_breaches(damtype, penetrated_dam)
+ if(penetrated_dam) SS.create_breaches(damtype, penetrated_dam)
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 2640f85819..5b0e7a0f6e 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -129,12 +129,10 @@
G.process()
-/mob/living/carbon/human/calculate_affecting_pressure(var/pressure)
- ..()
- var/pressure_difference = abs( pressure - ONE_ATMOSPHERE )
-
+//Much like get_heat_protection(), this returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
+/mob/living/carbon/human/proc/get_pressure_protection()
var/pressure_adjustment_coefficient = 1 //Determins how much the clothing you are wearing protects you in percent.
-
+
if(head && (head.flags & STOPSPRESSUREDMAGE))
pressure_adjustment_coefficient -= PRESSURE_HEAD_REDUCTION_COEFFICIENT
@@ -147,10 +145,16 @@
if(S.can_breach && S.damage)
var/pressure_loss = S.damage * 0.1
pressure_adjustment_coefficient += pressure_loss
-
+
pressure_adjustment_coefficient = min(1,max(pressure_adjustment_coefficient,0)) //So it isn't less than 0 or larger than 1.
+
+ return 1 - pressure_adjustment_coefficient //want 0 to be bad protection, 1 to be good protection
- pressure_difference = pressure_difference * pressure_adjustment_coefficient
+/mob/living/carbon/human/calculate_affecting_pressure(var/pressure)
+ ..()
+ var/pressure_difference = abs( pressure - ONE_ATMOSPHERE )
+
+ pressure_difference = pressure_difference * (1 - get_pressure_protection())
if(pressure > ONE_ATMOSPHERE)
return ONE_ATMOSPHERE + pressure_difference
@@ -316,16 +320,13 @@
if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell)) return
if(species && (species.flags & NO_BREATHE || species.flags & IS_SYNTHETIC)) return
- var/datum/organ/internal/lungs/L = internal_organs["lungs"]
- L.process()
-
var/datum/gas_mixture/environment = loc.return_air()
var/datum/gas_mixture/breath
-
+
// HACK NEED CHANGING LATER
if(health < config.health_threshold_crit && !reagents.has_reagent("inaprovaline"))
losebreath++
-
+
if(losebreath>0) //Suffocating so do not take a breath
losebreath--
if (prob(10)) //Gasp per 10 ticks? Sounds about right.
@@ -619,14 +620,14 @@
adjustOxyLoss(-5)
// Hot air hurts :(
- if( (abs(310.15 - breath.temperature) > 50) && !(COLD_RESISTANCE in mutations))
+ if( (breath.temperature < species.cold_level_1 || breath.temperature > species.heat_level_1) && !(COLD_RESISTANCE in mutations))
if(status_flags & GODMODE)
return 1
if(breath.temperature < species.cold_level_1)
if(prob(20))
- src << "\red You feel your face freezing and an icicle forming in your lungs!"
+ src << "\red You feel your face freezing and icicles forming in your lungs!"
else if(breath.temperature > species.heat_level_1)
if(prob(20))
src << "\red You feel your face burning and a searing heat in your lungs!"
@@ -650,9 +651,21 @@
if(species.heat_level_3 to INFINITY)
apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, "head", used_weapon = "Excessive Heat")
fire_alert = max(fire_alert, 2)
-
- //Temporary fixes to the alerts.
-
+
+ //breathing in hot/cold air also heats/cools you a bit
+ var/temp_adj = breath.temperature - bodytemperature
+ if (temp_adj < 0)
+ temp_adj /= (BODYTEMP_COLD_DIVISOR * 5) //don't raise temperature as much as if we were directly exposed
+ else
+ temp_adj /= (BODYTEMP_HEAT_DIVISOR * 5) //don't raise temperature as much as if we were directly exposed
+
+ var/relative_density = breath.total_moles() / (MOLES_CELLSTANDARD * BREATH_PERCENTAGE)
+ temp_adj *= relative_density
+
+ if (temp_adj > BODYTEMP_HEATING_MAX) temp_adj = BODYTEMP_HEATING_MAX
+ if (temp_adj < BODYTEMP_COOLING_MAX) temp_adj = BODYTEMP_COOLING_MAX
+ //world << "Breath: [breath.temperature], [src]: [bodytemperature], Adjusting: [temp_adj]"
+ bodytemperature += temp_adj
return 1
proc/handle_environment(datum/gas_mixture/environment)
@@ -668,60 +681,63 @@
if(istype(loc, /obj/mecha))
var/obj/mecha/M = loc
loc_temp = M.return_temperature()
- else if(istype(get_turf(src), /turf/space))
else if(istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
loc_temp = loc:air_contents.temperature
else
loc_temp = environment.temperature
- if(adjusted_pressure < species.warning_low_pressure && adjusted_pressure > species.warning_low_pressure && abs(loc_temp - 293.15) < 20 && abs(bodytemperature - 310.14) < 0.5 && environment.phoron < MOLES_PHORON_VISIBLE)
+ if(adjusted_pressure < species.warning_high_pressure && adjusted_pressure > species.warning_low_pressure && abs(loc_temp - bodytemperature) < 20 && bodytemperature < species.heat_level_1 && bodytemperature > species.cold_level_1 && environment.phoron < MOLES_PHORON_VISIBLE)
return // Temperatures are within normal ranges, fuck all this processing. ~Ccomp
- //Body temperature is adjusted in two steps. Firstly your body tries to stabilize itself a bit.
- if(stat != 2)
- stabilize_temperature_from_calories()
-
- //After then, it reacts to the surrounding atmosphere based on your thermal protection
- if(loc_temp < BODYTEMP_COLD_DAMAGE_LIMIT) //Place is colder than we are
+ //Body temperature adjusts depending on surrounding atmosphere based on your thermal protection
+ var/temp_adj = 0
+ if(loc_temp < bodytemperature) //Place is colder than we are
var/thermal_protection = get_cold_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
if(thermal_protection < 1)
- var/amt = min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR), BODYTEMP_COOLING_MAX)
- bodytemperature += amt
- else if (loc_temp > BODYTEMP_HEAT_DAMAGE_LIMIT) //Place is hotter than we are
+ temp_adj = (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_COLD_DIVISOR) //this will be negative
+ else if (loc_temp > bodytemperature) //Place is hotter than we are
var/thermal_protection = get_heat_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
if(thermal_protection < 1)
- var/amt = min((1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX)
- bodytemperature += amt
+ temp_adj = (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR)
+
+ //Use heat transfer as proportional to the gas density. However, we only care about the relative density vs standard 101 kPa/20 C air. Therefore we can use mole ratios
+ var/relative_density = environment.total_moles() / MOLES_CELLSTANDARD
+ temp_adj *= relative_density
+
+ if (temp_adj > BODYTEMP_HEATING_MAX) temp_adj = BODYTEMP_HEATING_MAX
+ if (temp_adj < BODYTEMP_COOLING_MAX) temp_adj = BODYTEMP_COOLING_MAX
+ //world << "Environment: [loc_temp], [src]: [bodytemperature], Adjusting: [temp_adj]"
+ bodytemperature += temp_adj
// +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt.
- if(bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT)
+ if(bodytemperature > species.heat_level_1)
//Body temperature is too hot.
fire_alert = max(fire_alert, 1)
if(status_flags & GODMODE) return 1 //godmode
switch(bodytemperature)
- if(360 to 400)
- apply_damage(HEAT_DAMAGE_LEVEL_1, BURN, used_weapon = "High Body Temperature")
+ if(species.heat_level_1 to species.heat_level_2)
+ take_overall_damage(burn=HEAT_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 2)
- if(400 to 1000)
- apply_damage(HEAT_DAMAGE_LEVEL_2, BURN, used_weapon = "High Body Temperature")
+ if(species.heat_level_2 to species.heat_level_3)
+ take_overall_damage(burn=HEAT_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 2)
- if(1000 to INFINITY)
- apply_damage(HEAT_DAMAGE_LEVEL_3, BURN, used_weapon = "High Body Temperature")
+ if(species.heat_level_3 to INFINITY)
+ take_overall_damage(burn=HEAT_DAMAGE_LEVEL_3, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 2)
- else if(bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
+ else if(bodytemperature < species.cold_level_1)
fire_alert = max(fire_alert, 1)
if(status_flags & GODMODE) return 1 //godmode
if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
switch(bodytemperature)
- if(200 to 260)
- apply_damage(COLD_DAMAGE_LEVEL_1, BURN, used_weapon = "Low Body Temperature")
+ if(species.cold_level_2 to species.cold_level_1)
+ take_overall_damage(burn=COLD_DAMAGE_LEVEL_1, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 1)
- if(120 to 200)
- apply_damage(COLD_DAMAGE_LEVEL_2, BURN, used_weapon = "Low Body Temperature")
+ if(species.cold_level_3 to species.cold_level_2)
+ take_overall_damage(burn=COLD_DAMAGE_LEVEL_2, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 1)
- if(-INFINITY to 120)
- apply_damage(COLD_DAMAGE_LEVEL_3, BURN, used_weapon = "Low Body Temperature")
+ if(-INFINITY to species.cold_level_3)
+ take_overall_damage(burn=COLD_DAMAGE_LEVEL_3, used_weapon = "High Body Temperature")
fire_alert = max(fire_alert, 1)
// Account for massive pressure differences. Done by Polymorph
@@ -729,7 +745,8 @@
if(status_flags & GODMODE) return 1 //godmode
if(adjusted_pressure >= species.hazard_high_pressure)
- adjustBruteLoss( min( ( (adjusted_pressure / species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) )
+ var/pressure_damage = min( ( (adjusted_pressure / species.hazard_high_pressure) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE)
+ take_overall_damage(brute=pressure_damage, used_weapon = "High Pressure")
pressure_alert = 2
else if(adjusted_pressure >= species.warning_high_pressure)
pressure_alert = 1
@@ -737,17 +754,9 @@
pressure_alert = 0
else if(adjusted_pressure >= species.hazard_low_pressure)
pressure_alert = -1
-
- if(species && species.flags & IS_SYNTHETIC)
- bodytemperature += 0.5 * TEMPERATURE_DAMAGE_COEFFICIENT //Synthetics suffer overheating in a vaccuum. ~Z
-
else
-
- if(species && species.flags & IS_SYNTHETIC)
- bodytemperature += 1 * TEMPERATURE_DAMAGE_COEFFICIENT
-
if( !(COLD_RESISTANCE in mutations))
- adjustBruteLoss( LOW_PRESSURE_DAMAGE )
+ take_overall_damage(brute=LOW_PRESSURE_DAMAGE, used_weapon = "Low Pressure")
pressure_alert = -2
else
pressure_alert = -1
@@ -774,27 +783,35 @@
temp_change = (temperature - current)
return temp_change
*/
-
- proc/stabilize_temperature_from_calories()
- var/body_temperature_difference = 310.15 - bodytemperature
+
+ proc/stabilize_body_temperature()
+ if (species.flags & IS_SYNTHETIC)
+ bodytemperature += species.synth_temp_gain //just keep putting out heat.
+ return
+
+ var/body_temperature_difference = species.body_temperature - bodytemperature
+
if (abs(body_temperature_difference) < 0.5)
return //fuck this precision
- switch(bodytemperature)
- if(-INFINITY to 260.15) //260.15 is 310.15 - 50, the temperature where you start to feel effects.
- if(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up.
- nutrition -= 2
- var/recovery_amt = max((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM)
+
+ if(bodytemperature < species.cold_level_1) //260.15 is 310.15 - 50, the temperature where you start to feel effects.
+ if(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up.
+ nutrition -= 2
+ var/recovery_amt = max((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM)
+ //world << "Cold. Difference = [body_temperature_difference]. Recovering [recovery_amt]"
// log_debug("Cold. Difference = [body_temperature_difference]. Recovering [recovery_amt]")
- bodytemperature += recovery_amt
- if(260.15 to 360.15)
- var/recovery_amt = body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR
+ bodytemperature += recovery_amt
+ else if(species.cold_level_1 <= bodytemperature && bodytemperature <= species.heat_level_1)
+ var/recovery_amt = body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR
+ //world << "Norm. Difference = [body_temperature_difference]. Recovering [recovery_amt]"
// log_debug("Norm. Difference = [body_temperature_difference]. Recovering [recovery_amt]")
- bodytemperature += recovery_amt
- if(360.15 to INFINITY) //360.15 is 310.15 + 50, the temperature where you start to feel effects.
- //We totally need a sweat system cause it totally makes sense...~
- var/recovery_amt = min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers
+ bodytemperature += recovery_amt
+ else if(bodytemperature > species.heat_level_1) //360.15 is 310.15 + 50, the temperature where you start to feel effects.
+ //We totally need a sweat system cause it totally makes sense...~
+ var/recovery_amt = min((body_temperature_difference / BODYTEMP_AUTORECOVERY_DIVISOR), -BODYTEMP_AUTORECOVERY_MINIMUM) //We're dealing with negative numbers
+ //world << "Hot. Difference = [body_temperature_difference]. Recovering [recovery_amt]"
// log_debug("Hot. Difference = [body_temperature_difference]. Recovering [recovery_amt]")
- bodytemperature += recovery_amt
+ bodytemperature += recovery_amt
//This proc returns a number made up of the flags for body parts which you are protected on. (such as HEAD, UPPER_TORSO, LOWER_TORSO, etc. See setup.dm for the full list)
proc/get_heat_protection_flags(temperature) //Temperature is the temperature you're being exposed to.
@@ -1074,12 +1091,6 @@
if(!(species.flags & IS_SYNTHETIC)) handle_trace_chems()
- var/datum/organ/internal/liver/liver = internal_organs["liver"]
- liver.process()
-
- var/datum/organ/internal/eyes/eyes = internal_organs["eyes"]
- eyes.process()
-
updatehealth()
return //TODO: DEFERRED
@@ -1091,6 +1102,7 @@
else //ALIVE. LIGHTS ARE ON
updatehealth() //TODO
if(!in_stasis)
+ stabilize_body_temperature() //Body temperature adjusts itself
handle_organs() //Optimized.
handle_blood()
@@ -1215,14 +1227,11 @@
if(druggy)
druggy = max(druggy-1, 0)
-/*
- // Increase germ_level regularly
- if(prob(40))
- germ_level += 1
+
// If you're dirty, your gloves will become dirty, too.
if(gloves && germ_level > gloves.germ_level && prob(10))
gloves.germ_level += 1
-*/
+
return 1
proc/handle_regular_hud_updates()
@@ -1449,17 +1458,46 @@
else fire.icon_state = "fire0"
if(bodytemp)
- switch(bodytemperature) //310.055 optimal body temp
- if(370 to INFINITY) bodytemp.icon_state = "temp4"
- if(350 to 370) bodytemp.icon_state = "temp3"
- if(335 to 350) bodytemp.icon_state = "temp2"
- if(320 to 335) bodytemp.icon_state = "temp1"
- if(300 to 320) bodytemp.icon_state = "temp0"
- if(295 to 300) bodytemp.icon_state = "temp-1"
- if(280 to 295) bodytemp.icon_state = "temp-2"
- if(260 to 280) bodytemp.icon_state = "temp-3"
- else bodytemp.icon_state = "temp-4"
-
+ if (!species)
+ switch(bodytemperature) //310.055 optimal body temp
+ if(370 to INFINITY) bodytemp.icon_state = "temp4"
+ if(350 to 370) bodytemp.icon_state = "temp3"
+ if(335 to 350) bodytemp.icon_state = "temp2"
+ if(320 to 335) bodytemp.icon_state = "temp1"
+ if(300 to 320) bodytemp.icon_state = "temp0"
+ if(295 to 300) bodytemp.icon_state = "temp-1"
+ if(280 to 295) bodytemp.icon_state = "temp-2"
+ if(260 to 280) bodytemp.icon_state = "temp-3"
+ else bodytemp.icon_state = "temp-4"
+ else
+ var/temp_step
+ if (bodytemperature >= species.body_temperature)
+ temp_step = (species.heat_level_1 - species.body_temperature)/4
+
+ if (bodytemperature >= species.heat_level_1)
+ bodytemp.icon_state = "temp4"
+ else if (bodytemperature >= species.body_temperature + temp_step*3)
+ bodytemp.icon_state = "temp3"
+ else if (bodytemperature >= species.body_temperature + temp_step*2)
+ bodytemp.icon_state = "temp2"
+ else if (bodytemperature >= species.body_temperature + temp_step*1)
+ bodytemp.icon_state = "temp1"
+ else
+ bodytemp.icon_state = "temp0"
+
+ else if (bodytemperature < species.body_temperature)
+ temp_step = (species.body_temperature - species.cold_level_1)/4
+
+ if (bodytemperature <= species.cold_level_1)
+ bodytemp.icon_state = "temp-4"
+ else if (bodytemperature <= species.body_temperature - temp_step*3)
+ bodytemp.icon_state = "temp-3"
+ else if (bodytemperature <= species.body_temperature - temp_step*2)
+ bodytemp.icon_state = "temp-2"
+ else if (bodytemperature <= species.body_temperature - temp_step*1)
+ bodytemp.icon_state = "temp-1"
+ else
+ bodytemp.icon_state = "temp0"
if(blind)
if(blinded) blind.layer = 18
else blind.layer = 0
@@ -1520,21 +1558,21 @@
for (var/ID in virus2)
var/datum/disease2/disease/V = virus2[ID]
V.cure(src)
+ if(life_tick % 3) //don't spam checks over all objects in view every tick.
+ for(var/obj/effect/decal/cleanable/O in view(1,src))
+ if(istype(O,/obj/effect/decal/cleanable/blood))
+ var/obj/effect/decal/cleanable/blood/B = O
+ if(B.virus2.len)
+ for (var/ID in B.virus2)
+ var/datum/disease2/disease/V = B.virus2[ID]
+ infect_virus2(src,V.getcopy())
- for(var/obj/effect/decal/cleanable/O in view(1,src))
- if(istype(O,/obj/effect/decal/cleanable/blood))
- var/obj/effect/decal/cleanable/blood/B = O
- if(B.virus2.len)
- for (var/ID in B.virus2)
- var/datum/disease2/disease/V = B.virus2[ID]
- infect_virus2(src,V)
-
- else if(istype(O,/obj/effect/decal/cleanable/mucus))
- var/obj/effect/decal/cleanable/mucus/M = O
- if(M.virus2.len)
- for (var/ID in M.virus2)
- var/datum/disease2/disease/V = M.virus2[ID]
- infect_virus2(src,V)
+ else if(istype(O,/obj/effect/decal/cleanable/mucus))
+ var/obj/effect/decal/cleanable/mucus/M = O
+ if(M.virus2.len)
+ for (var/ID in M.virus2)
+ var/datum/disease2/disease/V = M.virus2[ID]
+ infect_virus2(src,V.getcopy())
if(virus2.len)
diff --git a/code/modules/mob/living/carbon/monkey/diona.dm b/code/modules/mob/living/carbon/monkey/diona.dm
index cf1ea1ccb6..8e6f10df4b 100644
--- a/code/modules/mob/living/carbon/monkey/diona.dm
+++ b/code/modules/mob/living/carbon/monkey/diona.dm
@@ -10,6 +10,8 @@
icon_state = "nymph1"
var/list/donors = list()
var/ready_evolve = 0
+ universal_understand = 0 // Dionaea do not need to speak to people
+ universal_speak = 0 // before becoming an adult. Use *chirp.
/mob/living/carbon/monkey/diona/attack_hand(mob/living/carbon/human/M as mob)
@@ -207,7 +209,7 @@
src.visible_message("\red [src] flicks out a feeler and neatly steals a sample of [M]'s blood.","\red You flick out a feeler and neatly steal a sample of [M]'s blood.")
donors += M.real_name
for(var/datum/language/L in M.languages)
- languages += L
+ languages |= L
spawn(25)
update_progression()
@@ -245,14 +247,11 @@
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
-
if(stat == 2)
return say_dead(message)
var/datum/language/speaking = null
-
-
if(length(message) >= 2)
var/channel_prefix = copytext(message, 1 ,3)
if(languages.len)
@@ -270,6 +269,4 @@
if(!message || stat)
return
-
-
..(message, speaking, verb, null, null, message_range, null)
diff --git a/code/modules/mob/living/carbon/species.dm b/code/modules/mob/living/carbon/species.dm
index 028e93e5bb..b171bfb884 100644
--- a/code/modules/mob/living/carbon/species.dm
+++ b/code/modules/mob/living/carbon/species.dm
@@ -28,6 +28,9 @@
var/heat_level_1 = 360 // Heat damage level 1 above this point.
var/heat_level_2 = 400 // Heat damage level 2 above this point.
var/heat_level_3 = 1000 // Heat damage level 2 above this point.
+
+ var/body_temperature = 310.15 //non-IS_SYNTHETIC species will try to stabilize at this temperature. (also affects temperature processing)
+ var/synth_temp_gain = 0 //IS_SYNTHETIC species will gain this much temperature every second
var/darksight = 2
var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure.
@@ -279,6 +282,8 @@
heat_level_2 = 3000
heat_level_3 = 4000
+ body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not
+
flags = IS_WHITELISTED | NO_BREATHE | REQUIRE_LIGHT | NO_SCAN | IS_PLANT | RAD_ABSORB | NO_BLOOD | IS_SLOW | NO_PAIN
blood_color = "#004400"
@@ -317,15 +322,17 @@
burn_mod = 1
warning_low_pressure = 50
- hazard_low_pressure = 10
+ hazard_low_pressure = 0
cold_level_1 = 50
cold_level_2 = -1
cold_level_3 = -1
- heat_level_1 = 2000
- heat_level_2 = 3000
- heat_level_3 = 4000
+ heat_level_1 = 500 //gives them about 25 seconds in space before taking damage
+ heat_level_2 = 1000
+ heat_level_3 = 2000
+
+ synth_temp_gain = 10 //this should cause IPCs to stabilize at ~80 C in a 20 C environment.
flags = IS_WHITELISTED | NO_BREATHE | NO_SCAN | NO_BLOOD | NO_PAIN | IS_SYNTHETIC
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 4447c5f225..9865901886 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -431,7 +431,8 @@
else
stop_pulling()
. = ..()
- if ((s_active && !( s_active in contents ) ))
+
+ if (s_active && !( s_active in contents ) && get_turf(s_active) != get_turf(src)) //check !( s_active in contents ) first so we hopefully don't have to call get_turf() so much.
s_active.close(src)
if(update_slimes)
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 46da4b8469..98d64231ec 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -103,7 +103,7 @@ var/list/department_radio_keys = list(
var/obj/O = I
hearturfs += O.locs[1]
objects |= O
-
+
for(var/mob/M in player_list)
if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS))
listening |= M
@@ -113,7 +113,8 @@ var/list/department_radio_keys = list(
for(var/obj/O in objects)
spawn(0)
- O.hear_talk(src, message, verb, speaking)
+ if(O) //It's possible that it could be deleted in the meantime.
+ O.hear_talk(src, message, verb, speaking)
var/speech_bubble_test = say_test(message)
var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]")
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index bccb370c6f..005386f3d2 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -250,13 +250,13 @@ var/list/ai_list = list()
for (var/area_name in alarmlist)
var/datum/alarm/alarm = alarmlist[area_name]
dat += ""
-
+
var/cameratext = ""
if (alarm.cameras)
for (var/obj/machinery/camera/I in alarm.cameras)
cameratext += text("[][]", (cameratext=="") ? "" : " | ", src, I, I.c_tag)
dat += text("-- [] ([])", alarm.area.name, (cameratext)? cameratext : "No Camera")
-
+
if (alarm.sources.len > 1)
dat += text(" - [] sources", alarm.sources.len)
dat += "
\n"
@@ -407,23 +407,11 @@ var/list/ai_list = list()
if (href_list["track"])
var/mob/target = locate(href_list["track"]) in mob_list
-/*
- var/mob/living/silicon/ai/A = locate(href_list["track2"]) in mob_list
- if(A && target)
- A.ai_actual_track(target)
-*/
- //Strip off any "(as Derplord)".
- //If there's a way to do this via a var that doesn't give the AI extra info, please let me know.
- var/seeking = target.name
- var/index = findtext(seeking, "(as ")
- if(index)
- seeking = copytext(seeking, 1, index-1)
-
- if(target && html_decode(href_list["trackname"]) == seeking)
+ if(target && (!istype(target, /mob/living/carbon/human) || html_decode(href_list["trackname"]) == target:get_face_name()))
ai_actual_track(target)
- else
- src << "\red System error. Cannot locate [html_decode(href_list["trackname"])]."
+
+ src << "\red System error. Cannot locate [html_decode(href_list["trackname"])]."
return
else if (href_list["faketrack"])
@@ -539,24 +527,24 @@ var/list/ai_list = list()
/mob/living/silicon/ai/triggerAlarm(var/class, area/A, list/cameralist, var/source)
if (stat == 2)
return 1
-
+
..()
-
+
var/cameratext = ""
for (var/obj/machinery/camera/C in cameralist)
cameratext += "[(cameratext == "")? "" : "|"][C.c_tag]"
-
+
queueAlarm("--- [class] alarm detected in [A.name]! ([(cameratext)? cameratext : "No Camera"])", class)
-
+
if (viewalerts) ai_alerts()
/mob/living/silicon/ai/cancelAlarm(var/class, area/A as area, var/source)
var/has_alarm = ..()
-
+
if (!has_alarm)
queueAlarm(text("--- [] alarm in [] has been cleared.", class, A.name), class, 0)
if (viewalerts) ai_alerts()
-
+
return has_alarm
/mob/living/silicon/ai/cancel_camera()
diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm
index cee310ae59..d97d2a5391 100644
--- a/code/modules/mob/living/silicon/robot/component.dm
+++ b/code/modules/mob/living/silicon/robot/component.dm
@@ -188,7 +188,7 @@
if(!(istype(user, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
user << "\red You don't have the dexterity to do this!"
return
- if(!istype(M, /mob/living/silicon/robot))
+ if(!istype(M, /mob/living/silicon/robot) && !(ishuman(M) && (M:species.flags & IS_SYNTHETIC)))
user << "\red You can't analyze non-robotic things!"
return
@@ -200,22 +200,39 @@
user.show_message("\t Damage Specifics: [BU] - [BR]")
if(M.tod && M.stat == DEAD)
user.show_message("\blue Time of Disable: [M.tod]")
-
- var/mob/living/silicon/robot/H = M
- var/list/damaged = H.get_damaged_components(1,1,1)
- user.show_message("\blue Localized Damage:",1)
- if(length(damaged)>0)
- for(var/datum/robot_component/org in damaged)
- user.show_message(text("\blue \t []: [][] - [] - [] - []", \
- capitalize(org.name), \
- (org.installed == -1) ? "DESTROYED " :"",\
- (org.electronics_damage > 0) ? "[org.electronics_damage]" :0, \
- (org.brute_damage > 0) ? "[org.brute_damage]" :0, \
- (org.toggled) ? "Toggled ON" : "Toggled OFF",\
- (org.powered) ? "Power ON" : "Power OFF"),1)
- else
- user.show_message("\blue \t Components are OK.",1)
- if(H.emagged && prob(5))
- user.show_message("\red \t ERROR: INTERNAL SYSTEMS COMPROMISED",1)
+
+ if (istype(M, /mob/living/silicon/robot))
+ var/mob/living/silicon/robot/H = M
+ var/list/damaged = H.get_damaged_components(1,1,1)
+ user.show_message("\blue Localized Damage:",1)
+ if(length(damaged)>0)
+ for(var/datum/robot_component/org in damaged)
+ user.show_message(text("\blue \t []: [][] - [] - [] - []", \
+ capitalize(org.name), \
+ (org.installed == -1) ? "DESTROYED " :"",\
+ (org.electronics_damage > 0) ? "[org.electronics_damage]" :0, \
+ (org.brute_damage > 0) ? "[org.brute_damage]" :0, \
+ (org.toggled) ? "Toggled ON" : "Toggled OFF",\
+ (org.powered) ? "Power ON" : "Power OFF"),1)
+ else
+ user.show_message("\blue \t Components are OK.",1)
+ if(H.emagged && prob(5))
+ user.show_message("\red \t ERROR: INTERNAL SYSTEMS COMPROMISED",1)
+
+ if (ishuman(M) && (M:species.flags & IS_SYNTHETIC))
+ var/mob/living/carbon/human/H = M
+ var/list/damaged = H.get_damaged_organs(1,1)
+ user.show_message("\blue Localized Damage, Brute/Electronics:",1)
+ if(length(damaged)>0)
+ for(var/datum/organ/external/org in damaged)
+ user.show_message(text("\blue \t []: [] - []", \
+ capitalize(org.display_name), \
+ (org.brute_dam > 0) ? "\red [org.brute_dam]" :0, \
+ (org.burn_dam > 0) ? "[org.burn_dam]" :0),1)
+ else
+ user.show_message("\blue \t Components are OK.",1)
+
+ user.show_message("\blue Operating Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)", 1)
+
src.add_fingerprint(user)
return
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index fef26532be..18d415fd39 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -760,6 +760,12 @@ note dizziness decrements automatically in the mob's Life() proc.
canmove = 0
if( istype(buckled,/obj/structure/stool/bed/chair) )
lying = 0
+ else if(istype(buckled, /obj/vehicle))
+ var/obj/vehicle/V = buckled
+ if(V.standing_mob)
+ lying = 0
+ else
+ lying = 1
else
lying = 1
else if( stat || weakened || paralysis || resting || sleeping || (status_flags & FAKEDEATH))
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 067d010c29..fbc48841f4 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -199,7 +199,7 @@
if(!mob.canmove)
- if (mob.buckled && (istype(mob.buckled, /obj/structure/stool/bed/chair/wheelchair))) // Exception for wheelchairs
+ if (mob.buckled && (istype(mob.buckled, /obj/structure/stool/bed/chair/wheelchair) || istype(mob.buckled, /obj/vehicle))) // Exception for wheelchairs
else return
//if(istype(mob.loc, /turf/space) || (mob.flags & NOGRAV))
@@ -246,7 +246,9 @@
move_delay -= 1.3
var/tickcomp = ((1/(world.tick_lag))*1.3)
move_delay = move_delay + tickcomp
-
+
+ if(istype(mob.buckled, /obj/vehicle))
+ return mob.buckled.relaymove(mob,direct)
if(mob.pulledby || mob.buckled) // Wheelchair driving!
if(istype(mob.loc, /turf/space))
diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm
index 108e6e5ca9..5bfca3a02c 100644
--- a/code/modules/mob/new_player/preferences_setup.dm
+++ b/code/modules/mob/new_player/preferences_setup.dm
@@ -198,12 +198,7 @@ datum/preferences
preview_icon.Blend(new /icon(icobase, "groin_[g]"), ICON_OVERLAY)
preview_icon.Blend(new /icon(icobase, "head_[g]"), ICON_OVERLAY)
- for(var/name in list("l_arm","r_arm","l_leg","r_leg","l_foot","r_foot","l_hand","r_hand"))
- // make sure the organ is added to the list so it's drawn
- if(organ_data[name] == null)
- organ_data[name] = null
-
- for(var/name in organ_data)
+ for(var/name in list("r_arm","r_hand","r_leg","r_foot","l_leg","l_foot","l_arm","l_hand"))
if(organ_data[name] == "amputated") continue
var/icon/temp = new /icon(icobase, "[name]")
@@ -212,6 +207,11 @@ datum/preferences
preview_icon.Blend(temp, ICON_OVERLAY)
+ //Tail
+ if(current_species && (current_species.flags & HAS_TAIL))
+ var/icon/temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[current_species.tail]_s")
+ preview_icon.Blend(temp, ICON_OVERLAY)
+
// Skin color
if(current_species && (current_species.flags & HAS_SKIN_COLOR))
preview_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm
index c100e74725..e9f1563c15 100644
--- a/code/modules/organs/blood.dm
+++ b/code/modules/organs/blood.dm
@@ -159,6 +159,9 @@ var/const/BLOOD_VOLUME_SURVIVE = 122
this.icon_state = pick(iconL)
this.blood_DNA = list()
this.blood_DNA[dna.unique_enzymes] = dna.b_type
+ for (var/ID in virus2)
+ var/datum/disease2/disease/V = virus2[ID]
+ this.virus2[ID] = V.getcopy()
if (species) this.basecolor = species.blood_color
this.update_icon()
diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm
index 47a7f67a07..b5761df24c 100644
--- a/code/modules/organs/organ.dm
+++ b/code/modules/organs/organ.dm
@@ -5,6 +5,9 @@
var/list/datum/autopsy_data/autopsy_data = list()
var/list/trace_chemicals = list() // traces of chemicals in the organ,
// links chemical IDs to number of ticks for which they'll stay in the blood
+
+ var/germ_level = 0 // INTERNAL germs inside the organ, this is BAD if it's greater than INFECTION_LEVEL_ONE
+
proc/process()
return 0
@@ -46,13 +49,18 @@
if(damage_this_tick > last_dam)
force_process = 1
last_dam = damage_this_tick
- if(!force_process && !bad_external_organs.len)
- return
if(force_process)
bad_external_organs.Cut()
for(var/datum/organ/external/Ex in organs)
bad_external_organs += Ex
-
+
+ //processing internal organs is pretty cheap, do that first.
+ for(var/datum/organ/internal/I in internal_organs)
+ I.process()
+
+ if(!force_process && !bad_external_organs.len)
+ return
+
for(var/datum/organ/external/E in bad_external_organs)
if(!E)
continue
@@ -62,53 +70,24 @@
else
E.process()
number_wounds += E.number_wounds
- //Robotic limb malfunctions
- var/malfunction = 0
- if (E.status & ORGAN_ROBOT && prob(E.brute_dam + E.burn_dam))
- malfunction = 1
-
- //Broken limbs hurt too
- var/broken = 0
- if(E.status & ORGAN_BROKEN && !(E.status & ORGAN_SPLINTED) )
- broken = 1
+ if (!lying && world.time - l_move_time < 15)
//Moving around with fractured ribs won't do you any good
- if (broken && E.internal_organs && prob(15))
- if (!lying && world.timeofday - l_move_time < 15)
+ if (E.is_broken() && E.internal_organs && prob(15))
var/datum/organ/internal/I = pick(E.internal_organs)
custom_pain("You feel broken bones moving in your [E.display_name]!", 1)
I.take_damage(rand(3,5))
+
+ //Moving makes open wounds get infected much faster
+ if (E.wounds.len)
+ for(var/datum/wound/W in E.wounds)
+ if (W.infection_check())
+ W.germ_level += 1
- //Special effects for limbs.
- if(E.name in list("l_hand","l_arm","r_hand","r_arm"))
- var/obj/item/c_hand //Getting what's in this hand
- var/hand
- if(E.name == "l_hand" || E.name == "l_arm")
- c_hand = l_hand
- hand = "left hand"
- if(E.name == "r_hand" || E.name == "r_arm")
- c_hand = r_hand
- hand = "right hand"
- if (c_hand)
-
- if(broken)
- u_equip(c_hand)
- var/emote_scream = pick("screams in pain and", "let's out a sharp hiss and", "cries out and")
- emote("me", 1, "[(species && species.flags & NO_PAIN) ? "" : emote_scream ] drops what they were holding in their [hand]!")
- if(malfunction)
- u_equip(c_hand)
- emote("me", 1, "drops what they were holding, their [hand] malfunctioning!")
- var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
- spark_system.set_up(5, 0, src)
- spark_system.attach(src)
- spark_system.start()
- spawn(10)
- del(spark_system)
-
- else if(E.name in list("l_leg","l_foot","r_leg","r_foot") && !lying)
- if (!E.is_usable() || malfunction || (broken && !(E.status & ORGAN_SPLINTED)))
+ if(E.name in list("l_leg","l_foot","r_leg","r_foot") && !lying)
+ if (!E.is_usable() || E.is_malfunctioning() || (E.is_broken() && !(E.status & ORGAN_SPLINTED)))
leg_tally-- // let it fail even if just foot&leg
-
+
// standing is poor
if(leg_tally <= 0 && !paralysis && !(lying || resting) && prob(5))
if(species && species.flags & NO_PAIN)
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index acd9efcb65..e54de9c9c1 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -40,8 +40,6 @@
var/obj/item/hidden = null
var/list/implants = list()
- // INTERNAL germs inside the organ, this is BAD if it's greater 0
- var/germ_level = 0
// how often wounds should be updated, a higher number means less often
var/wound_update_accuracy = 1
@@ -239,28 +237,31 @@ This function completely restores a damaged organ to perfect condition.
for (var/datum/wound/W in wounds)
if (W.can_worsen(type, damage))
compatible_wounds += W
-
- var/datum/wound/W = pick(compatible_wounds)
- W.open_wound(damage)
- if(prob(25))
- //maybe have a separate message for BRUISE type damage?
- owner.visible_message("\red The wound on [owner.name]'s [display_name] widens with a nasty ripping voice.",\
- "\red The wound on your [display_name] widens with a nasty ripping voice.",\
- "You hear a nasty ripping noise, as if flesh is being torn apart.")
- return
+
+ if(compatible_wounds.len)
+ var/datum/wound/W = pick(compatible_wounds)
+ W.open_wound(damage)
+ if(prob(25))
+ //maybe have a separate message for BRUISE type damage?
+ owner.visible_message("\red The wound on [owner.name]'s [display_name] widens with a nasty ripping voice.",\
+ "\red The wound on your [display_name] widens with a nasty ripping voice.",\
+ "You hear a nasty ripping noise, as if flesh is being torn apart.")
+ return
//Creating wound
var/wound_type = get_wound_type(type, damage)
- var/datum/wound/W = new wound_type(damage)
- //Check whether we can add the wound to an existing wound
- for(var/datum/wound/other in wounds)
- if(other.can_merge(W))
- other.merge_wound(W)
- W = null // to signify that the wound was added
- break
- if(W)
- wounds += W
+ if(wound_type)
+ var/datum/wound/W = new wound_type(damage)
+
+ //Check whether we can add the wound to an existing wound
+ for(var/datum/wound/other in wounds)
+ if(other.can_merge(W))
+ other.merge_wound(W)
+ W = null // to signify that the wound was added
+ break
+ if(W)
+ wounds += W
/datum/organ/external/proc/get_wound_type(var/type = CUT, var/damage)
//if you look a the names in the wound's stages list for each wound type you will see the logic behind these values
@@ -279,7 +280,7 @@ This function completely restores a damaged organ to perfect condition.
if (damage <= 15) return /datum/wound/burn/large
if (damage <= 30) return /datum/wound/burn/severe
if (damage <= 40) return /datum/wound/burn/deep
- if (damage <= 50) return /datum/wound/burn/carbonised
+ return /datum/wound/burn/carbonised
/****************************************************
PROCESSING & UPDATING
@@ -295,7 +296,10 @@ This function completely restores a damaged organ to perfect condition.
if(last_dam != brute_dam + burn_dam) // Process when we are fully healed up.
last_dam = brute_dam + burn_dam
return 1
- last_dam = brute_dam + burn_dam
+ else
+ last_dam = brute_dam + burn_dam
+ if(germ_level)
+ return 1
return 0
/datum/organ/external/process()
@@ -327,50 +331,89 @@ This function completely restores a damaged organ to perfect condition.
if(!(status & ORGAN_BROKEN))
perma_injury = 0
+ //Infections
update_germs()
return
//Updating germ levels. Handles organ germ levels and necrosis.
-#define GANGREN_LEVEL_ONE 100
-#define GANGREN_LEVEL_TWO 1000
-#define GANGREN_LEVEL_TERMINAL 2500
-#define GERM_TRANSFER_AMOUNT germ_level/500
+/*
+The INFECTION_LEVEL values defined in setup.dm control the time it takes to reach the different
+infection levels. Since infection growth is exponential, you can adjust the time it takes to get
+from one germ_level to another using the rough formula:
+
+desired_germ_level = initial_germ_level*e^(desired_time_in_seconds/1000)
+
+So if I wanted it to take an average of 15 minutes to get from level one (100) to level two
+I would set INFECTION_LEVEL_TWO to 100*e^(15*60/1000) = 245. Note that this is the average time,
+the actual time is dependent on RNG.
+
+INFECTION_LEVEL_ONE below this germ level nothing happens, and the infection doesn't grow
+INFECTION_LEVEL_TWO above this germ level the infection will start to spread to internal and adjacent organs
+INFECTION_LEVEL_THREE above this germ level the player will take additional toxin damage per second, and will die in minutes without
+ antitox. also, above this germ level you will need to overdose on spaceacillin to reduce the germ_level.
+
+Note that amputating the affected organ does in fact remove the infection from the
+player's body, though, antitox and spaceacillin are easy enough to get I doubt it will ever be needed.
+*/
/datum/organ/external/proc/update_germs()
- if(status & ORGAN_ROBOT|ORGAN_DESTROYED) //Robotic limbs shouldn't be infected, nor should nonexistant limbs.
+ if(status & (ORGAN_ROBOT|ORGAN_DESTROYED)) //Robotic limbs shouldn't be infected, nor should nonexistant limbs.
germ_level = 0
return
- if(germ_level > 0 && owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs
+ if(owner.bodytemperature >= 170) //cryo stops germs from moving and doing their bad stuffs
//Syncing germ levels with external wounds
for(var/datum/wound/W in wounds)
- if(!W.bandaged && !W.salved)
- W.germ_level = max(W.germ_level, germ_level) //Wounds get all the germs
- if (W.germ_level > germ_level) //Badly infected wounds raise internal germ levels
- germ_level++
+ //Open wounds can become infected
+ if (owner.germ_level > W.germ_level && W.infection_check())
+ W.germ_level++
+
+ //Infected wounds raise the organ's germ level
+ W.germ_level = max(W.germ_level, germ_level) //Wounds get all the germs
+ if (W.germ_level > germ_level) //Badly infected wounds raise internal germ levels
+ germ_level++
- if(germ_level > GANGREN_LEVEL_ONE && prob(round(germ_level/100)))
- germ_level++
- owner.adjustToxLoss(1)
-
- if(germ_level > GANGREN_LEVEL_TWO)
- germ_level++
- owner.adjustToxLoss(1)
-/*
- if(germ_level > GANGREN_LEVEL_TERMINAL)
+ var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin")
+ if (germ_level > 0 && antibiotics > 5)
+ if (prob(4*antibiotics)) germ_level-- //the higher the germ level the more antibiotics you'll need.
+
+ if(germ_level >= INFECTION_LEVEL_ONE)
+ //having an infection raises your body temperature
+ var/fever_temperature = (owner.species.heat_level_1 - owner.species.body_temperature - 1)* min(germ_level/INFECTION_LEVEL_THREE, 1) + owner.species.body_temperature
+ if (owner.bodytemperature < fever_temperature)
+ //world << "fever: [owner.bodytemperature] < [fever_temperature], raising temperature."
+ owner.bodytemperature++
+
+ if(prob(round(germ_level/10)))
+ germ_level++
+ if (prob(5)) //adjust this to tweak how fast people take toxin damage from infections
+ owner.adjustToxLoss(1)
+
+ if(germ_level >= INFECTION_LEVEL_TWO)
+ //spread the infection
+ for (var/datum/organ/internal/I in internal_organs)
+ if (I.germ_level < germ_level)
+ I.germ_level++
+
+ if (children) //To child organs
+ for (var/datum/organ/external/child in children)
+ if (child.germ_level < germ_level && !(child.status & ORGAN_ROBOT))
+ if (child.germ_level < INFECTION_LEVEL_ONE*2 || prob(30))
+ child.germ_level++
+
+ if (parent)
+ if (parent.germ_level < germ_level && !(parent.status & ORGAN_ROBOT))
+ if (parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30))
+ parent.germ_level++
+
+ if(germ_level >= INFECTION_LEVEL_THREE && antibiotics < 30) //overdosing is necessary to stop severe infections
if (!(status & ORGAN_DEAD))
status |= ORGAN_DEAD
owner << "You can't feel your [display_name] anymore..."
- owner.update_body(1)
- if (prob(10)) //Spreading the fun
- if (children) //To child organs
- for (var/datum/organ/external/child in children)
- if (!(child.status & (ORGAN_DEAD|ORGAN_DESTROYED|ORGAN_ROBOT)))
- child.germ_level += round(GERM_TRANSFER_AMOUNT)
- if (parent)
- if (!(parent.status & (ORGAN_DEAD|ORGAN_DESTROYED|ORGAN_ROBOT)))
- parent.germ_level += round(GERM_TRANSFER_AMOUNT)
-*/
+
+ germ_level++
+ owner.adjustToxLoss(1)
+
//Updating wounds. Handles wound natural I had some free spachealing, internal bleedings and infections
/datum/organ/external/proc/update_wounds()
@@ -681,9 +724,9 @@ This function completely restores a damaged organ to perfect condition.
/datum/organ/external/proc/get_damage() //returns total damage
return max(brute_dam + burn_dam - perma_injury, perma_injury) //could use health?
-/datum/organ/external/proc/is_infected()
+/datum/organ/external/proc/has_infected_wound()
for(var/datum/wound/W in wounds)
- if(W.germ_level > 100)
+ if(W.germ_level > 150)
return 1
return 0
@@ -700,7 +743,42 @@ This function completely restores a damaged organ to perfect condition.
/datum/organ/external/proc/is_usable()
return !(status & (ORGAN_DESTROYED|ORGAN_MUTATED|ORGAN_DEAD))
-/****************************************************
+/datum/organ/external/proc/is_broken()
+ return ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED))
+
+/datum/organ/external/proc/is_malfunctioning()
+ return ((status & ORGAN_ROBOT) && prob(brute_dam + burn_dam))
+
+//for arms and hands
+/datum/organ/external/proc/process_grasp(var/obj/item/c_hand, var/hand_name)
+ if (!c_hand)
+ return
+
+ if(is_broken())
+ owner.u_equip(c_hand)
+ var/emote_scream = pick("screams in pain and", "lets out a sharp cry and", "cries out and")
+ owner.emote("me", 1, "[(owner.species && owner.species.flags & NO_PAIN) ? "" : emote_scream ] drops what they were holding in their [hand_name]!")
+ if(is_malfunctioning())
+ owner.u_equip(c_hand)
+ owner.emote("me", 1, "drops what they were holding, their [hand_name] malfunctioning!")
+ var/datum/effect/effect/system/spark_spread/spark_system = new /datum/effect/effect/system/spark_spread()
+ spark_system.set_up(5, 0, src)
+ spark_system.attach(src)
+ spark_system.start()
+ spawn(10)
+ del(spark_system)
+
+/datum/organ/external/proc/embed(var/obj/item/weapon/W, var/silent = 0)
+ if(!silent)
+ owner.visible_message("\The [W] sticks in the wound!")
+ implants += W
+ owner.embedded_flag = 1
+ owner.verbs += /mob/proc/yank_out_object
+ W.add_blood(owner)
+ if(ismob(W.loc))
+ var/mob/living/H = W.loc
+ H.drop_item()
+ W.loc = owner/****************************************************
ORGAN DEFINES
****************************************************/
@@ -728,6 +806,10 @@ This function completely restores a damaged organ to perfect condition.
max_damage = 50
min_broken_damage = 20
body_part = ARM_LEFT
+
+ process()
+ ..()
+ process_grasp(owner.l_hand, "left hand")
/datum/organ/external/l_leg
name = "l_leg"
@@ -745,6 +827,10 @@ This function completely restores a damaged organ to perfect condition.
max_damage = 50
min_broken_damage = 20
body_part = ARM_RIGHT
+
+ process()
+ ..()
+ process_grasp(owner.r_hand, "right hand")
/datum/organ/external/r_leg
name = "r_leg"
@@ -780,6 +866,10 @@ This function completely restores a damaged organ to perfect condition.
max_damage = 30
min_broken_damage = 15
body_part = HAND_RIGHT
+
+ process()
+ ..()
+ process_grasp(owner.r_hand, "right hand")
/datum/organ/external/l_hand
name = "l_hand"
@@ -788,6 +878,10 @@ This function completely restores a damaged organ to perfect condition.
max_damage = 30
min_broken_damage = 15
body_part = HAND_LEFT
+
+ process()
+ ..()
+ process_grasp(owner.l_hand, "left hand")
/datum/organ/external/head
name = "head"
diff --git a/code/modules/organs/organ_internal.dm b/code/modules/organs/organ_internal.dm
index bb1ce19ad2..d5e1b19b6c 100644
--- a/code/modules/organs/organ_internal.dm
+++ b/code/modules/organs/organ_internal.dm
@@ -21,6 +21,7 @@
return damage >= min_broken_damage
+
/datum/organ/internal/New(mob/living/carbon/human/H)
..()
var/datum/organ/external/E = H.organs_by_name[src.parent_organ]
@@ -30,6 +31,37 @@
H.internal_organs[src.name] = src
src.owner = H
+/datum/organ/internal/process()
+
+ //Process infections
+ if (!germ_level)
+ return
+
+ if (robotic >= 2) //TODO make robotic internal and external organs separate types of organ instead of a flag
+ germ_level = 0
+ return
+
+ var/antibiotics = owner.reagents.get_reagent_amount("spaceacillin")
+
+ if (germ_level > 0 && antibiotics > 5)
+ if (prob(4*antibiotics)) germ_level--
+ if (antibiotics > 30) germ_level--
+
+ if (germ_level >= INFECTION_LEVEL_ONE/2)
+ if(prob(round(germ_level/6))) //aiming for germ level to go from ambient to INFECTION_LEVEL_TWO in an average of 15 minutes
+ germ_level++
+ if(prob(1))
+ take_damage(1,silent=0)
+
+ if (germ_level >= INFECTION_LEVEL_TWO)
+ var/datum/organ/external/parent = owner.get_organ(parent_organ)
+ if (parent.germ_level < germ_level && ( parent.germ_level < INFECTION_LEVEL_ONE*2 || prob(30) ))
+ parent.germ_level++
+
+ if (prob(5)) //about once every 20 seconds
+ take_damage(1,silent=prob(30))
+
+
/datum/organ/internal/proc/take_damage(amount, var/silent=0)
if(src.robotic == 2)
src.damage += (amount * 0.8)
@@ -40,7 +72,6 @@
if (!silent)
owner.custom_pain("Something inside your [parent.display_name] hurts a lot.", 1)
-
/datum/organ/internal/proc/emp_act(severity)
switch(robotic)
if(0)
@@ -96,7 +127,7 @@
owner.drip(10)
if(prob(4))
spawn owner.emote("me", 1, "gasps for air!")
- owner.losebreath += 5
+ owner.losebreath += 15
/datum/organ/internal/liver
name = "liver"
diff --git a/code/modules/organs/wound.dm b/code/modules/organs/wound.dm
index a789248627..e2763d4697 100644
--- a/code/modules/organs/wound.dm
+++ b/code/modules/organs/wound.dm
@@ -119,7 +119,7 @@
// checks if wound is considered open for external infections
// untreated cuts (and bleeding bruises) and burns are possibly infectable, chance higher if wound is bigger
- proc/can_infect()
+ proc/infection_check()
if (is_treated() && damage < 10)
return 0
if (disinfected)
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index d64dd4ccfb..e693cc11f1 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -228,6 +228,8 @@
src.amount = length
if (param_color)
color = param_color
+ else
+ color = item_color
pixel_x = rand(-2,2)
pixel_y = rand(-2,2)
updateicon()
@@ -236,6 +238,7 @@
/obj/item/weapon/cable_coil/proc/updateicon()
if (!color)
color = pick(COLOR_RED, COLOR_BLUE, COLOR_GREEN, COLOR_ORANGE, COLOR_WHITE, COLOR_PINK, COLOR_YELLOW, COLOR_CYAN)
+ item_color = color
if(amount == 1)
icon_state = "coil1"
name = "cable piece"
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index 62d4fb19d4..d7238c5658 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -356,6 +356,7 @@
switchcount = L.switchcount
rigged = L.rigged
brightness = L.brightness
+ l_color = L.color
on = has_power()
update()
@@ -514,6 +515,7 @@
L.status = status
L.rigged = rigged
L.brightness = src.brightness
+ L.color = l_color
// light item inherits the switchcount, then zero it
L.switchcount = switchcount
@@ -539,6 +541,7 @@
L.status = status
L.rigged = rigged
L.brightness = brightness
+ L.color = l_color
// light item inherits the switchcount, then zero it
L.switchcount = switchcount
@@ -618,7 +621,7 @@
// called when on fire
-/obj/machinery/light/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
+/obj/machinery/light/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(prob(max(0, exposed_temperature - 673))) //0% at <400C, 100% at >500C
broken()
diff --git a/code/modules/reagents/Chemistry-Colours.dm b/code/modules/reagents/Chemistry-Colours.dm
index 55e76a07b8..a59147e85f 100644
--- a/code/modules/reagents/Chemistry-Colours.dm
+++ b/code/modules/reagents/Chemistry-Colours.dm
@@ -34,7 +34,7 @@
var/blue = mixOneColor(weight,bluecolor)
//assemble all the pieces
- var/finalcolor = "#[red][green][blue]"
+ var/finalcolor = rgb(red, green, blue)
return finalcolor
/proc/mixOneColor(var/list/weight, var/list/color)
@@ -58,10 +58,9 @@
mixedcolor = round(mixedcolor)
//until someone writes a formal proof for this algorithm, let's keep this in
- if(mixedcolor<0x00 || mixedcolor>0xFF)
- return 0
+// if(mixedcolor<0x00 || mixedcolor>0xFF)
+// return 0
+ //that's not the kind of operation we are running here, nerd
+ mixedcolor=min(max(mixedcolor,0),255)
- var/finalcolor = num2hex(mixedcolor)
- while(length(finalcolor)<2)
- finalcolor = text("0[]",finalcolor) //Takes care of leading zeroes
- return finalcolor
+ return mixedcolor
diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm
index c35ec24839..37703e0912 100644
--- a/code/modules/reagents/Chemistry-Machinery.dm
+++ b/code/modules/reagents/Chemistry-Machinery.dm
@@ -293,6 +293,7 @@
var/max_pill_count = 20
/obj/machinery/chem_master/New()
+ ..()
var/datum/reagents/R = new/datum/reagents(100)
reagents = R
R.my_atom = src
diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm
index 70e442a73d..46aafda18b 100644
--- a/code/modules/reagents/Chemistry-Reagents.dm
+++ b/code/modules/reagents/Chemistry-Reagents.dm
@@ -118,10 +118,15 @@ datum
else //injected
M.contract_disease(D, 1, 0)
if(self.data && self.data["virus2"] && istype(M, /mob/living/carbon))//infecting...
- if(method == TOUCH)
- infect_virus2(M,self.data["virus2"])
- else
- infect_virus2(M,self.data["virus2"],1) //injected, force infection!
+ var/list/vlist = self.data["virus2"]
+ if (vlist.len)
+ for (var/ID in vlist)
+ var/datum/disease2/disease/V = vlist[ID]
+
+ if(method == TOUCH)
+ infect_virus2(M,V.getcopy())
+ else
+ infect_virus2(M,V.getcopy(),1) //injected, force infection!
if(self.data && self.data["antibodies"] && istype(M, /mob/living/carbon))//... and curing
var/mob/living/carbon/C = M
C.antibodies |= self.data["antibodies"]
@@ -146,6 +151,9 @@ datum
blood_prop.viruses += newVirus
newVirus.holder = blood_prop
+ if(self.data["virus2"])
+ blood_prop.virus2 = virus_copylist(self.data["virus2"])
+
else if(istype(self.data["donor"], /mob/living/carbon/monkey))
var/obj/effect/decal/cleanable/blood/blood_prop = locate() in T
@@ -1573,14 +1581,14 @@ datum
var/turf/the_turf = get_turf(O)
var/datum/gas_mixture/napalm = new
var/datum/gas/volatile_fuel/fuel = new
- fuel.moles = 5
+ fuel.moles = volume
napalm.trace_gases += fuel
the_turf.assume_air(napalm)
reaction_turf(var/turf/T, var/volume)
src = null
var/datum/gas_mixture/napalm = new
var/datum/gas/volatile_fuel/fuel = new
- fuel.moles = 5
+ fuel.moles = volume
napalm.trace_gases += fuel
T.assume_air(napalm)
return
diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm
index da91085e27..853ee5b149 100644
--- a/code/modules/reagents/reagent_containers/food/snacks.dm
+++ b/code/modules/reagents/reagent_containers/food/snacks.dm
@@ -127,8 +127,39 @@
..() // -> item/attackby()
if(istype(W,/obj/item/weapon/storage))
..() // -> item/attackby()
+
+ if(istype(W,/obj/item/weapon/kitchen/utensil))
+
+ var/obj/item/weapon/kitchen/utensil/U = W
+
+ if(!U.reagents)
+ U.create_reagents(5)
+
+ if (U.reagents.total_volume > 0)
+ user << "\red You already have something on your [U]."
+ return
+
+ user.visible_message( \
+ "[user] scoops up some [src] with \the [U]!", \
+ "\blue You scoop up some [src] with \the [U]!" \
+ )
+
+ src.bitecount++
+ U.overlays.Cut()
+ U.loaded = "[src]"
+ var/image/I = new(U.icon, "loadedfood")
+ I.color = src.filling_color
+ U.overlays += I
+
+ reagents.trans_to(U,min(reagents.total_volume,5))
+
+ if (reagents.total_volume <= 0)
+ del(src)
+ return
+
if((slices_num <= 0 || !slices_num) || !slice_path)
return 0
+
var/inaccurate = 0
if( \
istype(W, /obj/item/weapon/kitchenknife) || \
@@ -173,8 +204,8 @@
)
else
user.visible_message( \
- "\blue [user] inaccurately slices \the [src] with [W]!", \
- "\blue You inaccurately slice \the [src] with your [W]!" \
+ "\blue [user] crudely slices \the [src] with [W]!", \
+ "\blue You crudely slice \the [src] with your [W]!" \
)
slices_lost = rand(1,min(1,round(slices_num/2)))
var/reagents_per_slice = reagents.total_volume/slices_num
@@ -182,6 +213,7 @@
var/obj/slice = new slice_path (src.loc)
reagents.trans_to(slice,reagents_per_slice)
del(src)
+
return
/obj/item/weapon/reagent_containers/food/snacks/Del()
@@ -876,33 +908,6 @@
..()
reagents.add_reagent("nutriment", 8)
bitesize = 1
- attackby(obj/item/weapon/W as obj, mob/user as mob)
- if(istype(W,/obj/item/weapon/kitchen/utensil/fork))
- if (W.icon_state == "forkloaded")
- user << "\red You already have omelette on your fork."
- return
- //W.icon = 'icons/obj/kitchen.dmi'
- W.icon_state = "forkloaded"
- /*if (herp)
- world << "[user] takes a piece of omelette with his fork!"*/
- //Why this unecessary check? Oh I know, because I'm bad >:C
- // Yes, you are. You griefing my badmin toys. --rastaf0
- user.visible_message( \
- "[user] takes a piece of omelette with their fork!", \
- "\blue You take a piece of omelette with your fork!" \
- )
- reagents.remove_reagent("nutriment", 1)
- if (reagents.total_volume <= 0)
- del(src)
-/*
- * Unsused.
-/obj/item/weapon/reagent_containers/food/snacks/omeletteforkload
- name = "Omelette Du Fromage"
- desc = "That's all you can say!"
- New()
- ..()
- reagents.add_reagent("nutriment", 1)
-*/
/obj/item/weapon/reagent_containers/food/snacks/muffin
name = "Muffin"
@@ -1532,7 +1537,7 @@
filling_color = "#ADAC7F"
var/wrapped = 0
- var/monkey_type = null
+ var/monkey_type = /mob/living/carbon/monkey
New()
..()
@@ -1550,19 +1555,46 @@
if(wrapped)
Unwrap(user)
+ On_Consume(var/mob/M)
+ M << "Something inside of you suddently expands!"
+
+
+ if (istype(M, /mob/living/carbon/human))
+ //Do not try to understand.
+ var/obj/item/weapon/surprise = new/obj/item/weapon(M)
+ var/mob/living/carbon/monkey/ook = new monkey_type(null) //no other way to get access to the vars, alas
+ surprise.icon = ook.icon
+ surprise.icon_state = ook.icon_state
+ surprise.name = "malformed [ook.name]"
+ surprise.desc = "Looks like \a very deformed [ook.name], a little small for its kind. It shows no signs of life."
+ del(ook) //rip nullspace monkey
+ surprise.transform *= 0.6
+ surprise.add_blood(M)
+ var/mob/living/carbon/human/H = M
+ var/datum/organ/external/E = H.get_organ("chest")
+ E.fracture()
+ for (var/datum/organ/internal/I in E.internal_organs)
+ I.take_damage(rand(I.min_bruised_damage, I.min_broken_damage+1))
+
+ if (!E.hidden && prob(60)) //set it snuggly
+ E.hidden = surprise
+ E.cavity = 0
+ else //someone is having a bad day
+ E.createwound(CUT, 30)
+ E.embed(surprise)
+ else if (ismonkey(M))
+ M.visible_message("[M] suddenly tears in half!")
+ var/mob/living/carbon/monkey/ook = new monkey_type(M.loc)
+ ook.name = "malformed [ook.name]"
+ ook.transform *= 0.6
+ ook.add_blood(M)
+ M.gib()
+ ..()
+
proc/Expand()
for(var/mob/M in viewers(src,7))
M << "\red \The [src] expands!"
- if(monkey_type)
- switch(monkey_type)
- if("tajara")
- new /mob/living/carbon/monkey/tajara(get_turf(src))
- if("unathi")
- new /mob/living/carbon/monkey/unathi(get_turf(src))
- if("skrell")
- new /mob/living/carbon/monkey/skrell(get_turf(src))
- else
- new /mob/living/carbon/monkey(get_turf(src))
+ new monkey_type(src)
del(src)
proc/Unwrap(mob/user as mob)
@@ -1580,18 +1612,18 @@
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/farwacube
name = "farwa cube"
- monkey_type ="tajara"
+ monkey_type = /mob/living/carbon/monkey/tajara
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/farwacube
name = "farwa cube"
- monkey_type ="tajara"
+ monkey_type =/mob/living/carbon/monkey/tajara
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/stokcube
name = "stok cube"
- monkey_type ="unathi"
+ monkey_type = /mob/living/carbon/monkey/unathi
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/stokcube
name = "stok cube"
- monkey_type ="unathi"
+ monkey_type =/mob/living/carbon/monkey/unathi
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/neaeracube
@@ -1599,7 +1631,7 @@
monkey_type ="skrell"
/obj/item/weapon/reagent_containers/food/snacks/monkeycube/wrapped/neaeracube
name = "neaera cube"
- monkey_type ="skrell"
+ monkey_type =/mob/living/carbon/monkey/skrell
/obj/item/weapon/reagent_containers/food/snacks/spellburger
diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm
index fc738957ac..fd5821784e 100644
--- a/code/modules/reagents/reagent_dispenser.dm
+++ b/code/modules/reagents/reagent_dispenser.dm
@@ -166,7 +166,7 @@
if(src)
del(src)
-/obj/structure/reagent_dispensers/fueltank/temperature_expose(datum/gas_mixture/air, temperature, volume)
+/obj/structure/reagent_dispensers/fueltank/fire_act(datum/gas_mixture/air, temperature, volume)
if(temperature > T0C+500)
explode()
return ..()
diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm
index c985d00372..782b14b9da 100755
--- a/code/modules/recycling/sortingmachinery.dm
+++ b/code/modules/recycling/sortingmachinery.dm
@@ -234,20 +234,8 @@
flush()
flushing = 1
flick("intake-closing", src)
- var/deliveryCheck = 0
var/obj/structure/disposalholder/H = new() // virtual holder object which actually
// travels through the pipes.
- for(var/obj/structure/bigDelivery/O in src)
- deliveryCheck = 1
- if(O.sortTag == 0)
- O.sortTag = 1
- for(var/obj/item/smallDelivery/O in src)
- deliveryCheck = 1
- if (O.sortTag == 0)
- O.sortTag = 1
- if(deliveryCheck == 0)
- H.destinationTag = 1
-
air_contents = new() // new empty gas resv.
sleep(10)
diff --git a/code/modules/research/xenoarchaeology/artifact/artifact_autocloner.dm b/code/modules/research/xenoarchaeology/artifact/artifact_autocloner.dm
index e602e4363f..fb01ee4661 100644
--- a/code/modules/research/xenoarchaeology/artifact/artifact_autocloner.dm
+++ b/code/modules/research/xenoarchaeology/artifact/artifact_autocloner.dm
@@ -5,8 +5,9 @@
icon = 'icons/obj/cryogenics.dmi'
icon_state = "cellold0"
var/spawn_type
- var/current_ticks_spawning = 0
- var/ticks_required_to_spawn
+ var/time_spent_spawning = 0
+ var/time_per_spawn = 0
+ var/last_process= 0
density = 1
var/previous_power_state = 0
@@ -17,7 +18,7 @@
/obj/machinery/auto_cloner/New()
..()
- ticks_required_to_spawn = rand(240,1440)
+ time_per_spawn = rand(1200,3600)
//33% chance to spawn nasties
if(prob(33))
@@ -53,13 +54,12 @@
src.visible_message("\blue \icon[src] [src] suddenly comes to life!")
//slowly grow a mob
- current_ticks_spawning++
if(prob(5))
src.visible_message("\blue \icon[src] [src] [pick("gloops","glugs","whirrs","whooshes","hisses","purrs","hums","gushes")].")
//if we've finished growing...
- if(current_ticks_spawning >= ticks_required_to_spawn)
- current_ticks_spawning = 0
+ if(time_spent_spawning >= time_per_spawn)
+ time_spent_spawning = 0
use_power = 1
src.visible_message("\blue \icon[src] [src] pings!")
icon_state = "cellold1"
@@ -68,7 +68,7 @@
new spawn_type(src.loc)
//if we're getting close to finished, kick into overdrive power usage
- if(current_ticks_spawning / ticks_required_to_spawn > 0.75)
+ if(time_spent_spawning / time_per_spawn > 0.75)
use_power = 2
icon_state = "cellold2"
desc = "It's full of a bubbling viscous liquid, and is lit by a mysterious glow. A dark shape appears to be forming inside..."
@@ -76,6 +76,8 @@
use_power = 1
icon_state = "cellold1"
desc = "It's full of a bubbling viscous liquid, and is lit by a mysterious glow."
+
+ time_spent_spawning = time_spent_spawning + world.time - last_process
else
if(previous_power_state)
previous_power_state = 0
@@ -83,5 +85,6 @@
src.visible_message("\blue \icon[src] [src] suddenly shuts down.")
//cloned mob slowly breaks down
- if(current_ticks_spawning > 0)
- current_ticks_spawning--
+ time_spent_spawning = max(time_spent_spawning + last_process - world.time, 0)
+
+ last_process = world.time
diff --git a/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm b/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm
index 63999f9921..56954dc6dd 100644
--- a/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm
+++ b/code/modules/research/xenoarchaeology/artifact/artifact_replicator.dm
@@ -10,10 +10,15 @@
active_power_usage = 1000
use_power = 1
- var/spawn_progress = 0
- var/max_spawn_ticks = 5
+ var/spawn_progress_time = 0
+ var/max_spawn_time = 50
+ var/last_process_time = 0
+
var/list/construction = list()
var/list/spawning_types = list()
+ var/list/stored_materials = list()
+
+ var/fail_message
/obj/machinery/replicator/New()
..()
@@ -66,32 +71,52 @@
var/quantity = rand(5,15)
for(var/i=0, i max_spawn_ticks)
+ spawn_progress_time += world.time - last_process_time
+ if(spawn_progress_time > max_spawn_time)
src.visible_message("\blue \icon[src] [src] pings!")
- var/spawn_type = spawning_types[1]
- new spawn_type(src.loc)
- spawning_types.Remove(spawning_types[1])
- spawn_progress = 0
- max_spawn_ticks = rand(5,30)
+ var/obj/source_material = pop(stored_materials)
+ var/spawn_type = pop(spawning_types)
+ var/obj/spawned_obj = new spawn_type(src.loc)
+ if(source_material)
+ if(lentext(source_material.name) < MAX_MESSAGE_LEN)
+ spawned_obj.name = "[source_material] " + spawned_obj.name
+ if(lentext(source_material.desc) < MAX_MESSAGE_LEN * 2)
+ if(spawned_obj.desc)
+ spawned_obj.desc += " It is made of [source_material]."
+ else
+ spawned_obj.desc = "It is made of [source_material]."
+ source_material.loc = null
- if(!spawning_types.len)
+ spawn_progress_time = 0
+ max_spawn_time = rand(30,100)
+
+ if(!spawning_types.len || !stored_materials.len)
use_power = 1
icon_state = "borgcharger0(old)"
else if(prob(5))
src.visible_message("\blue \icon[src] [src] [pick("clicks","whizzes","whirrs","whooshes","clanks","clongs","clonks","bangs")].")
+ last_process_time = world.time
+
/obj/machinery/replicator/attack_hand(mob/user as mob)
interact(user)
@@ -103,17 +128,26 @@
user << browse(dat, "window=alien_replicator")
+/obj/machinery/replicator/attackby(obj/item/weapon/W as obj, mob/living/user as mob)
+ user.drop_item()
+ W.loc = src
+ stored_materials.Add(W)
+ src.visible_message("\blue [user] inserts [W] into [src].")
+
/obj/machinery/replicator/Topic(href, href_list)
if(href_list["activate"])
var/index = text2num(href_list["activate"])
if(index > 0 && index <= construction.len)
- if(spawning_types.len)
- src.visible_message("\blue \icon[src] a [pick("light","dial","display","meter","pad")] on [src]'s front [pick("blinks","flashes")] [pick("red","yellow","blue","orange","purple","green","white")].")
- else
- src.visible_message("\blue \icon[src] [src]'s front compartment slides shut.")
+ if(stored_materials.len > spawning_types.len)
+ if(spawning_types.len)
+ src.visible_message("\blue \icon[src] a [pick("light","dial","display","meter","pad")] on [src]'s front [pick("blinks","flashes")] [pick("red","yellow","blue","orange","purple","green","white")].")
+ else
+ src.visible_message("\blue \icon[src] [src]'s front compartment slides shut.")
- spawning_types.Add(construction[construction[index]])
- spawn_progress = 0
- use_power = 2
- icon_state = "borgcharger1(old)"
+ spawning_types.Add(construction[construction[index]])
+ spawn_progress_time = 0
+ use_power = 2
+ icon_state = "borgcharger1(old)"
+ else
+ src.visible_message(fail_message)
diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_affect_cold.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_affect_cold.dm
index fcdb163ac7..f8dad2c4d3 100644
--- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_affect_cold.dm
+++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_affect_cold.dm
@@ -12,6 +12,7 @@
/datum/artifact_effect/cold/DoEffectTouch(var/mob/user)
if(holder)
+ user << "\blue A chill passes up your spine!"
var/datum/gas_mixture/env = holder.loc.return_air()
if(env)
env.temperature = max(env.temperature - rand(5,50), 0)
diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_badfeeling.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_badfeeling.dm
index 2e57907b50..1244f802cc 100644
--- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_badfeeling.dm
+++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_badfeeling.dm
@@ -41,7 +41,8 @@
/datum/artifact_effect/badfeeling/DoEffectAura()
if(holder)
- for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/carbon/human/H in range(src.effectrange,T))
if(prob(5))
if(prob(75))
H << "[pick(messages)]"
@@ -54,7 +55,8 @@
/datum/artifact_effect/badfeeling/DoEffectPulse()
if(holder)
- for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/carbon/human/H in range(src.effectrange,T))
if(prob(50))
if(prob(95))
H << "[pick(drastic_messages)]"
diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_cellcharge.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_cellcharge.dm
index 5105628cfe..d7ff967c2d 100644
--- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_cellcharge.dm
+++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_cellcharge.dm
@@ -15,7 +15,8 @@
/datum/artifact_effect/cellcharge/DoEffectAura()
if(holder)
- for (var/obj/machinery/power/apc/C in range(200, holder))
+ var/turf/T = get_turf(holder)
+ for (var/obj/machinery/power/apc/C in range(200, T))
for (var/obj/item/weapon/cell/B in C.contents)
B.charge += 25
for (var/obj/machinery/power/smes/S in range (src.effectrange,src))
@@ -28,7 +29,8 @@
/datum/artifact_effect/cellcharge/DoEffectPulse()
if(holder)
- for (var/obj/machinery/power/apc/C in range(200, holder))
+ var/turf/T = get_turf(holder)
+ for (var/obj/machinery/power/apc/C in range(200, T))
for (var/obj/item/weapon/cell/B in C.contents)
B.charge += rand() * 100
for (var/obj/machinery/power/smes/S in range (src.effectrange,src))
diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_celldrain.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_celldrain.dm
index 550b49b068..8af61035d4 100644
--- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_celldrain.dm
+++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_celldrain.dm
@@ -17,7 +17,8 @@
/datum/artifact_effect/celldrain/DoEffectAura()
if(holder)
- for (var/obj/machinery/power/apc/C in range(200, holder))
+ var/turf/T = get_turf(holder)
+ for (var/obj/machinery/power/apc/C in range(200, T))
for (var/obj/item/weapon/cell/B in C.contents)
B.charge = max(B.charge - 50,0)
for (var/obj/machinery/power/smes/S in range (src.effectrange,src))
@@ -30,7 +31,8 @@
/datum/artifact_effect/celldrain/DoEffectPulse()
if(holder)
- for (var/obj/machinery/power/apc/C in range(200, holder))
+ var/turf/T = get_turf(holder)
+ for (var/obj/machinery/power/apc/C in range(200, T))
for (var/obj/item/weapon/cell/B in C.contents)
B.charge = max(B.charge - rand() * 150,0)
for (var/obj/machinery/power/smes/S in range (src.effectrange,src))
diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_dnaswitch.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_dnaswitch.dm
index cff708b0c3..b74ab88a9a 100644
--- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_dnaswitch.dm
+++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_dnaswitch.dm
@@ -30,7 +30,8 @@
/datum/artifact_effect/dnaswitch/DoEffectAura()
if(holder)
- for(var/mob/living/carbon/human/H in range(src.effectrange,holder))
+ var/turf/T = get_turf(holder)
+ for(var/mob/living/carbon/human/H in range(src.effectrange,T))
var/weakness = GetAnomalySusceptibility(H)
if(prob(weakness * 100))
if(prob(30))
@@ -48,7 +49,8 @@
/datum/artifact_effect/dnaswitch/DoEffectPulse()
if(holder)
- for(var/mob/living/carbon/human/H in range(200, holder))
+ var/turf/T = get_turf(holder)
+ for(var/mob/living/carbon/human/H in range(200, T))
var/weakness = GetAnomalySusceptibility(H)
if(prob(weakness * 100))
if(prob(75))
diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_emp.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_emp.dm
index aeafa6387d..18165cf0d4 100644
--- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_emp.dm
+++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_emp.dm
@@ -9,5 +9,6 @@
/datum/artifact_effect/emp/DoEffectPulse()
if(holder)
- empulse(get_turf(holder), effectrange/2, effectrange)
+ var/turf/T = get_turf(holder)
+ empulse(T, effectrange/2, effectrange)
return 1
diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_goodfeeling.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_goodfeeling.dm
index 752aa61ce0..bc45260b2c 100644
--- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_goodfeeling.dm
+++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_goodfeeling.dm
@@ -39,7 +39,8 @@
/datum/artifact_effect/goodfeeling/DoEffectAura()
if(holder)
- for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/carbon/human/H in range(src.effectrange,T))
if(prob(5))
if(prob(75))
H << "[pick(messages)]"
@@ -52,7 +53,8 @@
/datum/artifact_effect/goodfeeling/DoEffectPulse()
if(holder)
- for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/carbon/human/H in range(src.effectrange,T))
if(prob(50))
if(prob(95))
H << "[pick(drastic_messages)]"
diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_heal.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_heal.dm
index 8b92784424..d1d3937c97 100644
--- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_heal.dm
+++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_heal.dm
@@ -36,7 +36,8 @@
/datum/artifact_effect/heal/DoEffectAura()
//todo: check over this properly
if(holder)
- for (var/mob/living/carbon/C in range(src.effectrange,holder))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/carbon/C in range(src.effectrange,T))
var/weakness = GetAnomalySusceptibility(C)
if(prob(weakness * 100))
if(prob(10))
@@ -51,7 +52,8 @@
/datum/artifact_effect/heal/DoEffectPulse()
//todo: check over this properly
if(holder)
- for (var/mob/living/carbon/C in range(src.effectrange,holder))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/carbon/C in range(src.effectrange,T))
var/weakness = GetAnomalySusceptibility(C)
if(prob(weakness * 100))
C << "\blue A wave of energy invigorates you."
diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_heat.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_heat.dm
index da59078a1b..21304df408 100644
--- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_heat.dm
+++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_heat.dm
@@ -15,6 +15,7 @@
/datum/artifact_effect/heat/DoEffectTouch(var/mob/user)
if(holder)
+ user << "\red You feel a wave of heat travel up your spine!"
var/datum/gas_mixture/env = holder.loc.return_air()
if(env)
env.temperature += rand(5,50)
diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm
index f69b9b9d9d..77074be63f 100644
--- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm
+++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_hurt.dm
@@ -21,7 +21,8 @@
/datum/artifact_effect/hurt/DoEffectAura()
if(holder)
- for (var/mob/living/carbon/C in range(src.effectrange,holder))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/carbon/C in range(src.effectrange,T))
var/weakness = GetAnomalySusceptibility(C)
if(prob(weakness * 100))
if(prob(10))
@@ -35,7 +36,8 @@
/datum/artifact_effect/hurt/DoEffectPulse()
if(holder)
- for (var/mob/living/carbon/C in range(effectrange, holder))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/carbon/C in range(effectrange, T))
var/weakness = GetAnomalySusceptibility(C)
if(prob(weakness * 100))
C << "\red A wave of painful energy strikes you!"
diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_radiate.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_radiate.dm
index e6c49c96ce..4310ffb2e7 100644
--- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_radiate.dm
+++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_radiate.dm
@@ -16,14 +16,16 @@
/datum/artifact_effect/radiate/DoEffectAura()
if(holder)
- for (var/mob/living/M in range(src.effectrange,holder))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/M in range(src.effectrange,T))
M.apply_effect(radiation_amount,IRRADIATE,0)
M.updatehealth()
return 1
/datum/artifact_effect/radiate/DoEffectPulse()
if(holder)
- for (var/mob/living/M in range(src.effectrange,holder))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/M in range(src.effectrange,T))
M.apply_effect(radiation_amount * 25,IRRADIATE,0)
M.updatehealth()
return 1
diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_roboheal.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_roboheal.dm
index 8e154f0b66..a1a89e42cf 100644
--- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_roboheal.dm
+++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_roboheal.dm
@@ -17,7 +17,8 @@
/datum/artifact_effect/roboheal/DoEffectAura()
if(holder)
- for (var/mob/living/silicon/robot/M in range(src.effectrange,holder))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/silicon/robot/M in range(src.effectrange,T))
if(prob(10))
M << "\blue SYSTEM ALERT: Beneficial energy field detected!"
M.adjustBruteLoss(-1)
@@ -27,7 +28,8 @@
/datum/artifact_effect/roboheal/DoEffectPulse()
if(holder)
- for (var/mob/living/silicon/robot/M in range(src.effectrange,holder))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/silicon/robot/M in range(src.effectrange,T))
M << "\blue SYSTEM ALERT: Structural damage has been repaired by energy pulse!"
M.adjustBruteLoss(-10)
M.adjustFireLoss(-10)
diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_robohurt.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_robohurt.dm
index b230efa33e..bc55a76cef 100644
--- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_robohurt.dm
+++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_robohurt.dm
@@ -17,7 +17,8 @@
/datum/artifact_effect/robohurt/DoEffectAura()
if(holder)
- for (var/mob/living/silicon/robot/M in range(src.effectrange,holder))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/silicon/robot/M in range(src.effectrange,T))
if(prob(10)) M << "\red SYSTEM ALERT: Harmful energy field detected!"
M.adjustBruteLoss(1)
M.adjustFireLoss(1)
@@ -26,7 +27,8 @@
/datum/artifact_effect/robohurt/DoEffectPulse()
if(holder)
- for (var/mob/living/silicon/robot/M in range(src.effectrange,holder))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/silicon/robot/M in range(src.effectrange,T))
M << "\red SYSTEM ALERT: Structural damage inflicted by energy pulse!"
M.adjustBruteLoss(10)
M.adjustFireLoss(10)
diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_sleepy.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_sleepy.dm
index 1da02ceaa9..61979c5f69 100644
--- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_sleepy.dm
+++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_sleepy.dm
@@ -22,7 +22,8 @@
/datum/artifact_effect/sleepy/DoEffectAura()
if(holder)
- for (var/mob/living/carbon/human/H in range(src.effectrange,holder))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/carbon/human/H in range(src.effectrange,T))
var/weakness = GetAnomalySusceptibility(H)
if(prob(weakness * 100))
if(prob(10))
@@ -35,7 +36,8 @@
/datum/artifact_effect/sleepy/DoEffectPulse()
if(holder)
- for(var/mob/living/carbon/human/H in range(src.effectrange, holder))
+ var/turf/T = get_turf(holder)
+ for(var/mob/living/carbon/human/H in range(src.effectrange, T))
var/weakness = GetAnomalySusceptibility(H)
if(prob(weakness * 100))
H << pick("\blue You feel like taking a nap.","\blue You feel a yawn coming on.","\blue You feel a little tired.")
diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_stun.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_stun.dm
index b37862eb0c..b7b2864de4 100644
--- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_stun.dm
+++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_stun.dm
@@ -9,33 +9,35 @@
/datum/artifact_effect/stun/DoEffectTouch(var/mob/toucher)
if(toucher && iscarbon(toucher))
var/mob/living/carbon/C = toucher
- var/weakness = GetAnomalySusceptibility(C)
- if(prob(weakness * 100))
+ var/susceptibility = GetAnomalySusceptibility(C)
+ if(prob(susceptibility * 100))
C << "\red A powerful force overwhelms your consciousness."
- C.weakened += 45 * weakness
- C.stuttering += 45 * weakness
- C.stunned += rand(1,10) * weakness
+ C.Weaken(rand(1,10) * susceptibility)
+ C.stuttering += 30 * susceptibility
+ C.Stun(rand(1,10) * susceptibility)
/datum/artifact_effect/stun/DoEffectAura()
if(holder)
- for (var/mob/living/carbon/C in range(src.effectrange,holder))
- var/weakness = GetAnomalySusceptibility(C)
- if(prob(10 * weakness))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/carbon/C in range(src.effectrange,T))
+ var/susceptibility = GetAnomalySusceptibility(C)
+ if(prob(10 * susceptibility))
C << "\red Your body goes numb for a moment."
- C.weakened += 2
+ C.Weaken(2)
C.stuttering += 2
if(prob(10))
- C.stunned += 1
+ C.Stun(1)
else if(prob(10))
C << "\red You feel numb."
/datum/artifact_effect/stun/DoEffectPulse()
if(holder)
- for (var/mob/living/carbon/C in range(src.effectrange,holder))
- var/weakness = GetAnomalySusceptibility(C)
- if(prob(100 * weakness))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/carbon/C in range(src.effectrange,T))
+ var/susceptibility = GetAnomalySusceptibility(C)
+ if(prob(100 * susceptibility))
C << "\red A wave of energy overwhelms your senses!"
- C.weakened += 4 * weakness
- C.stuttering += 4 * weakness
+ C.SetWeakened(4 * susceptibility)
+ C.stuttering = 4 * susceptibility
if(prob(10))
- C.stunned += 1 * weakness
+ C.SetStunned(1 * susceptibility)
diff --git a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_teleport.dm b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_teleport.dm
index e1580e2073..254be3f3d0 100644
--- a/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_teleport.dm
+++ b/code/modules/research/xenoarchaeology/artifact/effects/unknown_effect_teleport.dm
@@ -6,60 +6,53 @@
/datum/artifact_effect/teleport/DoEffectTouch(var/mob/user)
var/weakness = GetAnomalySusceptibility(user)
if(prob(100 * weakness))
- var/list/randomturfs = new/list()
- for(var/turf/simulated/floor/T in orange(user, 50))
- randomturfs.Add(T)
- if(randomturfs.len > 0)
- user << "\red You are suddenly zapped away elsewhere!"
- if (user.buckled)
- user.buckled.unbuckle()
+ user << "\red You are suddenly zapped away elsewhere!"
+ if (user.buckled)
+ user.buckled.unbuckle()
- var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
- sparks.set_up(3, 0, get_turf(user))
- sparks.start()
- user.loc = pick(randomturfs)
- sparks = new /datum/effect/effect/system/spark_spread()
- sparks.set_up(3, 0, get_turf(user))
- sparks.start()
+ var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
+ sparks.set_up(3, 0, get_turf(user))
+ sparks.start()
+ //
+ user.loc = pick(orange(get_turf(holder), 50))
+ sparks = new /datum/effect/effect/system/spark_spread()
+ sparks.set_up(3, 0, get_turf(user))
+ sparks.start()
/datum/artifact_effect/teleport/DoEffectAura()
if(holder)
- for (var/mob/living/M in range(src.effectrange,holder))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/M in range(src.effectrange,T))
var/weakness = GetAnomalySusceptibility(M)
if(prob(100 * weakness))
- var/list/randomturfs = new/list()
- for(var/turf/simulated/floor/T in orange(M, 30))
- randomturfs.Add(T)
- if(randomturfs.len > 0)
- M << "\red You are displaced by a strange force!"
- if(M.buckled)
- M.buckled.unbuckle()
+ M << "\red You are displaced by a strange force!"
+ if(M.buckled)
+ M.buckled.unbuckle()
- var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
- sparks.set_up(3, 0, get_turf(M))
- sparks.start()
- M.loc = pick(randomturfs)
- sparks = new /datum/effect/effect/system/spark_spread()
- sparks.set_up(3, 0, get_turf(M))
- sparks.start()
+ var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
+ sparks.set_up(3, 0, get_turf(M))
+ sparks.start()
+ //
+ M.loc = pick(orange(get_turf(T), 50))
+ sparks = new /datum/effect/effect/system/spark_spread()
+ sparks.set_up(3, 0, get_turf(M))
+ sparks.start()
/datum/artifact_effect/teleport/DoEffectPulse()
if(holder)
- for (var/mob/living/M in range(src.effectrange, holder))
+ var/turf/T = get_turf(holder)
+ for (var/mob/living/M in range(src.effectrange, T))
var/weakness = GetAnomalySusceptibility(M)
if(prob(100 * weakness))
- var/list/randomturfs = new/list()
- for(var/turf/simulated/floor/T in orange(M, 15))
- randomturfs.Add(T)
- if(randomturfs.len > 0)
- M << "\red You are displaced by a strange force!"
+ M << "\red You are displaced by a strange force!"
+ if(M.buckled)
+ M.buckled.unbuckle()
- var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
- sparks.set_up(3, 0, get_turf(M))
- sparks.start()
- if(M.buckled)
- M.buckled.unbuckle()
- M.loc = pick(randomturfs)
- sparks = new /datum/effect/effect/system/spark_spread()
- sparks.set_up(3, 0, get_turf(M))
- sparks.start()
+ var/datum/effect/effect/system/spark_spread/sparks = new /datum/effect/effect/system/spark_spread()
+ sparks.set_up(3, 0, get_turf(M))
+ sparks.start()
+ //
+ M.loc = pick(orange(get_turf(T), 50))
+ sparks = new /datum/effect/effect/system/spark_spread()
+ sparks.set_up(3, 0, get_turf(M))
+ sparks.start()
diff --git a/code/modules/research/xenoarchaeology/finds/finds.dm b/code/modules/research/xenoarchaeology/finds/finds.dm
index 1d77a68f0f..09f91d0342 100644
--- a/code/modules/research/xenoarchaeology/finds/finds.dm
+++ b/code/modules/research/xenoarchaeology/finds/finds.dm
@@ -113,7 +113,10 @@
switch(find_type)
if(1)
item_type = "bowl"
- new_item = new /obj/item/weapon/reagent_containers/glass(src.loc)
+ if(prob(33))
+ new_item = new /obj/item/weapon/reagent_containers/glass/replenishing(src.loc)
+ else
+ new_item = new /obj/item/weapon/reagent_containers/glass/beaker(src.loc)
new_item.icon = 'icons/obj/xenoarchaeology.dmi'
new_item.icon_state = "bowl"
apply_image_decorations = 1
@@ -121,7 +124,10 @@
additional_desc = "There appear to be [pick("dark","faintly glowing","pungent","bright")] [pick("red","purple","green","blue")] stains inside."
if(2)
item_type = "urn"
- new_item = new /obj/item/weapon/reagent_containers/glass(src.loc)
+ if(prob(33))
+ new_item = new /obj/item/weapon/reagent_containers/glass/replenishing(src.loc)
+ else
+ new_item = new /obj/item/weapon/reagent_containers/glass/beaker(src.loc)
new_item.icon = 'icons/obj/xenoarchaeology.dmi'
new_item.icon_state = "urn"
apply_image_decorations = 1
@@ -139,11 +145,14 @@
"It's a mystery how anyone is supposed to eat with this",\
"You wonder what the creator's mouth was shaped like")]."
if(4)
+ name = "statuette"
item_type = "statuette"
icon_state = "statuette"
additional_desc = "It depicts a [pick("small","ferocious","wild","pleasing","hulking")] \
[pick("alien figure","rodent-like creature","reptilian alien","primate","unidentifiable object")] \
[pick("performing unspeakable acts","posing heroically","in a fetal position","cheering","sobbing","making a plaintive gesture","making a rude gesture")]."
+ if(prob(25))
+ new_item = new /obj/item/weapon/vampiric(src.loc)
if(5)
item_type = "instrument"
icon_state = "instrument"
@@ -194,6 +203,9 @@
new_item = new /obj/item/weapon/storage/box(src.loc)
new_item.icon = 'icons/obj/xenoarchaeology.dmi'
new_item.icon_state = "box"
+ var/obj/item/weapon/storage/box/new_box = new_item
+ new_box.max_w_class = pick(1,2,2,3,3,3,4,4)
+ new_box.max_combined_w_class = rand(new_box.max_w_class, new_box.max_w_class * 10)
if(prob(30))
apply_image_decorations = 1
if(12)
@@ -260,6 +272,10 @@
apply_material_decorations = 0
if(prob(10))
apply_image_decorations = 1
+ if(prob(25))
+ new_item = new /obj/item/device/soulstone(src.loc)
+ new_item.icon = 'icons/obj/xenoarchaeology.dmi'
+ new_item.icon_state = icon_state
if(17)
//cultblade
apply_prefix = 0
@@ -462,7 +478,12 @@
"It doesn't look human.")
apply_image_decorations = 0
apply_material_decorations = 0
-
+ if(35)
+ //gas mask
+ if(prob(25))
+ new_item = new /obj/item/clothing/mask/gas/poltergeist(src.loc)
+ else
+ new_item = new /obj/item/clothing/mask/gas(src.loc)
var/decorations = ""
if(apply_material_decorations)
source_material = pick("cordite","quadrinium","steel","titanium","aluminium","ferritic-alloy","plasteel","duranium")
@@ -520,18 +541,14 @@
new_item.name = name
new_item.desc = src.desc
- if(talkative && istype(new_item,/obj/item/weapon))
- new_item.listening_to_players = 1
- if(prob(25))
- new_item.speaking_to_players = 1
- processing_objects.Add(src)
- var/turf/T = get_turf(src)
- if(istype(T, /turf/simulated/mineral))
- T:last_find = new_item
+ if(talkative)
+ new_item.talking_atom = new()
+ talking_atom.holder_atom = new_item
+ talking_atom.init()
+
del(src)
else if(talkative)
- listening_to_players = 1
- if(prob(25))
- speaking_to_players = 1
- processing_objects.Add(src)
+ src.talking_atom = new()
+ talking_atom.holder_atom = src
+ talking_atom.init()
diff --git a/code/modules/research/xenoarchaeology/finds/finds_defines.dm b/code/modules/research/xenoarchaeology/finds/finds_defines.dm
index a28742d6c5..4026cc0a03 100644
--- a/code/modules/research/xenoarchaeology/finds/finds_defines.dm
+++ b/code/modules/research/xenoarchaeology/finds/finds_defines.dm
@@ -33,7 +33,8 @@
#define ARCHAEO_REMAINS_HUMANOID 32
#define ARCHAEO_REMAINS_ROBOT 33
#define ARCHAEO_REMAINS_XENO 34
-#define MAX_ARCHAEO 34
+#define ARCHAEO_GASMASK 35
+#define MAX_ARCHAEO 35
//eggs
//droppings
//footprints
@@ -119,6 +120,8 @@
return "carbon"
if(ARCHAEO_REMAINS_XENO)
return "carbon"
+ if(ARCHAEO_GASMASK)
+ return "carbon"
return "phoron"
//see /turf/simulated/mineral/New() in code/modules/mining/mine_turfs.dm
@@ -153,6 +156,7 @@
100;ARCHAEO_PEN,\
100;ARCHAEO_LIGHTER,\
100;ARCHAEO_BOX,\
+ 75;ARCHAEO_GASMASK,\
75;ARCHAEO_COIN,\
75;ARCHAEO_UNKNOWN,\
50;ARCHAEO_SHARD,\
@@ -161,6 +165,7 @@
)
if(DIGSITE_TECHNICAL)
find_type = pick(\
+ 125;ARCHAEO_GASMASK,\
100;ARCHAEO_METAL,\
100;ARCHAEO_GASTANK,\
100;ARCHAEO_TELEBEACON,\
@@ -175,6 +180,7 @@
if(DIGSITE_TEMPLE)
find_type = pick(\
200;ARCHAEO_CULTROBES,\
+ 200;ARCHAEO_STATUETTE,\
100;ARCHAEO_URN,\
100;ARCHAEO_BOWL,\
100;ARCHAEO_KNIFE,\
@@ -188,7 +194,8 @@
10;ARCHAEO_CLAYMORE,\
10;ARCHAEO_SHARD,\
10;ARCHAEO_RODS,\
- 10;ARCHAEO_METAL\
+ 10;ARCHAEO_METAL,\
+ 10;ARCHAEO_GASMASK,\
)
if(DIGSITE_WAR)
find_type = pick(\
@@ -200,6 +207,7 @@
50;ARCHAEO_UNKNOWN,\
50;ARCHAEO_CULTROBES,\
50;ARCHAEO_CULTBLADE,\
+ 50;ARCHAEO_GASMASK,\
25;ARCHAEO_HANDCUFFS,\
25;ARCHAEO_BEARTRAP,\
25;ARCHAEO_TOOL\
@@ -262,6 +270,8 @@ var/list/finds_as_strings = list( \
#undef ARCHAEO_REMAINS_HUMANOID
#undef ARCHAEO_REMAINS_ROBOT
#undef ARCHAEO_REMAINS_XENO
+#undef ARCHAEO_GASMASK
+#undef MAX_ARCHAEO
#undef DIGSITE_GARDEN
#undef DIGSITE_ANIMAL
diff --git a/code/modules/research/xenoarchaeology/finds/finds_fossils.dm b/code/modules/research/xenoarchaeology/finds/finds_fossils.dm
index 89fc33396d..57d510015f 100644
--- a/code/modules/research/xenoarchaeology/finds/finds_fossils.dm
+++ b/code/modules/research/xenoarchaeology/finds/finds_fossils.dm
@@ -7,6 +7,7 @@
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "bone"
desc = "It's a fossil."
+ var/animal = 1
/obj/item/weapon/fossil/base/New()
var/list/l = list("/obj/item/weapon/fossil/bone"=9,"/obj/item/weapon/fossil/skull"=3,
@@ -97,6 +98,7 @@
name = "Fossilised plant"
icon_state = "plant1"
desc = "It's fossilised plant remains."
+ animal = 0
/obj/item/weapon/fossil/plant/New()
icon_state = "plant[rand(1,4)]"
diff --git a/code/modules/research/xenoarchaeology/finds/finds_special.dm b/code/modules/research/xenoarchaeology/finds/finds_special.dm
new file mode 100644
index 0000000000..b2c0fb3898
--- /dev/null
+++ b/code/modules/research/xenoarchaeology/finds/finds_special.dm
@@ -0,0 +1,203 @@
+
+
+
+//endless reagents!
+/obj/item/weapon/reagent_containers/glass/replenishing
+ var/spawning_id
+
+/obj/item/weapon/reagent_containers/glass/replenishing/New()
+ ..()
+ processing_objects.Add(src)
+ spawning_id = pick("blood","holywater","lube","stoxin","ethanol","ice","glycerol","fuel","cleaner")
+
+/obj/item/weapon/reagent_containers/glass/replenishing/process()
+ reagents.add_reagent(spawning_id, 0.3)
+
+
+
+//a talking gas mask!
+/obj/item/clothing/mask/gas/poltergeist
+ var/list/heard_talk = list()
+ var/last_twitch = 0
+ var/max_stored_messages = 100
+
+/obj/item/clothing/mask/gas/poltergeist/New()
+ processing_objects.Add(src)
+
+/obj/item/clothing/mask/gas/poltergeist/process()
+ if(heard_talk.len && istype(src.loc, /mob/living) && prob(10))
+ var/mob/living/M = src.loc
+ M.say(pick(heard_talk))
+
+/obj/item/clothing/mask/gas/poltergeist/hear_talk(mob/M as mob, text)
+ ..()
+ if(heard_talk.len > max_stored_messages)
+ heard_talk.Remove(pick(heard_talk))
+ heard_talk.Add(text)
+ if(istype(src.loc, /mob/living) && world.time - last_twitch > 50)
+ last_twitch = world.time
+
+
+
+//a vampiric statuette
+//todo: cult integration
+/obj/item/weapon/vampiric
+ name = "statuette"
+ icon_state = "statuette"
+ icon = 'icons/obj/xenoarchaeology.dmi'
+ var/charges = 0
+ var/list/nearby_mobs = list()
+ var/last_bloodcall = 0
+ var/bloodcall_interval = 50
+ var/last_eat = 0
+ var/eat_interval = 100
+ var/wight_check_index = 1
+ var/list/shadow_wights = list()
+
+/obj/item/weapon/vampiric/New()
+ ..()
+ processing_objects.Add(src)
+
+/obj/item/weapon/vampiric/process()
+ //see if we've identified anyone nearby
+ if(world.time - last_bloodcall > bloodcall_interval && nearby_mobs.len)
+ var/mob/living/carbon/human/M = pop(nearby_mobs)
+ if(M in view(7,src) && M.health > 20)
+ if(prob(50))
+ bloodcall(M)
+ nearby_mobs.Add(M)
+
+ //suck up some blood to gain power
+ if(world.time - last_eat > eat_interval)
+ var/obj/effect/decal/cleanable/blood/B = locate() in range(2,src)
+ if(B)
+ last_eat = world.time
+ B.loc = null
+ if(istype(B, /obj/effect/decal/cleanable/blood/drip))
+ charges += 0.25
+ else
+ charges += 1
+ playsound(src.loc, 'sound/effects/splat.ogg', 50, 1, -3)
+
+ //use up stored charges
+ if(charges >= 10)
+ charges -= 10
+ new /obj/effect/spider/eggcluster(pick(view(1,src)))
+
+ if(charges >= 3)
+ if(prob(5))
+ charges -= 1
+ var/spawn_type = pick(/mob/living/simple_animal/hostile/creature)
+ new spawn_type(pick(view(1,src)))
+ playsound(src.loc, pick('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg'), 50, 1, -3)
+
+ if(charges >= 1)
+ if(shadow_wights.len < 5 && prob(5))
+ shadow_wights.Add(new /obj/effect/shadow_wight(src.loc))
+ playsound(src.loc, 'sound/effects/ghost.ogg', 50, 1, -3)
+ charges -= 0.1
+
+ if(charges >= 0.1)
+ if(prob(5))
+ src.visible_message("\red \icon[src] [src]'s eyes glow ruby red for a moment!")
+ charges -= 0.1
+
+ //check on our shadow wights
+ if(shadow_wights.len)
+ wight_check_index++
+ if(wight_check_index > shadow_wights.len)
+ wight_check_index = 1
+
+ var/obj/effect/shadow_wight/W = shadow_wights[wight_check_index]
+ if(isnull(W))
+ shadow_wights.Remove(wight_check_index)
+ else if(isnull(W.loc))
+ shadow_wights.Remove(wight_check_index)
+ else if(get_dist(W, src) > 10)
+ shadow_wights.Remove(wight_check_index)
+
+/obj/item/weapon/vampiric/hear_talk(mob/M as mob, text)
+ ..()
+ if(world.time - last_bloodcall >= bloodcall_interval && M in view(7, src))
+ bloodcall(M)
+
+/obj/item/weapon/vampiric/proc/bloodcall(var/mob/living/carbon/human/M)
+ last_bloodcall = world.time
+ if(istype(M))
+ playsound(src.loc, pick('sound/hallucinations/wail.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/far_noise.ogg'), 50, 1, -3)
+ nearby_mobs.Add(M)
+
+ var/target = pick("chest","groin","head","l_arm","r_arm","r_leg","l_leg","l_hand","r_hand","l_foot","r_foot")
+ M.apply_damage(rand(5, 10), BRUTE, target)
+ M << "\red The skin on your [parse_zone(target)] feels like it's ripping apart, and a stream of blood flies out."
+ var/obj/effect/decal/cleanable/blood/splatter/animated/B = new(M.loc)
+ B.target_turf = pick(range(1, src))
+ B.blood_DNA = list()
+ B.blood_DNA[M.dna.unique_enzymes] = M.dna.b_type
+ M.vessel.remove_reagent("blood",rand(25,50))
+
+//animated blood 2 SPOOKY
+/obj/effect/decal/cleanable/blood/splatter/animated
+ var/turf/target_turf
+ var/loc_last_process
+
+/obj/effect/decal/cleanable/blood/splatter/animated/New()
+ ..()
+ processing_objects.Add(src)
+ loc_last_process = src.loc
+
+/obj/effect/decal/cleanable/blood/splatter/animated/process()
+ if(target_turf && src.loc != target_turf)
+ step_towards(src,target_turf)
+ if(src.loc == loc_last_process)
+ target_turf = null
+ loc_last_process = src.loc
+
+ //leave some drips behind
+ if(prob(50))
+ var/obj/effect/decal/cleanable/blood/drip/D = new(src.loc)
+ D.blood_DNA = src.blood_DNA.Copy()
+ if(prob(50))
+ D = new(src.loc)
+ D.blood_DNA = src.blood_DNA.Copy()
+ if(prob(50))
+ D = new(src.loc)
+ D.blood_DNA = src.blood_DNA.Copy()
+ else
+ ..()
+
+/obj/effect/shadow_wight
+ name = "shadow wight"
+ icon = 'icons/mob/mob.dmi'
+ icon_state = "shade"
+ density = 1
+
+/obj/effect/shadow_wight/New()
+ processing_objects.Add(src)
+
+/obj/effect/shadow_wight/process()
+ if(src.loc)
+ src.loc = get_turf(pick(orange(1,src)))
+ var/mob/living/carbon/M = locate() in src.loc
+ if(M)
+ playsound(src.loc, pick('sound/hallucinations/behind_you1.ogg',\
+ 'sound/hallucinations/behind_you2.ogg',\
+ 'sound/hallucinations/i_see_you1.ogg',\
+ 'sound/hallucinations/i_see_you2.ogg',\
+ 'sound/hallucinations/im_here1.ogg',\
+ 'sound/hallucinations/im_here2.ogg',\
+ 'sound/hallucinations/look_up1.ogg',\
+ 'sound/hallucinations/look_up2.ogg',\
+ 'sound/hallucinations/over_here1.ogg',\
+ 'sound/hallucinations/over_here2.ogg',\
+ 'sound/hallucinations/over_here3.ogg',\
+ 'sound/hallucinations/turn_around1.ogg',\
+ 'sound/hallucinations/turn_around2.ogg',\
+ ), 50, 1, -3)
+ M.sleeping = max(M.sleeping,rand(5,10))
+ src.loc = null
+ else
+ processing_objects.Remove(src)
+
+/obj/effect/shadow_wight/Bump(var/atom/obstacle)
+ obstacle << "\red You feel a chill run down your spine!"
diff --git a/code/modules/research/xenoarchaeology/finds/finds_talkingitem.dm b/code/modules/research/xenoarchaeology/finds/finds_talkingitem.dm
index f518030075..65a2e24ca0 100644
--- a/code/modules/research/xenoarchaeology/finds/finds_talkingitem.dm
+++ b/code/modules/research/xenoarchaeology/finds/finds_talkingitem.dm
@@ -4,50 +4,64 @@
// This could be extended to atoms, but it's bad enough as is
// I genuinely tried to Add and Remove them from var and proc lists, but just couldn't get it working
-/obj/item/weapon
- var/list/heard_words = list()
- var/lastsaid
- var/listening_to_players = 0
- var/speaking_to_players = 0
+//for easy reference
+/obj/var/datum/talking_atom/talking_atom
-/obj/item/weapon/process()
- if(!speaking_to_players)
+/datum/talking_atom
+ var/list/heard_words = list()
+ var/last_talk_time = 0
+ var/atom/holder_atom
+ var/talk_interval = 50
+ var/talk_chance = 10
+
+/datum/talking_atom/proc/init()
+ if(holder_atom)
+ processing_objects.Add(src)
+
+/datum/talking_atom/proc/process()
+ if(!holder_atom)
processing_objects.Remove(src)
- return
- if(prob(10) && world.timeofday >= lastsaid && heard_words.len >= 1)
+
+ else if(heard_words.len >= 1 && world.time > last_talk_time + talk_interval && prob(talk_chance))
SaySomething()
-/obj/item/weapon/proc/catchMessage(var/msg, var/mob/source)
- if(speaking_to_players)
- var/list/seperate = list()
- if(findtext(msg,"(("))
- return
- else if(findtext(msg,"))"))
- return
- else if(findtext(msg," ")==0)
- return
- else
- /*var/l = lentext(msg)
- if(findtext(msg," ",l,l+1)==0)
- msg+=" "*/
- seperate = text2list(msg, " ")
+/datum/talking_atom/proc/catchMessage(var/msg, var/mob/source)
+ if(!holder_atom)
+ return
- for(var/Xa = 1,Xa 20 + rand(10,20))
- heard_words.Remove(heard_words[1])
- if(!heard_words["[lowertext(seperate[Xa])]"])
- heard_words["[lowertext(seperate[Xa])]"] = list()
- var/list/w = heard_words["[lowertext(seperate[Xa])]"]
- if(w)
- w.Add("[lowertext(seperate[next])]")
- //world << "Adding [lowertext(seperate[next])] to [lowertext(seperate[Xa])]"
+ var/list/seperate = list()
+ if(findtext(msg,"(("))
+ return
+ else if(findtext(msg,"))"))
+ return
+ else if(findtext(msg," ")==0)
+ return
+ else
+ /*var/l = lentext(msg)
+ if(findtext(msg," ",l,l+1)==0)
+ msg+=" "*/
+ seperate = text2list(msg, " ")
+
+ for(var/Xa = 1,Xa 20 + rand(10,20))
+ heard_words.Remove(heard_words[1])
+ if(!heard_words["[lowertext(seperate[Xa])]"])
+ heard_words["[lowertext(seperate[Xa])]"] = list()
+ var/list/w = heard_words["[lowertext(seperate[Xa])]"]
+ if(w)
+ w.Add("[lowertext(seperate[next])]")
+ //world << "Adding [lowertext(seperate[next])] to [lowertext(seperate[Xa])]"
- if(!rand(0, 5))
- spawn(2) SaySomething(pick(seperate))
if(prob(30))
- for(var/mob/O in viewers(src))
- O.show_message("\blue [src] hums for bit then stops...", 1)
+ var/list/options = list("[holder_atom] seems to be listening intently to [source]...",\
+ "[holder_atom] seems to be focussing on [source]...",\
+ "[holder_atom] seems to turn it's attention to [source]...")
+ holder_atom.loc.visible_message("\blue \icon[holder_atom] [pick(options)]")
+
+ if(prob(20))
+ spawn(2)
+ SaySomething(pick(seperate))
/*/obj/item/weapon/talkingcrystal/proc/debug()
//set src in view()
@@ -57,7 +71,9 @@
for(var/X in d)
world << "[X]"*/
-/obj/item/weapon/proc/SaySomething(var/word = null)
+/datum/talking_atom/proc/SaySomething(var/word = null)
+ if(!holder_atom)
+ return
var/msg
var/limit = rand(max(5,heard_words.len/2))+3
@@ -95,7 +111,7 @@
else
msg+="!"
- var/list/listening = viewers(src)
+ var/list/listening = viewers(holder_atom)
for(var/mob/M in mob_list)
if (!M.client)
continue //skip monkeys and leavers
@@ -105,5 +121,5 @@
listening|=M
for(var/mob/M in listening)
- M << "[src] reverberates, \blue\"[msg]\""
- lastsaid = world.timeofday + rand(300,800)
+ M << "\icon[holder_atom] [holder_atom] reverberates, \blue\"[msg]\""
+ last_talk_time = world.time
diff --git a/code/modules/research/xenoarchaeology/genetics/prehistoric_animals.dm b/code/modules/research/xenoarchaeology/genetics/prehistoric_animals.dm
new file mode 100644
index 0000000000..c9022726a6
--- /dev/null
+++ b/code/modules/research/xenoarchaeology/genetics/prehistoric_animals.dm
@@ -0,0 +1,77 @@
+/mob/living/simple_animal/hostile/samak
+ name = "samak"
+ desc = "A fast, armoured predator accustomed to hiding and ambushing in cold terrain."
+ faction = "samak"
+ icon_state = "samak"
+ icon_living = "samak"
+ icon_dead = "samak_dead"
+ icon = 'code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi'
+ move_to_delay = 2
+ maxHealth = 125
+ health = 125
+ speed = 2
+ melee_damage_lower = 5
+ melee_damage_upper = 15
+ attacktext = "mauls"
+ cold_damage_per_tick = 0
+ speak_chance = 5
+ speak = list("Hruuugh!","Hrunnph")
+ emote_see = list("paws the ground","shakes its mane","stomps")
+ emote_hear = list("snuffles")
+
+/mob/living/simple_animal/hostile/diyaab
+ name = "diyaab"
+ desc = "A small pack animal. Although omnivorous, it will hunt meat on occasion."
+ faction = "diyaab"
+ icon_state = "diyaab"
+ icon_living = "diyaab"
+ icon_dead = "diyaab_dead"
+ icon = 'code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi'
+ move_to_delay = 1
+ maxHealth = 25
+ health = 25
+ speed = 1
+ melee_damage_lower = 1
+ melee_damage_upper = 8
+ attacktext = "gouges"
+ cold_damage_per_tick = 0
+ speak_chance = 5
+ speak = list("Awrr?","Aowrl!","Worrl")
+ emote_see = list("sniffs the air cautiously","looks around")
+ emote_hear = list("snuffles")
+
+/mob/living/simple_animal/hostile/shantak
+ name = "shantak"
+ desc = "A piglike creature with a bright iridiscent mane that sparkles as though lit by an inner light. Don't be fooled by its beauty though."
+ faction = "shantak"
+ icon_state = "shantak"
+ icon_living = "shantak"
+ icon_dead = "shantak_dead"
+ icon = 'code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi'
+ move_to_delay = 1
+ maxHealth = 75
+ health = 75
+ speed = 1
+ melee_damage_lower = 3
+ melee_damage_upper = 12
+ attacktext = "gouges"
+ cold_damage_per_tick = 0
+ speak_chance = 5
+ speak = list("Shuhn","Shrunnph?","Shunpf")
+ emote_see = list("scratches the ground","shakes out it's mane","tinkles gently")
+
+/mob/living/simple_animal/yithian
+ name = "yithian"
+ desc = "A friendly creature vaguely resembling an oversized snail without a shell."
+ icon_state = "yithian"
+ icon_living = "yithian"
+ icon_dead = "yithian_dead"
+ icon = 'code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi'
+
+/mob/living/simple_animal/tindalos
+ name = "tindalos"
+ desc = "It looks like a large, flightless grasshopper."
+ icon_state = "tindalos"
+ icon_living = "tindalos"
+ icon_dead = "tindalos_dead"
+ icon = 'code/WorkInProgress/Cael_Aislinn/Jungle/jungle.dmi'
diff --git a/code/modules/research/xenoarchaeology/genetics/prehistoric_plants.dm b/code/modules/research/xenoarchaeology/genetics/prehistoric_plants.dm
new file mode 100644
index 0000000000..8496869c85
--- /dev/null
+++ b/code/modules/research/xenoarchaeology/genetics/prehistoric_plants.dm
@@ -0,0 +1,202 @@
+
+/obj/item/seeds/telriis
+ name = "pack of telriis seeds"
+ desc = "These seeds grow into telriis grass. Not recommended for consumption by sentient species."
+ icon_state = "seed-alien1"
+ mypath = "/obj/item/seeds/telriis"
+ species = "telriis"
+ plantname = "Telriis grass"
+ productname = "/obj/item/weapon/telriis_clump"
+ lifespan = 50 //number of ticks
+ endurance = 50 //
+ maturation = 5 //ticks to full growth stage
+ production = 5 //ticks till ready to harvest
+ yield = 4 //number produced when harvest
+ potency = 5
+ plant_type = 1 //1=weed, 2=shroom, 0=normal
+ growthstages = 4
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/telriis_clump
+ name = "telriis grass"
+ desc = "A clump of telriis grass, not recommended for consumption by sentients."
+ icon = 'icons/obj/xenoarchaeology.dmi'
+ icon_state = "telriisclump"
+ New(var/loc, var/potency)
+ ..()
+ reagents.add_reagent("pwine", potency * 5)
+ reagents.add_reagent("nutriment", potency)
+ bitesize = 1+round(reagents.total_volume / 2, 1)
+
+
+/obj/item/seeds/thaadra
+ name = "pack of thaa'dra seeds"
+ desc = "These seeds grow into Thaa'dra lichen. Likes the cold."
+ icon_state = "seed-alien3"
+ mypath = "/obj/item/seeds/thaadra"
+ species = "thaadra"
+ plantname = "Thaa'dra lichen"
+ productname = "/obj/item/weapon/reagent_containers/food/snacks/grown/thaadra"
+ lifespan = 20
+ endurance = 10
+ maturation = 5
+ production = 9
+ yield = 2
+ potency = 5
+ plant_type = 2
+ growthstages = 4
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/thaadrabloom
+ name = "thaa'dra bloom"
+ desc = "Looks chewy, might be good to eat."
+ icon = 'icons/obj/xenoarchaeology.dmi'
+ icon_state = "thaadrabloom"
+ New(var/loc, var/potency)
+ ..()
+ reagents.add_reagent("frostoil", potency * 1.5 + 5)
+ reagents.add_reagent("nutriment", potency)
+ bitesize = 1+round(reagents.total_volume / 2, 1)
+
+
+/obj/item/seeds/jurlmah
+ name = "pack of jurl'mah seeds"
+ desc = "These seeds grow into jurl'mah reeds, which produce large syrupy pods."
+ icon_state = "seed-alien3"
+ mypath = "/obj/item/seeds/jurlmah"
+ species = "jurlmah"
+ plantname = "jurl'mah reeds"
+ productname = "/obj/item/weapon/reagent_containers/food/snacks/grown/jurlmah"
+ lifespan = 20
+ endurance = 12
+ maturation = 8
+ production = 9
+ yield = 3
+ potency = 10
+ growthstages = 5
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/jurlmah
+ name = "jurl'mah pod"
+ desc = "Bulbous and veiny, it appears to pulse slightly as you look at it."
+ icon = 'icons/obj/xenoarchaeology.dmi'
+ icon_state = "jurlmahpod"
+ New(var/loc, var/potency)
+ ..()
+ reagents.add_reagent("serotrotium", potency)
+ reagents.add_reagent("nutriment", potency)
+ bitesize = 1+round(reagents.total_volume / 2, 1)
+
+
+/obj/item/seeds/amauri
+ name = "pack of amauri seeds"
+ desc = "Grows into a straight, dark plant with small round fruit."
+ icon_state = "seed-alien3"
+ mypath = "/obj/item/seeds/amauri"
+ species = "amauri"
+ plantname = "amauri plant"
+ productname = "/obj/item/weapon/reagent_containers/food/snacks/grown/amauri"
+ lifespan = 30
+ endurance = 10
+ maturation = 8
+ production = 9
+ yield = 4
+ potency = 10
+ growthstages = 3
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/amauri
+ name = "amauri fruit"
+ desc = "It is small, round and hard. Its skin is a thick dark purple."
+ icon = 'icons/obj/xenoarchaeology.dmi'
+ icon_state = "amaurifruit"
+ New(var/loc, var/potency)
+ ..()
+ reagents.add_reagent("zombiepowder", potency * 10)
+ reagents.add_reagent("condensedcapsaicin", potency * 5)
+ reagents.add_reagent("nutriment", potency)
+ bitesize = 1+round(reagents.total_volume / 2, 1)
+
+
+/obj/item/seeds/gelthi
+ name = "pack of gelthi seeds"
+ desc = "Grows into a bright, wavy plant with many small fruits."
+ icon_state = "seed-alien2"
+ mypath = "/obj/item/seeds/gelthi"
+ species = "gelthi"
+ plantname = "gelthi plant"
+ productname = "/obj/item/weapon/reagent_containers/food/snacks/grown/gelthi"
+ lifespan = 20
+ endurance = 15
+ maturation = 6
+ production = 6
+ yield = 2
+ potency = 1
+ growthstages = 3
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/gelthi
+ name = "gelthi berries"
+ desc = "They feel fluffy and slightly warm to the touch."
+ icon = 'icons/obj/xenoarchaeology.dmi'
+ icon_state = "gelthiberries"
+ New(var/loc, var/potency)
+ ..()
+ //this may prove a little strong
+ reagents.add_reagent("stoxin", (potency * potency) / 5)
+ reagents.add_reagent("capsaicin", (potency * potency) / 5)
+ reagents.add_reagent("nutriment", potency)
+ bitesize = 1+round(reagents.total_volume / 2, 1)
+
+
+/obj/item/seeds/vale
+ name = "pack of vale seeds"
+ desc = "The vale bush is often depicted in ancient heiroglyphs and is similar to cherry blossoms."
+ icon_state = "seed-alien2"
+ mypath = "/obj/item/seeds/vale"
+ species = "vale"
+ plantname = "vale bush"
+ productname = "/obj/item/weapon/reagent_containers/food/snacks/grown/vale"
+ lifespan = 25
+ endurance = 15
+ maturation = 8
+ production = 10
+ yield = 3
+ potency = 3
+ growthstages = 4
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/vale
+ name = "vale leaves"
+ desc = "Small, curly leaves covered in a soft pale fur."
+ icon = 'icons/obj/xenoarchaeology.dmi'
+ icon_state = "valeleaves"
+ New(var/loc, var/potency)
+ ..()
+ reagents.add_reagent("paracetamol", potency * 5)
+ reagents.add_reagent("dexalin", potency * 2)
+ reagents.add_reagent("nutriment", potency)
+ bitesize = 1+round(reagents.total_volume / 2, 1)
+
+
+/obj/item/seeds/surik
+ name = "pack of surik seeds"
+ desc = "A spiky blue vine with large fruit resembling pig ears."
+ icon_state = "seed-alien3"
+ mypath = "/obj/item/seeds/surik"
+ species = "surik"
+ plantname = "surik vine"
+ productname = "/obj/item/weapon/reagent_containers/food/snacks/grown/surik"
+ lifespan = 30
+ endurance = 18
+ maturation = 7
+ production = 7
+ yield = 3
+ potency = 3
+ growthstages = 4
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/surik
+ name = "surik fruit"
+ desc = "Multiple layers of blue skin peeling away to reveal a spongey core, vaguely resembling an ear."
+ icon = 'icons/obj/xenoarchaeology.dmi'
+ icon_state = "surikfruit"
+ New(var/loc, var/potency)
+ ..()
+ reagents.add_reagent("impedrezene", potency * 3)
+ reagents.add_reagent("synaptizine", potency * 2)
+ reagents.add_reagent("nutriment", potency)
+ bitesize = 1+round(reagents.total_volume / 2, 1)
diff --git a/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm b/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm
new file mode 100644
index 0000000000..b4afc4ff0c
--- /dev/null
+++ b/code/modules/research/xenoarchaeology/genetics/reconstitutor.dm
@@ -0,0 +1,319 @@
+//gene sequence datum
+datum/genesequence
+ var/spawned_type
+ var/spawned_type_text
+ var/list/full_genome_sequence = list()
+
+
+
+#define SCANFOSSIL_RETVAL_WRONGTYPE 1
+#define SCANFOSSIL_RETVAL_NOMOREGENESEQ 2
+#define SCANFOSSIL_RETVAL_SUCCESS 4
+
+/obj/machinery/computer/reconstitutor
+ name = "Flora reconstitution console"
+ icon = 'icons/obj/computer.dmi'
+ icon_state = "dna"
+ circuit = "/obj/item/weapon/circuitboard/reconstitutor"
+ req_access = list(access_heads) //Only used for record deletion right now.
+ var/obj/machinery/clonepod/pod1 = 1 //Linked cloning pod.
+ var/temp = ""
+ var/menu = 1 //Which menu screen to display
+ var/list/records = list()
+ var/datum/dna2/record/active_record = null
+ var/obj/item/weapon/disk/data/diskette = null //Mostly so the geneticist can steal everything.
+ var/loading = 0 // Nice loading text
+ var/list/undiscovered_genesequences = null
+ var/list/discovered_genesequences = list()
+ var/list/completed_genesequences = list()
+ var/list/undiscovered_genomes = list()
+ var/list/manually_placed_genomes = list()
+ var/list/discovered_genomes = list("! Clear !")
+ var/list/accepted_fossil_types = list(/obj/item/weapon/fossil/plant)
+
+
+/obj/machinery/computer/reconstitutor/New()
+ if(!undiscovered_genesequences)
+ undiscovered_genesequences = master_controller.all_plant_genesequences.Copy()
+ ..()
+
+/obj/machinery/computer/reconstitutor/animal
+ name = "Fauna reconstitution console"
+ accepted_fossil_types = list(/obj/item/weapon/fossil/bone,/obj/item/weapon/fossil/shell,/obj/item/weapon/fossil/skull)
+ pod1 = null
+ circuit = "/obj/item/weapon/circuitboard/reconstitutor/animal"
+
+/obj/machinery/computer/reconstitutor/animal/New()
+ undiscovered_genesequences = master_controller.all_animal_genesequences.Copy()
+ ..()
+
+/obj/machinery/computer/reconstitutor/attackby(obj/item/W, mob/user)
+ if(istype(W,/obj/item/weapon/fossil))
+ user.drop_item()
+ W.loc = src.loc
+ switch(scan_fossil(W))
+ if(1)
+ src.visible_message("\red \icon[src] [src] scans the fossil and rejects it.")
+ if(2)
+ visible_message("\red \icon[src] [src] can not extract any more genetic data from new fossils.")
+ if(4)
+ src.visible_message("\blue \icon[src] [user] inserts [W] into [src], the fossil is consumed as [src] extracts genetic data from it.")
+ del(W)
+ updateDialog()
+ else if (istype(W, /obj/item/weapon/storage))
+ var/obj/item/weapon/storage/S = W
+ S.hide_from(usr)
+ var/numaccepted = 0
+ var/numrejected = 0
+ var/full = 0
+ for(var/obj/item/weapon/fossil/F in S.contents)
+ switch(scan_fossil(F))
+ if(SCANFOSSIL_RETVAL_WRONGTYPE)
+ numrejected += 1
+ if(SCANFOSSIL_RETVAL_NOMOREGENESEQ)
+ full = 1
+ if(SCANFOSSIL_RETVAL_SUCCESS)
+ numaccepted += 1
+ S.remove_from_storage(F, src) //This will move the item to this item's contents
+ del(F)
+ updateDialog()
+ var/outmsg = "\blue You empty all the fossils from [S] into [src]."
+ if(numaccepted)
+ outmsg += " \blue[numaccepted] fossils were accepted and consumed as [src] extracts genetic data from them."
+ if(numrejected)
+ outmsg += " \red[numrejected] fossils were rejected."
+ if(full)
+ outmsg += " \red[src] can not extract any more genetic data from new fossils."
+ visible_message(outmsg)
+
+ else
+ ..()
+
+/obj/machinery/computer/reconstitutor/attack_hand(var/mob/user as mob)
+ src.add_fingerprint(user)
+ interact(user)
+
+/obj/machinery/computer/reconstitutor/interact(mob/user)
+ if(stat & (NOPOWER|BROKEN) || get_dist(src, user) > 1)
+ user.unset_machine(src)
+ return
+
+ var/dat = "Garland Corp genetic reconstitutor
"
+ dat += "
"
+ if(!pod1)
+ pod1 = locate() in orange(1, src)
+
+ if(!pod1)
+ dat += "Unable to locate cloning pod.
"
+ else if(istype(pod1))
+ dat += "Cloning pod connected.
"
+
+ dat += ""
+ dat += ""
+ dat += "| GENE1 | "
+ dat += "GENE2 | "
+ dat += "GENE3 | "
+ dat += "GENE4 | "
+ dat += "GENE5 | "
+ dat += "GENE6 | "
+ dat += "GENE7 | "
+ dat += " | "
+ dat += " | "
+ dat += "
"
+
+ //WIP gene sequences
+ for(var/sequence_num = 1, sequence_num <= discovered_genesequences.len, sequence_num += 1)
+ var/datum/genesequence/cur_genesequence = discovered_genesequences[sequence_num]
+ dat += ""
+ var/num_correct = 0
+ for(var/curindex = 1, curindex <= 7, curindex++)
+ var/bgcolour = "#ffffff"//white ffffff, red ff0000
+
+ //background colour hints at correct positioning
+ if(manually_placed_genomes[sequence_num][curindex])
+ //green background if slot is correctly filled
+ if(manually_placed_genomes[sequence_num][curindex] == cur_genesequence.full_genome_sequence[curindex])
+ bgcolour = "#008000"
+ num_correct += 1
+ if(num_correct == 7)
+ discovered_genesequences -= cur_genesequence
+ completed_genesequences += cur_genesequence
+ manually_placed_genomes[sequence_num] = new/list(7)
+ interact(user)
+ return
+ //yellow background if adjacent to correct slot
+ if(curindex > 1 && manually_placed_genomes[sequence_num][curindex] == cur_genesequence.full_genome_sequence[curindex - 1])
+ bgcolour = "#ffff00"
+ else if(curindex < 7 && manually_placed_genomes[sequence_num][curindex] == cur_genesequence.full_genome_sequence[curindex + 1])
+ bgcolour = "#ffff00"
+
+ var/this_genome_slot = manually_placed_genomes[sequence_num][curindex]
+ if(!this_genome_slot)
+ this_genome_slot = "- - - - -"
+ dat += "| [this_genome_slot] | "
+ dat += "Reset | "
+ //dat += "Clone | "
+ dat += "
"
+
+ //completed gene sequences
+ for(var/sequence_num = 1, sequence_num <= completed_genesequences.len, sequence_num += 1)
+ var/datum/genesequence/cur_genesequence = completed_genesequences[sequence_num]
+ dat += ""
+ for(var/curindex = 1, curindex <= 7, curindex++)
+ var/this_genome_slot = cur_genesequence.full_genome_sequence[curindex]
+ dat += "| [this_genome_slot] | "
+ dat += "Wipe | "
+ dat += "Clone | "
+ dat += "
"
+
+ dat += "
"
+
+ dat += "
"
+ dat += "
"
+ dat += "Close"
+ user << browse(dat, "window=reconstitutor;size=600x500")
+ user.set_machine(src)
+ onclose(user, "reconstitutor")
+
+/obj/machinery/computer/reconstitutor/animal/Topic(href, href_list)
+ if(href_list["clone"])
+ var/sequence_num = text2num(href_list["sequence_num"])
+ var/datum/genesequence/cloned_genesequence = completed_genesequences[sequence_num]
+ if(pod1)
+ if(pod1.occupant)
+ visible_message("\red \icon[src] The cloning pod is currently occupied.")
+ else if(pod1.biomass < CLONE_BIOMASS)
+ visible_message("\red \icon[src] Not enough biomass in the cloning pod.")
+ else if(pod1.mess)
+ visible_message("\red \icon[src] Error: clonepod malfunction.")
+ else
+ visible_message("\blue \icon[src] [src] clones something from a reconstituted gene sequence!")
+ playsound(src.loc, 'sound/effects/screech.ogg', 50, 1, -3)
+ pod1.occupant = new cloned_genesequence.spawned_type(pod1)
+ pod1.locked = 1
+ pod1.icon_state = "pod_1"
+ //pod1.occupant.name = "[pod1.occupant.name] ([rand(0,999)])"
+ pod1.biomass -= CLONE_BIOMASS
+ else
+ usr << "\red \icon[src] Unable to locate cloning pod!"
+ else
+ ..()
+
+/obj/machinery/computer/reconstitutor/Topic(href, href_list)
+ if(href_list["insertpos"])
+ //world << "inserting gene for genesequence [href_list["insertgenome"]] at pos [text2num(href_list["insertpos"])]"
+ var/sequence_num = text2num(href_list["sequence_num"])
+ var/insertpos = text2num(href_list["insertpos"])
+
+ var/old_genome = manually_placed_genomes[sequence_num][insertpos]
+ discovered_genomes = sortList(discovered_genomes)
+ var/new_genome = input(usr, "Which genome do you want to insert here?") as null|anything in discovered_genomes
+ if(new_genome == "! Clear !")
+ manually_placed_genomes[sequence_num][insertpos] = null
+ else if(new_genome)
+ manually_placed_genomes[sequence_num][insertpos] = new_genome
+ discovered_genomes.Remove(new_genome)
+ if(old_genome)
+ discovered_genomes.Add(old_genome)
+ updateDialog()
+
+ else if(href_list["reset"])
+ var/sequence_num = text2num(href_list["sequence_num"])
+ for(var/curindex = 1, curindex <= 7, curindex++)
+ var/old_genome = manually_placed_genomes[sequence_num][curindex]
+ manually_placed_genomes[sequence_num][curindex] = null
+ if(old_genome)
+ discovered_genomes.Add(old_genome)
+ updateDialog()
+
+ else if(href_list["wipe"])
+ var/sequence_num = text2num(href_list["sequence_num"])
+ var/datum/genesequence/wiped_genesequence = completed_genesequences[sequence_num]
+ completed_genesequences.Remove(wiped_genesequence)
+ discovered_genesequences.Add(wiped_genesequence)
+
+ discovered_genomes.Add(wiped_genesequence.full_genome_sequence)
+ discovered_genomes = sortList(discovered_genomes)
+ updateDialog()
+
+ else if(href_list["clone"])
+ var/sequence_num = text2num(href_list["sequence_num"])
+ var/datum/genesequence/cloned_genesequence = completed_genesequences[sequence_num]
+ visible_message("\blue \icon[src] [src] clones a packet of seeds from a reconstituted gene sequence!")
+ playsound(src.loc, 'sound/effects/screech.ogg', 50, 1, -3)
+ new cloned_genesequence.spawned_type(src.loc)
+
+ else if(href_list["close"])
+ usr.unset_machine(src)
+ usr << browse(null, "window=reconstitutor")
+
+ else
+ ..()
+
+/obj/machinery/computer/reconstitutor/proc/scan_fossil(var/obj/item/weapon/fossil/scan_fossil)
+ //see whether we accept these kind of fossils
+ if(accepted_fossil_types.len && !accepted_fossil_types.Find(scan_fossil.type))
+ return SCANFOSSIL_RETVAL_WRONGTYPE
+
+ //see whether we are going to discover a new sequence, new genome for existing sequence or nothing
+ var/new_genome_prob = discovered_genesequences.len * 50
+
+ if( (new_genome_prob >= 100 || prob(new_genome_prob)) && undiscovered_genomes.len)
+ //create a new genome for an existing gene sequence
+ var/newly_discovered_genome = pick(undiscovered_genomes)
+ undiscovered_genomes -= newly_discovered_genome
+ discovered_genomes.Add(newly_discovered_genome)
+
+ //chance to discover a second genome
+ if(prob(75))
+ newly_discovered_genome = pick(undiscovered_genomes)
+ undiscovered_genomes -= newly_discovered_genome
+ discovered_genomes.Add(newly_discovered_genome)
+ //chance to discover a third genome
+ if(prob(50))
+ newly_discovered_genome = pick(undiscovered_genomes)
+ undiscovered_genomes -= newly_discovered_genome
+ discovered_genomes.Add(newly_discovered_genome)
+
+ else if(undiscovered_genesequences.len)
+ //discover new gene sequence
+ var/datum/genesequence/newly_discovered_genesequence = pick(undiscovered_genesequences)
+ undiscovered_genesequences -= newly_discovered_genesequence
+ discovered_genesequences += newly_discovered_genesequence
+ //add genomes for new gene sequence to pool of discoverable genomes
+ undiscovered_genomes.Add(newly_discovered_genesequence.full_genome_sequence)
+ manually_placed_genomes.Add(null)
+ manually_placed_genomes[manually_placed_genomes.len] = new/list(7)
+
+ else
+ //there's no point scanning any more fossils, we've already discovered everything
+ return SCANFOSSIL_RETVAL_NOMOREGENESEQ
+
+ return SCANFOSSIL_RETVAL_SUCCESS
+
+#undef SCANFOSSIL_RETVAL_WRONGTYPE
+#undef SCANFOSSIL_RETVAL_NOMOREGENESEQ
+#undef SCANFOSSIL_RETVAL_SUCCESS
+
+
+/obj/item/weapon/circuitboard/reconstitutor
+ name = "Circuit board (Flora Reconstitution Console)"
+ build_path = "/obj/machinery/computer/reconstitutor"
+ origin_tech = "programming=2;biotech=4;materials=6"
+ frame_desc = "Requires 2 Advanced Scanning Module, 1 Nano Manipulator, 1 Matter Bin and 1 Advanced Capacitor."
+ req_components = list(
+ "/obj/item/weapon/stock_parts/scanning_module/adv" = 2,
+ "/obj/item/weapon/stock_parts/manipulator/nano" = 1,
+ "/obj/item/weapon/stock_parts/matter_bin" = 1,
+ "/obj/item/weapon/stock_parts/capacitor/adv" = 1)
+
+/obj/item/weapon/circuitboard/reconstitutor/animal
+ name = "Circuit board (Fauna Reconstitution Console)"
+ build_path = "/obj/machinery/computer/reconstitutor/animal"
+ origin_tech = "programming=2;biotech=4;materials=6"
+ frame_desc = "Requires 2 Advanced Scanning Module, 1 Nano Manipulator, 1 Matter Bin and 1 Advanced Capacitor."
+ req_components = list(
+ "/obj/item/weapon/stock_parts/scanning_module/adv" = 2,
+ "/obj/item/weapon/stock_parts/manipulator/nano" = 1,
+ "/obj/item/weapon/stock_parts/matter_bin" = 1,
+ "/obj/item/weapon/stock_parts/capacitor/adv" = 1)
diff --git a/code/modules/research/xenoarchaeology/machinery/artifact_harvester.dm b/code/modules/research/xenoarchaeology/machinery/artifact_harvester.dm
index 117be557da..495d393766 100644
--- a/code/modules/research/xenoarchaeology/machinery/artifact_harvester.dm
+++ b/code/modules/research/xenoarchaeology/machinery/artifact_harvester.dm
@@ -12,6 +12,7 @@
var/obj/item/weapon/anobattery/inserted_battery
var/obj/machinery/artifact/cur_artifact
var/obj/machinery/artifact_scanpad/owned_scanner = null
+ var/last_process = 0
/obj/machinery/artifact_harvester/New()
..()
@@ -47,14 +48,14 @@
if(owned_scanner)
if(harvesting)
if(harvesting > 0)
- dat += "Please wait. Harvesting in progress ([(inserted_battery.stored_charge/inserted_battery.capacity)*100]%).
"
+ dat += "Please wait. Harvesting in progress ([round((inserted_battery.stored_charge/inserted_battery.capacity)*100)]%).
"
else
- dat += "Please wait. Energy dump in progress ([(inserted_battery.stored_charge/inserted_battery.capacity)*100]%).
"
+ dat += "Please wait. Energy dump in progress ([round((inserted_battery.stored_charge/inserted_battery.capacity)*100)]%).
"
dat += "Halt early
"
else
if(inserted_battery)
dat += "[inserted_battery.name] inserted, charge level: [inserted_battery.stored_charge]/[inserted_battery.capacity] ([(inserted_battery.stored_charge/inserted_battery.capacity)*100]%)
"
- dat += "Energy signature ID:[inserted_battery.battery_effect.artifact_id == "" ? "???" : "[inserted_battery.battery_effect.artifact_id]"]
"
+ dat += "Energy signature ID:[inserted_battery.battery_effect ? (inserted_battery.battery_effect.artifact_id == "" ? "???" : "[inserted_battery.battery_effect.artifact_id]") : "NA"]
"
dat += "Eject battery
"
dat += "Drain battery of all charge
"
dat += "Begin harvesting
"
@@ -74,8 +75,9 @@
return
if(harvesting > 0)
- //gain a bit of charge
- inserted_battery.stored_charge += 0.5
+ //charge at 33% consumption rate
+ inserted_battery.stored_charge += (world.time - last_process) / 3
+ last_process = world.time
//check if we've finished
if(inserted_battery.stored_charge >= inserted_battery.capacity)
@@ -88,14 +90,14 @@
else if(harvesting < 0)
//dump some charge
- inserted_battery.stored_charge -= 2
+ inserted_battery.stored_charge -= (world.time - last_process) / 3
//do the effect
if(inserted_battery.battery_effect)
inserted_battery.battery_effect.process()
//if the effect works by touch, activate it on anyone viewing the console
- if(inserted_battery.battery_effect.effect == 0)
+ if(inserted_battery.battery_effect.effect == EFFECT_TOUCH)
var/list/nearby = viewers(1, src)
for(var/mob/M in nearby)
if(M.machine == src)
@@ -114,79 +116,115 @@
/obj/machinery/artifact_harvester/Topic(href, href_list)
if (href_list["harvest"])
- //locate artifact on analysis pad
- cur_artifact = null
- var/articount = 0
- var/obj/machinery/artifact/analysed
- for(var/obj/machinery/artifact/A in get_turf(owned_scanner))
- analysed = A
- articount++
+ if(!inserted_battery)
+ src.visible_message("[src] states, \"Cannot harvest. No battery inserted.\"")
- var/mundane = 0
- for(var/obj/O in get_turf(owned_scanner))
- if(O.invisibility)
- continue
- if(!istype(O, /obj/machinery/artifact) && !istype(O, /obj/machinery/artifact_scanpad))
- mundane++
- break
- for(var/mob/O in get_turf(owned_scanner))
- if(O.invisibility)
- continue
- mundane++
- break
+ else if(inserted_battery.stored_charge >= inserted_battery.capacity)
+ src.visible_message("[src] states, \"Cannot harvest. battery is full.\"")
- if(analysed.being_used)
- var/message = "[src] states, \"Cannot harvest. Too much interference.\""
- src.visible_message(message)
- else if(articount == 1 && !mundane)
- cur_artifact = analysed
- //there should already be a battery inserted, but this is just in case
- if(inserted_battery)
- //see if we can clear out an old effect
- //delete it when the ids match to account for duplicate ids having different effects
- if(inserted_battery.battery_effect && inserted_battery.stored_charge <= 0)
- del(inserted_battery.battery_effect)
+ else
- //only charge up
- var/matching_id = 0
- if(inserted_battery.battery_effect)
- matching_id = (inserted_battery.battery_effect.artifact_id == cur_artifact.my_effect.artifact_id)
- var/matching_effecttype = 0
- if(inserted_battery.battery_effect)
- matching_effecttype = (inserted_battery.battery_effect.type == cur_artifact.my_effect.type)
- if(!inserted_battery.battery_effect || (matching_id && matching_effecttype))
- harvesting = 1
- use_power = 2
- cur_artifact.anchored = 1
- cur_artifact.being_used = 1
- icon_state = "incubator_on"
- var/message = "[src] states, \"Beginning artifact energy harvesting.\""
- src.visible_message(message)
+ //locate artifact on analysis pad
+ cur_artifact = null
+ var/articount = 0
+ var/obj/machinery/artifact/analysed
+ for(var/obj/machinery/artifact/A in get_turf(owned_scanner))
+ analysed = A
+ articount++
- //duplicate the artifact's effect datum
- if(!inserted_battery.battery_effect)
- var/effecttype = cur_artifact.my_effect.type
- var/datum/artifact_effect/E = new effecttype(inserted_battery)
-
- //duplicate it's unique settings
- for(var/varname in list("chargelevelmax","artifact_id","effect","effectrange","trigger"))
- E.vars[varname] = cur_artifact.my_effect.vars[varname]
-
- //copy the new datum into the battery
- inserted_battery.battery_effect = E
- inserted_battery.stored_charge = 0
- else
- var/message = "[src] states, \"Cannot harvest. Incompatible energy signatures detected.\""
- src.visible_message(message)
- else if(cur_artifact)
- var/message = "[src] states, \"Cannot harvest. No battery inserted.\""
+ if(articount <= 0)
+ var/message = "[src] states, \"Cannot harvest. No noteworthy energy signature isolated.\""
src.visible_message(message)
- else if(articount > 1 || mundane)
- var/message = "[src] states, \"Cannot harvest. Error isolating energy signature.\""
- src.visible_message(message)
- else if(!articount)
- var/message = "[src] states, \"Cannot harvest. No noteworthy energy signature isolated.\""
- src.visible_message(message)
+
+ else if(analysed && analysed.being_used)
+ src.visible_message("[src] states, \"Cannot harvest. Source already being harvested.\"")
+
+ else
+ var/mundane = 0
+ for(var/obj/O in get_turf(owned_scanner))
+ if(O.invisibility)
+ continue
+ if(!istype(O, /obj/machinery/artifact) && !istype(O, /obj/machinery/artifact_scanpad))
+ mundane++
+ break
+ for(var/mob/O in get_turf(owned_scanner))
+ if(O.invisibility)
+ continue
+ mundane++
+ break
+
+ if(articount > 1 || mundane)
+ var/message = "[src] states, \"Cannot harvest. Too many artifacts on the pad.\""
+ src.visible_message(message)
+ else
+ cur_artifact = analysed
+
+ //if both effects are active, we can't harvest either
+ if(cur_artifact.my_effect.activated && cur_artifact.secondary_effect.activated)
+ src.visible_message("[src] states, \"Cannot harvest. Source is emitting conflicting energy signatures.\"")
+ else if(!cur_artifact.my_effect.activated && !cur_artifact.secondary_effect.activated)
+ src.visible_message("[src] states, \"Cannot harvest. No energy emitting from source.\"")
+
+ else
+ //see if we can clear out an old effect
+ //delete it when the ids match to account for duplicate ids having different effects
+ if(inserted_battery.battery_effect && inserted_battery.stored_charge <= 0)
+ del(inserted_battery.battery_effect)
+
+ //
+ var/datum/artifact_effect/source_effect
+
+ //if we already have charge in the battery, we can only recharge it from the source artifact
+ if(inserted_battery.stored_charge > 0)
+ var/battery_matches_primary_id = 0
+ if(inserted_battery.battery_effect && inserted_battery.battery_effect.artifact_id == cur_artifact.my_effect.artifact_id)
+ battery_matches_primary_id = 1
+ if(battery_matches_primary_id && cur_artifact.my_effect.activated)
+ //we're good to recharge the primary effect!
+ source_effect = cur_artifact.my_effect
+
+ var/battery_matches_secondary_id = 0
+ if(inserted_battery.battery_effect && inserted_battery.battery_effect.artifact_id == cur_artifact.secondary_effect.artifact_id)
+ battery_matches_secondary_id = 1
+ if(battery_matches_secondary_id && cur_artifact.secondary_effect.activated)
+ //we're good to recharge the secondary effect!
+ source_effect = cur_artifact.secondary_effect
+
+ if(!source_effect)
+ src.visible_message("[src] states, \"Cannot harvest. Battery is charged with a different energy signature.\"")
+ else
+ //we're good to charge either
+ if(cur_artifact.my_effect.activated)
+ //charge the primary effect
+ source_effect = cur_artifact.my_effect
+
+ else if(cur_artifact.secondary_effect.activated)
+ //charge the secondary effect
+ source_effect = cur_artifact.secondary_effect
+
+
+ if(source_effect)
+ harvesting = 1
+ use_power = 2
+ cur_artifact.anchored = 1
+ cur_artifact.being_used = 1
+ icon_state = "incubator_on"
+ var/message = "[src] states, \"Beginning energy harvesting.\""
+ src.visible_message(message)
+ last_process = world.time
+
+ //duplicate the artifact's effect datum
+ if(!inserted_battery.battery_effect)
+ var/effecttype = source_effect.type
+ var/datum/artifact_effect/E = new effecttype(inserted_battery)
+
+ //duplicate it's unique settings
+ for(var/varname in list("chargelevelmax","artifact_id","effect","effectrange","trigger"))
+ E.vars[varname] = source_effect.vars[varname]
+
+ //copy the new datum into the battery
+ inserted_battery.battery_effect = E
+ inserted_battery.stored_charge = 0
if (href_list["stopharvest"])
if(harvesting)
@@ -195,7 +233,7 @@
harvesting = 0
cur_artifact.anchored = 0
cur_artifact.being_used = 0
- src.visible_message("[name] states, \"Activity interrupted.\"")
+ src.visible_message("[name] states, \"Energy harvesting interrupted.\"")
icon_state = "incubator"
if (href_list["ejectbattery"])
@@ -207,7 +245,8 @@
if(inserted_battery.battery_effect && inserted_battery.stored_charge > 0)
if(alert("This action will dump all charge, safety gear is recommended before proceeding","Warning","Continue","Cancel"))
if(!inserted_battery.battery_effect.activated)
- inserted_battery.battery_effect.ToggleActivate(0)
+ inserted_battery.battery_effect.ToggleActivate(1)
+ last_process = world.time
harvesting = -1
use_power = 2
icon_state = "incubator_on"
diff --git a/code/modules/research/xenoarchaeology/machinery/geosample_scanner.dm b/code/modules/research/xenoarchaeology/machinery/geosample_scanner.dm
index eaf92181b2..bddd133ade 100644
--- a/code/modules/research/xenoarchaeology/machinery/geosample_scanner.dm
+++ b/code/modules/research/xenoarchaeology/machinery/geosample_scanner.dm
@@ -285,10 +285,8 @@
data = " - Mundane object (archaic xenos origins)
"
var/obj/item/weapon/archaeological_find/A = scanned_item
- if(A.speaking_to_players)
- data = " - Exhibits properties consistent with sonic reproduction.
"
- if(A.listening_to_players)
- data = " - Exhibits properties similar to audio capture technology.
"
+ if(A.talking_atom)
+ data = " - Exhibits properties consistent with sonic reproduction and audio capture technologies.
"
var/anom_found = 0
if(G)
diff --git a/code/modules/research/xenoarchaeology/master_controller.dm b/code/modules/research/xenoarchaeology/master_controller.dm
new file mode 100644
index 0000000000..9d347e19c6
--- /dev/null
+++ b/code/modules/research/xenoarchaeology/master_controller.dm
@@ -0,0 +1,145 @@
+
+/datum/controller/game_controller
+ var/list/all_animal_genesequences = list()
+ var/list/all_plant_genesequences = list()
+ var/list/genome_prefixes = null
+ var/list/artifact_spawning_turfs = list()
+ var/list/digsite_spawning_turfs = list()
+
+ var/list/spawn_types_animal = list("/mob/living/carbon/slime",\
+ "/mob/living/simple_animal/hostile/alien",\
+ "/mob/living/simple_animal/hostile/alien/drone",\
+ "/mob/living/simple_animal/hostile/alien/sentinel",\
+ "/mob/living/simple_animal/hostile/giant_spider",\
+ "/mob/living/simple_animal/hostile/giant_spider/hunter",\
+ "/mob/living/simple_animal/hostile/giant_spider/nurse",\
+ "/mob/living/simple_animal/hostile/creature",\
+ "/mob/living/simple_animal/hostile/samak",\
+ "/mob/living/simple_animal/hostile/diyaab",\
+ "/mob/living/simple_animal/hostile/shantak",\
+ "/mob/living/simple_animal/tindalos",\
+ "/mob/living/simple_animal/yithian")
+
+ var/list/spawn_types_plant = list("/obj/item/seeds/walkingmushroommycelium",\
+ "/obj/item/seeds/killertomatoseed",\
+ "/obj/item/seeds/shandseed",
+ "/obj/item/seeds/mtearseed",
+ "/obj/item/seeds/thaadra",\
+ "/obj/item/seeds/telriis",\
+ "/obj/item/seeds/jurlmah",\
+ "/obj/item/seeds/amauri",\
+ "/obj/item/seeds/gelthi",\
+ "/obj/item/seeds/vale",\
+ "/obj/item/seeds/surik")
+
+#define XENOARCH_SPAWN_CHANCE 0.5
+#define DIGSITESIZE_LOWER 4
+#define DIGSITESIZE_UPPER 12
+#define ARTIFACTSPAWNNUM_LOWER 6
+#define ARTIFACTSPAWNNUM_UPPER 12
+
+datum/controller/game_controller/proc/SetupXenoarch()
+ //create digsites
+ for(var/turf/simulated/mineral/M in block(locate(1,1,1), locate(world.maxx, world.maxy, world.maxz)))
+ if(isnull(M.geologic_data))
+ M.geologic_data = new/datum/geosample(M)
+
+ if(!prob(XENOARCH_SPAWN_CHANCE))
+ continue
+
+ digsite_spawning_turfs.Add(M)
+ var/digsite = get_random_digsite_type()
+ var/target_digsite_size = rand(DIGSITESIZE_LOWER, DIGSITESIZE_UPPER)
+ var/list/processed_turfs = list()
+ var/list/turfs_to_process = list(M)
+ while(turfs_to_process.len)
+ var/turf/simulated/mineral/archeo_turf = pop(turfs_to_process)
+
+ if(target_digsite_size > 1)
+ var/list/viable_adjacent_turfs = orange(1, archeo_turf)
+ for(var/turf/simulated/mineral/T in orange(1, archeo_turf))
+ if(T.finds)
+ continue
+ if(T in processed_turfs)
+ continue
+ viable_adjacent_turfs.Add(T)
+
+ for(var/turf/simulated/mineral/T in viable_adjacent_turfs)
+ if(prob(target_digsite_size/viable_adjacent_turfs.len))
+ turfs_to_process.Add(T)
+ target_digsite_size -= 1
+ if(target_digsite_size <= 0)
+ break
+
+ processed_turfs.Add(archeo_turf)
+ if(isnull(archeo_turf.finds))
+ archeo_turf.finds = list()
+ if(prob(50))
+ archeo_turf.finds.Add(new /datum/find(digsite, rand(5,95)))
+ else if(prob(75))
+ archeo_turf.finds.Add(new /datum/find(digsite, rand(5,45)))
+ archeo_turf.finds.Add(new /datum/find(digsite, rand(55,95)))
+ else
+ archeo_turf.finds.Add(new /datum/find(digsite, rand(5,30)))
+ archeo_turf.finds.Add(new /datum/find(digsite, rand(35,75)))
+ archeo_turf.finds.Add(new /datum/find(digsite, rand(75,95)))
+
+ //sometimes a find will be close enough to the surface to show
+ var/datum/find/F = archeo_turf.finds[1]
+ if(F.excavation_required <= F.view_range)
+ archeo_turf.archaeo_overlay = "overlay_archaeo[rand(1,3)]"
+ archeo_turf.overlays += archeo_turf.archaeo_overlay
+
+ //have a chance for an artifact to spawn here, but not in animal or plant digsites
+ if(isnull(M.artifact_find) && digsite != 1 && digsite != 2)
+ artifact_spawning_turfs.Add(archeo_turf)
+
+ //create artifact machinery
+ var/num_artifacts_spawn = rand(ARTIFACTSPAWNNUM_LOWER, ARTIFACTSPAWNNUM_UPPER)
+ while(artifact_spawning_turfs.len > num_artifacts_spawn)
+ pick_n_take(artifact_spawning_turfs)
+
+ var/list/artifacts_spawnturf_temp = artifact_spawning_turfs.Copy()
+ while(artifacts_spawnturf_temp.len > 0)
+ var/turf/simulated/mineral/artifact_turf = pop(artifacts_spawnturf_temp)
+ artifact_turf.artifact_find = new()
+
+ //make sure we have some prefixes for the gene sequences
+ if(!genome_prefixes)
+ genome_prefixes = alphabet_uppercase.Copy()
+ if(!genome_prefixes.len)
+ del genome_prefixes
+ genome_prefixes = alphabet_uppercase.Copy()
+
+ //create animal gene sequences
+ while(spawn_types_animal.len && genome_prefixes.len)
+ var/datum/genesequence/new_sequence = new/datum/genesequence()
+ new_sequence.spawned_type_text = pick(spawn_types_animal)
+ new_sequence.spawned_type = text2path(new_sequence.spawned_type_text)
+ spawn_types_animal -= new_sequence.spawned_type_text
+
+ var/prefixletter = pick(genome_prefixes)
+ genome_prefixes -= prefixletter
+ while(new_sequence.full_genome_sequence.len < 7)
+ new_sequence.full_genome_sequence.Add("[prefixletter][pick(alphabet_uppercase)][pick(alphabet_uppercase)][pick(1,2,3,4,5,6,7,8,9,0)][pick(1,2,3,4,5,6,7,8,9,0)]")
+
+ all_animal_genesequences.Add(new_sequence)
+
+ //create plant gene sequences
+ while(spawn_types_plant.len && genome_prefixes.len)
+ var/datum/genesequence/new_sequence = new/datum/genesequence()
+ new_sequence.spawned_type = pick(spawn_types_plant)
+ spawn_types_plant -= new_sequence.spawned_type_text
+
+ var/prefixletter = pick(genome_prefixes)
+ genome_prefixes -= prefixletter
+ while(new_sequence.full_genome_sequence.len < 7)
+ new_sequence.full_genome_sequence.Add("[prefixletter][pick(1,2,3,4,5,6,7,8,9,0)][pick(1,2,3,4,5,6,7,8,9,0)][pick(alphabet_uppercase)][pick(alphabet_uppercase)]")
+
+ all_plant_genesequences.Add(new_sequence)
+
+#undef XENOARCH_SPAWN_CHANCE
+#undef DIGSITESIZE_LOWER
+#undef DIGSITESIZE_UPPER
+#undef ARTIFACTSPAWNNUM_LOWER
+#undef ARTIFACTSPAWNNUM_UPPER
diff --git a/code/modules/research/xenoarchaeology/misc.dm b/code/modules/research/xenoarchaeology/misc.dm
index 6b95d6dfc8..3cfa9d10a5 100644
--- a/code/modules/research/xenoarchaeology/misc.dm
+++ b/code/modules/research/xenoarchaeology/misc.dm
@@ -1,52 +1,3 @@
-#define XENOARCH_SPAWN_CHANCE 0.5
-#define XENOARCH_SPREAD_CHANCE 15
-#define ARTIFACT_SPAWN_CHANCE 20
-
-proc/SetupXenoarch()
- for(var/turf/simulated/mineral/M in block(locate(1,1,1), locate(world.maxx, world.maxy, world.maxz)))
- if(!M.geologic_data)
- M.geologic_data = new/datum/geosample(M)
-
- if(!prob(XENOARCH_SPAWN_CHANCE))
- continue
-
- var/digsite = get_random_digsite_type()
- var/list/processed_turfs = list()
- var/list/turfs_to_process = list(M)
- for(var/turf/simulated/mineral/archeo_turf in turfs_to_process)
-
- for(var/turf/simulated/mineral/T in orange(1, archeo_turf))
- if(T.finds)
- continue
- if(T in processed_turfs)
- continue
- if(prob(XENOARCH_SPREAD_CHANCE))
- turfs_to_process.Add(T)
-
- processed_turfs.Add(archeo_turf)
- if(!archeo_turf.finds)
- archeo_turf.finds = list()
- if(prob(50))
- archeo_turf.finds.Add(new /datum/find(digsite, rand(5,95)))
- else if(prob(75))
- archeo_turf.finds.Add(new /datum/find(digsite, rand(5,45)))
- archeo_turf.finds.Add(new /datum/find(digsite, rand(55,95)))
- else
- archeo_turf.finds.Add(new /datum/find(digsite, rand(5,30)))
- archeo_turf.finds.Add(new /datum/find(digsite, rand(35,75)))
- archeo_turf.finds.Add(new /datum/find(digsite, rand(75,95)))
-
- //sometimes a find will be close enough to the surface to show
- var/datum/find/F = archeo_turf.finds[1]
- if(F.excavation_required <= F.view_range)
- archeo_turf.archaeo_overlay = "overlay_archaeo[rand(1,3)]"
- archeo_turf.overlays += archeo_turf.archaeo_overlay
-
- //dont create artifact machinery in animal or plant digsites, or if we already have one
- if(!M.artifact_find && digsite != 1 && digsite != 2 && prob(ARTIFACT_SPAWN_CHANCE))
- M.artifact_find = new()
- artifact_spawn.Add(src)
-
//---- Noticeboard
@@ -152,6 +103,7 @@ proc/SetupXenoarch()
new /obj/item/weapon/pickaxe(src)
new /obj/item/device/measuring_tape(src)
new /obj/item/weapon/pickaxe/hand(src)
+ new /obj/item/weapon/storage/bag/fossils(src)
return
//---- Isolation room air alarms
diff --git a/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm b/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm
index c7779dd5ca..3886f6fec0 100644
--- a/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm
+++ b/code/modules/research/xenoarchaeology/tools/ano_device_battery.dm
@@ -4,7 +4,7 @@
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "anobattery0"
var/datum/artifact_effect/battery_effect
- var/capacity = 200
+ var/capacity = 300
var/stored_charge = 0
var/effect_id = ""
@@ -20,13 +20,15 @@
name = "Anomaly power utilizer"
icon = 'icons/obj/xenoarchaeology.dmi'
icon_state = "anodev"
- var/cooldown = 0
var/activated = 0
- var/timing = 0
- var/time = 50
- var/archived_time = 50
+ var/duration = 0
+ var/interval = 0
+ var/time_end = 0
+ var/last_activation = 0
+ var/last_process = 0
var/obj/item/weapon/anobattery/inserted_battery
var/turf/archived_loc
+ var/energy_consumed_on_touch = 100
/obj/item/weapon/anodevice/New()
..()
@@ -47,54 +49,35 @@
return src.interact(user)
/obj/item/weapon/anodevice/interact(var/mob/user)
- user.set_machine(src)
var/dat = "Anomalous Materials Energy Utiliser
"
if(inserted_battery)
- if(cooldown)
- dat += "Cooldown in progress, please wait.
"
- else if(activated)
- if(timing)
- dat += "Device active.
"
- else
- dat += "Device active in timed mode.
"
+ if(activated)
+ dat += "Device active.
"
dat += "[inserted_battery] inserted, anomaly ID: [inserted_battery.battery_effect.artifact_id ? inserted_battery.battery_effect.artifact_id : "NA"]
"
- dat += "Total Power: [inserted_battery.stored_charge]/[inserted_battery.capacity]
"
- dat += "Timed activation: -- - [time >= 1000 ? "[time/10]" : time >= 100 ? " [time/10]" : " [time/10]" ] + ++
"
- if(cooldown)
- dat += "Cooldown in progress.
"
- dat += "
"
- else if(!activated)
- dat += "Start
"
- dat += "Start in timed mode
"
+ dat += "Charge: [inserted_battery.stored_charge] / [inserted_battery.capacity]
"
+ dat += "Time left activated: [round(max((time_end - last_process) / 10, 0))]
"
+ if(activated)
+ dat += "Shutdown
"
else
- dat += "Shutdown emission
"
- dat += "
"
+ dat += "Start
"
+ dat += "
"
+
+ dat += "Activate duration (sec): -- - [duration/10] + ++
"
+ dat += "Activate interval (sec): -- - [interval/10] + ++
"
+ dat += "
"
dat += "Eject battery
"
else
dat += "Please insert battery
"
- dat += "
"
- dat += "
"
- dat += "
"
-
- dat += "
"
- dat += "
"
- dat += "
"
-
dat += "
"
- dat += "Refresh Close"
+ dat += "Refresh Close"
user << browse(dat, "window=anodevice;size=400x500")
onclose(user, "anodevice")
/obj/item/weapon/anodevice/process()
- if(cooldown > 0)
- cooldown -= 1
- if(cooldown <= 0)
- cooldown = 0
- src.visible_message("\blue \icon[src] [src] chimes.", "\blue \icon[src] You hear something chime.")
- else if(activated)
+ if(activated)
if(inserted_battery && inserted_battery.battery_effect)
//make sure the effect is active
if(!inserted_battery.battery_effect.activated)
@@ -106,71 +89,83 @@
archived_loc = T
inserted_battery.battery_effect.UpdateMove()
- //process the effect
- inserted_battery.battery_effect.process()
//if someone is holding the device, do the effect on them
- if(inserted_battery.battery_effect.effect == 0 && ismob(src.loc))
- inserted_battery.battery_effect.DoEffectTouch(src.loc)
+ var/mob/holder
+ if(ismob(src.loc))
+ holder = src.loc
//handle charge
- inserted_battery.stored_charge -= 1
- if(inserted_battery.stored_charge <= 0)
- shutdown_emission()
+ if(world.time - last_activation > interval)
+ if(inserted_battery.battery_effect.effect == EFFECT_TOUCH)
+ if(interval > 0)
+ //apply the touch effect to the holder
+ if(holder)
+ holder << "the \icon[src] [src] held by [holder] shudders in your grasp."
+ else
+ src.loc.visible_message("the \icon[src] [src] shudders.")
+ inserted_battery.battery_effect.DoEffectTouch(holder)
- //handle timed mode
- if(timing)
- time -= 1
- if(time <= 0)
- shutdown_emission()
+ //consume power
+ inserted_battery.stored_charge -= energy_consumed_on_touch
+ else
+ //consume power equal to time passed
+ inserted_battery.stored_charge -= world.time - last_process
+
+ else if(inserted_battery.battery_effect.effect == EFFECT_PULSE)
+ inserted_battery.battery_effect.chargelevel = inserted_battery.battery_effect.chargelevelmax
+
+ //consume power relative to the time the artifact takes to charge and the effect range
+ inserted_battery.stored_charge -= inserted_battery.battery_effect.effectrange * inserted_battery.battery_effect.effectrange * inserted_battery.battery_effect.chargelevelmax
+
+ else
+ //consume power equal to time passed
+ inserted_battery.stored_charge -= world.time - last_process
+
+ last_activation = world.time
+
+ //process the effect
+ inserted_battery.battery_effect.process()
+
+ //work out if we need to shutdown
+ if(inserted_battery.stored_charge <= 0)
+ src.loc.visible_message("\blue \icon[src] [src] buzzes.", "\blue \icon[src] You hear something buzz.")
+ shutdown_emission()
+ else if(world.time > time_end)
+ src.loc.visible_message("\blue \icon[src] [src] chimes.", "\blue \icon[src] You hear something chime.")
+ shutdown_emission()
else
- shutdown()
+ src.visible_message("\blue \icon[src] [src] buzzes.", "\blue \icon[src] You hear something buzz.")
+ shutdown_emission()
+ last_process = world.time
/obj/item/weapon/anodevice/proc/shutdown_emission()
if(activated)
activated = 0
- timing = 0
- src.visible_message("\blue \icon[src] [src] buzzes.", "\icon[src]\blue You hear something buzz.")
-
- cooldown = archived_time / 2
-
if(inserted_battery.battery_effect.activated)
inserted_battery.battery_effect.ToggleActivate(1)
/obj/item/weapon/anodevice/Topic(href, href_list)
- if(href_list["neg_changetime_max"])
- time += -100
- if(time > inserted_battery.capacity)
- time = inserted_battery.capacity
- else if (time < 0)
- time = 0
- if(href_list["neg_changetime"])
- time += -10
- if(time > inserted_battery.capacity)
- time = inserted_battery.capacity
- else if (time < 0)
- time = 0
if(href_list["changetime"])
- time += 10
- if(time > inserted_battery.capacity)
- time = inserted_battery.capacity
- else if (time < 0)
- time = 0
- if(href_list["changetime_max"])
- time += 100
- if(time > inserted_battery.capacity)
- time = inserted_battery.capacity
- else if (time < 0)
- time = 0
+ var/timedif = text2num(href_list["changetime"])
+ if(href_list["duration"])
+ duration += timedif
+ //max 30 sec duration
+ duration = min(max(duration, 0), 300)
+ if(activated)
+ time_end += timedif
+ else if(href_list["interval"])
+ interval += timedif
+ //max 10 sec interval
+ interval = min(max(interval, 0), 100)
if(href_list["startup"])
activated = 1
+ src.visible_message("\blue \icon[src] [src] whirrs.", "\icon[src]\blue You hear something whirr.")
if(!inserted_battery.battery_effect.activated)
inserted_battery.battery_effect.ToggleActivate(1)
+ time_end = world.time + duration
if(href_list["shutdown"])
activated = 0
- if(href_list["starttimer"])
- timing = 1
- archived_time = time
if(href_list["ejectbattery"])
shutdown_emission()
inserted_battery.loc = get_turf(src)
@@ -178,10 +173,10 @@
UpdateSprite()
if(href_list["close"])
usr << browse(null, "window=anodevice")
- usr.unset_machine(src)
-
+ else if(ismob(src.loc))
+ var/mob/M = src.loc
+ src.interact(M)
..()
- updateDialog()
/obj/item/weapon/anodevice/proc/UpdateSprite()
if(!inserted_battery)
@@ -194,3 +189,23 @@
/obj/item/weapon/anodevice/Del()
processing_objects.Remove(src)
..()
+
+/obj/item/weapon/anodevice/attack(mob/living/M as mob, mob/living/user as mob, def_zone)
+ if (!istype(M))
+ return
+
+ if(activated && inserted_battery.battery_effect.effect == EFFECT_TOUCH && !isnull(inserted_battery))
+ inserted_battery.battery_effect.DoEffectTouch(M)
+ inserted_battery.stored_charge -= energy_consumed_on_touch
+ user.visible_message("\blue [user] taps [M] with [src], and it shudders on contact.")
+ else
+ user.visible_message("\blue [user] taps [M] with [src], but nothing happens.")
+
+ //admin logging
+ user.lastattacked = M
+ M.lastattacker = user
+
+ if(inserted_battery.battery_effect)
+ user.attack_log += "\[[time_stamp()]\] Tapped [M.name] ([M.ckey]) with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])"
+ M.attack_log += "\[[time_stamp()]\] Tapped by [user.name] ([user.ckey]) with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])"
+ msg_admin_attack("[key_name(user)] tapped [key_name(M)] with [name] (EFFECT: [inserted_battery.battery_effect.effecttype])" )
diff --git a/code/modules/research/xenoarchaeology/tools/anomaly_suit.dm b/code/modules/research/xenoarchaeology/tools/anomaly_suit.dm
index 05e6d02d35..67ac1bd867 100644
--- a/code/modules/research/xenoarchaeology/tools/anomaly_suit.dm
+++ b/code/modules/research/xenoarchaeology/tools/anomaly_suit.dm
@@ -20,7 +20,7 @@
icon_state = "cespace_suit"
item_state = "cespace_suit"
armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 100, rad = 100)
- allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank)
+ allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit)
/obj/item/clothing/head/helmet/space/anomaly
name = "Excavation hood"
diff --git a/code/modules/research/xenoarchaeology/tools/tools.dm b/code/modules/research/xenoarchaeology/tools/tools.dm
index 889e833259..479d0240fa 100644
--- a/code/modules/research/xenoarchaeology/tools/tools.dm
+++ b/code/modules/research/xenoarchaeology/tools/tools.dm
@@ -22,3 +22,15 @@
w_class = 2
//todo: dig site tape
+
+/obj/item/weapon/storage/bag/fossils
+ name = "Fossil Satchel"
+ desc = "Transports delicate fossils in suspension so they don't break during transit."
+ icon = 'icons/obj/mining.dmi'
+ icon_state = "satchel"
+ slot_flags = SLOT_BELT | SLOT_POCKET
+ w_class = 3
+ storage_slots = 50
+ max_combined_w_class = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * ore.w_class
+ max_w_class = 3
+ can_hold = list("/obj/item/weapon/fossil")
diff --git a/code/modules/supermatter/supermatter.dm b/code/modules/supermatter/supermatter.dm
index df4516a19f..122da9f236 100644
--- a/code/modules/supermatter/supermatter.dm
+++ b/code/modules/supermatter/supermatter.dm
@@ -44,6 +44,10 @@
var/emergency_alert = "CRYSTAL DELAMINATION IMMINENT."
var/explosion_point = 1000
+ l_color = "#8A8A00"
+ var/warning_color = "#B8B800"
+ var/emergency_color = "#D9D900"
+
var/grav_pulling = 0
var/pull_radius = 14
@@ -99,6 +103,13 @@
del src
return
+//Changes color and luminosity of the light to these values if they were not already set
+/obj/machinery/power/supermatter/proc/shift_light(var/lum, var/clr)
+ if(l_color != clr)
+ l_color = clr
+ if(luminosity != lum)
+ SetLuminosity(lum)
+
/obj/machinery/power/supermatter/process()
var/turf/L = loc
@@ -109,12 +120,15 @@
if(!istype(L)) //We are in a crate or somewhere that isn't turf, if we return to turf resume processing but for now.
return //Yeah just stop.
+
if(damage > warning_point) // while the core is still damaged and it's still worth noting its status
+
+ shift_light(5, warning_color)
if((world.timeofday - lastwarning) / 10 >= WARNING_DELAY)
var/stability = num2text(round((damage / explosion_point) * 100))
if(damage > emergency_point)
-
+ shift_light(7, emergency_color)
radio.autosay(addtext(emergency_alert, " Instability: ",stability,"%"), "Supermatter Monitor")
lastwarning = world.timeofday
@@ -135,7 +149,8 @@
mob.apply_effect(rads, IRRADIATE)
explode()
-
+ else
+ shift_light(4,initial(l_color))
if(grav_pulling)
supermatter_pull()
diff --git a/code/modules/surgery/appendix.dm b/code/modules/surgery/appendix.dm
index ede75704ee..91332eab06 100644
--- a/code/modules/surgery/appendix.dm
+++ b/code/modules/surgery/appendix.dm
@@ -8,6 +8,8 @@
can_infect = 1
blood_level = 1
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ if (!hasorgans(target))
+ return 0
if (target_zone != "groin")
return 0
var/datum/organ/external/groin = target.get_organ("groin")
diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm
index d0d30cfd20..0bc1407567 100644
--- a/code/modules/surgery/bones.dm
+++ b/code/modules/surgery/bones.dm
@@ -15,6 +15,8 @@
max_duration = 60
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ if (!hasorgans(target))
+ return 0
var/datum/organ/external/affected = target.get_organ(target_zone)
return affected.open == 2 && affected.stage == 0
@@ -47,6 +49,8 @@
max_duration = 70
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ if (!hasorgans(target))
+ return 0
var/datum/organ/external/affected = target.get_organ(target_zone)
return affected.name != "head" && affected.open == 2 && affected.stage == 1
@@ -84,6 +88,8 @@
max_duration = 70
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ if (!hasorgans(target))
+ return 0
var/datum/organ/external/affected = target.get_organ(target_zone)
return affected.name == "head" && affected.open == 2 && affected.stage == 1
@@ -118,6 +124,8 @@
max_duration = 60
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ if (!hasorgans(target))
+ return 0
var/datum/organ/external/affected = target.get_organ(target_zone)
return affected.open == 2 && affected.stage == 2
diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm
index dc0af3936a..5109b72ef2 100644
--- a/code/modules/surgery/generic.dm
+++ b/code/modules/surgery/generic.dm
@@ -35,8 +35,9 @@
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"
+ if(..())
+ 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)
@@ -74,8 +75,9 @@
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"
+ if(..())
+ 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)
@@ -114,10 +116,9 @@
max_duration = 110
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- if(isslime(target))
- return 0
- var/datum/organ/external/affected = target.get_organ(target_zone)
- return ..() && affected.open == 0 && target_zone != "mouth"
+ if(..())
+ 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)
@@ -153,8 +154,9 @@
max_duration = 60
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 && (affected.status & ORGAN_BLEEDING)
+ if(..())
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ return affected.open && (affected.status & ORGAN_BLEEDING)
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
@@ -187,8 +189,9 @@
max_duration = 40
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 == 1 && !(affected.status & ORGAN_BLEEDING)
+ if(..())
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ return affected.open == 1 && !(affected.status & ORGAN_BLEEDING)
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
@@ -242,8 +245,9 @@
max_duration = 100
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 && target_zone != "mouth"
+ if(..())
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ return affected.open && 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)
diff --git a/code/modules/surgery/headreattach.dm b/code/modules/surgery/headreattach.dm
index 038ba1dfcd..17db2c30e3 100644
--- a/code/modules/surgery/headreattach.dm
+++ b/code/modules/surgery/headreattach.dm
@@ -28,8 +28,9 @@
max_duration = 100
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.status & ORGAN_CUT_AWAY)
+ if(..())
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ return !(affected.status & ORGAN_CUT_AWAY)
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("[user] starts peeling back tattered flesh where [target]'s head used to be with \the [tool].", \
@@ -61,8 +62,9 @@
max_duration = 100
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.status & ORGAN_CUT_AWAY && affected.open < 3 && !(affected.status & ORGAN_ATTACHABLE)
+ if(..())
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ return affected.status & ORGAN_CUT_AWAY && affected.open < 3 && !(affected.status & ORGAN_ATTACHABLE)
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
@@ -94,8 +96,9 @@
max_duration = 100
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 == 3
+ if(..())
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ return affected.open == 3
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("[user] is stapling and suturing flesh into place in [target]'s esophagal and vocal region with \the [tool].", \
@@ -128,8 +131,9 @@
max_duration = 70
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 == 4
+ if(..())
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ return affected.open == 4
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("[user] starts adjusting area around [target]'s neck with \the [tool].", \
@@ -162,8 +166,9 @@
max_duration = 100
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/datum/organ/external/head = target.get_organ(target_zone)
- return ..() && head.status & ORGAN_ATTACHABLE
+ if(..())
+ var/datum/organ/external/head = target.get_organ(target_zone)
+ return head.status & ORGAN_ATTACHABLE
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
user.visible_message("[user] starts attaching [tool] to [target]'s reshaped neck.", \
diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm
index a57d1d89ca..c3f4f3298a 100644
--- a/code/modules/surgery/implant.dm
+++ b/code/modules/surgery/implant.dm
@@ -7,6 +7,8 @@
/datum/surgery_step/cavity
priority = 1
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ if(!hasorgans(target))
+ return 0
var/datum/organ/external/affected = target.get_organ(target_zone)
return affected.open == 2 && !(affected.status & ORGAN_BLEEDING) && (target_zone != "chest" || target.op_stage.ribcage == 2)
@@ -41,8 +43,9 @@
max_duration = 80
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.cavity && !affected.hidden
+ if(..())
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ return !affected.cavity && !affected.hidden
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
@@ -76,8 +79,9 @@
max_duration = 80
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.cavity
+ if(..())
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ return affected.cavity
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
@@ -106,11 +110,9 @@
max_duration = 100
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- if(isslime(target))
- return 0
- var/datum/organ/external/affected = target.get_organ(target_zone)
- var/can_fit = !affected.hidden && affected.cavity && tool.w_class <= get_max_wclass(affected)
- return ..() && can_fit
+ if(..())
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ return !affected.hidden && affected.cavity && tool.w_class <= get_max_wclass(affected)
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
@@ -185,7 +187,7 @@
affected.implants -= obj
target.hud_updateflag |= 1 << IMPLOYAL_HUD
-
+
//Handle possessive brain borers.
if(istype(obj,/mob/living/simple_animal/borer))
var/mob/living/simple_animal/borer/worm = obj
diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm
index 55fc59dd35..bd1002b06d 100644
--- a/code/modules/surgery/other.dm
+++ b/code/modules/surgery/other.dm
@@ -17,6 +17,9 @@
max_duration = 90
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ if(!hasorgans(target))
+ return 0
+
var/datum/organ/external/affected = target.get_organ(target_zone)
var/internal_bleeding = 0
diff --git a/code/modules/surgery/ribcage.dm b/code/modules/surgery/ribcage.dm
index c48c77f16d..1532dda210 100644
--- a/code/modules/surgery/ribcage.dm
+++ b/code/modules/surgery/ribcage.dm
@@ -19,7 +19,7 @@
max_duration = 70
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- if (!istype(target))
+ if (!hasorgans(target))
return
var/datum/organ/external/affected = target.get_organ(target_zone)
return ..() && target.op_stage.ribcage == 0 && affected.open >= 2
@@ -197,6 +197,9 @@
max_duration = 90
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ if(!hasorgans(target))
+ return 0
+
var/is_chest_organ_damaged = 0
var/datum/organ/external/chest/chest = target.get_organ("chest")
for(var/datum/organ/internal/I in chest.internal_organs) if(I.damage > 0)
@@ -278,6 +281,9 @@
max_duration = 90
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
+ if(!hasorgans(target))
+ return 0
+
var/is_chest_organ_damaged = 0
var/datum/organ/internal/heart/heart = target.internal_organs["heart"]
var/datum/organ/external/chest/chest = target.get_organ("chest")
diff --git a/code/modules/surgery/robolimbs.dm b/code/modules/surgery/robolimbs.dm
index f4af506c63..354b448378 100644
--- a/code/modules/surgery/robolimbs.dm
+++ b/code/modules/surgery/robolimbs.dm
@@ -30,8 +30,9 @@
max_duration = 100
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.status & ORGAN_CUT_AWAY)
+ if(..())
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ return !(affected.status & ORGAN_CUT_AWAY)
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
@@ -64,8 +65,9 @@
max_duration = 100
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.status & ORGAN_CUT_AWAY && affected.open < 3 && !(affected.status & ORGAN_ATTACHABLE)
+ if(..())
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ return affected.status & ORGAN_CUT_AWAY && affected.open < 3 && !(affected.status & ORGAN_ATTACHABLE)
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
@@ -100,8 +102,9 @@
max_duration = 70
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 == 3
+ if(..())
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ return affected.open == 3
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
@@ -134,12 +137,13 @@
max_duration = 100
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
- var/obj/item/robot_parts/p = tool
- if (p.part)
- if (!(target_zone in p.part))
- return 0
- var/datum/organ/external/affected = target.get_organ(target_zone)
- return ..() && affected.status & ORGAN_ATTACHABLE
+ if(..())
+ var/obj/item/robot_parts/p = tool
+ if (p.part)
+ if (!(target_zone in p.part))
+ return 0
+ var/datum/organ/external/affected = target.get_organ(target_zone)
+ return affected.status & ORGAN_ATTACHABLE
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/datum/organ/external/affected = target.get_organ(target_zone)
diff --git a/code/modules/vehicles/cargo_train.dm b/code/modules/vehicles/cargo_train.dm
index b9a36f4c9c..ba6318588f 100644
--- a/code/modules/vehicles/cargo_train.dm
+++ b/code/modules/vehicles/cargo_train.dm
@@ -1,18 +1,27 @@
/obj/vehicle/train/cargo/engine
name = "cargo train tug"
+ desc = "A ridable electric car designed for pulling cargo trolleys."
icon = 'icons/obj/aibots.dmi'
icon_state = "mulebot1" //mulebot icons until I get some proper icons
- on = 1
+ on = 0
powered = 1
locked = 0
+ standing_mob = 1
load_item_visible = 1
load_offset_x = 0
load_offset_y = 9
var/car_limit = 3 //how many cars an engine can pull before performance degrades
- var/lead_engine = 1 //if the engine is the lead engine - set automatically
active_engines = 1
+ var/obj/item/weapon/key/cargo_train/key
+
+/obj/item/weapon/key/cargo_train
+ name = "key"
+ desc = "A keyring with a small steel key, and a yellow fob reading \"Choo Choo!\"."
+ icon = 'icons/obj/vehicles.dmi'
+ icon_state = "train_keys"
+ w_class = 1
/obj/vehicle/train/cargo/trolley
name = "cargo train trolley"
@@ -22,6 +31,7 @@
passenger_allowed = 0
locked = 0
+ standing_mob = 1
load_item_visible = 1
load_offset_x = 0
load_offset_y = 9
@@ -33,17 +43,16 @@
..()
cell = new /obj/item/weapon/cell/high
verbs -= /atom/movable/verb/pull
-
-/obj/vehicle/train/cargo/engine/initialize()
- ..()
+ key = new()
/obj/vehicle/train/cargo/engine/Move()
if(on && cell.charge < power_use)
turn_off()
update_stats()
- if(load && lead_engine)
- load << "The drive motor briefly whines, then crawls to a stop."
- if(lead_engine && !on)
+ if(load && is_train_head())
+ load << "The drive motor briefly whines, then drones to a stop."
+
+ if(is_train_head() && !on)
return 0
return ..()
@@ -55,6 +64,16 @@
else
..()
+/obj/vehicle/train/cargo/engine/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(istype(W, /obj/item/weapon/key/cargo_train))
+ if(!key)
+ user.drop_item()
+ key = W
+ W.loc = src
+ verbs += /obj/vehicle/train/cargo/engine/verb/remove_key
+ return
+ ..()
+
/obj/vehicle/train/cargo/update_icon()
if(open)
icon_state = "mulebot-hatch"
@@ -92,6 +111,13 @@
//-------------------------------------------
// Train procs
//-------------------------------------------
+/obj/vehicle/train/cargo/engine/turn_on()
+ if(!key)
+ return
+ else
+ ..()
+ update_stats()
+
/obj/vehicle/train/cargo/RunOver(var/mob/living/carbon/human/H)
var/list/parts = list("head", "chest", "l_leg", "r_leg", "l_arm", "r_arm")
@@ -106,7 +132,7 @@
/obj/vehicle/train/cargo/engine/RunOver(var/mob/living/carbon/human/H)
..()
- if(lead_engine && istype(load, /mob/living/carbon/human))
+ if(is_train_head() && istype(load, /mob/living/carbon/human))
var/mob/living/carbon/human/D = load
D << "\red \b You ran over [H]!"
visible_message("\red \The [src] ran over [H]!")
@@ -119,44 +145,11 @@
//-------------------------------------------
// Interaction procs
//-------------------------------------------
-/obj/vehicle/train/cargo/trolley/verb/rotate()
- set name = "Rotate"
- set category = "Object"
- set src in view(1)
-
- if(anchored)
- usr << "You cannot turn the trolley while it is latched onto a train."
- return
-
- var/cur_dir = null
- switch(dir)
- if(NORTH)
- cur_dir = "North"
- if(SOUTH)
- cur_dir = "South"
- if(EAST)
- cur_dir = "East"
- if(WEST)
- cur_dir = "West"
-
- var/new_dir = input("Select a new direction:", "Rotate", cur_dir) in list("North", "South", "East", "West")
-
- switch(new_dir)
- if("North")
- dir = NORTH
- if("South")
- dir = SOUTH
- if("East")
- dir = EAST
- if("West")
- dir = WEST
-
-
/obj/vehicle/train/cargo/engine/relaymove(mob/user, direction)
if(user != load)
return 0
- if(lead_engine)
+ if(is_train_head())
if(direction == reverse_direction(dir))
return 0
if(Move(get_step(src, direction)))
@@ -165,70 +158,86 @@
else
return ..()
+/obj/vehicle/train/cargo/engine/examine()
+ ..()
+
+ if(!istype(usr, /mob/living/carbon/human))
+ return
+
+ if(get_dist(usr,src) <= 1)
+ usr << "The power light is [on ? "on" : "off"].\nThere are[key ? "" : " no"] keys in the ignition."
+
+/obj/vehicle/train/cargo/engine/verb/check_power()
+ set name = "Check power level"
+ set category = "Object"
+ set src in view(1)
+
+ if(!istype(usr, /mob/living/carbon/human))
+ return
+
+ if(!cell)
+ usr << "There is no power cell installed in [src]."
+ return
+
+ usr << "The power meter reads [round(cell.percent(), 0.01)]%"
/obj/vehicle/train/cargo/engine/verb/start_engine()
set name = "Start engine"
set category = "Object"
set src in view(1)
+ if(!istype(usr, /mob/living/carbon/human))
+ return
+
if(on)
usr << "The engine is already running."
return
- if(turn_on())
- usr << "You start [src]."
+ turn_on()
+ if (on)
+ usr << "You start [src]'s engine."
else
if(cell.charge < power_use)
usr << "[src] is out of power."
else
- usr << "[src] won't start."
+ usr << "[src]'s engine won't start."
-//-------------------------------------------
-// Latching/unlatching procs
-//-------------------------------------------
-/obj/vehicle/train/cargo/trolley/latch(var/obj/vehicle/train/T)
- if(..())
- //if this is a trolley, and is now part of a train, anchor it so it cant be pushed around
- if(lead)
- anchored = 1
- lead.anchored = 1
- if(tow)
- anchored = 1
- tow.anchored = 1
- return 1
- else
- return 0
+/obj/vehicle/train/cargo/engine/verb/stop_engine()
+ set name = "Stop engine"
+ set category = "Object"
+ set src in view(1)
+
+ if(!istype(usr, /mob/living/carbon/human))
+ return
+
+ if(!on)
+ usr << "The engine is already stopped."
+ return
-/obj/vehicle/train/cargo/trolley/unlatch()
- if(..())
- //if this carraige isn't part of a train anymore; unanchor it so it can be pushed around
- if(!tow && !lead)
- anchored = 0
- return 1
- else
- return 0
+ turn_off()
+ if (!on)
+ usr << "You stop [src]'s engine."
+/obj/vehicle/train/cargo/engine/verb/remove_key()
+ set name = "Remove key"
+ set category = "Object"
+ set src in view(1)
-/obj/vehicle/train/cargo/engine/latch(var/obj/vehicle/train/T)
- if(..())
- //check if this is not the lead engine
- if(lead)
- lead_engine = 0
- if(tow)
- tow.anchored = 1
- return 1
- else
- return 0
+ if(!istype(usr, /mob/living/carbon/human))
+ return
+
+ if(!key || (load && load != usr))
+ return
+
+ if(on)
+ turn_off()
-/obj/vehicle/train/cargo/engine/unlatch()
- if(..())
- //check if this is now the lead engine
- if(!lead)
- lead_engine = 1
- return 1
- else
- return 0
+ key.loc = usr.loc
+ if(!usr.get_active_hand())
+ usr.put_in_hands(key)
+ key = null
+ verbs -= /obj/vehicle/train/cargo/engine/verb/remove_key
//-------------------------------------------
// Loading/unloading procs
@@ -262,13 +271,23 @@
/obj/vehicle/train/cargo/engine/update_train_stats()
..()
- speed_calc()
+ update_move_delay()
- if(!lead) //check if this is the lead engine
- lead_engine = 1
+/obj/vehicle/train/cargo/trolley/update_train_stats()
+ ..()
+
+ if(!lead && !tow)
+ anchored = 0
+ if(verbs.Find(/atom/movable/verb/pull))
+ return
+ else
+ verbs += /atom/movable/verb/pull
+ else
+ anchored = 1
+ verbs -= /atom/movable/verb/pull
-/obj/vehicle/train/cargo/engine/proc/speed_calc()
- if(!lead_engine)
+/obj/vehicle/train/cargo/engine/proc/update_move_delay()
+ if(!is_train_head() || !on)
move_delay = initial(move_delay) //so that engines that have been turned off don't lag behind
else
move_delay = max(0, (-car_limit * active_engines) + train_length - active_engines) //limits base overweight so you cant overspeed trains
diff --git a/code/modules/vehicles/train.dm b/code/modules/vehicles/train.dm
index 4a853d3811..faad42d1cc 100644
--- a/code/modules/vehicles/train.dm
+++ b/code/modules/vehicles/train.dm
@@ -56,6 +56,7 @@
msg_admin_attack("[D.name] ([D.ckey]) hit [M.name] ([M.ckey]) with [src]. (JMP)")
+
//-------------------------------------------
// Interaction procs
//-------------------------------------------
@@ -66,8 +67,9 @@
return 0
if(user != load)
- if(user in src) //for handling players stuck in src
- unload(user, direction, 1)
+ if(user in src) //for handling players stuck in src - this shouldn't happen - but just in case it does
+ user.loc = T
+ contents -= user
return 1
return 0
@@ -80,23 +82,19 @@
/obj/vehicle/train/MouseDrop_T(var/atom/movable/C, mob/user as mob)
if(!usr.canmove || usr.stat || usr.restrained() || !Adjacent(usr) || !user.Adjacent(C))
return
-
if(istype(C,/obj/vehicle/train))
- if(latch(C))
- user << "\blue You successfully connect the [C] to [src]."
- else
- user << "\red You were unable to connect the [C] to [src]."
- return
-
- if(!load(C))
- user << "\red You were unable to load [C] on [src]."
+ latch(C, user)
+ else
+ if(!load(C))
+ user << "\red You were unable to load [C] on [src]."
/obj/vehicle/train/attack_hand(mob/user as mob)
- if(!user.canmove || user.stat || user.restrained() || !Adjacent(user))
+ if(user.stat || user.restrained() || !Adjacent(user))
return 0
if(user != load && (user in src))
- unload(user, null, 1) //for handling players stuck in src
+ user.loc = loc //for handling players stuck in src
+ contents -= user
else if(load)
unload(user) //unload if loaded
else if(!load)
@@ -106,74 +104,78 @@
/obj/vehicle/train/verb/unlatch_v()
set name = "Unlatch"
+ set desc = "Unhitches this train from the one in front of it."
set category = "Object"
set src in view(1)
+
+ if(!istype(usr, /mob/living/carbon/human))
+ return
if(!usr.canmove || usr.stat || usr.restrained() || !Adjacent(usr))
return
- if(unlatch())
- usr << "\blue You unlatch [src]."
- else
- usr << "\red [src] is already unlatched."
+ unattach(usr)
//-------------------------------------------
// Latching/unlatching procs
//-------------------------------------------
-/obj/vehicle/train/proc/latch(var/obj/vehicle/train/T)
+
+//attempts to attach src as a follower of the train T
+/obj/vehicle/train/proc/attach_to(obj/vehicle/train/T, mob/user)
+ if (get_dist(src, T) > 1)
+ user << "\red [src] is too far away from [T] to hitch them together."
+ return
+
+ if (lead)
+ user << "\red [src] is already hitched to something."
+ return
+
+ if (T.tow)
+ user << "\red [T] is already towing something."
+ return
+ //latch with src as the follower
+ lead = T
+ T.tow = src
+ dir = lead.dir
+
+ if(user)
+ user << "\blue You hitch [src] to [T]."
+
+ update_stats()
+
+
+//detaches the train from whatever is towing it
+/obj/vehicle/train/proc/unattach(mob/user)
+ if (!lead)
+ user << "\red [src] is not hitched to anything."
+ return
+
+ lead.tow = null
+ lead.update_stats()
+
+ user << "\blue You unhitch [src] from [lead]."
+ lead = null
+
+ update_stats()
+
+/obj/vehicle/train/proc/latch(obj/vehicle/train/T, mob/user)
if(!istype(T) || !Adjacent(T))
return 0
- /* --- commented out until we get directional sprites ---
- if(dir != T.dir) //cars need to be inline to latch
+ var/T_dir = get_dir(src, T) //figure out where T is wrt src
+
+ if(dir == T_dir) //if car is ahead
+ src.attach_to(T, user)
+ else if(reverse_direction(dir) == T_dir) //else if car is behind
+ T.attach_to(src, user)
+
+//returns 1 if this is the lead car of the train
+/obj/vehicle/train/proc/is_train_head()
+ if (lead)
return 0
- */
-
- var/T_dir = get_dir(src, T)
-
- if(dir & T_dir) //if car is ahead
- if(!lead && !T.tow)
- lead = T
- T.tow = src
- else
- return 0
- else if(reverse_direction(dir) & T_dir) //else if car is behind
- if(!tow && !T.lead)
- tow = T
- T.lead = src
- else
- return 0
- else
- return 0
-
- update_stats()
-
return 1
-/obj/vehicle/train/proc/unlatch(var/obj/vehicle/train/T)
- if(!lead && !tow)
- return 0
-
- if(T)
- if(T == tow)
- tow = null
- else if(T == lead)
- lead = null
- else
- if(tow)
- tow.unlatch(src)
- tow = null
- if(lead)
- lead.unlatch(src)
- lead = null
-
- update_stats()
-
- return 1
-
-
-
//-------------------------------------------------------
// Stat update procs
//
@@ -182,10 +184,10 @@
// size of the train, to limit super long trains.
//-------------------------------------------------------
/obj/vehicle/train/update_stats()
- if(!tow)
- update_train_stats()
+ if(tow)
+ return tow.update_stats() //take us to the very end
else
- return tow.update_stats()
+ update_train_stats() //we're at the end
/obj/vehicle/train/proc/update_train_stats()
if(powered && on)
@@ -195,10 +197,10 @@
train_length = 1
- if(tow)
+ if(istype(tow))
active_engines += tow.active_engines
train_length += tow.train_length
//update the next section of train ahead of us
- if(lead)
+ if(istype(lead))
lead.update_train_stats()
\ No newline at end of file
diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm
index 6ae7f3ee14..27ce16d113 100644
--- a/code/modules/vehicles/vehicle.dm
+++ b/code/modules/vehicles/vehicle.dm
@@ -1,7 +1,7 @@
/obj/vehicle
name = "vehicle"
icon = 'icons/obj/vehicles.dmi'
- layer = MOB_LAYER
+ layer = MOB_LAYER + 0.1 //so it sits above objects including mobs
density = 1
anchored = 1
animate_movement=1
@@ -23,6 +23,7 @@
var/obj/item/weapon/cell/cell
var/power_use = 5 //set this to adjust the amount of power the vehicle uses per move
+ var/standing_mob = 0 //if a mob loaded on the vehicle should be standing
var/atom/movable/load //all vehicles can take a load, since they should all be a least drivable
var/load_item_visible = 1 //set if the loaded item should be overlayed on the vehicle sprite
var/load_offset_x = 0 //pixel_x offset for item overlay
@@ -36,7 +37,7 @@
//spawn the cell you want in each vehicle
/obj/vehicle/Move()
- if(world.timeofday > l_move_time + move_delay)
+ if(world.time > l_move_time + move_delay)
if(on && powered && cell.charge < power_use)
turn_off()
@@ -46,6 +47,10 @@
if(on && powered)
cell.use(power_use)
anchored = init_anc
+
+ if(load)
+ load.loc = loc
+ load.dir = dir
return 1
else
@@ -262,49 +267,28 @@
crate.close()
C.loc = loc
- sleep(2)
- if(C.loc != loc) //To prevent you from going onto more than one train.
- return 0
- C.loc = src
+ C.dir = dir
+ C.anchored = 1
load = C
if(load_item_visible)
C.pixel_x += load_offset_x
C.pixel_y += load_offset_y
- C.layer = layer
-
- overlays += C
-
- //we can set these back now since we have already cloned the icon into the overlay
- C.pixel_x = initial(C.pixel_x)
- C.pixel_y = initial(C.pixel_y)
- C.layer = initial(C.layer)
+ C.layer = layer + 0.1 //so it sits above the vehicle
if(ismob(C))
var/mob/M = C
- if(M.client)
- M.client.perspective = EYE_PERSPECTIVE
- M.client.eye = src
+ M.buckled = src
+ M.update_canmove()
return 1
-/obj/vehicle/proc/unload(var/mob/user, var/direction, var/exception = 0)
+/obj/vehicle/proc/unload(var/mob/user, var/direction)
if(!load)
- // in case non-load items end up in contents, dump everything else too
- for(var/atom/movable/AM in src)
- AM.loc = get_turf(src)
- AM.pixel_x = initial(AM.pixel_x)
- AM.pixel_y = initial(AM.pixel_y)
- AM.layer = initial(AM.layer)
- if(ismob(AM))
- var/mob/M = AM
- if(M.client)
- M.client.perspective = MOB_PERSPECTIVE
- M.client.eye = src
- return 0
-
+ return
+
var/turf/dest = null
//find a turf to unload to
@@ -332,42 +316,21 @@
return 0
- if(exception) //for handling any players that end up in src.contents that are trying to climb off
- user.loc = dest
- user.pixel_x = initial(user.pixel_x)
- user.pixel_y = initial(user.pixel_y)
- user.layer = initial(user.layer)
-
- if(ismob(user))
- var/mob/M = user
- if(M.client)
- M.client.perspective = MOB_PERSPECTIVE
- M.client.eye = src
-
- src.contents -= user
-
- return 1
-
- overlays.Cut()
-
load.loc = dest
-
- /*
+ load.dir = get_dir(loc, dest)
+ load.anchored = initial(load.anchored)
load.pixel_x = initial(load.pixel_x)
load.pixel_y = initial(load.pixel_y)
load.layer = initial(load.layer)
- */
if(ismob(load))
var/mob/M = load
- if(M.client)
- M.client.perspective = MOB_PERSPECTIVE
- M.client.eye = src
+ M.buckled = null
+ M.anchored = initial(M.anchored)
+ M.update_canmove()
load = null
- unload() //recursive check for anything left in contents
-
return 1
diff --git a/code/modules/virus2/helpers.dm b/code/modules/virus2/helpers.dm
index 93acbd6ef4..6118dade42 100644
--- a/code/modules/virus2/helpers.dm
+++ b/code/modules/virus2/helpers.dm
@@ -68,10 +68,11 @@ proc/airborne_can_reach(turf/source, turf/target)
if ("[disease.uniqueID]" in M.virus2)
return
// if one of the antibodies in the mob's body matches one of the disease's antigens, don't infect
- if(M.antibodies & disease.antigen != 0)
+ if((M.antibodies & disease.antigen) != 0)
return
if(M.reagents.has_reagent("spaceacillin"))
return
+
if(istype(M,/mob/living/carbon/monkey))
var/mob/living/carbon/monkey/chimp = M
if (!(chimp.greaterform in disease.affected_species))
diff --git a/code/setup.dm b/code/setup.dm
index b40cd05fa7..de6353c0d6 100644
--- a/code/setup.dm
+++ b/code/setup.dm
@@ -35,10 +35,10 @@
#define TEMPERATURE_DAMAGE_COEFFICIENT 1.5 //This is used in handle_temperature_damage() for humans, and in reagents that affect body temperature. Temperature damage is multiplied by this amount.
#define BODYTEMP_AUTORECOVERY_DIVISOR 12 //This is the divisor which handles how much of the temperature difference between the current body temperature and 310.15K (optimal temperature) humans auto-regenerate each tick. The higher the number, the slower the recovery. This is applied each tick, so long as the mob is alive.
-#define BODYTEMP_AUTORECOVERY_MINIMUM 10 //Minimum amount of kelvin moved toward 310.15K per tick. So long as abs(310.15 - bodytemp) is more than 50.
+#define BODYTEMP_AUTORECOVERY_MINIMUM 1 //Minimum amount of kelvin moved toward 310.15K per tick. So long as abs(310.15 - bodytemp) is more than 50.
#define BODYTEMP_COLD_DIVISOR 6 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is lower than their body temperature. Make it lower to lose bodytemp faster.
#define BODYTEMP_HEAT_DIVISOR 6 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is higher than their body temperature. Make it lower to gain bodytemp faster.
-#define BODYTEMP_COOLING_MAX 30 //The maximum number of degrees that your body can cool in 1 tick, when in a cold area.
+#define BODYTEMP_COOLING_MAX -30 //The maximum number of degrees that your body can cool in 1 tick, when in a cold area.
#define BODYTEMP_HEATING_MAX 30 //The maximum number of degrees that your body can heat up in 1 tick, when in a hot area.
#define BODYTEMP_HEAT_DAMAGE_LIMIT 360.15 // The limit the human body can take before it starts taking damage from heat.
@@ -764,6 +764,18 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse
+/*
+ Germs and infections
+*/
+
+#define GERM_LEVEL_AMBIENT 110 //maximum germ level you can reach by standing still
+#define GERM_LEVEL_MOVE_CAP 200 //maximum germ level you can reach by running around
+
+#define INFECTION_LEVEL_ONE 100
+#define INFECTION_LEVEL_TWO 500
+#define INFECTION_LEVEL_THREE 1000
+
+
/*
Shuttles
*/
@@ -784,4 +796,4 @@ var/list/RESTRICTED_CAMERA_NETWORKS = list( //Those networks can only be accesse
#define IDLE_STATE 0
#define WAIT_LAUNCH 1
#define WAIT_ARRIVE 2
-#define WAIT_FINISH 3
+#define WAIT_FINISH 3
diff --git a/code/world.dm b/code/world.dm
index b3fe9940a8..b74a1abccd 100644
--- a/code/world.dm
+++ b/code/world.dm
@@ -71,7 +71,7 @@ var/world_topic_spam_protect_time = world.timeofday
/world/Topic(T, addr, master, key)
diary << "TOPIC: \"[T]\", from:[addr], master:[master], key:[key][log_end]"
-
+
if (T == "ping")
var/x = 1
for (var/client/C)
@@ -108,7 +108,6 @@ var/world_topic_spam_protect_time = world.timeofday
n++
s["players"] = n
- if(revdata) s["revision"] = revdata.revision
s["admins"] = admins
return list2params(s)
@@ -127,7 +126,7 @@ var/world_topic_spam_protect_time = world.timeofday
var/input[] = params2list(T)
if(input["key"] != config.comms_password)
if(world_topic_spam_protect_ip == addr && abs(world_topic_spam_protect_time - world.time) < 50)
-
+
spawn(50)
world_topic_spam_protect_time = world.time
return "Bad Key (Throttled)"
@@ -136,9 +135,9 @@ var/world_topic_spam_protect_time = world.timeofday
world_topic_spam_protect_ip = addr
return "Bad Key"
-
+
var/client/C
-
+
for(var/client/K in clients)
if(K.ckey == input["adminmsg"])
C = K
@@ -155,7 +154,7 @@ var/world_topic_spam_protect_time = world.timeofday
C << 'sound/effects/adminhelp.ogg'
C << message
-
+
for(var/client/A in admins)
if(A != C)
A << amessage
@@ -182,9 +181,9 @@ var/world_topic_spam_protect_time = world.timeofday
return "Bad Key"
return show_player_info_irc(input["notes"])
-
-
+
+
/world/Reboot(var/reason)
@@ -271,7 +270,7 @@ var/world_topic_spam_protect_time = world.timeofday
var/title = "Moderator"
if(config.mods_are_mentors) title = "Mentor"
var/rights = admin_ranks[title]
-
+
var/ckey = copytext(line, 1, length(line)+1)
var/datum/admins/D = new /datum/admins(title, rights, ckey)
D.associate(directory[ckey])
diff --git a/html/changelog.html b/html/changelog.html
index 8a248d22e8..334cb8e6ae 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -122,6 +122,18 @@ should be listed in the changelog upon commit though. Thanks. -->
+
+
20 June 2014
+
Cael_Aislinn updated:
+
+ - New discoverable items added to xenoarchaeology, and new features for some existing ones. Artifact harvesters can now harvest the secondary effect of artifacts as well as the primary one.
+
+ - Artifact utilisers should be much nicer/easier to use now.
+ - Alden-Saraspova counters and talking items should work properly now.
+
+
+
+
3 Juni 2014
Hubblenaut updated:
@@ -171,6 +183,19 @@ should be listed in the changelog upon commit though. Thanks. -->
+
+
+
3 May 2014
+
Cael_Aislinn updated:
+
+ - Coming out of nowhere the past few months, the Garland Corporation has made headlines with a new prehistoric theme park delighting travellers with species thought extinct. Now available for research stations everywhere is the technology that made it all possible! Features include:
+ - 13 discoverable prehistoric species to clone from fossils (including 5 brand new ones).
+ - 11 discoverable prehistoric plants to clone from fossils (including 9 brand new ones).
+ - New minigame that involves correctly ordering the genomes inside each genetic sequence to unlock an animal/plant.
+ - Some prehistoric animals and plants may seem strangely familiar... while others may bring more than the erstwhile scientist bargains for.
+
+
+
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index fa6e8649ec..7c86950ba6 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/effects/ss13_dark_alpha6.dmi b/icons/effects/ss13_dark_alpha6.dmi
new file mode 100644
index 0000000000..742337358d
Binary files /dev/null and b/icons/effects/ss13_dark_alpha6.dmi differ
diff --git a/icons/mob/human.dmi b/icons/mob/human.dmi
index cb21e0f502..c867b0d886 100644
Binary files a/icons/mob/human.dmi and b/icons/mob/human.dmi differ
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index 54ea7f9f4c..bf2b6c4d5b 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/icons/obj/hydroponics.dmi b/icons/obj/hydroponics.dmi
index 2db5f8a1f1..5459ad4cb2 100644
Binary files a/icons/obj/hydroponics.dmi and b/icons/obj/hydroponics.dmi differ
diff --git a/icons/obj/kitchen.dmi b/icons/obj/kitchen.dmi
index 9cccbfeb83..7c1bce89fb 100644
Binary files a/icons/obj/kitchen.dmi and b/icons/obj/kitchen.dmi differ
diff --git a/icons/obj/vehicles.dmi b/icons/obj/vehicles.dmi
index fd6daee8bd..699a372983 100644
Binary files a/icons/obj/vehicles.dmi and b/icons/obj/vehicles.dmi differ
diff --git a/icons/obj/xenoarchaeology.dmi b/icons/obj/xenoarchaeology.dmi
index 144dfaf1e1..b40ae3db6e 100644
Binary files a/icons/obj/xenoarchaeology.dmi and b/icons/obj/xenoarchaeology.dmi differ
diff --git a/maps/tgstation2.dmm b/maps/tgstation2.dmm
index 8134b4404d..ec14643a3a 100644
--- a/maps/tgstation2.dmm
+++ b/maps/tgstation2.dmm
@@ -1542,7 +1542,7 @@
"aDH" = (/obj/structure/table,/obj/item/weapon/paper/pamphlet,/turf/simulated/floor,/area/gateway)
"aDI" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/gateway)
"aDJ" = (/obj/structure/table,/obj/item/device/radio/off{pixel_y = 6},/obj/item/device/radio/off{pixel_x = 6; pixel_y = 4},/obj/item/device/radio/off{pixel_x = -6; pixel_y = 4},/obj/item/device/radio/off,/turf/simulated/floor,/area/gateway)
-"aDK" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/maintenance/fpmaint)
+"aDK" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/library)
"aDL" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/maintenance/fpmaint)
"aDM" = (/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = -30},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/table/reinforced,/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = -1},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/ai_monitored/storage/eva)
"aDN" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva)
@@ -1626,7 +1626,7 @@
"aFn" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/structure/table/reinforced,/obj/machinery/cell_charger,/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/cell/high{charge = 100; maxcharge = 15000},/obj/item/weapon/cable_coil{pixel_x = 3; pixel_y = -7},/obj/item/weapon/cable_coil{pixel_x = 3; pixel_y = -7},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/ai_monitored/storage/eva)
"aFo" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor{icon_state = "dark"},/area/ai_monitored/storage/eva)
"aFp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/tank/oxygen,/obj/item/weapon/tank/oxygen,/obj/item/clothing/mask/breath,/obj/item/clothing/mask/breath,/obj/item/device/flashlight,/obj/item/device/flashlight,/obj/item/weapon/storage/box/lights/mixed,/turf/simulated/floor/plating,/area/storage/emergency2)
-"aFq" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/device/modkit/tajaran,/obj/item/device/modkit/tajaran,/obj/item/device/modkit/tajaran,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/ai_monitored/storage/eva)
+"aFq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/weapon/cigbutt,/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/port)
"aFr" = (/obj/machinery/light_switch{pixel_y = 28},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; icon_state = "off"; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/wood,/area/bridge/meeting_room)
"aFs" = (/obj/machinery/door/airlock/glass{name = "Central Access"},/turf/simulated/floor,/area/hallway/primary/fore)
"aFt" = (/obj/machinery/door/airlock/glass{name = "Central Access"},/turf/simulated/floor{icon_state = "bluecorner"},/area/hallway/primary/fore)
@@ -1837,13 +1837,13 @@
"aJq" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor{dir = 6; icon_state = "whitehall"},/area/crew_quarters/fitness)
"aJr" = (/obj/structure/stool/bed/chair/office/dark{dir = 4},/turf/simulated/floor/wood,/area/library)
"aJs" = (/obj/structure/window/basic{dir = 8},/turf/simulated/floor/beach/water{tag = "icon-seadeep"; icon_state = "seadeep"},/area/crew_quarters/fitness)
-"aJt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/weapon/cigbutt,/obj/structure/disposalpipe/tagger/partial{name = "Sorting Office"; sort_tag = "Disposals"},/turf/simulated/floor/plating,/area/maintenance/port)
+"aJt" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor/plating,/area/maintenance/fpmaint)
"aJu" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/turf/simulated/floor/wood,/area/library)
"aJv" = (/obj/machinery/alarm{dir = 4; pixel_x = -23; pixel_y = 0},/obj/structure/disposalpipe/segment,/obj/machinery/camera{c_tag = "Fitness Room West"; dir = 4},/turf/simulated/floor{icon_state = "neutral"; dir = 8},/area/crew_quarters/fitness)
"aJw" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Holodeck Door"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor,/area/crew_quarters/fitness)
"aJx" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Holodeck Door"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor,/area/crew_quarters/fitness)
"aJy" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/light/small,/turf/simulated/floor,/area/crew_quarters/fitness)
-"aJz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/port)
+"aJz" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/device/modkit/tajaran,/obj/item/device/modkit/tajaran,/obj/item/device/modkit/tajaran,/obj/item/device/suit_cooling_unit,/obj/item/device/suit_cooling_unit,/obj/item/device/suit_cooling_unit,/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/ai_monitored/storage/eva)
"aJA" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/ai_monitored/storage/eva)
"aJB" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/fpmaint)
"aJC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/crew_quarters/fitness)
@@ -3306,7 +3306,7 @@
"blD" = (/obj/machinery/atmospherics/pipe/simple{dir = 4; icon_state = "intact"; level = 2},/turf/simulated/floor,/area/medical/sleeper)
"blE" = (/obj/machinery/light_switch{pixel_x = 27},/obj/machinery/camera{c_tag = "Telescience Control Room"; dir = 8; network = list("SS13","Research"); pixel_y = -22},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab)
"blF" = (/obj/machinery/atmospherics/pipe/simple/insulated{icon_state = "intact"; dir = 4},/obj/machinery/meter,/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "tox_airlock_pump"; tag_exterior_door = "tox_airlock_exterior"; id_tag = "tox_airlock_control"; tag_interior_door = "tox_airlock_interior"; pixel_x = -24; pixel_y = 0; tag_chamber_sensor = "tox_airlock_sensor"},/turf/simulated/floor{dir = 1; icon_state = "warnwhitecorner"},/area/rnd/mixing)
-"blG" = (/obj/machinery/door_control{id = "scanhide"; name = "Diagnostics Room Separation Shutters"; pixel_x = -6; pixel_y = 25; req_access_txt = "5"},/obj/machinery/camera{c_tag = "Medbay Scanning"; network = list("SS13")},/obj/machinery/atmospherics/unary/cold_sink/freezer{dir = 8; icon_state = "freezer_0"; tag = ""},/obj/machinery/door_control{id = "scanhideside"; name = "Diagnostics Room Privacy Shutters"; pixel_x = 6; pixel_y = 25; req_access_txt = "5"},/turf/simulated/floor{icon_state = "delivery"},/area/medical/sleeper)
+"blG" = (/obj/machinery/door_control{id = "scanhide"; name = "Diagnostics Room Separation Shutters"; pixel_x = -6; pixel_y = 25; req_access_txt = "5"},/obj/machinery/camera{c_tag = "Medbay Scanning"; network = list("SS13")},/obj/machinery/atmospherics/unary/cold_sink/freezer{dir = 8; icon_state = "freezer"; tag = ""},/obj/machinery/door_control{id = "scanhideside"; name = "Diagnostics Room Privacy Shutters"; pixel_x = 6; pixel_y = 25; req_access_txt = "5"},/turf/simulated/floor{icon_state = "delivery"},/area/medical/sleeper)
"blH" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"; tag = "icon-whitebluecorner"},/area/medical/medbay2)
"blI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor{icon_state = "white"},/area/medical/medbay2)
"blJ" = (/obj/machinery/camera{c_tag = "Medbay Lounge"; network = list("SS13")},/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor{tag = "icon-whiteblue (NORTH)"; icon_state = "whiteblue"; dir = 1},/area/medical/medbay2)
@@ -4216,7 +4216,7 @@
"bDd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = "0"},/turf/simulated/floor,/area/hallway/primary/central)
"bDe" = (/obj/machinery/atmospherics/portables_connector{dir = 1; name = "Connector Port (Air Supply)"},/obj/machinery/portable_atmospherics/canister/oxygen,/obj/machinery/light/small,/obj/machinery/light_switch{pixel_x = -22; pixel_y = 0},/turf/simulated/floor{icon_state = "delivery"},/area/medical/cryo)
"bDf" = (/obj/machinery/atmospherics/portables_connector{dir = 1; name = "Connector Port (Air Supply)"},/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/floor{icon_state = "delivery"},/area/medical/cryo)
-"bDg" = (/obj/machinery/atmospherics/unary/cold_sink/freezer{dir = 1},/obj/machinery/light/small,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{icon_state = "delivery"},/area/medical/cryo)
+"bDg" = (/obj/machinery/atmospherics/unary/cold_sink/freezer{dir = 1; icon_state = "freezer"},/obj/machinery/light/small,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{icon_state = "delivery"},/area/medical/cryo)
"bDh" = (/obj/machinery/clonepod,/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/turf/simulated/floor{dir = 2; icon_state = "whitepurple"},/area/medical/genetics_cloning)
"bDi" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/hallway/primary/central)
"bDj" = (/obj/structure/closet/secure_closet/scientist,/obj/machinery/light_switch{pixel_y = 28},/turf/simulated/floor{icon_state = "white"},/area/rnd/mixing)
@@ -4696,7 +4696,7 @@
"bMp" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"})
"bMq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/research{name = "Research Division"})
"bMr" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/obj/structure/table,/obj/item/weapon/storage/firstaid/o2{pixel_x = 5; pixel_y = 5},/obj/item/weapon/storage/firstaid/o2,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry)
-"bMs" = (/obj/machinery/door/airlock/maintenance{name = "Teleporter Maintenance"; req_access_txt = "17"},/obj/structure/sign/securearea{pixel_x = -32; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/teleporter)
+"bMs" = (/obj/machinery/door/airlock/maintenance{name = "Teleporter Maintenance"; req_access_txt = "17"},/obj/structure/sign/securearea{pixel_x = -32; pixel_y = 0},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/teleporter)
"bMt" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/rnd/lab)
"bMu" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry)
"bMv" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/rnd/lab)
@@ -5104,13 +5104,13 @@
"bUh" = (/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos)
"bUi" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor{icon_state = "white"},/area/medical/reception)
"bUj" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "virology_inner"; locked = 1; name = "Engineering External Access"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/maintenance/asmaint)
-"bUk" = (/obj/structure/closet/crate/internals,/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
+"bUk" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/wall/r_wall,/area/bridge/meeting_room)
"bUl" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/maintenance/port)
"bUm" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/airlock/maintenance{req_access_txt = "12"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/crew_quarters/locker)
"bUn" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/mob/living/simple_animal/mouse,/turf/simulated/floor/plating,/area/maintenance/port)
"bUo" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/maintenance/port)
"bUp" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/wall,/area/maintenance/port)
-"bUq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/wall,/area/quartermaster/office)
+"bUq" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/wall,/area/quartermaster/office)
"bUr" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/wall,/area/crew_quarters/locker/locker_toilet)
"bUs" = (/obj/machinery/camera{c_tag = "Locker Room Toilets"; dir = 8; network = list("SS13")},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet)
"bUt" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/locker/locker_toilet)
@@ -5118,7 +5118,7 @@
"bUv" = (/obj/item/weapon/stock_parts/console_screen,/obj/structure/table,/obj/item/weapon/stock_parts/console_screen,/obj/item/weapon/stock_parts/console_screen,/obj/item/weapon/stock_parts/matter_bin,/obj/item/weapon/stock_parts/matter_bin,/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor{icon_state = "white"},/area/rnd/lab)
"bUw" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plating,/area/storage/emergency)
"bUx" = (/obj/structure/rack{dir = 1},/obj/item/weapon/extinguisher,/obj/item/clothing/head/hardhat/red,/obj/item/device/flashlight,/turf/simulated/floor/plating,/area/maintenance/asmaint)
-"bUy" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
+"bUy" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/structure/disposalpipe/sortjunction/untagged{dir = 1},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
"bUz" = (/turf/simulated/floor{icon_state = "warnwhite"; dir = 1},/area/rnd/lab)
"bUA" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor{icon_state = "warnwhite"; dir = 1},/area/rnd/lab)
"bUB" = (/obj/structure/table,/obj/item/device/camera{name = "Autopsy Camera"; pixel_x = -2; pixel_y = 7},/obj/item/weapon/paper_bin{pixel_y = -6},/obj/item/weapon/pen/red{pixel_x = -1; pixel_y = -9},/obj/item/weapon/pen/blue{pixel_x = 3; pixel_y = -5},/turf/simulated/floor{dir = 9; icon_state = "blue"},/area/medical/morgue)
@@ -5133,19 +5133,19 @@
"bUK" = (/obj/machinery/atmospherics/valve,/turf/simulated/floor/plating,/area/maintenance/asmaint2)
"bUL" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor{dir = 8; icon_state = "browncorner"},/area/hallway/primary/central)
"bUM" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating/airless,/area)
-"bUN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/port)
-"bUO" = (/obj/structure/disposaloutlet{dir = 1},/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor/plating,/area/quartermaster/office)
+"bUN" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/wall,/area/quartermaster/storage)
+"bUO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/disposalpipe/junction{dir = 8},/turf/simulated/floor/plating,/area/maintenance/port)
"bUP" = (/obj/machinery/r_n_d/circuit_imprinter,/obj/item/weapon/reagent_containers/glass/beaker/sulphuric,/turf/simulated/floor,/area/rnd/lab)
"bUQ" = (/obj/structure/table/woodentable,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_x = -30; pixel_y = 0},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/item/device/megaphone,/turf/simulated/floor/wood,/area/crew_quarters/captain)
"bUR" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/wall/r_wall,/area/crew_quarters/captain)
-"bUS" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/sortjunction/untagged{dir = 1},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
+"bUS" = (/obj/structure/disposaloutlet{dir = 1},/obj/structure/disposalpipe/trunk,/turf/simulated/floor/plating,/area/quartermaster/office)
"bUT" = (/obj/effect/landmark/start{name = "Scientist"},/turf/simulated/floor,/area/rnd/lab)
"bUU" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{icon_state = "white"},/area/medical/sleeper)
"bUV" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/wall,/area/maintenance/disposal)
"bUW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/latexballon,/turf/simulated/floor/plating,/area/maintenance/port)
"bUX" = (/obj/item/weapon/table_parts,/turf/simulated/floor/plating,/area/construction)
"bUY" = (/obj/machinery/computer/rdconsole/core,/turf/simulated/floor,/area/rnd/lab)
-"bUZ" = (/obj/structure/closet/crate/medical,/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
+"bUZ" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
"bVa" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/hallway/primary/central)
"bVb" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/door/poddoor/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "medbayquar"; name = "Medbay Emergency Quarantine Shutters"; opacity = 0},/obj/machinery/door/firedoor,/turf/simulated/floor{dir = 4; icon_state = "loadingarea"; tag = "loading"},/area/medical/sleeper)
"bVc" = (/obj/machinery/conveyor{dir = 4; id = "packageExternal"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor{icon_state = "floorgrime"},/area/hallway/primary/central)
@@ -5322,14 +5322,14 @@
"bYr" = (/turf/simulated/wall/r_wall,/area/engine/engine_monitoring)
"bYs" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/grille,/turf/simulated/floor/plating,/area/engine/engine_airlock)
"bYt" = (/obj/machinery/door/airlock/maintenance_hatch{frequency = 1379; icon_state = "door_closed"; id_tag = "engine_airlock_exterior"; locked = 0; name = "Engine Airlock Exterior"; req_access_txt = "10"},/turf/simulated/floor/plating,/area/engine/engine_airlock)
-"bYu" = (/obj/structure/closet/crate,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
+"bYu" = (/obj/structure/closet/crate/internals,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
"bYv" = (/obj/structure/table/reinforced,/obj/machinery/light_switch{pixel_x = 27},/turf/simulated/floor,/area/engine/engine_monitoring)
"bYw" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/engine/engine_monitoring)
"bYx" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor,/area/engine/engine_monitoring)
"bYy" = (/obj/structure/grille,/obj/structure/grille,/turf/simulated/wall/r_wall,/area/atmos)
"bYz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/structure/closet/emcloset,/turf/simulated/floor/plating,/area/engine/engine_airlock)
"bYA" = (/obj/machinery/atmospherics/binary/dp_vent_pump/high_volume{dir = 8; frequency = 1379; id = "engine_airlock_pump"},/turf/simulated/floor/plating,/area/engine/engine_airlock)
-"bYB" = (/obj/item/stack/sheet/cardboard,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
+"bYB" = (/obj/structure/closet/crate/medical,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
"bYC" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/medical/virology)
"bYD" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/stool/bed/chair/office/dark,/obj/effect/landmark/start{name = "Station Engineer"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engine/engine_monitoring)
"bYE" = (/obj/structure/table/reinforced,/obj/machinery/door_control{desc = "A remote control-switch for the engine control room blast doors."; id = "EngineBlast"; name = "Engine Room Blast Doors"; pixel_x = 0; pixel_y = 0; req_access_txt = "10"},/turf/simulated/floor,/area/engine/engine_monitoring)
@@ -5562,7 +5562,7 @@
"ccX" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/atmos)
"ccY" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 30},/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/medical/virology)
"ccZ" = (/obj/machinery/door/firedoor/border_only{dir = 1; layer = 2.4; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Hallway"; req_one_access_txt = "11;24"},/turf/simulated/floor,/area/engine/hallway)
-"cda" = (/obj/machinery/camera{c_tag = "Cargo Bay Storage"; dir = 8; network = list("SS13")},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
+"cda" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating,/area/maintenance/port)
"cdb" = (/obj/machinery/door/firedoor/border_only{dir = 1; layer = 2.4; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Hallway"; req_one_access_txt = "11;24"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engine/hallway)
"cdc" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/wall/r_wall,/area/rnd/xenobiology)
"cdd" = (/turf/simulated/wall/r_wall,/area/engine/hallway)
@@ -5645,7 +5645,7 @@
"ceC" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/turf/simulated/floor,/area/engine/engine_airlock)
"ceD" = (/obj/structure/table,/obj/machinery/microwave{pixel_x = -2; pixel_y = 5},/turf/simulated/floor,/area/engine/engine_monitoring)
"ceE" = (/obj/machinery/atmospherics/unary/cryo_cell,/turf/simulated/floor{dir = 9; icon_state = "whitered"},/area/medical/cryo)
-"ceF" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/port)
+"ceF" = (/obj/item/stack/sheet/cardboard,/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
"ceG" = (/obj/machinery/light/small,/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/atmos)
"ceH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/engine/engine_hallway)
"ceI" = (/obj/machinery/light/small,/turf/simulated/floor/engine{name = "vacuum floor"; nitrogen = 0.01; oxygen = 0.01},/area/atmos)
@@ -5708,7 +5708,7 @@
"cfN" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor,/area/engine/engine_hallway)
"cfO" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/engine/engine_hallway)
"cfP" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/engine/engine_hallway)
-"cfQ" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
+"cfQ" = (/obj/machinery/camera{c_tag = "Cargo Bay Storage"; dir = 8; network = list("SS13")},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
"cfR" = (/turf/simulated/wall/r_wall,/area/engine/drone_fabrication)
"cfS" = (/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/obj/machinery/pipedispenser/disposal,/turf/simulated/floor,/area/atmos)
"cfT" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (NORTHWEST)"; icon_state = "intact"; dir = 9},/turf/simulated/floor,/area/atmos)
@@ -5775,7 +5775,7 @@
"chc" = (/obj/structure/lattice,/obj/structure/grille,/turf/space,/area)
"chd" = (/obj/structure/lattice,/obj/structure/grille{density = 0; icon_state = "brokengrille"},/turf/space,/area)
"che" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating/airless,/area/solar/port)
-"chf" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/junction{icon_state = "pipe-j2"; dir = 2},/turf/simulated/floor/plating,/area/maintenance/port)
+"chf" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
"chg" = (/obj/machinery/atmospherics/binary/pump{dir = 0; icon_state = "intact_on"; name = "Waste In"; on = 1},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/atmos)
"chh" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/engine/workshop)
"chi" = (/obj/structure/extinguisher_cabinet{pixel_x = 25},/turf/simulated/floor,/area/engine/workshop)
@@ -5874,7 +5874,7 @@
"ciX" = (/obj/machinery/atmospherics/binary/pump{dir = 4; icon_state = "intact_off"; name = "O2 to Pure"; on = 0},/turf/simulated/floor,/area/atmos)
"ciY" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{tag = "icon-intact (SOUTHEAST)"; icon_state = "intact"; dir = 6},/obj/machinery/meter,/turf/simulated/floor,/area/atmos)
"ciZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/turf/simulated/floor/plating,/area/maintenance/asmaint)
-"cja" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/disposalpipe/tagger/partial{name = "Sorting Office"; sort_tag = "Disposals"},/turf/simulated/floor,/area/quartermaster/office)
+"cja" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/tagger/partial{name = "Sorting Office"; sort_tag = "Sorting Office"},/turf/simulated/floor/plating,/area/maintenance/port)
"cjb" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/atmos)
"cjc" = (/turf/simulated/floor{icon_state = "yellowfull"; dir = 8},/area/crew_quarters/sleep/engi)
"cjd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/floor,/area/atmos)
@@ -7029,7 +7029,7 @@
"cFi" = (/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start)
"cFj" = (/obj/machinery/door/window{dir = 4; name = "Infirmary"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start)
"cFk" = (/obj/machinery/door/window/westright{name = "Tool Storage"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start)
-"cFl" = (/obj/structure/table,/obj/item/weapon/storage/toolbox/syndicate,/obj/effect/spawner/newbomb/timer/syndicate,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start)
+"cFl" = (/obj/structure/disposalpipe/tagger/partial{name = "Sorting Office"; sort_tag = "Sorting Office"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/turf/simulated/floor,/area/quartermaster/office)
"cFm" = (/obj/machinery/door/window{base_state = "right"; dir = 4; icon_state = "right"; name = "Infirmary"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start)
"cFn" = (/obj/machinery/door/window{dir = 8; name = "Tool Storage"; req_access_txt = "150"},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start)
"cFo" = (/obj/structure/closet/crate/medical,/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/storage/firstaid/o2,/obj/item/weapon/storage/firstaid/regular,/obj/item/weapon/storage/firstaid/toxin,/obj/item/weapon/storage/firstaid/adv,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/syndicate_station/start)
@@ -7093,8 +7093,8 @@
"cGu" = (/obj/structure/table/reinforced{icon_state = "reinf_tabledir"},/obj/item/weapon/lighter/zippo,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom)
"cGv" = (/obj/structure/table/reinforced{icon_state = "reinf_tabledir"},/obj/item/weapon/storage/fancy/cigarettes,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom)
"cGw" = (/obj/machinery/door/airlock/glass,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom)
-"cGx" = (/obj/item/stack/sheet/glass{amount = 5000},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom)
-"cGy" = (/obj/item/stack/sheet/metal{amount = 5000},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom)
+"cGx" = (/obj/item/weapon/inflatable_duck,/turf/simulated/floor/beach/sand{tag = "icon-desert1"; icon_state = "desert1"},/area/holodeck/source_beach)
+"cGy" = (/obj/item/stack/sheet/glass{amount = 50},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom)
"cGz" = (/obj/structure/table,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/living)
"cGA" = (/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/living)
"cGB" = (/obj/structure/closet/secure_closet/personal,/turf/unsimulated/floor{icon_state = "carpet"; dir = 2},/area/centcom/living)
@@ -7361,7 +7361,7 @@
"cLC" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/belt/security,/obj/item/weapon/storage/belt/security,/obj/item/weapon/storage/belt/security,/obj/item/device/flash,/obj/item/device/flash,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/baton,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom)
"cLD" = (/obj/structure/table/reinforced,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/obj/item/weapon/gun/energy/gun/nuclear,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom)
"cLE" = (/obj/structure/rack,/obj/item/clothing/head/helmet/space/rig/ert/engineer,/obj/item/clothing/suit/space/rig/ert/engineer,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/head/helmet/space/rig/ert/engineer,/obj/item/clothing/suit/space/rig/ert/engineer,/obj/item/clothing/tie/storage/brown_vest,/obj/item/clothing/head/helmet/space/rig/ert/engineer,/obj/item/clothing/suit/space/rig/ert/engineer,/obj/item/clothing/tie/storage/brown_vest,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom)
-"cLF" = (/obj/structure/table/reinforced,/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/sheet/plasteel{amount = 50},/obj/item/stack/sheet/plasteel{amount = 50},/turf/unsimulated/floor{icon_state = "dark"},/area/centcom)
+"cLF" = (/obj/item/stack/sheet/metal{amount = 50},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/administration/centcom)
"cLG" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/unsimulated/floor{icon_state = "vault"; dir = 1},/area/centcom)
"cLH" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops)
"cLI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/unsimulated/floor{name = "plating"},/area/centcom/specops)
@@ -7525,7 +7525,7 @@
"cOK" = (/turf/unsimulated/beach/sand{tag = "icon-seashallow"; icon_state = "seashallow"},/area/centcom/ferry)
"cOL" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "engine_sensor"; output = 63},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/engine/engine_room)
"cOM" = (/obj/structure/stool/bed/chair{dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom)
-"cON" = (/obj/machinery/computer/shuttle_control/emergency,/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom)
+"cON" = (/obj/structure/table,/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/toolbox/syndicate{pixel_x = -3; pixel_y = -3},/obj/effect/spawner/newbomb/timer/syndicate,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/syndicate_station/start)
"cOO" = (/turf/unsimulated/beach/sand{tag = "icon-beachcorner"; icon_state = "beachcorner"},/area/centcom/ferry)
"cOP" = (/turf/unsimulated/beach/sand{tag = "icon-beach (SOUTHEAST)"; icon_state = "beach"; dir = 6},/area/centcom/ferry)
"cOQ" = (/obj/structure/shuttle/engine/propulsion{icon_state = "burst_r"; dir = 4},/turf/space,/area/shuttle/specops/centcom)
@@ -8451,7 +8451,7 @@
"dgA" = (/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "vox_east_vent"; tag_exterior_door = "vox_northeast_lock"; frequency = 1331; id_tag = "vox_east_control"; tag_interior_door = "vox_southeast_lock"; pixel_x = -24; req_access_txt = "150"; tag_chamber_sensor = "vox_east_sensor"},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1331; id_tag = "vox_east_vent"},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station)
"dgB" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 4},/turf/simulated/shuttle/plating/vox,/area/shuttle/vox/station)
"dgC" = (/obj/machinery/body_scanconsole{known_implants = list(/obj/item/weapon/implant/cortical)},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station)
-"dgD" = (/obj/machinery/atmospherics/pipe/tank/nitrogen,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station)
+"dgD" = (/turf/unsimulated/beach/sand{tag = "icon-desert"; icon_state = "desert"},/obj/item/weapon/inflatable_duck,/turf/unsimulated/floor{tag = "icon-siding4"; name = "plating"; icon_state = "siding4"},/area/centcom/holding)
"dgE" = (/obj/machinery/sleep_console,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station)
"dgF" = (/obj/machinery/bodyscanner,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station)
"dgG" = (/obj/machinery/sleeper,/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station)
@@ -8688,7 +8688,7 @@
"dld" = (/obj/machinery/light/small{dir = 1},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 1},/area/mine/explored)
"dle" = (/obj/structure/dispenser,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plating,/area/research_outpost/maintstore2)
"dlf" = (/obj/machinery/mineral/input,/turf/simulated/floor{dir = 2; icon_state = "loadingarea"},/area/research_outpost/tempstorage)
-"dlg" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/airlock/glass_mining{name = "Expedition Prep"; req_access_txt = "65"},/obj/machinery/door/firedoor/border_only{dir = 4; layer = 2.6; name = "Firelock"},/turf/space,/area/research_outpost/entry)
+"dlg" = (/obj/item/weapon/inflatable_duck,/turf/unsimulated/beach/sand{tag = "icon-desert"; icon_state = "desert"},/area/centcom/ferry)
"dlh" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/turf/simulated/floor{dir = 5; icon_state = "warning"},/area/research_outpost/tempstorage)
"dli" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor,/area/research_outpost/tempstorage)
"dlj" = (/obj/structure/sign/science{desc = "A warning sign which reads 'ANOMALOUS MATERIALS'"; name = "\improper ANOMALOUS MATERIALS"; pixel_x = 32},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/research_outpost/hallway)
@@ -8717,7 +8717,7 @@
"dlG" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/obj/machinery/firealarm{pixel_y = -24},/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway)
"dlH" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/sample)
"dlI" = (/obj/machinery/door/airlock/research{name = "Sample Preparation"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only{dir = 4; layer = 2.6; name = "Firelock"},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway)
-"dlJ" = (/obj/machinery/door/airlock/atmos{name = "Outpost Atmospherics"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/firedoor/border_only{dir = 4; layer = 2.6; name = "Firelock"},/turf/simulated/floor/plating,/area/research_outpost/hallway)
+"dlJ" = (/obj/structure/table/reinforced,/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/glass{amount = 50},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/sheet/metal{amount = 50; pixel_x = 2; pixel_y = 2},/obj/item/stack/sheet/plasteel{amount = 50},/obj/item/stack/sheet/plasteel{amount = 50},/obj/item/weapon/storage/briefcase/inflatable{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/briefcase/inflatable,/turf/unsimulated/floor{icon_state = "dark"},/area/centcom)
"dlK" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump{dir = 2; layer = 2.4; on = 1},/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor{dir = 6; icon_state = "whitegreen"},/area/research_outpost/spectro)
"dlL" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_Toxins = 0},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/research_outpost/hallway)
"dlM" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 1},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/research_outpost/hallway)
@@ -8826,16 +8826,58 @@
"dnL" = (/obj/machinery/embedded_controller/radio/simple_docking_controller{frequency = 1380; id_tag = "supply_shuttle"; pixel_x = 25; pixel_y = 0; req_access_txt = "0"; req_one_access_txt = "13;31"; tag_door = "supply_shuttle_hatch"},/turf/simulated/shuttle/floor,/area/supply/dock)
"dnM" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad2"},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "supply_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access_txt = "13"},/turf/simulated/shuttle/plating,/area/supply/dock)
"dnN" = (/obj/machinery/conveyor{dir = 4; id = "QMLoad"},/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "supply_shuttle_hatch"; locked = 1; name = "Shuttle Hatch"; req_access_txt = "13"},/turf/simulated/shuttle/plating,/area/supply/dock)
-"dqx" = (/turf/simulated/floor/plating/airless/asteroid,/area)
+"dnO" = (/obj/machinery/computer/shuttle_control/emergency,/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom)
+"dnP" = (/obj/machinery/atmospherics/pipe/tank/nitrogen{dir = 1; initialize_directions = 1},/turf/simulated/shuttle/floor4/vox,/area/shuttle/vox/station)
+"dnQ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/airlock/glass_mining{name = "Expedition Prep"; req_access_txt = "65"},/obj/machinery/door/firedoor/border_only{dir = 4; layer = 2.6; name = "Firelock"},/turf/simulated/floor,/area/research_outpost/entry)
+"dnR" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/window/westleft{base_state = "right"; dir = 1; icon_state = "right"},/obj/machinery/door/window/westleft{dir = 2},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/longtermstorage)
+"dnS" = (/obj/structure/transit_tube{icon_state = "N-S"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored)
+"dnT" = (/obj/machinery/mass_driver{dir = 4; id = "research"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored)
+"dnU" = (/obj/structure/transit_tube{icon_state = "N-S"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored)
+"dnV" = (/obj/structure/disposaloutlet{dir = 2},/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored)
+"dnW" = (/obj/structure/sign/deathsposal{pixel_x = 32},/obj/machinery/disposal/deliveryChute{dir = 8; name = "disposal inlet"},/obj/structure/disposalpipe/trunk{dir = 4},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplate"; nitrogen = 0.01; oxygen = 0.01},/area/research_outpost/power)
+"dnX" = (/obj/machinery/driver_button{id = "research"; pixel_x = 6; pixel_y = -26},/obj/machinery/conveyor{dir = 4; id = "archgunc"},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/window/westleft{base_state = "right"; dir = 1; icon_state = "right"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 9},/area/research_outpost/power)
+"dnY" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/research_outpost/power)
+"dnZ" = (/obj/machinery/atmospherics/trinary/filter{dir = 4; filter_type = 1; icon_state = "intact_on"; name = "Gas filter (O2 tank)"; on = 1; target_pressure = 4500},/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"doa" = (/obj/machinery/atmospherics/tvalve/digital{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"dob" = (/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/obj/machinery/meter,/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"doc" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/trinary/filter{dir = 4; filter_type = 2; icon_state = "intact_on"; name = "Gas filter (N2 tank)"; on = 1; target_pressure = 4500},/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"dod" = (/obj/machinery/atmospherics/portables_connector{dir = 2; name = "Connector Port (Air Supply)"},/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"doe" = (/obj/structure/sign/nosmoking_1{pixel_x = -32},/obj/machinery/atmospherics/pipe/simple/visible/supply{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/obj/machinery/meter,/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"dof" = (/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/obj/machinery/atmospherics/pipe/tank/air{dir = 8; volume = 4000},/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"dog" = (/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister,/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"doh" = (/obj/machinery/atmospherics/trinary/mixer{dir = 2; icon_state = "intact_on"; name = "Gas mixer (N2/O2)"; node1_concentration = 0.8; node2_concentration = 0.2; on = 1; pixel_x = 0; pixel_y = 0; req_access = null; target_pressure = 4500},/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"doi" = (/obj/machinery/atmospherics/pipe/manifold/visible/supply{tag = "icon-manifold (WEST)"; icon_state = "manifold"; dir = 8},/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"doj" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible/supply,/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"dok" = (/obj/machinery/atmospherics/binary/pump{dir = 2; icon_state = "intact_off"; name = "Port to Air"; on = 0},/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"dol" = (/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"dom" = (/obj/machinery/atmospherics/binary/pump{dir = 2; icon_state = "intact_on"; name = "Filter to Waste"; on = 1; target_pressure = 4500},/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"don" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers,/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway)
+"doo" = (/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_Toxins = 0},/obj/machinery/atmospherics/pipe/simple/visible/supply,/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"dop" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/machinery/atmospherics/binary/pump{dir = 8; icon_state = "intact_on"; name = "Air to Distro"; on = 1; target_pressure = 285},/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"doq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/firedoor/border_only{dir = 4; layer = 2.6; name = "Firelock"},/obj/machinery/meter,/obj/machinery/door/airlock/atmos{name = "Outpost Atmospherics"; req_access_txt = "0"; req_one_access_txt = "65;10;24"},/turf/simulated/floor/plating,/area/research_outpost/hallway)
+"dor" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored)
+"dos" = (/obj/structure/transit_tube{icon_state = "N-SW"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored)
+"dot" = (/obj/structure/sign/fire{pixel_x = 32},/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/obj/machinery/atmospherics/pipe/tank/air{dir = 8; volume = 4000},/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"dou" = (/obj/machinery/light/small,/obj/machinery/atmospherics/pipe/manifold/visible/supply,/obj/machinery/meter,/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"dov" = (/obj/machinery/atmospherics/pipe/manifold/visible/supply,/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"dow" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"dox" = (/obj/machinery/atmospherics/pipe/manifold/visible/supply{tag = "icon-manifold (WEST)"; icon_state = "manifold"; dir = 8},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; layer = 2.4; level = 2; on = 1},/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"doy" = (/obj/machinery/atmospherics/unary/cold_sink/freezer{dir = 4; icon_state = "freezer"; on = 1},/turf/simulated/floor/plating,/area/research_outpost/atmos)
+"doz" = (/obj/structure/transit_tube{icon_state = "N-S"},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored)
+"doA" = (/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/structure/transit_tube{icon_state = "S-NE"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/explored)
+"doB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/transit_tube{icon_state = "D-NW"},/turf/simulated/mineral,/area/mine/explored)
+"doC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/mineral,/area/mine/explored)
+"doD" = (/obj/structure/transit_tube{icon_state = "W-SE"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored)
+"doE" = (/obj/machinery/light/small,/obj/structure/transit_tube,/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored)
+"doF" = (/obj/structure/transit_tube{icon_state = "E-SW"},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating/airless/asteroid,/area/research_outpost/hallway)
+"doG" = (/obj/structure/transit_tube,/turf/simulated/floor/plating/airless/asteroid,/area/research_outpost/hallway)
+"doH" = (/obj/structure/transit_tube,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating/airless/asteroid,/area/research_outpost/hallway)
+"doI" = (/obj/structure/rack,/obj/item/stack/sheet/metal{amount = 50; pixel_x = 5; pixel_y = 5},/obj/item/stack/sheet/glass{amount = 50},/obj/item/weapon/storage/belt/utility{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/toolbox/mechanical,/obj/item/weapon/storage/toolbox/emergency{pixel_x = 5; pixel_y = 5},/turf/simulated/floor/plating,/area/research_outpost/maintstore1)
"dqT" = (/turf/simulated/mineral,/area/mine/unexplored)
"dqU" = (/turf/space,/area/syndicate_station/mining)
"dqV" = (/obj/structure/transit_tube{icon_state = "D-SE"},/obj/structure/lattice,/turf/space,/area)
"dqW" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "E-SW"},/turf/space,/area)
"dqX" = (/obj/structure/lattice,/obj/structure/transit_tube,/turf/space,/area)
-"dqY" = (/obj/structure/transit_tube,/turf/simulated/floor/plating/airless/asteroid,/area)
-"dqZ" = (/obj/machinery/light/small,/obj/structure/transit_tube,/turf/simulated/floor/plating/airless/asteroid,/area/research_outpost/maintstore1)
-"dra" = (/obj/structure/transit_tube,/turf/simulated/floor/plating/airless/asteroid,/area/research_outpost/maintstore1)
-"drb" = (/obj/structure/transit_tube{icon_state = "W-SE"},/turf/simulated/floor/plating/airless/asteroid,/area/research_outpost/maintstore1)
"drc" = (/obj/structure/transit_tube{icon_state = "D-SW"},/turf/simulated/mineral,/area/mine/unexplored)
"drd" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway)
"dre" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway)
@@ -8846,9 +8888,7 @@
"drj" = (/obj/structure/transit_tube{icon_state = "D-NE"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1)
"drk" = (/obj/structure/transit_tube{icon_state = "NW-SE"},/turf/simulated/wall/r_wall,/area/research_outpost/maintstore1)
"drl" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/mineral,/area/mine/unexplored)
-"drm" = (/obj/structure/transit_tube{icon_state = "E-SW"},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored)
"drn" = (/obj/structure/transit_tube,/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored)
-"dro" = (/obj/structure/transit_tube,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored)
"drp" = (/obj/structure/transit_tube/station,/turf/simulated/floor{icon_state = "bot"; dir = 1},/area/research_outpost/hallway)
"drq" = (/obj/structure/transit_tube,/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/research_outpost/hallway)
"drr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/transit_tube,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/hallway)
@@ -8870,7 +8910,6 @@
"drH" = (/obj/structure/transit_tube{icon_state = "NW-SE"},/obj/structure/lattice,/turf/space,/area)
"drI" = (/obj/structure/lattice,/obj/structure/transit_tube{icon_state = "N-S"},/turf/space,/area)
"drJ" = (/turf/simulated/wall/r_wall,/area/research_outpost/spectro)
-"drK" = (/obj/structure/rack,/obj/item/stack/sheet/metal{pixel_x = 5; pixel_y = 5},/obj/item/stack/sheet/glass,/obj/item/weapon/storage/belt/utility{pixel_x = 3; pixel_y = 3},/obj/item/weapon/storage/toolbox/mechanical,/obj/item/weapon/storage/toolbox/emergency{pixel_x = 5; pixel_y = 5},/turf/simulated/floor/plating,/area/research_outpost/maintstore1)
"drL" = (/turf/simulated/floor/plating,/area/research_outpost/maintstore1)
"drM" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor/plating,/area/research_outpost/maintstore1)
"drN" = (/turf/simulated/wall,/area/research_outpost/maintstore1)
@@ -8930,9 +8969,6 @@
"dsQ" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply{req_access_txt = "0"},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomsat)
"dsR" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/lattice,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/space,/area/turret_protected/tcomsat)
"dsS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/turret_protected/tcomsat)
-"dsT" = (/obj/machinery/atmospherics/trinary/filter{dir = 4; filter_type = 2; icon_state = "intact_on"; name = "Gas filter (N2 tank)"; on = 1},/turf/simulated/floor/plating,/area/research_outpost/atmos)
-"dsU" = (/obj/machinery/atmospherics/trinary/filter{dir = 4; filter_type = 1; icon_state = "intact_on"; name = "Gas filter (O2 tank)"; on = 1},/obj/machinery/light/small{dir = 1},/turf/simulated/floor/plating,/area/research_outpost/atmos)
-"dsW" = (/obj/machinery/atmospherics/portables_connector{dir = 8},/obj/machinery/portable_atmospherics/canister,/turf/simulated/floor/plating,/area/research_outpost/atmos)
"dsX" = (/obj/structure/window/reinforced{dir = 8},/obj/machinery/light/small{dir = 1},/turf/simulated/floor,/area/research_outpost/atmos)
"dsY" = (/obj/structure/transit_tube{icon_state = "N-S"},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/research_outpost/atmos)
"dsZ" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/atmos)
@@ -8975,7 +9011,6 @@
"dtL" = (/obj/structure/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomsat)
"dtM" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomsat)
"dtN" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/turret_protected/tcomfoyer)
-"dtO" = (/obj/machinery/atmospherics/unary/heat_reservoir/heater{dir = 4},/obj/structure/sign/nosmoking_1{pixel_x = -32},/turf/simulated/floor/plating,/area/research_outpost/atmos)
"dtP" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/turret_protected/tcomfoyer)
"dtQ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/turf/simulated/floor,/area/turret_protected/tcomfoyer)
"dtR" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/turf/simulated/floor,/area/research_outpost/atmos)
@@ -9002,11 +9037,9 @@
"duo" = (/obj/machinery/conveyor{dir = 1; id = "anolaser"},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/research_outpost/anomaly)
"dup" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/airlock/hatch{name = "Telecoms East Wing"; req_access_txt = "61"},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/turret_protected/tcomfoyer)
"duq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor,/area/turret_protected/tcomfoyer)
-"dur" = (/obj/machinery/atmospherics/unary/cold_sink/freezer{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/atmos)
"dus" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor{icon_state = "warningcorner"; dir = 8},/area/turret_protected/tcomfoyer)
"dut" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/turretid{ailock = 1; control_area = "\improper Telecoms Satellite"; desc = "A firewall prevents AIs from interacting with this device."; icon_state = "motion1"; lethal = 1; name = "Telecoms lethal turret control"; pixel_y = 29; req_access = list(61)},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/camera{c_tag = "Telecoms Foyer"; dir = 2; network = list("Tcomsat")},/turf/simulated/floor{dir = 1; icon_state = "warning"},/area/turret_protected/tcomfoyer)
"duu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/transit_tube{icon_state = "N-S"},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/atmos)
-"duv" = (/obj/structure/window/reinforced{dir = 4},/obj/structure/grille,/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area)
"duw" = (/obj/structure/shuttle/engine/propulsion{icon_state = "propulsion"; dir = 4},/obj/structure/window/reinforced/tinted{dir = 4; icon_state = "twindow"},/turf/simulated/floor/plating/airless,/area/shuttle/alien/mine)
"dux" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/alien/mine)
"duy" = (/obj/effect/alien/weeds{icon_state = "weeds"},/turf/simulated/shuttle/floor{icon_state = "floor2"},/area/shuttle/alien/mine)
@@ -9033,8 +9066,6 @@
"duT" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "research_inner"; locked = 1; name = "Research Outpost External Access"; req_access = null; req_access_txt = null},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor,/area/research_outpost/gearstore)
"duV" = (/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact-f (NORTHEAST)"; icon_state = "intact-f"; dir = 5},/turf/simulated/wall,/area/research_outpost/gearstore)
"duW" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{tag = "icon-intact-f (NORTHWEST)"; icon_state = "intact-f"; dir = 9},/turf/simulated/wall/r_wall,/area/research_outpost/iso1)
-"duX" = (/obj/structure/transit_tube{icon_state = "N-S"},/turf/simulated/floor/plating/airless/asteroid,/area/research_outpost/atmos)
-"duY" = (/turf/simulated/mineral,/area/research_outpost/atmos)
"duZ" = (/turf/space,/turf/simulated/shuttle/wall{icon_state = "pwall"; dir = 5},/area/shuttle/alien/mine)
"dva" = (/turf/simulated/floor/plating,/turf/simulated/shuttle/wall{icon_state = "pwall"; dir = 6},/area/shuttle/alien/mine)
"dvb" = (/obj/item/weapon/shard,/turf/simulated/floor/airless{icon_state = "floorscorched1"},/area/mine/abandoned)
@@ -9096,7 +9127,6 @@
"dwh" = (/obj/machinery/power/port_gen/pacman{anchored = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/sign/nosmoking_1{pixel_y = 32},/turf/simulated/floor/plating,/area/research_outpost/power)
"dwi" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/door/airlock/glass_mining{name = "Loading area"; req_access_txt = "65"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door/firedoor/border_only{dir = 4; layer = 2.6; name = "Firelock"},/turf/simulated/floor,/area/research_outpost/tempstorage)
"dwj" = (/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = 30},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/turf/simulated/floor,/area/research_outpost/gearstore)
-"dwk" = (/obj/structure/transit_tube{icon_state = "N-S"},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating/airless/asteroid,/area/research_outpost/atmos)
"dwl" = (/obj/structure/lattice,/obj/item/weapon/shard{icon_state = "medium"},/turf/space,/area)
"dwm" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/mine/abandoned)
"dwn" = (/obj/effect/alien/weeds{icon_state = "weeds2"},/obj/item/clothing/mask/facehugger{icon_state = "facehugger_dead"; stat = 2},/turf/simulated/floor/airless{icon_state = "damaged2"},/area/mine/abandoned)
@@ -9123,9 +9153,6 @@
"dwK" = (/obj/machinery/power/terminal{dir = 4},/obj/structure/cable,/turf/simulated/floor/plating,/area/research_outpost/power)
"dwL" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 100; on = 1; pressure_checks = 1},/turf/simulated/floor,/area/research_outpost/iso1)
"dwM" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/wall/r_wall,/area/research_outpost/power)
-"dwN" = (/obj/structure/transit_tube{icon_state = "N-S"},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating/airless/asteroid,/area/research_outpost/power)
-"dwO" = (/obj/structure/disposaloutlet{dir = 2},/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor/plating/airless/asteroid,/area/research_outpost/power)
-"dwP" = (/turf/simulated/mineral,/area/research_outpost/power)
"dwQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/mine/abandoned)
"dwR" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/turf/simulated/floor/plating/airless,/area/mine/abandoned)
"dwS" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating/airless,/area/mine/abandoned)
@@ -9147,9 +9174,6 @@
"dxi" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/research_outpost/power)
"dxj" = (/obj/machinery/portable_atmospherics/scrubber,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/research_outpost/power)
"dxk" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/research_outpost/power)
-"dxl" = (/obj/structure/transit_tube{icon_state = "N-S"},/turf/simulated/floor/plating/airless/asteroid,/area/research_outpost/power)
-"dxm" = (/obj/machinery/mass_driver{dir = 4; id = "research"},/turf/simulated/floor/plating/airless/asteroid,/area/research_outpost/power)
-"dxn" = (/turf/simulated/floor/plating/airless/asteroid,/area/research_outpost/power)
"dxo" = (/obj/item/stack/rods,/obj/structure/lattice,/turf/space,/area)
"dxp" = (/obj/item/weapon/shard,/obj/item/stack/rods,/turf/simulated/floor/plating/airless,/area/mine/abandoned)
"dxq" = (/turf/simulated/floor/plating/airless,/area/mine/abandoned)
@@ -9206,8 +9230,6 @@
"dys" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/structure/sign/science{desc = "A warning sign which reads 'ANOMALOUS MATERIALS'"; name = "\improper ANOMALOUS MATERIALS"; pixel_x = -32},/turf/simulated/floor{dir = 1; icon_state = "whitepurplecorner"},/area/research_outpost/hallway)
"dyv" = (/obj/machinery/power/smes{charge = 5e+006},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{d2 = 2; icon_state = "0-2"; pixel_y = 0},/obj/structure/cable,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/cable,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/power)
"dyw" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_Toxins = 0},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/research_outpost/power)
-"dyx" = (/obj/machinery/driver_button{id = "research"; pixel_x = 6; pixel_y = -26},/obj/machinery/conveyor{dir = 4; id = "archgunc"},/turf/simulated/floor/plating,/area/research_outpost/power)
-"dyy" = (/obj/structure/sign/deathsposal{pixel_x = 32},/obj/machinery/disposal/deliveryChute{dir = 8; name = "disposal inlet"},/obj/structure/disposalpipe/trunk{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/power)
"dyz" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/wall/r_wall,/area/research_outpost/power)
"dyA" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/transit_tube{icon_state = "N-SE"},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/hallway)
"dyB" = (/obj/structure/transit_tube{icon_state = "D-SW"},/turf/simulated/wall/r_wall,/area/research_outpost/hallway)
@@ -9232,7 +9254,6 @@
"dyX" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/research_outpost/tempstorage)
"dyY" = (/obj/structure/cable,/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/turf/simulated/floor/plating,/area/research_outpost/maint)
"dyZ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway)
-"dza" = (/obj/machinery/portable_atmospherics/canister/nitrogen,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/power)
"dzb" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/closet/secure_closet/xenoarchaeologist{req_access_txt = "47"},/obj/structure/window/reinforced,/turf/simulated/floor,/area/research_outpost/hallway)
"dzc" = (/obj/structure/closet/secure_closet/xenoarchaeologist{req_access_txt = "47"},/obj/structure/disposalpipe/segment,/obj/structure/window/reinforced,/turf/simulated/floor,/area/research_outpost/hallway)
"dzd" = (/obj/structure/closet/secure_closet/scientist,/obj/structure/window/reinforced,/turf/simulated/floor,/area/research_outpost/hallway)
@@ -9409,7 +9430,6 @@
"dCG" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_Toxins = 1},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/alarm/isolation{pixel_y = 24},/turf/simulated/floor,/area/research_outpost/iso3)
"dCH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plating,/area/research_outpost/maintstore2)
"dCI" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/research_outpost/harvesting)
-"dCJ" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/longtermstorage)
"dCK" = (/turf/simulated/wall/r_wall,/area/research_outpost/longtermstorage)
"dCL" = (/obj/structure/sign/nosmoking_2{pixel_y = -32},/obj/machinery/camera{c_tag = "Research Outpost Exotic Particles Lab"; dir = 4; network = list("Research","SS13")},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/research_outpost/harvesting)
"dCM" = (/obj/machinery/alarm{dir = 1; pixel_y = -24},/turf/simulated/floor{icon_state = "vault"; dir = 8},/area/research_outpost/harvesting)
@@ -9453,11 +9473,8 @@
"dDy" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway)
"dDz" = (/obj/machinery/camera{c_tag = "Research Outpost Anomalous Materials Lab"; dir = 8; network = list("Research","SS13")},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/anomaly)
"dDA" = (/obj/machinery/door/airlock/research{name = "Anomalous Materials Loading"; req_access_txt = "65"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only{dir = 4; layer = 2.6; name = "Firelock"},/turf/simulated/floor,/area/research_outpost/anomaly)
-"dDB" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 8},/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/turf/simulated/floor/plating,/area/research_outpost/atmos)
"dDC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/cable,/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/hallway)
"dDD" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; icon_state = "off"; on = 0; scrub_N2O = 0; scrub_Toxins = 0},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plating,/area/research_outpost/maintstore2)
-"dDE" = (/obj/machinery/atmospherics/pipe/manifold/visible/supply{tag = "icon-manifold (EAST)"; icon_state = "manifold"; dir = 4},/turf/simulated/floor/plating,/area/research_outpost/atmos)
-"dDF" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; level = 2; on = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/visible/supply{tag = "icon-intact (SOUTHEAST)"; icon_state = "intact"; dir = 6},/turf/simulated/floor/plating,/area/research_outpost/atmos)
"dDG" = (/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_Toxins = 0},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/longtermstorage)
"dDH" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/turf/simulated/floor,/area/research_outpost/harvesting)
"dDI" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/light/small{dir = 1},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/longtermstorage)
@@ -9472,9 +9489,7 @@
"dDR" = (/obj/structure/transit_tube{icon_state = "N-S"},/turf/simulated/wall,/area/mine/explored)
"dDS" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; icon_state = "off"; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor,/area/research_outpost/gearstore)
"dDT" = (/obj/structure/cable,/obj/structure/table,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/item/weapon/storage/toolbox/mechanical,/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/turf/simulated/floor{dir = 2; icon_state = "cmo"},/area/research_outpost/entry)
-"dDU" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/visible/scrubbers{tag = "icon-manifold (WEST)"; icon_state = "manifold"; dir = 8},/turf/simulated/floor/plating,/area/research_outpost/atmos)
"dDV" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_Toxins = 0},/turf/simulated/floor,/area/research_outpost/gearstore)
-"dDW" = (/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/simulated/floor/plating,/area/research_outpost/atmos)
"dDX" = (/obj/structure/cable,/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/med)
"dDY" = (/turf/simulated/wall,/area/research_outpost/tempstorage)
"dEa" = (/obj/machinery/conveyor{dir = 1; id = "anosample"},/obj/structure/plasticflaps/mining,/turf/simulated/floor/plating,/area/research_outpost/maint)
@@ -9484,7 +9499,6 @@
"dEf" = (/obj/machinery/door/airlock{id_tag = "rbath"; name = "Bathroom"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 4; layer = 2.6; name = "Firelock"},/turf/simulated/floor{icon_state = "showroomfloor"},/area/research_outpost/hallway)
"dEg" = (/obj/machinery/door_control{id = "rbath"; name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 0; pixel_y = -25; req_access_txt = "0"; specialfunctions = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "showroomfloor"},/area/research_outpost/hallway)
"dEh" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; layer = 2.4; on = 1},/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plating,/area/research_outpost/maintstore2)
-"dEi" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway)
"dEj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway)
"dEk" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/longtermstorage)
"dEl" = (/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/longtermstorage)
@@ -9501,7 +9515,6 @@
"dEw" = (/obj/structure/transit_tube{icon_state = "N-S"},/turf/simulated/floor{icon_state = "delivery"; name = "floor"},/area/mine/explored)
"dEx" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/lattice,/turf/space,/area)
"dEy" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 4; layer = 2.4; on = 1},/turf/simulated/floor,/area/research_outpost/gearstore)
-"dEz" = (/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/pipe/simple/visible/supply{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor/plating,/area/research_outpost/atmos)
"dEA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/research_outpost/maintstore1)
"dEB" = (/obj/machinery/hydroponics/soil,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/floor/grass,/area/research_outpost/maintstore1)
"dEC" = (/turf/simulated/floor,/area/research_outpost/gearstore)
@@ -9511,12 +9524,8 @@
"dEI" = (/obj/machinery/conveyor{dir = 1; id = "anosample"},/turf/simulated/floor/airless{icon_state = "asteroidwarning"; dir = 1},/area/mine/explored)
"dEJ" = (/obj/machinery/atmospherics/binary/pump{dir = 4},/turf/simulated/floor/plating,/area/research_outpost/maint)
"dEK" = (/obj/machinery/artifact_analyser,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/bluegrid,/area/research_outpost/anomaly)
-"dEN" = (/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/visible/supply{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/plating,/area/research_outpost/atmos)
"dEP" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor{dir = 4; icon_state = "whiteyellow"},/area/research_outpost/hallway)
"dEQ" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor{icon_state = "cafeteria"; dir = 2},/area/research_outpost/hallway)
-"dER" = (/obj/structure/sign/fire{pixel_x = 32},/obj/machinery/atmospherics/pipe/tank/air{dir = 8},/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/obj/machinery/atmospherics/pipe/simple/visible/scrubbers,/turf/simulated/floor/plating,/area/research_outpost/atmos)
-"dES" = (/obj/machinery/light/small,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/visible/supply,/turf/simulated/floor/plating,/area/research_outpost/atmos)
-"dET" = (/obj/machinery/meter,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/manifold/visible/supply,/turf/simulated/floor/plating,/area/research_outpost/atmos)
"dEU" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/wall/r_wall,/area/research_outpost/spectro)
"dEV" = (/obj/machinery/camera{c_tag = "Isolation Room Three"; dir = 8; network = list("Anomaly Isolation")},/turf/simulated/floor{dir = 2; icon_state = "warning"},/area/research_outpost/iso3)
"dEW" = (/obj/structure/closet/walllocker/emerglocker/west,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/turf/simulated/floor/plating,/area/research_outpost/maintstore2)
@@ -9543,7 +9552,6 @@
"dFs" = (/obj/machinery/conveyor{dir = 1; id = "anosample"},/turf/simulated/floor/plating/airless{icon_state = "asteroidplating"},/area/mine/explored)
"dFt" = (/obj/machinery/door/airlock/research{name = "Spectrometry Lab"; req_access_txt = "65"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/door/firedoor/border_only{dir = 4; layer = 2.6; name = "Firelock"},/turf/simulated/floor{icon_state = "white"},/area/research_outpost/spectro)
"dFu" = (/obj/machinery/atmospherics/pipe/manifold4w/visible/supply,/turf/simulated/floor/plating,/area/research_outpost/atmos)
-"dFv" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; layer = 2.4; level = 2; on = 1},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/manifold/visible/supply{tag = "icon-manifold (WEST)"; icon_state = "manifold"; dir = 8},/turf/simulated/floor/plating,/area/research_outpost/atmos)
"dFw" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 0},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/iso1)
"dFx" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 0; scrub_CO2 = 0; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/iso1)
"dFy" = (/obj/structure/table,/obj/item/device/flashlight/lamp,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/iso1)
@@ -9554,7 +9562,6 @@
"dFD" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 0; scrub_CO2 = 0; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/iso3)
"dFE" = (/obj/structure/table,/obj/item/device/flashlight/lamp,/turf/simulated/floor{icon_state = "vault"; dir = 5},/area/research_outpost/iso3)
"dFF" = (/obj/structure/closet/hydrant{pixel_x = -32},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/turf/simulated/floor/plating,/area/research_outpost/maintstore2)
-"dFG" = (/obj/machinery/meter,/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/atmospherics/pipe/manifold/visible/scrubbers{tag = "icon-manifold (NORTH)"; icon_state = "manifold"; dir = 1},/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor/plating,/area/research_outpost/atmos)
"dFH" = (/turf/simulated/wall/r_wall,/area/research_outpost/maintstore2)
"dFI" = (/obj/structure/transit_tube{icon_state = "D-SE"},/turf/simulated/wall/r_wall,/area/research_outpost/longtermstorage)
"dFJ" = (/obj/structure/transit_tube{icon_state = "N-SW"},/turf/simulated/floor/plating/airless/asteroid,/area/mine/unexplored)
@@ -9819,9 +9826,7 @@
"dKQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/turf/simulated/wall/r_wall,/area/research_outpost/power)
"dKR" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor,/area/mine/west_outpost)
"dKS" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters)
-"dKT" = (/obj/structure/transit_tube{icon_state = "N-S"},/obj/machinery/atmospherics/pipe/simple/visible/scrubbers{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/plating/airless/asteroid,/area/research_outpost/atmos)
"dKU" = (/obj/machinery/door/airlock/glass{name = "Crew Area"; req_access_txt = "48"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/mine/living_quarters)
-"dKV" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/mineral,/area/research_outpost/atmos)
"dKW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters)
"dKX" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/living_quarters)
"dKY" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/mine/production)
@@ -10382,7 +10387,6 @@
"dWg" = (/obj/structure/table,/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/monkeycubes,/obj/item/weapon/storage/box/monkeycubes,/turf/simulated/floor{icon_state = "white"},/area/medical/virology)
"dWi" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/turf/simulated/floor{dir = 1; icon_state = "green"},/area/medical/virology)
"dWj" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{dir = 8; icon_state = "whitegreen"},/area/medical/virology)
-"dWl" = (/obj/item/inflatable,/turf/simulated/floor/beach/sand{tag = "icon-desert1"; icon_state = "desert1"},/area/holodeck/source_beach)
"dWn" = (/obj/structure/table,/obj/item/weapon/storage/fancy/vials,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/medical/virology)
"dWo" = (/obj/structure/table,/obj/item/weapon/storage/lockbox/vials,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/obj/item/weapon/reagent_containers/syringe/antiviral,/turf/simulated/floor{icon_state = "white"},/area/medical/virology)
"dWp" = (/obj/machinery/door/window/southright{name = "Virology Isolation Room Three"; req_access_txt = "39"},/turf/simulated/floor{dir = 2; icon_state = "whitegreen"; tag = "icon-whitehall (WEST)"},/area/medical/virology)
@@ -10444,14 +10448,12 @@
"dXE" = (/turf/unsimulated/wall{icon_state = "phoron5"},/area/alien)
"dXF" = (/turf/simulated/wall/r_wall,/area/medical/virologyaccess)
"dXG" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 8},/turf/simulated/floor/plating{dir = 1; icon_state = "warnplate"; nitrogen = 0.01; oxygen = 0.01},/area/maintenance/asmaint)
-"dXH" = (/turf/unsimulated/beach/sand{tag = "icon-desert"; icon_state = "desert"},/obj/item/inflatable,/turf/unsimulated/floor{tag = "icon-siding4"; name = "plating"; icon_state = "siding4"},/area/centcom/holding)
"dXI" = (/obj/structure/window/shuttle,/obj/structure/grille,/turf/simulated/shuttle/plating,/area/shuttle/escape/centcom)
"dXJ" = (/obj/machinery/light/small{dir = 8},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery)
"dXK" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery)
"dXL" = (/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery)
"dXM" = (/obj/machinery/door/airlock/medical{name = "Operating Theatre 1 Storage"; req_access_txt = "45"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgeryprep)
"dXN" = (/turf/simulated/floor{icon_state = "blue"; dir = 10},/area/medical/surgeryprep)
-"dXO" = (/obj/item/inflatable,/turf/unsimulated/beach/sand{tag = "icon-desert"; icon_state = "desert"},/area/centcom/ferry)
"dXP" = (/turf/simulated/floor{icon_state = "blue"; dir = 6},/area/medical/surgeryprep)
"dXQ" = (/obj/machinery/door/airlock/medical{name = "Operating Theatre 2 Storage"; req_access_txt = "45"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgeryprep)
"dXR" = (/turf/simulated/floor{icon_state = "freezerfloor"},/area/medical/surgery2)
@@ -10707,7 +10709,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatHasTatIasTatHasVatJasVatHatKatLatMaPLatOatOatPatKatKaafaaaalPaafaoTaoUaoUaoUaoUaoVaoWaoXaoYaoYaoYaoYaoZaafalPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafapxaJpatRatSapbapxarEarAatXatWasqarEarbauaaubaucaucaudaueaOzapAapEapFalNaNDaNFaHyaPqaHqaHrauhauiaGVaPHaPCaOEaOEaOFaOGaOParTaSOauqaJsavYavYaKkaSFaMmaTsaODasRasRasRasRasRaOSasPasPasPaaaalQaaaapvapvapvapvapvaafaoPaafapvapvapvapvapvaaaampaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatHauzauAauBatHauCauDauEatHaqYaqYauFauGauHauIauJaKFatKaaaaaaampaaaapwapwapwapwapwaafaoWaafapwapwapwapwapwaaaalPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaagapxauLapaapxaHDapxarEarAaAqarCasqarBarbaHAauSauTauTaLxaHCaKLaHsaHtaJbaHvaHwaHxaHyaHzaHqaHravdauiaGVaGVaGVaGWaGWaGXaGVaGVarTaJvaJqaJsavYavYaKkaKoaJCaKiaGZasRasRasRasRasRaGUaGSavqavraaaalQaaaaafaaaaafaafaaaaaaaoPaaaaaaaafaaaaaaaafaaaalPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatHavsavtavuatHavsavtavuatHaBcaAJaAtaAtaAtaAtaBOaBearwaaaaaaalPaaaaafaaaaafaafaaaaaaavAaaaaaaaafaaaaaaaafaaaalPaafaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaagapxapxapxapxaHDapxarbarbarbarbarbaBVaHIaHHaHGaHGaHGaHGaHKaHJaNqapEaJmalNaIjaIkaIhaIiaHYaIfaHNaHVaNQaLlavPavRavRaTIavRaKSavVavWavhaKPaviaviaKPaLcaKXaLaawbasRasRasRasRasRawbawcawdaweaaaalQalQalPaaaaaaaafaaaaaaaoPaaaaafaafaafaafalPalPalPaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaasSatHawfawgasSatHawfawgasSatKaDmatKatKatKatKatKaDlaspaaaaaaalPalPalPaaaaaaaafaaaawjawkawjaafaafaafaafalPalPalPaafapxapxapxapxawlawmawmawmawmawmawmawmawnapxapxawoawpawqapxawrawsaNJaDKaDraJfaJfaJfaJfaJfaDqaJfaDpaLDaJfaJfaJeaJeaJlaIYaJaaJnahmaIxaIAaIDaITaIvaHravdaIwawLawLbcxawMawNaVcawLauiawPawQaLQayMayMayMayMaMdaMmaMqawUasRasRasRasRasRawUawVawdaweaaaaaaaaaaafaafaaaaafaaaaaaawWaaaaaaaafaaaaaaaafaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaasSatHawfawgasSatHawfawgasSatKaDmatKatKatKatKatKaDlaspaaaaaaalPalPalPaaaaaaaafaaaawjawkawjaafaafaafaafalPalPalPaafapxapxapxapxawlawmawmawmawmawmawmawmawnapxapxawoawpawqapxawrawsaNJaJtaDraJfaJfaJfaJfaJfaDqaJfaDpaLDaJfaJfaJeaJeaJlaIYaJaaJnahmaIxaIAaIDaITaIvaHravdaIwawLawLbcxawMawNaVcawLauiawPawQaLQayMayMayMayMaMdaMmaMqawUasRasRasRasRasRawUawVawdaweaaaaaaaaaaafaafaaaaafaaaaaaawWaaaaaaaafaaaaaaaafaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawXawYawYawYawZaxaawYawYaxbaxcaExaxbaxbaxbaEJatKaEOaspaaaaafaafaaaaaaaaaaaaaafaaaaxgaGQaKgaafaaaaafaaaaaaaaaaaaaaaapxapaapaaxjapaapaapaapaapaapaapaapaaxkaxlaxmaxnaxnaxnaxnaxnaxnaxoaJBaMMaxraxraxraxraxsaJAaxraMIaxraxsaxraxraxraxraxwaxxaxyaKdaKaaHxaJRaJRaJRaHrauhaJQawLawOawMaxCawMaVeaxEaWraxGaxHaMuaMmaMmaMmaMBaMEaMGaMHaJwasRasRasRasRasRaJxaJyaxNaxOaaaaaaaaaaaaaafaaaaafaaaaxPaxQaxPaaaaafaaaaaaaafaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxRaxSaxTaxUaxVaxTaxTaxWaxUaxTaxXaxYaxZaxZaVtatKaEOatLaafaafaaaaaaaaaaaaaaaaafaybaycaydbdBayfaaaaafaaaaaaaaaaaaaaaapxapaapxaygayhayiayiayiayiayiayiayiayjaygaykaylaylaylaylaylaylaylaQnaynaxrayoaypayqayrbdCbbraPaaPdaywayxaypayyaxrayzapEayAalNaQvaNFaNIbdEaHqaHravdbdFayDaxFaxFayEayFayGbeDayIavVbdHbdcbbUbbUbbUbaNbaTaPnbavbdGasRasRasRasRasRbdIasPasPasPaaaaaaaaaaafaafaafaafaaaaySaVuaySaaaaafaaaaaaaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafatHayUayVayUayWaxTaxTayXayUayVayUayYaxSaxVaWtatHaEOatKatKazaatOatOatOatOatPatKazbazcazdazeazbapxapxawoawpawqapxapxapxapaaryaygaaaaafaaaaafaaaaafaaaaafaaaaygaykaylazfazgazhaziazjaylaQnapaaxrazkazkazlazmaznazoaPpaBdazrazsaztaztaxrayzapEazualNaQvaNFaHybdEaHqaHrauhazvbbOazxazyazzazAazBazBazCazBasPbeXbfGbeFbeGbeHbeObeEasPbdLasRasRasRasRasRbdKasPaafaaaaaaaaaaaaaafaafaaaaafazLazMbdMazOazPaafaaaaaaaafaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -10715,9 +10717,9 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxRayVaAEaAFaAFaAFaAFaAGayVaxRaAHasSaAIbeAaAKaAKaAKaAKaAKaAKaAKaAKaDlbfxbfzazbbckaANaAOazbaAPaAQaAPaAPaAPaAPaAPaAPaAPaAPaARaaaaAkaASaATaAUbbTaAWaAkaaaaygaykaylaAlaAXbewaAZaAlaylaQnapxaxraBaaBbazlbebaBdazoazpaBdbeuazsaBfaBfaxrayzapEayAalNbdZaIkaIhbdEbejbelavdaAvaHraBiaAxaBjaBjazBaAwaBkaAyazBaBlaBmaBnaBobhDaULaBqaafbfBbfdbfdbfdbfdbfdbfgaafaaaaaaaaaaaaaaaaaaaaaaaaaafaAAaBuaBvaBwaAAaafaaaaaaaBqaBqaBqaBqaBqbhqbhCaBqaBqaBqaBqaBqaBqaBqbgHaBFaBFaBFaBGaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaBHaBIaBJaBIaBIaDRaDSaBIaBIaBJaBMaBNasSaKhaLRaQlaTaaTiaBSaBTaBUaSQaAKaDlaPOatKazbazbaBXaBYaARaBZaCaaCbaCcaCdaCeaCfaCgaXEaCiaARaafaAkaQmaCkaClaCmaCnaAkaafaygaykaylaCoaCpaCqaCpaCraylaQnaCsaxrayoaypaCtaCuaAraCvaAsaAraCwaCxaypaCyaxrayzapEayAalNaQvaIAaIDaQxaIvaHraCAaCBaHraCCaAxaAxaAxazCaCDaCEaCFazBaCGaCHaCIaCJaYFaULaBqaaaaafaaaaafaaaaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaAAaZbaCMaCNaAAaBqaCOaCPaBqaQSaQDaQDaQDaQDaQDaQDaQFaRdaRdaRdaRdaRfaRdaRdaRdaRhaDaaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBHaBMaBIaDbaDcaDcaDdaDeaDfaDgaDhaDcaDcaDiaDjayUayWaZuaAKbfbbiraDnaDoaDnbfaaZeaMZaDsaqYaZnaDuaDvaAcaDwaDxaDyaDzaDzaDzaDAaDzaDzaDBaCaaARaaaaAkaRAaRTaRVaCmaSaaAkaaaaygaykaylaRuaDHaDIaDJaRyaylaQnaDLaxraxraxraxraDMaAraypaDNaBdaDOaTuaypaDQaVHaVzaVAaVpaVwaKJaVGaShaShaShaSEaScaVdaQjaTnbabaSPaSPaSPaUgaSPaTFaTTaTUaTVaUkaUGaVQaULaBqaBqaBqaBqaBqaBqaBqaBqaBqaCOaCPaBqaBqaBqaCOaEjaEkaBqaBqaAAaAAaElaEmaAAaEnaVqaVoaVoaVsaEsaEsaEsaEsaEsaWyaVraEuaEuaEuaEuaUNaEuaEyaEyaVnaEyaEyaEyaEyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDiaEBaECaEDaDcaEEaDcaEEaDcaEEaDcaEEaDcaEFaEGazSayWaEHaAKbizbiCaEKaELaEMaENaAKaQIaRqaAcaEQaAcaERaqYaAPaESaDBaDzaDzaDzaDzaDzaDzaETaWjaWgaVJaVIaWMaWNaWKaWLaWJaAkaafaygaWIaWpaWuaWxaWqaWsaWkaWpaZdaZcaxraFmaypazlaFnaBdazoaFoaAraCwaVvaypaFqaVHaWTaFsaFtaXcbdZagjagjagjagjaVEaVFaWSaVxaVybazaVxaXfaVxaXeaVxaXgaXhaFGaFHaFIaBoaXjaXmaXXaXVaXVaXCaYcaXYaXYaXYaXYaXYbaCaXYaXYaYwaYgaYeaXnaYHaYGaYxaWOaWPaWQaWQaWQaWRaEsaEsaGeaEsaGfaGgaGhaEsaEuaWUaEuaGjaXlaXkaGmaGnaGoaIbasHaGraGsaGtaGuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGvaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDiaEBaECaEDaDcaEEaDcaEEaDcaEEaDcaEEaDcaEFaEGazSayWaEHaAKbizbiCaEKaELaEMaENaAKaQIaRqaAcaEQaAcaERaqYaAPaESaDBaDzaDzaDzaDzaDzaDzaETaWjaWgaVJaVIaWMaWNaWKaWLaWJaAkaafaygaWIaWpaWuaWxaWqaWsaWkaWpaZdaZcaxraFmaypazlaFnaBdazoaFoaAraCwaVvaypaJzaVHaWTaFsaFtaXcbdZagjagjagjagjaVEaVFaWSaVxaVybazaVxaXfaVxaXeaVxaXgaXhaFGaFHaFIaBoaXjaXmaXXaXVaXVaXCaYcaXYaXYaXYaXYaXYbaCaXYaXYaYwaYgaYeaXnaYHaYGaYxaWOaWPaWQaWQaWQaWRaEsaEsaGeaEsaGfaGgaGhaEsaEuaWUaEuaGjaXlaXkaGmaGnaGoaIbasHaGraGsaGtaGuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGvaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaXoaDcaDcaBJaDcaEEaDcaEEaGxaEEaDcaEEaDcaEFaEGazSayWaGyaAKblqbluaYKaYPaYKaQlaQlaYJaYNaYOaYLaYMaYLaYLbakbajaGKaGLaGLaGLaGMaGLaGLaGNaGOaARaaaaZXaAkayJaUlayJaAkaAkaaaaygavOaylbaiaZIaZiaZqaZDaZEaZhbglaxraHbaypaCxaCuaAraypaAsaAraCwaZgaypaHdawGaYhaHfaHgaUnaYfalNalNalNalNalNaHjaYbazBaHlaAxazBaHmazBaHnazBaHobcvbcwbcNbczbdNbcXaYUbdlbdmbbvbdAbbwbbvbbvbbxbbzbbybbAbbybbFbbybbybbibcubcbbawbawbbEbaSbawbaxbawbaWaYIaHOaHPaHQaHRaHSaHTaEsaHUbaXaEuaHWaHXaYiaHZaGnaIaaIbasHaIcaEyaEyaEyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDiaIdaECaEDaDcaEEaDcaEEaDcaEEaDcaEEaDcaEFaEGazSaIeawzawyawxawuawuawuawzawCawDawzawAaImaInawBauKauKaAPaGOaIpaCaaIqaGOaGOaIraIsaItaIuaARaaaawaaaaavMavNavMaaaaafaaaaygavOaylaIyaIzavZaIBaICaylavyavzaxraIEaypazlaIFaIGazoaIHaIIaIJaIKaILaIMawGaBsaIOaIPavxaBKaISaaaaaaaUnaIUaIVaBLazBaIXaAxaAxaAxaCEaAxaAxaAxauOaBoaKyaBoaBoavJaBoaJcaBoaJdavHavGaJgaJhaJiaJjaJkavFaJjavEaJjaJjaJjaJjavDaJjaJjavCaJjaJjaJjaJjasIayRayvaAzaAiaBraBpazHaEsazIavpavlavmavnazFayNayPazDazEasHaIbaJDaJEaJFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDiaIdaECaEDaDcaEEaDcaEEaDcaEEaDcaEEaDcaEFaEGazSaIeawzawyawxawuawuawuawzawCawDawzawAaImaInawBauKauKaAPaGOaIpaCaaIqaGOaGOaIraIsaItaIuaARaaaawaaaaavMavNavMaaaaafaaaaygavOaylaIyaIzavZaIBaICaylavyavzaxraIEaypazlaIFaIGazoaIHaIIaIJaIKaILaIMawGaBsaIOaIPavxaBKaISaaaaaaaUnaIUaIVaBLazBaIXaAxaAxaAxaCEaAxaAxaAxauOaBoaKyaBoaBoavJaBoaJcaBoaJdavHavGaJgaJhaJiaJjaJkavFaJjavEaJjaJjaJjaJjavDaJjaJjavCaJjaJjaJjaJjasIayRayvaAzaAiaBraBpazHaDKazIavpavlavmavnazFayNayPazDazEasHaIbaJDaJEaJFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJHaJIaBIaDbaDcaDcaDcaJJaDcaDcaJKaDcaDcaDiaJLaJMayWaxTaJNaJOaJOaJOaJOaJOaJOaJOaJPasDatKatKaHLatKatKaAPaJSaJTaJUaJVaJVaJVaJVaJWaJXaFSaARaJZavaaKbaKcavbaKeaKbaKbaKfaygavcaylaylaylavwayJayLawGaUnavkaxraxraxraxraKlaKmaCxaCxaKnayHawGawGaxraxraIOaIOaIOaIOaKpaKqaKraKsaUnaKtaIVaKuazBazBazBazBazBazBazBazBazBauOaKwaKvaKxaIZauMavIaKBaKCaJdauyauWauXaKGaKHaJjaKIauVaKKawtaKKaKMaKNaKOauQaKQaKRauxaKTauUaKVaJjauwauvaKYaJraKZavjaJuaysaEsaLbauuaLdavfauoaveaunaEuaEyaLhasHaIbaLiaLjaLkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJHaBIaBJaBIaBIaDRaDSaBIaBIaBJaJIaLmasSaLnaxTawXaLoaLoaLpaLoaLqatHaLraLsasDaLtaLuaACaLwazwaLyaLzaLAaLzaLzaLzaLzaLzaLzaLzaLBaLCazNaAdaLFaLFayTaLHaLFaLFaLFaLIazKaLKaLLaLFazJaLNaLOaLPawvawwaMkaLSawiaIPaLTaLTaLTaLTaLTaLTaLUaLVaLWaLXaLYaLZaMaaMbaMcaIOaIOaIOaDGaMeaMfaMeaMgaMhaMiaMjaIOaMkawhaBoaMlaxMaOOaMoaMnaMpaxKaMraMsaMtaJdaxLaMvaMwaMwaMxaJjaMyaxJaMAaxBaMAaMAaMCaMDaxDaMDaMFayOayCayQaMDaJjasIarZaHPaHPaCXaDFaHPaHPaEsaMOaMPaEuaytaMRaHZavTaEuaMSaymayeaIbaEyaEyaEyaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawXayVaMVaAFaAFaAFaAFaMWayVawXaAHasSaAIaMXaMYavLavSaNbaNbaNcatHaNdaLsaxAaNfaLuaxzaNhaNiaNjaNkaNlaLzaLzaLzaLzaLzaLzaLzaxhaxiaxuaLzaLzaLzaxpayuaLzaLzaLzaLzaxvaLzaLzaLzaxtaNmaLuaLPaIOaIOaIOaIOaIOaIOaIOaIOaIOaIOaIOaIOaNsaNtaNuaNvaNwaNxaNyaNzaNAaIOaIOaIOaLPaIOaIOaIOaIOaIOaIOaIOaIOaNBbNwaCjaCWaCQaMpaNEaMpaMpawEaNGaMsavKaJdawFawJawSaNLaNMaJjaNNawTaNPawHaNRaNSaJjaNTawIaNTaJjaJjaJjavCaJjaJjasIarZaNVaHPaHPaNWaHPaNXaEsaEuaEuaEuaEuaEuaEuavQaEuaIbaIbasHaIbaNZaOaaEyaaaaafaaaaaaaaaaaaaaaaaaaaaaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -10731,16 +10733,16 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaYnaCTbdSbcGaYoaBgaYpaYqaYraYraYraYraYsaYtaTSaYuaYvaOlaCSaYyaYyaYyaYzaYyaOsaRnaTWaUKaWZaWZaPDaSGaFOaFPaFEaFDaFJaFFaFAaIgaFCaFBaFLaFKaFMaYSaYSaYSaYTaUnaHhaIOaYVaYWaYXaYYaYZaZaaPWaHkaHiaNCaZfaPWaPWaPWaPWaPWaPWaPWaPWaPWaHeaXwaZkaZlaPWaZaaYZaZmaGTaYWaZoaIOaIOaThaQoaZpaQoaQoaQoaFHaQoaQoaFUaQoaZraZraZraZraZsaZtaKAaRXaRXaRXaZvaZwaZxaJdaZyaZzaSgaZAaZAaZBaZzaZCaJjaFWaBDaZFaZGaPgaPgaPgaPgaZHaPgaPgaPgaFVawKaIbaPoaPraSoaPoaPraIbasHawKaYjaSsaSsaZJaSsaSsaZKaYmaafaaaaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaZLaZMaWGbdUaZNaBWaZPaZQaZRaZSaZTaYraZUaZVaTSaZWbaEaOlaCSaZYaZZbaaaCLaYybacbadbaeaPEbafbagbahaOnaPEaCRaBtbalbalbalbalaHubalbalbanbaobaobaobapbaobaqaUnbasbatbauawGawGawGbaAaFTbaAbayaFQbaybaAbaBbaBbaBbaBbaBbaBbaBbaBbaBaCVbaDbbubaDaPWaPWaPWawGawGawGaZoaIOaIOaUnbaFbaGaBlbaHaQobaIaQobaJbaKbaLaZrbaMaFRbaOaJdaJdaJdbaPbaQbaQbaQaJdaJdaJdbaRaSgaSgaLeaFNbaUbaVaGwaJjaBEaBDbaYaEsbaZbbabbbaWmbbcbbabbdaWmbbeaEybbfaQMaQNbbgaQMaQNaIbbbhaEyaDkbbjbbkaSsaSsbblbbmaYmaafaafaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlaVlbdVaxRbbnbdWbboaBgbbpbbpbbqaAMbbsbbqbbtbbpaTSaQpaOTaGHaByaBzaBzaBAaBBaBzbbBbadbbCaPEbafbagbbDaGPaPEaBxaHMbalbbGbbHbbHazqbbIbalbbJbbKbbLbbMbarbarbaraUnaIOaIOaYVawGbbPbbQbbRbbSaBRaFraFlbbWbaAbaBbbXbbYbbZbcaaBhbccbcdbaBaCVbcebcfbcgbchbcibcjaAVbdsawGbcmbcnbcnaUnbcqbcqaBoaBobcoaThbcobcpaBoaBoaRRaBoaBoaBobcqbcrbcrbcrbcrbcrbcrbcsaIQbcqaxfbctbctaCKaZFaZFaZFaxebcqaBEaBDbaYaEsaEsaEsaEsaEsarZaEsaEsaEsaEsaEyaBCbcAawKavUawKbcyaxdbcqaPtbcBaSsbcCaSsaSsaWAbcDbcEaTMaWDaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazQasSbcFaAFaWGatHatHatHatHatHatHbjoayZaBgaTSaTSaTSaTSaTSaTSaTSaTSaTSbmRbmRaOlaCSaZYbcIbcJbcKaYybcLbcMaDEaPEbafbagbcOaOpaPEaJzaJYbalbbHbcQbcQbbHbcQbalbbJbcRbcSbcSbcTbcUbcVbarbcWaIOaYVaGpbcYbgCbdabdbbdbbdaaGibddbaAbaBbdebdfbdgbdhbdibdjbdkaGYaHabdnbdobclbdpbdqbdrbclaLgawGazGbdtaIOaNsbdubdvaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFbdxaZFaZFaZFaZFaZFaZFaZFaZFbdyaZFaZFaZFaZFaZFaZFaZFaBDbdzaDPaDTaCYaDUaCYaDVaCYaDXaDWaDYaCYaDZaCYaEaaEbaCYaCYaCYaCYaCYaCYaEcaEdaEebdObcCaSsaSsaSsaVkbdPaVjaVkaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdQbdQbdQbdQbdQbdQbdQbdQbdQbdQaaaaafbdRazTcDadmkcGedmxdmxdmxdmxdmxdmxdmJdmzdmLdmKdmMaOlaCSaYyaYybdXbdYaYyaPEaPEaCUaPEbafbeabcOaOoaPEaJtaHMbalbecbedbbHbcQbeebalbbJbefbcSbcSbcSbegbehbarbeiaIOaYVaGkbekbgCbembenbeobepaGibeqbaAbaBberbesbetbetbetayabevbaBaCVbexbclbclbdpbeybdrbclaLfawGayBaIOaIOaNsbdubdvaZFaZFaZFaZFaZFaZFaZFbeBaZFaZFaZFaZFaZFaZFbeCaCYaCYaCYaCYaCYaCYaCZaCYaCYaCYaCYaCYaCYaCYayKaDDaDCaDtaZFaZFaZFaZFaZFaBDaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFbeIbdzbeJaSsaSsbcCaSsaSsbeKbeLaTMaTMaTNaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdQbdQbdQbdQbdQbdQbdQbdQbdQbdQbdQaWEaWFbeMbdUbeNbUVbePbePbeQbePbePbePbeRaPBaPBaPBaPBaOlaCSaZYbeSbeTbeUaYybeVbeWbUWaPEaPEaPEaPEbUmaPEchfceFbUCcfQcglbYubYBcdabalbbJbarbfcbcSbcSbPhbfebarbULaIOaYVbTrbfhbgCbembfibfjbepaGibfkbaAbflbfmbfnbetbfobetbdfbfpbfqaCVbfrbfsbftbfubfubfvbclbfwawGcpvcuScpzcvvcxRdPwdPxdTPdPxcqMdPxcqPdTQbTtdTSctbctbctaaZFaZFaZFaZFbfDaZFbfybfOaZFctccoOctdbfIbWUcqYbfIbfKdTUdTVdTWaZFaZFaZFaZFaZFbfObfPbfDaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFbdzbfQbfRbfSbfTbfUbfVbbmbfWaafaaaaafaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdQbdQbdQbdQbdQbdQbdQbdQbdQbdQbdQdmOdmNcNOdmPbfXbePbfYbfZbgabgabgbbgcbgdbgebgebgebgebPBbUubUrbUrbUtbUsbUrbUobUobUpbUobUnbUlbUlbSbbRubUNaBtbalbUZbbHbbHbUkbUSbUCbUObarbgybcSbcSbPhbgzbgAbffaIOaYVbaAbgCbTpbdabdabdabdaaGibgEbaAbaBbgFbgGbWJbgIbgJbgGbgKbaBaCVbURbUQbgNbgObgPbgQbgRbgSawGcmKaHfclMawGbTqbTqbgUbgUbgUbgUcmTcmTcsUcsVcsrcsscsVcsUcmTcmTcmTckbckbckbckbckbbcqbcqcmVbhbbhbbhbbhbbhbbktcmWbcqcsYcnucoabhkbhkbhlbhlbhlbhlbhlbhmbhnbhnbhobhnaZFbhnbhobhnbhnbhpbTqcoNcoNbNtbhrbhgaPtaPtaPtaaaaaaaaaaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdQbdQbdQbdQbdQbdQbdQbdQbdQbdQbdQaZLaZMbeMbdUbhsbePbhtbePbhubhvbePbePbePaRebhwbhxbhxbTHaYyaZYbhzbcJbhAaYybUabTZbTTbTSbTVbTUbTXbTWbTYbTXbTMbTNbTObTPbTObTObUybTNbUqbTbbhSbcSbcSbTLbhUbhVbffaIObhWbaAbhXbaAbhZbVnbibbSOaGibaAbaAbaBbiebifbigbihbiibijbikbaBaCVbTybimckrbiobipbgQbclbiqawGcjwckLclFawGcqlcqncqSbTncrDcrGcrMbUHcqUcqVcrAcrBcogcofcpscoYcmTcmIchOcmUcpMckbbUBcpNciicptbVUcktcktclSbktcggbiSbiScksbiSbiUbiUbhlbiVbiWbiXbhlbiYbiZbiYbhlbhmbhnbhpbNtbSQbTibSQbNtbThbTgbNtbjebTEbjgbhgaaaaaaaaaaaaaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdQbdQbdQbdQbdQbdQbdQbdQbdQbdQaaadmRaMYbbnbdWbjhbePbjibePbjjbjkbjlbQYbePbjnaReaXibcHbTjaYyaYyaYyaYyaYyaYybTAbjrbjsaRebjtbalbalbalbTzbalbalbalbTKbalbalbalbTQbalbTJbRFbjzbcSbcSbPhbjAbgAbSwaIObSybaAbjCbaAbaAbaAbaAbaAbTkbaAbTmbTlbjGbjHbbXbjIbbXbjJbjKbTvbTxbTybjNbclbjObjPbgQbjQbjRbaDbSNaIObDbcgQbTRcgPcgjcfLcgkchMcfMbUichochocgRcgScjtcjpciHciEciDciCciBciAckcckbcjDcgechNcgecjvcjucgecgfbktcggbiSbkwcfKcgdbkzbkAbkBbkCbkDbkCbSjbkFbkGbkHbhlbkIbkJbkKbNtbSzbSEbSDbSMbNHbSAbNtbkRbkSbkTbhgaaaaaaaaaaaeaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazQasSbcFaAFaWGatHatHatHatHatHatHbjoayZaBgaTSaTSaTSaTSaTSaTSaTSaTSaTSbmRbmRaOlaCSaZYbcIbcJbcKaYybcLbcMaDEaPEbafbagbcOaOpaPEaBxaHMbalbbHbcQbcQbbHbcQbalbbJbcRbcSbcSbcTbcUbcVbarbcWaIOaYVaGpbcYbgCbdabdbbdbbdaaGibddbaAbaBbdebdfbdgbdhbdibdjbdkaGYaHabdnbdobclbdpbdqbdrbclaLgawGazGbdtaIOaNsbdubdvaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFbdxaZFaZFaZFaZFaZFaZFaZFaZFbdyaZFaZFaZFaZFaZFaZFaZFaBDbdzaDPaDTaCYaDUaCYaDVaCYaDXaDWaDYaCYaDZaCYaEaaEbaCYaCYaCYaCYaCYaCYaEcaEdaEebdObcCaSsaSsaSsaVkbdPaVjaVkaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdQbdQbdQbdQbdQbdQbdQbdQbdQbdQaaaaafbdRazTcDadmkcGedmxdmxdmxdmxdmxdmxdmJdmzdmLdmKdmMaOlaCSaYyaYybdXbdYaYyaPEaPEaCUaPEbafbeabcOaOoaPEaFqaJYbalbecbedbbHbcQbeebalbbJbefbcSbcSbcSbegbehbarbeiaIOaYVaGkbekbgCbembenbeobepaGibeqbaAbaBberbesbetbetbetayabevbaBaCVbexbclbclbdpbeybdrbclaLfawGayBaIOaIOaNsbdubdvaZFaZFaZFaZFaZFaZFaZFbeBaZFaZFaZFaZFaZFaZFbeCaCYaCYaCYaCYaCYaCYaCZaCYaCYaCYaCYaCYaCYaCYayKaDDaDCaDtaZFaZFaZFaZFaZFaBDaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFbeIbdzbeJaSsaSsbcCaSsaSsbeKbeLaTMaTMaTNaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdQbdQbdQbdQbdQbdQbdQbdQbdQbdQbdQaWEaWFbeMbdUbeNbUVbePbePbeQbePbePbePbeRaPBaPBaPBaPBaOlaCSaZYbeSbeTbeUaYybeVbeWbUWaPEaPEaPEaPEbUmaPEcjaaHMbalchfbbHbcQceFcfQbalbbJbarbfcbcSbcSbPhbfebarbULaIOaYVbTrbfhbgCbembfibfjbepaGibfkbaAbflbfmbfnbetbfobetbdfbfpbfqaCVbfrbfsbftbfubfubfvbclbfwawGcpvcuScpzcvvcxRdPwdPxdTPdPxcqMdPxcqPdTQbTtdTSctbctbctaaZFaZFaZFaZFbfDaZFbfybfOaZFctccoOctdbfIbWUcqYbfIbfKdTUdTVdTWaZFaZFaZFaZFaZFbfObfPbfDaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFaZFbdzbfQbfRbfSbfTbfUbfVbbmbfWaafaaaaafaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdQbdQbdQbdQbdQbdQbdQbdQbdQbdQbdQdmOdmNcNOdmPbfXbePbfYbfZbgabgabgbbgcbgdbgebgebgebgebPBbUubUrbUrbUtbUsbUrbUobUobUpbUobUnbUlbUlbSbbRubUOcdabUCbYBcglcglbYubUZbalbUSbarbgybcSbcSbPhbgzbgAbffaIOaYVbaAbgCbTpbdabdabdabdaaGibgEbaAbaBbgFbgGbWJbgIbgJbgGbgKbaBaCVbURbUQbgNbgObgPbgQbgRbgSawGcmKaHfclMawGbTqbTqbgUbgUbgUbgUcmTcmTcsUcsVcsrcsscsVcsUcmTcmTcmTckbckbckbckbckbbcqbcqcmVbhbbhbbhbbhbbhbbktcmWbcqcsYcnucoabhkbhkbhlbhlbhlbhlbhlbhmbhnbhnbhobhnaZFbhnbhobhnbhnbhpbTqcoNcoNbNtbhrbhgaPtaPtaPtaaaaaaaaaaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdQbdQbdQbdQbdQbdQbdQbdQbdQbdQbdQaZLaZMbeMbdUbhsbePbhtbePbhubhvbePbePbePaRebhwbhxbhxbTHaYyaZYbhzbcJbhAaYybUabTZbTTbTSbTVbTUbTXbTWbTYbTXbTMbTNbTObTPbTObTObUybUNbUqbTbbhSbcSbcSbTLbhUbhVbffaIObhWbaAbhXbaAbhZbVnbibbSOaGibaAbaAbaBbiebifbigbihbiibijbikbaBaCVbTybimckrbiobipbgQbclbiqawGcjwckLclFawGcqlcqncqSbTncrDcrGcrMbUHcqUcqVcrAcrBcogcofcpscoYcmTcmIchOcmUcpMckbbUBcpNciicptbVUcktcktclSbktcggbiSbiScksbiSbiUbiUbhlbiVbiWbiXbhlbiYbiZbiYbhlbhmbhnbhpbNtbSQbTibSQbNtbThbTgbNtbjebTEbjgbhgaaaaaaaaaaaaaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabdQbdQbdQbdQbdQbdQbdQbdQbdQbdQaaadmRaMYbbnbdWbjhbePbjibePbjjbjkbjlbQYbePbjnaReaXibcHbTjaYyaYyaYyaYyaYyaYybTAbjrbjsaRebjtbalbalbalbTzbalbalbalbTKbalbalbalbTQbalbTJbRFbjzbcSbcSbPhbjAbgAbSwaIObSybaAbjCbaAbaAbaAbaAbUkbTkbaAbTmbTlbjGbjHbbXbjIbbXbjJbjKbTvbTxbTybjNbclbjObjPbgQbjQbjRbaDbSNaIObDbcgQbTRcgPcgjcfLcgkchMcfMbUichochocgRcgScjtcjpciHciEciDciCciBciAckcckbcjDcgechNcgecjvcjucgecgfbktcggbiSbkwcfKcgdbkzbkAbkBbkCbkDbkCbSjbkFbkGbkHbhlbkIbkJbkKbNtbSzbSEbSDbSMbNHbSAbNtbkRbkSbkTbhgaaaaaaaaaaaeaJGaJGaJGaJGaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazQasSbcFaAFaZMaTPaTPaTPbkUaTPbkVayWdmSaxTbePbkWbkXbkYbkZblablbblcbldbldbldbldbXnbWDbWDbWDbTXbTXbTXbWCblhblhblhblibalbljblkbWEblmblnbloblpblpblrblscntcnGcnZbgAbjzbcSbXvbWwbWxbWxbWRbEvbWMbXmbWXbWLbZTbWIbXmbWTbXkbXjbXibTvbTvbTvbTvbWHbTvbTvbTvbTvbWjbWGbWQbWSbWObWPbWKbWNbWsbWFbWVaIObDbbgUdVHdVIdVJcsXcslbgUcsodUTcjtcjtcjtcjtcjtcjpdVzdVydVBdVAdVDdVCdVuckbdVwdVvcskcgecjvcjucgedVLbktcggdVNbYedVMbYbbXHbXMbXFbXGbXGbXGbXUbXWbXAbXzbXybXxbXEbXDbXhbXgbXebNHbXcbXbbXfbNtbmPbkSbmsbhgaaaaaaaaaaaaaaaaJGaJGaJGaJGaJGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabmQdmUdmTdmWdmVdmXdmXdmZdmYaxTbePbmSbmTbkZbmUbePbePbePaPBbmVbmWbmXbmYbmXbmXbmXbmYbmXaPBaPBbalbalbalbmZbalblpblpbnablpblpblpblpblpbnbcnsbndbcSbWebWdbWdbWdbWabWcbVYbVcbVgbWibWncrpbWfbWfbWhbWgbWqbWpbVsbWrbWobnxbnybnzbnAbnBbnCbnzbnDbnxbPVbTybnFbnGbnFbaDbaDbaDbWAbaDdUZaIObDbcgQbTRcgPdVadVbbWBbgUdUSdUTdUXdUYdUVdUWdVndVmdVldVkcmTdVpdUEdVodVfdVedVddVccrZdVidVhdVgdVidVqbUedVrdVsdTXbnYdTYboabobbocbodboebofbofbogbkCbohbhlbWvbojbokbNtbVZbVAbVzbUJbVVbVXbNtbmPbkSborbhgaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaabmQdnbdnadncaxSaxSaxSbosaxSaxSbePbotboubovbkZbePaaaaaaaaaaafaafbowbowbowbowbowbowbowaaaaaaboxboybozboAboBblpblpblpblpblpblpblpblpckRbjzcnddYAboEboFbarbarbVGbVHbaraUnboHboIbVEaUnboLboMboMbNsboMbVFbUGboMabLboQboRbnzboSbnBboSbnzboTboQbPVbVkboVbfuboWbVybVBbVDbUFbnFbpcaIObDbbgUbWmcqndUQdURdUNbixdUOdUPdUJdUKdULbVWdUGdUFdUIdUHcmTckbdUEdUDdUAckbdUCdUBdUydUxdUzdUzdUvdUwbktcggbiSdUubkxbkxboabpybpzbpAbpBbpCbpCbpDbpEbpFbhlbpGbojbpHbNtbUYbUTbUPbUJbNHbUIbNtbkRbkSbpMbhgaaaaaaaaaaaaaafbpNbpObMebpObMebpObpQaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadndaxRdnednebpRaTPbpSazQasSbpTbpSbePbpUbpVbpWbpXbePaaaaaaaaaaaaaaabowbowbowbowbowbowbowaaaaaabpYbpZblpbqabqbbqbbqbbqbbqbbqcbqbbqbbqbbqdbqebqfcjabqhbqibarbqjbPhbqkbqlbtfbffbqnbqoaUnaUnboMbqpbVdbqrbXdbTuboMbTwbVfbVhbqxbqybqzbqybqAbVibVjbTxbVkbqEbfubqFbaDbqGbnFbTIbnFbpcaIOcrobgUdUjdUkdUhdUidUgbixdUedUfdUcdUddUadUbbZzdUsdUrdUqdUpbPZdUodUnbPZbPZbPZbPZdUmdUlbPZbPZbktdTZbktcggbiSdTXbnYdTYbrabrbbrcbrdbrebrebrebpDbkCbrfbrgbrhbkJbVlbNtbUEbUAbUzbUDbNHbUvbNtbUwbmrbhgbhgaaaaaaaaaaaaaafbrobrpbrqbrrbrrbrsbroaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadndaxRdnednebpRaTPbpSazQasSbpTbpSbePbpUbpVbpWbpXbePaaaaaaaaaaaaaaabowbowbowbowbowbowbowaaaaaabpYbpZblpbqabqbbqbbqbbqbbqbbqcbqbbqbbqbbqdbqebqfcFlbqhbqibarbqjbPhbqkbqlbtfbffbqnbqoaUnaUnboMbqpbVdbqrbXdbTuboMbTwbVfbVhbqxbqybqzbqybqAbVibVjbTxbVkbqEbfubqFbaDbqGbnFbTIbnFbpcaIOcrobgUdUjdUkdUhdUidUgbixdUedUfdUcdUddUadUbbZzdUsdUrdUqdUpbPZdUodUnbPZbPZbPZbPZdUmdUlbPZbPZbktdTZbktcggbiSdTXbnYdTYbrabrbbrcbrdbrebrebrebpDbkCbrfbrgbrhbkJbVlbNtbUEbUAbUzbUDbNHbUvbNtbUwbmrbhgbhgaaaaaaaaaaaaaafbrobrpbrqbrrbrrbrsbroaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabowbowbowbowbowbowbowbrubrvbrwbrxblpblpblpbrybrybrybryboAblpblpblpbnbbqgbqTbrzboZbrCbrDbrEbPhbcSbrFbRgbffbqnbrHbrIbrJbNNbrLbPPbrNbPObNMboMaafbrQbrRbnzbqybrSbqybnzbrTbrUbPVbPWbrWbrXbrYbaDbrZbnFbOlaUnbpcbNybNdbNzbNAbNCbNDbPKbIibixbPMbPQbLDbPRbPubPSbLDbLDbPYbPUbPZbPZbQxbQpbQFbIrbQIbQHbQSbQJbQVbPZbJqbRabQWbQXbRfbRhbRbbRbbPGbsEbkBbsFbrebrebrebsGbkCbsHbrhbsIbsIbPHbrhbNEbNKbNJbNIbNHbNLbNtbmPbsPbhgaaaaaaaaaaaaaaaaafbsQbsRbrqbrrbrqbNBbMeaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabowbowbowbowbowbowbowbGObsUbGObsVbsWblpblpblpblpblpblpboAblpbsXbalbalbsYbcSbndboCbtabtbbtcbPhbcSbcSbtdaIObqnbtebtfbtgbPrbtibtjbtkbPqbNxboMaafbrUbrUbIgbtobtpbnzbtqbOvbNgbPpbNqbtvbtvbtvbtvbtvbtvbMsawGbLTaHfaHfawGbMcbMmbLUbMubPfbixbCAbOYbPubPvbPsbPtbOibOhbCfbNUbOybOubOkbOjbOCbOBbOAbOzbMbbOFbOEbODbNubPAbPAboDbPCbPDbPDbPDbtZbHWbkBbubbkCbkCbucbPgbkCbuebkIbCEbugbORbkIbMtbMCbMvbMNbxBbrhbNtbuobhgbhgbupbuqbuqbuqburbkIbrobrrbrqbrrbrrbvYbroaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtbrtaaaaaaaaaaaaaaaaaaaaeaaaaaaaaabowbowbowbowbowbowbowbCebutbCebuublpblpblpbrybrybrybryboAblpbuvbuwbalbuxbcSbndboCbuybuzbtcbOxbuBbqfbuCbuDbuEbpcbuFbtgbuGbuHbuIbuJbOmbMfboMbLQbLubKubOnbuRbrSbuRbOvbOwbuTbuTbNqbuUbuVbuWbuXbuYbuZbMkawGbvcaIOaIOawGbLSbMnbMrbMBbMSbMTbMUbnebMLbMPbHhbMRbNabMZbBPbNbbApbHvbMYbMWbNlbNkbNGbNobNfbNebNibNhbMjbMlbMhbMibiSbvybvzbMgbvBbvBbkBbvCbvDbvEbkBbNVbkCbvGbGRbvIbvJbOebvLbvMbOfbvObvPbvQbsIbkJbHabGWbHjbHFbHMbvVbvVbInbvWbvXbpObMebJgbMebpObvZaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -10880,7 +10882,7 @@ ctDcuAcuocuycuqcuucuCcuzcwRcwucwQcwycwlcwkcwfcwOcwicwhcxccuocuycuzcupcuqcuBcurct
ctLcuqcurcuvcuzcutcuocuCcxccwOcwicwjcwxcwgcwlcwycwwcwvcxxcurcuvcuCcuwcuzcuycuuctBctSctTcuDcuEcuFcuGcuKctZcuIcuJctNctOctPctQctRctSctPcuFcuGcuKcuHcuDcuHcuIcuJctNctOctPctQctRctScuicujaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuLcxgcxhcxfcxgcxhcuOcxicxycxicxicxicuOcxjcxzcxAcxBcxjcuOcxCcxCcxDcxEcxEcuOcxqcxFcxGcxHcxIcuOcxJcxKcxKcxKcxLcuOcxMcxNcxNcxNcxOcuZ
ctIcuzcuucuxcuCcupcurcuocxxcwycwwcwhcwQcwucwxcwjcwPcwfcxPcuucuxcuocuscuCcuvcutctJcuGcuKcuHcuIcuJctNctOcuectQctRctSctTcuDcuEcuFcuGcvVcvWcvXcvYcvZcwactPctQctRctSctTcuDcuEcuFcuGctYcujaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuLcxhcxfcxgcxhcxfcuOcxicxicxicxQcxicuOcxjebVebVebVcxjcuOcxCcxScxScxScxEcuOcxncxTcxncxocxncuOcxJcxKcxKcxKcxLcuOcxMcxNcxNcxNcxOcuZ
ctycuCcutcuAcuocuwcuucurcxPcwjcwPcwvcwicwOcwQcwhcwkcwlcxUcutcuAcurcuBcuocuxcupctMcuHcuIcuJctNctOctPctQcugctSctTcuDcuEcuFcuGcuKcuHcwacxVcxWcxXcxYcwrctRctSctTcuDcuEcuFcuGcuKcuHcuacujaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuLcxfcxgcxhcxfcxgcuOcxicxicxicxicxicuOcxjcxjcxjcxjcxjcuOcxCcxDcxDcxDcxEcuOcxocxncxqcxGcxqcuOcxJcxKcxKcxKcxLcuOcxMcxNcxNcxNcxOcuZ
-ctHcuocupcuqcurcuscutcuucxUcwhcwkcwfcwwcwycwicwvcwgcwxcxZcupcuqcuucuycurcuAcuwctzctTcuDcuEcuFcuGcuKcuHcuacuJctNctOctPctQctRctSctTcwAcyacybcyccydcwFcuIcuJctNctOctPctQctRctSctTctUcujaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuLcxgcxhcxfcxgcxhcuOcxicxicxicyecxicuOcxjdQMdQKdQLcxjcuOcyicyjcyjcyjcykcuOcxncxpcxndWlcxpcuOcymcyncyncyncyocuOcxMcxNcxNcxNcxOcuZ
+ctHcuocupcuqcurcuscutcuucxUcwhcwkcwfcwwcwycwicwvcwgcwxcxZcupcuqcuucuycurcuAcuwctzctTcuDcuEcuFcuGcuKcuHcuacuJctNctOctPctQctRctSctTcwAcyacybcyccydcwFcuIcuJctNctOctPctQctRctSctTctUcujaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuLcxgcxhcxfcxgcxhcuOcxicxicxicyecxicuOcxjdQMdQKdQLcxjcuOcyicyjcyjcyjcykcuOcxncxpcxncGxcxpcuOcymcyncyncyncyocuOcxMcxNcxNcxNcxOcuZ
ctKcurcuwcuzcuucuBcupcutcxZcwvcwgcwlcwPcwjcwwcwfcwucwQcypcuwcuzcutcuvcuucuqcusctCcuKcuHcuIcuJctNctOctPcufctRctSctTcuDcuEcuFcuGcuKcwScyqcyrcyscyacwWctQctRctSctTcuDcuEcuFcuGcuKctZcujaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuLcxhcxfcxgcxhcxfcuOcxicytcxicxicxicuOcxjdQJdQHdQIcxjcuOcyxcyycyycyycyzcuOcxqcyAcyBcyCcxocuOcyDcyEcyEcyEcyFcuOcyGcxNcxNcxNcyHcuZ
ctBcuucuscuCcutcuycuwcupcypcwfcwucwxcwkcwhcwPcwlcwOcwicyIcuscuCcupcuxcutcuzcuBctFctPctQctRctSctTcuDcuEctWcuGcuKcuHcuIcuJctNctOctPcxdcwAcxecvWcvXcvYcuFcuGcuKcuHcuIcuJctNctOctPcufcujaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuLcxfcxgcxhcxfcxgcuOcxicxicxicxicxycuOcxjdQJdQHdQIcxjcuOcyJcxDcyKcxDcyLcuOcyAcyMcyNcyOcyCcuOcyPcxKcxKcxKcyQcuOcyGcxNcxNcxNcyHcuZ
ctJcutcuBcuocupcuvcuscuwcyIcwlcwOcwQcwgcwvcwkcwxcwycwwcyRcuBcuocuwcuAcupcuCcuyctEcuFcuGcuKcuHcuIcuJctNcudctPctQctRctSctTcuDcuEcuFcuGcuKcuHcuIcuJctNctOctPctQctRctSctTcuDcuEcuFctXcujaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacuLcxgcxhcxfcxgcxhcuOcyScxicxicxicxicuOcxjdQJdQHdQIcxjcuOcyJcyTcyTcyTcyLcuOcyMcyNcyNcyNcyOcuOcyPcxKcxKcxKcyQcuOcyGcxNcxNcxNcyHcuZ
@@ -10931,8 +10933,8 @@ cuAcuscuCcupcuxcutcupcuxcutcuscuCcupcuxcutcuscuCcupcuxcutcuscuCcupcuxcutcuzcuBcu
cuqcuBcuocuwcuAcupcuwcuAcupcuBcuocuwcuAcupcuBcuocuwcuAcupcuBcuocuwcuAcupcuCcuycuucujctCctLctKctActIctJctHctyctCctBctFctzctGctEctMctDctHctJctFctKctActyctzctIctEctBctDcujaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBtcBKcBKcCFcEecCRcCRcCRcEPcCRcCRcCRcEQcCRcERcEScCFcETcBKcDgcDqcEFcEUcEOcBtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
cuzcuycurcuscuqcuwcuscuqcuwcuycurcuscuqcuwcuycurcuscuqcuwcuycurcuscuqcuwcuocuvcutcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBtcBKcCEcCFcCFcCFcCFcCFcCFcEVcCRcCRcCFcCFcCFcCFcCFcCFcCJcDgcDNcEFcEGcEOcBtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
cujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujcujaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBtcBKcCFcEWcEXcEYcVocVncCFcCRcCRcCRcCFcFbcFccFdcFecFfcCFcFgcBtcEFcEGcFhcBtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBtcBKcCFcFicFicFicFicFicFjcCRcCRcCRcFkcCRcCRcCRcCRcFlcCFcFgcBtcBtcBtcBtcBtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBtcBKcCFcEWcEXcFicFicFicFmcCRcCRcCRcFncCRcCRcCRcCRcFlcCFcCWcBKcBtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBtcBKcCFcFicFicFicFicFicFjcCRcCRcCRcFkcCRcCRcCRcCRcONcCFcFgcBtcBtcBtcBtcBtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBtcBKcCFcEWcEXcFicFicFicFmcCRcCRcCRcFncCRcCRcCRcCRcONcCFcCWcBKcBtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBtcBKcCFcFicFicFicFicFocCFcFpcFqcFrcCFcVtcCFcFtcCFcCFcCFcFucBKcBtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBtcBKcCFcFicFicFicCFcCFcCFcFvcFwcFicCFcCFcCFcCRcCRcCRcCFcCWcBKcBtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacBtcBKcCFcEWcEXcFxcCFcBKcCFcFycFycFycCFcBKcCFcCVcFzcFAcCFcCWcBKcBtaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -10978,7 +10980,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFZcGacGbcGbcGbcGccGdcGdcGdcGddngdngcGdcGdcGdcGdcGfcGbcGbcGbcGbcFYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFZcGacGbcGbcGccGgcGhcGicGjcGddnhcGkcGdcGlcGmcGdcGdcGdcGfcGbcGbcFYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFZcGacGbcGccGdcGncGncGncGncGdcGocGocGdcGncGncGpcGqcGdcGdcGfcGbcGrcGrcGrcGrcGraaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFZcGacGccGdcGdcGscGtcGucGvcGdcGncGncGwcGncGncGncGncGxcGycGdcGbcGrcGzcGAcGBcGrcGrcGrcGrcGrcGCcGDcGDcGEcGrcGraaaaaaaaaaaaaaaaaaaaaaaacGFcGFcGFcGFcGFcGFcGFcGFcGFcGFcGFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFZcGacGccGdcGdcGscGtcGucGvcGdcGncGncGwcGncGncGncGncGycLFcGdcGbcGrcGzcGAcGBcGrcGrcGrcGrcGrcGCcGDcGDcGEcGrcGraaaaaaaaaaaaaaaaaaaaaaaacGFcGFcGFcGFcGFcGFcGFcGFcGFcGFcGFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFZcGacGGcGHcGIcGncGJcGJcGJcGdcGncGncGdcGKcGLcGMcGNcGOcGPcGdcGbcGrcGQcGAcGAcGRcGScGTcGUcGVcygcGUcGXcGYcGZcGrcGrcGrcGrcGrcGrcGrcGrcGrcGrcHacHbcHbcHbcHbcHbcHbcHbcHccHdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFZcGacHecGHcGncGncGncGncGncGwcGncGncGdcGdcGdcGdcGdcGdcGdcHfcOfcGrcGrcGrcGrcGrcGScGXcGUcyfcHhcGUcGXcGXcGXcHicHjcHjcHjcHjcHjcHjcHjcHjcHkcHacHlcHmcHmcHmcHmcHmcHncHccHdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacFZcGacHocGdcHpcGncHpcGncHpcGdcGncGncGndnicHqcGbcGbcGbcGbcGbcHrcOncHjcHjcHjcHicGXcGXcGXcGXcGXcGXcGXcGXcGXcHicHjcHjcHjcHjcHjcHjcHjcHjcHkcHacHscHtcHtcHtcHtcHtcHscHccHdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -11000,7 +11002,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJvcJwcJwcJwcJwcJwcJwcJwcJwcJwcJwcJwcJwcJwcKHcJycJwcJwcJwcJwcJzcKHcKIcJBcJCcJDcIPcJEcKJcFYcFYcFYcFYcFYcFYcFYcFYcFYcFYcFYcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcJncIRcJJcJJcKKcKbcKbcKbcKbcKbcKbcKbcKbcKbcKLcJJcJJcKMcKAcKAcKAcKAcKAcJKcKNcKjcJNcIRcJQcJQcJQcIRcKOcKOcKPcKOcKOcKFcKGcKGcIRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacIXcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIYcKqcJacJDcIPcJEcKQcKRcKRcFYcKScKTcKUcKVcFYcKWcKXcKXcIPcKYcKYcKYcKYcKYcKYcKZcLacLbcIPcJncIRcJJcJJcLccLdcLecLecLecLecLecLecLecLfcJIcJJcJJcJKcLgcLhcLicLjcLkcJKcLlcKjcJOcIRcJQcJQcJQcIRcLmcLmcKjcLmcLmcKFcKGcKGcIRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJvcJwcJwcJwcJwcJwcJwcJwcJwcJwcJwcJwcJwcJwcLncJycJwcJwcJwcJwcJzcLncLocLpcJCcJDcIPcJEcJEcJEcJEcFYcJEcJEcJEcLqcFYcKXcJEcLrcLscLtcLtcLtcLtcLtcLtcLucIPcIPcIPcIPcIPcJJcJJcLccLvcLwcJJcLxcLycLzcJJcLwcLvcJIcJJcJJcJKcJKcJKcJKcJKcJKcJKcLlcKjcJOcIRcJQcJQcJQcIRcLAcLAcKjcLAcLAcKFcKGcKGcIRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacIXcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcLBcLCcLDcJEcFYcJEcLEcLEcLFcFYcKXcJEcLGcIPcLHcLIcLIcLIcLJcLIcLKcIPcLLcLLcLLcIPcJJcJJcLMcLNcLOcLPcLQcLRcLScLTcLUcLNcLVcJJcJJcIRcLWcLWcLWcLWcLWcIRcIRcKkcIRcIRcIRcKkcIRcIRcKjcKjcKjcKjcKjcKFcKGcKGcIRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacIXcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcLBcLCcLDcJEcFYcJEcLEcLEdlJcFYcKXcJEcLGcIPcLHcLIcLIcLIcLJcLIcLKcIPcLLcLLcLLcIPcJJcJJcLMcLNcLOcLPcLQcLRcLScLTcLUcLNcLVcJJcJJcIRcLWcLWcLWcLWcLWcIRcIRcKkcIRcIRcIRcKkcIRcIRcKjcKjcKjcKjcKjcKFcKGcKGcIRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacIPcIPcFYcFYcLXcFYcLYcFYcFYcFYcFYcKXcJEcLrcLZcMacMacMacMacMacMacMacMbcMacMacMacMbcJJcJJcJJcMccJJcJJcMdcJJcMdcJJcJJcMccJJcJJcJJcMecJQcJQcJQcJQcJQcMecJQcJQcJQcJQcJQcJQcJQcMecLAcLAcLAcLAcLAcKFcKGcKGcIRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacIPcMfcMgcFYcJEcMhcJEcMicJEcMjcJEcJEcJEcMkcIPcMlcMmcMmcMncMocMpcMqcIPcMrcMrcMrcIPcJJcJJcKKcMscMtcLPcMucJJcMvcLTcMwcMscKLcJJcJJcMecJQcJQcJQcJQcJQcMecJQcJQcJQcJQcJQcJQcJQcMecLAcLAcLAcLAcLAcIRcKkcKkcIRcIRcIRcIRcIRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacIPcLtcJEcMxcJEcMycJEcKXcKXcKXcMzcMzcKXcMkcIPcMAcMAcMAcMBcMCcMBcMDcIPcIPcIPcIPcIPcJJcJJcLccLNcMEcJJcMdcJJcMdcJJcMEcLNcJIcJJcJJcIRcMFcMGcMGcMGcMHcIRcIRcMIcIRcIRcIRcKkcIRcIRcIRcMJcMJcMJcIRcIRcJQcJQcJQcMKcJQcMLcIRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -11011,7 +11013,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacIPcIPcIPcIPcIPcIPcIPcIPcIPcIPcOxcOxcIPcIPcIPcIPcMQcNrcNPcNQcNRcNScMQdRydRYdRYdRydRHdRXcJJdRzcIRcIRcIRcOacIRcIRcwZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacIRcIRcIRcIRcIRcIRcIRcIRcNdaaaaaaaaaaaaaaacNUcJQcNwcKlcKlcNxcJQcNyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacNVcNWcNWcNVaaaaaaaaacMQcNrcNXcNYcNZcNYcMQdRydRZdRZdRydRJdRCcJJdRzcIRcJocLVcJJcLMcOhcIRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacObcJQcJQcOccOccJQcJQcObaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOdcOecOecOecOecOGcOGcOecOecOgaaacMQcNrcNrcNrcNrcNrcMQdRydRYdRYdRydRRdRCcJJdRzcIRcJIcJJcJJcJJcLccIRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOBdXUdXTcOFaaaaaaaaaaaaaaaaaaaaaaaaaaacIRcOicJQcJQcJQcJQcOjcIRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOkcOlcOmdmQdnjcOpcOpcOqcOqcOecOgcMQcMQcMQcMQcMQcMQcMQdRydRydRydRydRBdRCcJJdRzcIRdRAcORdRAdRDdRAcIRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOBdaCcONdROdaFcOFaaaaaaaaaaaaaaaaaaaaaaaacIRcIRcIRcIRcIRcIRcIRcIRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOkcOlcOmdmQdnjcOpcOpcOqcOqcOecOgcMQcMQcMQcMQcMQcMQcMQdRydRydRydRydRBdRCcJJdRzcIRdRAcORdRAdRDdRAcIRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOBdaCdnOdROdaFcOFaaaaaaaaaaaaaaaaaaaaaaaacIRcIRcIRcIRcIRcIRcIRcIRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOkcOlcOvcOpcOpcOpcOpcOpcOpdnodnpaaaaaaaaaaaaaaaaaacIRdREdRydREdRydRHdRCcJJdRFdRGcJIcJJdRIcJJcMvcNdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOVdaLcOMcOMdaJcOVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOkcOlcOpcOHcOHcOHcOHcOHcOHcOecOIaaaaaaaaaaaaaaaaaacIRdREdRydREdRydRJdRCcJJdRFdRGcKacJJcLxdRLcMXcNdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadXIcOYcOYcOYcOMdXIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOQcOecOecOecOecOecOecOecOecOIaaaaaaaaaaaaaaaaaaaaacIRdREdRydREdRydRRdRQcMEdRTcOydRAdRSdRVdRWdRAcNdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOVcZpcOYcOZdaNcOVdaMaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -11027,10 +11029,10 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOycUXcUYcUYcUYcURcUVcQLcQAcQAcQAcQAcQAcQAcQAcQAcQAcQAcQAcQAcQAcQAcQAcQAcQzcPkcLvcPlcJJcJJcJJcVqcVpcRVcVrcQhcQhcQScVscNdaaaaaadXXcPLcOYcPMdYecPLcOYcPMdXXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOycPbcPbcPbcPbcPbcUJcQTcUHcUKcQYcQAcQWcUOcUNcQYcQAcQAcQAcQAcQAcQAcQAcQAcQzcPkcLvcPIcJJcJJcJJcJJcUPcQhcQhcQhcQhcQhcUGcSacRVcRXcOVcZIcOYcPMdXXcPLcOYcZKcOVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOycPbcQxcPbcPbcPbcQVcQTcUfcUicQYcQAcQWcSAcSzcQYcQAcQAcSecSecSecSecSecSecQzcShcSgcSrcSicUzcUzcUzcUAcUzcUzcQhcQhcQhcUGcUBcUDcUBcQkcOYcOYcOYcOYcOYcOYcPMdXIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOycPbdXOcPbcPbcPbcQVcQLcQAcQAcQAcQAcQAcQAcQAcQAcQAcQCcRUcRUcRUcRUcRUcRUcQzcQzcQzcQzcQzcRZcRZcQzcQzcQzcQzcSacRVcRVcRVcRVcRVcRXcOVdXUdXTcRCdXIcZBcOYcZrcOVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOycPbdlgcPbcPbcPbcQVcQLcQAcQAcQAcQAcQAcQAcQAcQAcQAcQCcRUcRUcRUcRUcRUcRUcQzcQzcQzcQzcQzcRZcRZcQzcQzcQzcQzcSacRVcRVcRVcRVcRVcRXcOVdXUdXTcRCdXIcZBcOYcZrcOVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOycPbcPbcREcPbcRGcQVcQTcRNcRFcQYcQAcQWcRAcRzcQYcQAcQCcRycQBcQBcQBcQBcQBcQzcRBcRBcRBcRDcOtcOtcRRcRhcRhcQzcPKcPKcPKcPKcNdaaaaaacOVcRLcRMcPAcRgcOVcZpcZrcOVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOycQRcPbcPbcQPcPbcQVcQTcQUcQXcQYcQAcQWcRacQZcQYcQAcQCcQBcQBcQBcQBcQBcQBcQzcZccWncWkcWgcOtcOtcOtcRhcRhcQzcNdcNdcNdcNdcNdaaaaaadXIcPAcPAcPAcZecOVcZdcZdcOVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOycPbcPbcPbcPbcPbdXHcQLcQAcQAcQAcQAcQAcQAcQAcQAcQAcQCcQBcQBcQDcQFcQEcQGcQzcQIcWccWdcOtcPzcQpcOtcOtcQOcQzaaaaaaaaaaaaaaaaaaaaacOVcRLcRMcPAcWfcPocQjcQjcPsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOycPbcPbcPbcPbcPbdgDcQLcQAcQAcQAcQAcQAcQAcQAcQAcQAcQCcQBcQBcQDcQFcQEcQGcQzcQIcWccWdcOtcPzcQpcOtcOtcQOcQzaaaaaaaaaaaaaaaaaaaaacOVcRLcRMcPAcWfcPocQjcQjcPsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOycPbcQycPbcQxcOOcQvcQucQtcQtcQtcRjcRjcRjcRkcRlcQscRncRocRjcRjcRjcQzcQzcQzcQrcQqcQqcPzcQocQlcQpcQecQicQzaaaaaaaaaaaaaaaaaaaaacSncSocSpcSpcSpcPscSscSscSqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOycPbcPbcPbcOOcOPcOKcOUcOUcOUcOUcRjcRrcRscRtcRucRvcRwcRxcRscRrcRjcQzcQzcQzcQzcQzcQzcPPcQgcQfcPJcQecQicQzaaaaaaaaaaaaaaaaaaaaaaaacSncSscSscSscSqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOycQdcPbcOOcOPcOKcOKcOUcOUcOUcOUcRjcRscRHcRIcRucRvcRwcRJcRKcRscRjcPTcPRcPQcQbcQacQzcOtcPPcPJcOtcOtcPzcPfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -11109,7 +11111,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUscUvcUvcUvcUvcUvcUvdS
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUscVlcVmcVmdSTcVmcVmcVmdSTcVmcVmcVmdSTcVmcVmdSUcUsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacVcdgqdgpdgodgodgodgodgodgocVgdgocVgdgodgodgodgodgodgodgpdgqcVcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUsdTbdTcdTccVzdTfdTgdThcVzdTddTddTecVzdTjdTicVycUsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacVcdgRdgQdgTdgSdgZdhacVgdglcVgdglcVgdglcVgdgXdgVdgWdgYdgQdgRcVcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUsdTcdTkdTbcVXdTodTndTgcVXdTmdTldTdcVXdTpcVydTqcUsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacVcdgzdgQdfHdfHdfHdfHcVgdfHdfHdfHdfHdfHcVgdfHdfHdhbdfHdgQdgzcVcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUscUscUscUscUscUscUscUscUscUscUscUscUscUscUscUscUsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacVbcVgdgDdgMdgLdgJdgKcVgdgIdfHdfHdfHdgHcVgdgGdgEdgFdgCdgDcVgcVdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacUscUscUscUscUscUscUscUscUscUscUscUscUscUscUscUscUsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacVbcVgdnPdgMdgLdgJdgKcVgdgIdfHdfHdfHdgHcVgdgGdgEdgFdgCdnPcVgcVdaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacWJcVgdgNdgNcVgcVgcVgcVgdgPdfHdfHdfHdgOcVgcVgcVgcVgdgNdgNcVgcWNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacWJcWOcWOcWNaaaaaacVgdgadfHdfHdfHdgbcVgaaaaaacWJcWOcWOcWNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacVgdgcdfHdfHdfHdgbcVgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -11679,29 +11681,29 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqxdqTdqTdqTdqTdqTdqTdqTdqTaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqVdqWdqXdqXdqYdqYdqYdqYdqYdqZdradrbdrcdqTdqTdqTdqTdqTdqTdqTdqTdqTdrddredrfaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqVdrgdrhdqTdqTdqTdqTdqTdqTdridridridrjdrkdrcdqTdqTdqTdrldrmdrndrndrodrpdrqdrrdrsdrsdqXdrtdruaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrvdrhdqTdqTdqTdqTdqTdqTdqTdridrwdrxdrydrjdrkdrzdridrAdrBdrCdrDdrDdrDdrEdrFdrDdrDdrDdrDdrGdrHdruaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrIdqTdqTdqTdqTdqTdqTdqTdqTdrJdrKdrLdrMdrNdrOdrPdrQdrRdrSdrTdrUdrVdrTdrWdrEdrTdrXdrUdrDaafdrYdrZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdsadsadqTdqTdsadsadsadsadqTdsadsadsadsadsadsadsadqTdqTdqTdqTdqTdqTdqTdqTaaaaaaaaaaaaaaaaaaaaaaaaaaadrIdqTdqTdqTdqTdqTdrJdrJdrJdrJdsbdscdlOdsddsedsedsedsfdsgdrTdshdsidsjdrEdrEdskdsidshdrDaafaafdslaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdsadqTdqTdqTdqTdqTdqTdsadsadqTdqTdqTdqTdsadsadsadsadqTdsadsadsadsadsadsadsadsadsadsadsadsadsadsadqTaaaaaaaaaaaaaaaaaaaaaaaaaaadrIdqTdqTdqTdqTdrJdrJdsmdsndrJdsodsodsodsodJIdsedsqdDvdDudrTdrTdrTdrTdstdsudsvdsvdsvdsvdsvdswdsxdsyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadszdsAdszaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdsadqTdqTdqTdsadsadqTdsadsadsadqTdqTdsadsadsadsadsadsadsadsadsadsadsadsadsadsadqTdsaaaaaaaaaaaaaaaaaaaaaaaaadrIdqTdqTdqTdqTdrJdsBdsCdsDdsEdlHdsGdsHdsIdsJdsKdsLdDldDkdrTdsOdsPdrTdDjdDidDhdsTdsUdFGdsWdsXdsYdsZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtadtbdtaaafaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdsadsadsadsadsadsadqTdqTdqTdqTdqTdqTdqTdsadsadsadsadsadqTdqTdqTdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaaaaaaaaaaaaaaaaaaaaaaaaadrIdqTdqTdqTdqTdrJdtcdtddKIdrJdtfdsFdtgdthdtidtjdtkdEBdEAdEedEddEgdEfdEjdEidsvdEzdDEdDUdDWdtxdtydsZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtzdtAdtBdtCaafaaaaaadqTdqTdqTdqTdqTdqTdqTdsadqTdqTdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaaaaaaaaaaaaaaaaaaaaaadqVdtDaaadqTdqTdqTdrJdtcdtddtEdrJdtFdtgdtGdtHdKbdtJdtKdtJdDAdtJdtJdtJdrDdDydDxdrDdtOdDEdDFdDBdtRdsYdsZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtSdtTdtTdtUdtVdtWdtaaafaaaaaadqTdqTdqTdqTdsadsadsadqTdqTdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaaafdtXdtYdrsdrsdrsdtZduaaaadqTdqTdqTdrJdtcdubdlKdrJdudduedGwdGNduhduidMrdukdGudumdunduodrDdHhdGOdrDdurdFudFvdDBdsvduuduvaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaduwduxduyduzduAduBduCaafaafdsadsadqTdqTdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaduDduDduDaafduEduaaafaafaafaafaafaaadrJdrJdrJdrJdrJdEUdFtdrJdsodrDdlCdlIduJdtJduKduLdEKduNduOduPdrDdEQdEPdlJdENdESdETdERdsvduXduYaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUaaadqUdqUdqUdqUdqUaaadqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaduZdtTdtTdvadvbdtWdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaduDduDduDaaaaaadrIdvddvddvddvddvddvddvddrTdvedvfdObdvhdKOdKPdKJdKKdLddLcdLgdLfdtJdvqdvrdLhdvtdLndLMdLAdMbdLVdvzdvzdvzdvAdKQdyOdKTdKVdKVcrHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUaaadqUdqUdqUdqUdqUaaadqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafdvGdvHdvIdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaduDaaaaaadrIdvddvddvddvddvddvddvddvJdvKdvLdvMdHidICdIKdILdIQdJFdJEdlMdlLdvWdvXdvYdJGdKcdNidMWdJHdKudKtdvzdlNdwhdKEdKCdvzdwkduYduYduYaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafdwldwmdwndwodvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaaaaaaaaaaaaadrIdvddvddvddvddvddvddvddwpdwqdwrdwsdymdwudwudwvdwwdwxdrDdlkdljdrDdwAdwBdwCdwDdwEdDzdtJdysdyndwIdwJdwJdwKdyvdwMdwNdwOdwPdwPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafdwQdwRdwSdvcdwTdwUdvcdvcdvcdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaaaaaaaaaaaaaaaaaaadrIdvddvddvddvddvddvddvddwVdwqdwrdwsdymdwWdwXdwvdwYdwZdrDdyldxNdrDdxcdtJdtJdtJdtJdxddtJdxMdxLdvzdDwdxhdxidxjdxkdxldxmdxndxnaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafdxodxpdxqdxrdxsdxtdszduBdxudvcdxvdxwdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaaaaaaaaaaaaaaaaaaadrIdvddvddvddvddvddvddvddrTdwqdwrdwsdymdxxdxydwvdxzdxAdrDdzkdlpdlqdxEdxFdxGdxHdrDdxIdxJdyZdDCdzgdzadxOdxPdxQdxRdxldwPdwPdwPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafdxSdxTdxpdxUdxVdxWdxXdxYdxudxZdxwdyadxvdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaaaaaaaaaaaaaaaaaaadybdycdyddyedmndycdyddygdyhdyidyjdykdyMdykdrDdrDdrDdrDdrDdySdlndlodxEdrEdxGdzQdrDdyqdyrdyQdyPdlmdYzdywdyxdyydyzdyAdyBdrDdyCdtYdrsdrsdrsdrsdrsdrsdrtdyDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadGpdqTdqTdqTdqTdqTdqTdqTdqTaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqVdqWdqXdqXdrndrndrndrndrndoEdrndoDdrcdqTdqTdqTdqTdqTdqTdqTdqTdqTdrddredrfaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqVdrgdrhdqTdqTdqTdqTdqTdqTdridridridrjdrkdrcdqTdqTdqTdrldoFdoGdoGdoHdrpdrqdrrdrsdrsdqXdrsdrtdruaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrvdrhdqTdqTdqTdqTdqTdqTdqTdridrwdrxdrydrjdrkdrzdridrAdrBdrCdrDdrDdrDdrEdrFdrDdrDdrDdrDaafdrGdrHdruaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadrIdqTdqTdqTdqTdqTdqTdqTdqTdrJdoIdrLdrMdrNdrOdrPdrQdrRdrSdrTdrUdrVdrTdrWdrEdrTdrXdrUdrDaafaafdrYdrZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdsadsadqTdqTdsadsadsadsadqTdsadsadsadsadsadsadsadqTdqTdqTdqTdqTdqTdqTdqTaaaaaaaaaaaaaaaaaaaaaaaaaaadrIdqTdqTdqTdqTdqTdrJdrJdrJdrJdsbdscdlOdsddsedsedsedsfdsgdrTdshdsidsjdrEdrEdskdsidshdrDaafaafaafdslaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdsadqTdqTdqTdqTdqTdqTdsadsadqTdqTdqTdqTdsadsadsadsadqTdsadsadsadsadsadsadsadsadsadsadsadsadsadsadqTaaaaaaaaaaaaaaaaaaaaaaaaaaadrIdqTdqTdqTdqTdrJdrJdsmdsndrJdsodsodsodsodJIdsedsqdDvdDudrTdrTdrTdrTdstdsudsvdsvdsvdsvdsvdsvdswdsxdsyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadszdsAdszaaaaaaaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdsadqTdqTdqTdsadsadqTdsadsadsadqTdqTdsadsadsadsadsadsadsadsadsadsadsadsadsadsadqTdsaaaaaaaaaaaaaaaaaaaaaaaaadrIdqTdqTdqTdqTdrJdsBdsCdsDdsEdlHdsGdsHdsIdsJdsKdsLdDldDkdrTdsOdsPdrTdDjdDidDhdnZdocdoddoadobdsXdsYdsZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtadtbdtaaafaaaaaaaaadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdsadsadsadsadsadsadqTdqTdqTdqTdqTdqTdqTdsadsadsadsadsadqTdqTdqTdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaaaaaaaaaaaaaaaaaaaaaaaaadrIdqTdqTdqTdqTdrJdtcdtddKIdrJdtfdsFdtgdthdtidtjdtkdEBdEAdEedEddEgdEfdEjdondDhdoodojdokdoldomdtxdtydsZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtzdtAdtBdtCaafaaaaaadqTdqTdqTdqTdqTdqTdqTdsadqTdqTdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaaaaaaaaaaaaaaaaaaaaaadqVdtDaaadqTdqTdqTdrJdtcdtddtEdrJdtFdtgdtGdtHdKbdtJdtKdtJdDAdtJdtJdtJdrDdDydDxdrDdoedohdoidofdogdtRdsYdsZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadtSdtTdtTdtUdtVdtWdtaaafaaaaaadqTdqTdqTdqTdsadsadsadqTdqTdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaaafdtXdtYdrsdrsdrsdtZduaaaadqTdqTdqTdrJdtcdubdlKdrJdudduedGwdGNduhduidMrdukdGudumdunduodrDdHhdGOdrDdoydFudoxdofdsvdsvduudowaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaduwduxduyduzduAduBduCaafaafdsadsadqTdqTdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaduDduDduDaafduEduaaafaafaafaafaafaaadrJdrJdrJdrJdrJdEUdFtdrJdsodrDdlCdlIduJdtJduKduLdEKduNduOduPdrDdEQdEPdoqdopdoudovdotdsvdordosdBvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUaaadqUdqUdqUdqUdqUaaadqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaduZdtTdtTdvadvbdtWdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaduDduDduDaaaaaadrIdvddvddvddvddvddvddvddrTdvedvfdObdvhdKOdKPdKJdKKdLddLcdLgdLfdtJdvqdvrdLhdvtdLndLMdLAdMbdLVdvzdvzdvzdvAdKQdyOdoAdoBdoCcrHaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUaaadqUdqUdqUdqUdqUaaadqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafdvGdvHdvIdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaduDaaaaaadrIdvddvddvddvddvddvddvddvJdvKdvLdvMdHidICdIKdILdIQdJFdJEdlMdlLdvWdvXdvYdJGdKcdNidMWdJHdKudKtdvzdlNdwhdKEdKCdvzdozdBvdBvdBvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaadqUdqUdqUdqUdqUaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafdwldwmdwndwodvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaaaaaaaaaaaaadrIdvddvddvddvddvddvddvddwpdwqdwrdwsdymdwudwudwvdwwdwxdrDdlkdljdrDdwAdwBdwCdwDdwEdDzdtJdysdyndwIdwJdwJdwKdyvdwMdnUdnVdBvdBvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafdwQdwRdwSdvcdwTdwUdvcdvcdvcdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaaaaaaaaaaaaaaaaaaadrIdvddvddvddvddvddvddvddwVdwqdwrdwsdymdwWdwXdwvdwYdwZdrDdyldxNdrDdxcdtJdtJdtJdtJdxddtJdxMdxLdvzdDwdxhdxidxjdxkdnSdnTdCidCiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafdxodxpdxqdxrdxsdxtdszduBdxudvcdxvdxwdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaaaaaaaaaaaaaaaaaaadrIdvddvddvddvddvddvddvddrTdwqdwrdwsdymdxxdxydwvdxzdxAdrDdzkdlpdlqdxEdxFdxGdxHdrDdxIdxJdyZdDCdzgdnYdxOdxPdxQdxRdnSdBvdBvdBvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafdxSdxTdxpdxUdxVdxWdxXdxYdxudxZdxwdyadxvdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaaaaaaaaaaaaaaaaaaadybdycdyddyedmndycdyddygdyhdyidyjdykdyMdykdrDdrDdrDdrDdrDdySdlndlodxEdrEdxGdzQdrDdyqdyrdyQdyPdlmdYzdywdnXdnWdyzdyAdyBdrDdyCdtYdrsdrsdrsdrsdrsdrsdrtdyDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadyEdxSdyFdxSdxqdxqdwTdyGdxVdvcdwodyHdvcdxwdyIdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsaaaaaaaaaaaaaaaaaaadyJdlxdyLdmqdAUdATdATdARdASdAXdATdlydAWdyTdyUdyVdyWdyXdAGdlvdludzbdzcdzddzedzfdrDdzhdzidAQdAMdrDdvzdzldvzdrDdrDdzmdzndzodzpdzqdzrdzrdzsdzrdzrdzrdztdrZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafdzudzvdxqdzwdzxdxqdvIdzydxWdzzdzAdzBdvcdvcdvcdvcdvcdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTaaaaaaaaaaaaaaadzCdzDdyLdyLdzEdyLdzFdzGdAjdzIdzJdltdzLdzMdyUdAkdAldAcdAbdAadzZdzYdzXdzWdzPdAidAhdAgdzPdAfdAedlsdAddzRdzSdzOdlrdzWdzPdzHdzNdzUdDHdzTdAmdAndAodApdzrdslaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafdAqdArdAsdxqdzxdAtdxUdAudxVdAvdvcdAwdAxdvcdAydxudAzdAAdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTdqTaaaaaaaaaaaadABdACdyLdyLdADdyLdAEdAFdBDdAHdBFdlEdAKdDXdyUdBfdANdAOdAPdBHdBGdBQdBPdBTdBSdBWdBVdBZdBYdBWdCpdBVdCrdBWdBVdCsdlFdlGdCBdCCdCEdCFdCIdDfdBldBmdBmdBndzrdslaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafdsadsadvcdxtdBodBpdBqdAsdBrdBsdxWdBtdszduBdBudvcdAydwodxudAAdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadqTdqTdqTdqTdBvdBvdBvdBvdBvdBvdqTdqTdqTdqTdqTdqTdBwdBxaaaaaaaaadBydBzdyLdBAdAYdAZdDTdBbdBcdBddBedlzdBJdBKdyUdlAdyVdBLdBMdBMdrDdrDdlDdBOdBidBkdBOdBRdBjdBCdBRdBUdBBdBgdBUdrDdlBdlCdvZdCadzrdCbdCcdzrdCddBmdBmdCedzrdslaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafdvcdvcdvcdvcdvcdvcdxsdxVdCfdBodxVdzydCgdBtdBtdxYdxudAwdvcdAydvIdChdAAdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadqTdqTdBvdBvdBvdCidCidCidCidBvdBvdBvdqTdqTdCjdCkdCldyDaaaaaaaaadCmdCndyddyedCodCodCodCodvUdlgdvSdrTdrTdrTdyUdvTdBMdCtdBMdCudCvdCwdyYdBOdwfdwcdCAdBRdwbdwedCDdBUdwddvVdCGdBUdCHdwadvZdCJdCKdzrdzrdzrdCLdCMdCNdApdzrdslaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafdvcdvcdvcdvcdvcdvcdxsdxVdCfdBodxVdzydCgdBtdBtdxYdxudAwdvcdAydvIdChdAAdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadqTdqTdBvdBvdBvdCidCidCidCidBvdBvdBvdqTdqTdCjdCkdCldyDaaaaaaaaadCmdCndyddyedCodCodCodCodvUdnQdvSdrTdrTdrTdyUdvTdBMdCtdBMdCudCvdCwdyYdBOdwfdwcdCAdBRdwbdwedCDdBUdwddvVdCGdBUdCHdwadvZdnRdCKdzrdzrdzrdCLdCMdCNdApdzrdslaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafdvcdCOduBdxWdCPdvcdCQdCRdCSdvcdzzdvcdCTdCUdCVdvcduBdCWdtbdCXdvIdwndtbdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadqTdqTdqTdBvdBvdCidCidCidCidCidCidCidCidBvdBvdqTdCYdCZdrYdDadrsdrsdrsdtZduaaafaafdDbdDcdDddDedwHdDgdwtdwjdwidwGdlidlhdDndDodDpdDqdDrdDsdDtdBOdxfdwLdALdBRdxadxbdBadBUdxedxBdCxdBUdDDdxKdxCdDGdDmdDIdDJdzrdzrdzrdzrdzrdDKdtDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsadvcdCOdvIduBdxUdzzdCWdBodDLdBodDMduBduBdDNdxuduBdvIdvIdvcdtbdDOdvIduBdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadqTdqTdBvdBvdCidCidCidCidCidCidCidCidCidCidDPdDQdDRdDQaaaaaaaaaaaaaaaaaaaaaaaaaafdDbdDcdDSdvudvsdDVdvpdxgdDYdDYdladlbdBMdCtdBMdEadBMdkZdEcdvodBOdvndBOdBRdBRdvmdBRdBUdBUdvldBUdBUdEhdvkdvjdEkdEldEldEmdCKdEndqWdrsdrsdEodEpaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadsadsadvcdCOdEqdvIdvIdzzdvIdChdwTdvIdErdDMdChdBudEsdvIdEtdwodvcdBodtbdCWduBdvcdsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadsadqTdBvdDQdCidCidCidCidCidCidCidCidCidCidCidEudEvdEwdExaaaaaaaaaaaaaaaaaaaaaaaaaafdDbdDcdEydvQdvRdvQdvPdECdEDdDYdlfdyUdyUdEGdlddEIdBMdlcdEJdvFdvNdvBdvCdvDdvEdvvdvwdvxdvydvOdEVdBUdEWdledCKdEYdEZdEYdEZdCKdFadFbdsaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa