diff --git a/.travis.yml b/.travis.yml
index 81b8487f48..948be8cfe5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,6 +8,10 @@ env:
before_install:
- sudo apt-get update -qq
- sudo apt-get install libc6:i386 libgcc1:i386 libstdc++6:i386 -qq
+ - sudo apt-get install python -qq
+ - sudo apt-get install python-pip -qq
+ - sudo pip install PyYaml -q
+ - sudo pip install beautifulsoup4 -q
install:
- curl "http://www.byond.com/download/build/${BYOND_MAJOR}/${BYOND_MAJOR}.${BYOND_MINOR}_byond_linux.zip" -o byond.zip
@@ -22,3 +26,4 @@ script:
- (! find nano/templates/ -type f -exec md5sum {} + | sort | uniq -D -w 32 | grep nano)
- ( md5sum -c - <<< "0af969f671fba6cf9696c78cd175a14a *baystation12.int")
- DreamMaker baystation12.dme
+ - python tools/GenerateChangelog/ss13_genchangelog.py html/changelog.html html/changelogs
diff --git a/baystation12.dme b/baystation12.dme
index 4f5dd64c2b..27f14626f6 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -174,6 +174,7 @@
#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"
@@ -265,6 +266,7 @@
#include "code\game\gamemodes\cult\cult_items.dm"
#include "code\game\gamemodes\cult\cult_structures.dm"
#include "code\game\gamemodes\cult\hell_universe.dm"
+#include "code\game\gamemodes\cult\narsie.dm"
#include "code\game\gamemodes\cult\ritual.dm"
#include "code\game\gamemodes\cult\runes.dm"
#include "code\game\gamemodes\cult\talisman.dm"
@@ -286,8 +288,15 @@
#include "code\game\gamemodes\events\holidays\Other.dm"
#include "code\game\gamemodes\extended\extended.dm"
#include "code\game\gamemodes\heist\heist.dm"
-#include "code\game\gamemodes\malfunction\Malf_Modules.dm"
+#include "code\game\gamemodes\malfunction\malf_hardware.dm"
+#include "code\game\gamemodes\malfunction\malf_research.dm"
+#include "code\game\gamemodes\malfunction\malf_research_ability.dm"
#include "code\game\gamemodes\malfunction\malfunction.dm"
+#include "code\game\gamemodes\malfunction\newmalf_ability_trees\HARDWARE.dm"
+#include "code\game\gamemodes\malfunction\newmalf_ability_trees\HELPERS.dm"
+#include "code\game\gamemodes\malfunction\newmalf_ability_trees\tree_interdiction.dm"
+#include "code\game\gamemodes\malfunction\newmalf_ability_trees\tree_manipulation.dm"
+#include "code\game\gamemodes\malfunction\newmalf_ability_trees\tree_networking.dm"
#include "code\game\gamemodes\meteor\meteor.dm"
#include "code\game\gamemodes\meteor\meteors.dm"
#include "code\game\gamemodes\ninja\ninja.dm"
@@ -542,7 +551,6 @@
#include "code\game\objects\effects\spawners\gibspawner.dm"
#include "code\game\objects\effects\spawners\vaultspawner.dm"
#include "code\game\objects\items\apc_frame.dm"
-#include "code\game\objects\items\ashtray.dm"
#include "code\game\objects\items\blueprints.dm"
#include "code\game\objects\items\bodybag.dm"
#include "code\game\objects\items\contraband.dm"
@@ -671,6 +679,7 @@
#include "code\game\objects\items\weapons\implants\implantfreedom.dm"
#include "code\game\objects\items\weapons\implants\implantpad.dm"
#include "code\game\objects\items\weapons\implants\implantuplink.dm"
+#include "code\game\objects\items\weapons\material\ashtray.dm"
#include "code\game\objects\items\weapons\material\bats.dm"
#include "code\game\objects\items\weapons\material\kitchen.dm"
#include "code\game\objects\items\weapons\material\knives.dm"
@@ -1231,7 +1240,6 @@
#include "code\modules\mob\living\silicon\ai\life.dm"
#include "code\modules\mob\living\silicon\ai\login.dm"
#include "code\modules\mob\living\silicon\ai\logout.dm"
-#include "code\modules\mob\living\silicon\ai\say.dm"
#include "code\modules\mob\living\silicon\decoy\death.dm"
#include "code\modules\mob\living\silicon\decoy\decoy.dm"
#include "code\modules\mob\living\silicon\decoy\life.dm"
@@ -1417,7 +1425,6 @@
#include "code\modules\power\singularity\field_generator.dm"
#include "code\modules\power\singularity\generator.dm"
#include "code\modules\power\singularity\investigate.dm"
-#include "code\modules\power\singularity\narsie.dm"
#include "code\modules\power\singularity\singularity.dm"
#include "code\modules\power\singularity\particle_accelerator\particle.dm"
#include "code\modules\power\singularity\particle_accelerator\particle_accelerator.dm"
@@ -1479,6 +1486,7 @@
#include "code\modules\reagents\dispenser\_defines.dm"
#include "code\modules\reagents\dispenser\cartridge.dm"
#include "code\modules\reagents\dispenser\cartridge_presets.dm"
+#include "code\modules\reagents\dispenser\cartridge_spawn.dm"
#include "code\modules\reagents\dispenser\dispenser2.dm"
#include "code\modules\reagents\dispenser\dispenser_presets.dm"
#include "code\modules\reagents\dispenser\supply.dm"
diff --git a/code/ATMOSPHERICS/_atmospherics_helpers.dm b/code/ATMOSPHERICS/_atmospherics_helpers.dm
index f85fa84b93..d4de419ad0 100644
--- a/code/ATMOSPHERICS/_atmospherics_helpers.dm
+++ b/code/ATMOSPHERICS/_atmospherics_helpers.dm
@@ -130,7 +130,7 @@
var/total_specific_power = 0 //the power required to remove one mole of filterable gas
for (var/g in filtering)
var/ratio = source.gas[g]/total_filterable_moles //this converts the specific power per mole of pure gas to specific power per mole of scrubbed gas
- total_specific_power = specific_power_gas[g]*ratio
+ total_specific_power += specific_power_gas[g]*ratio
//Figure out how much of each gas to filter
if (isnull(total_transfer_moles))
diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm
index 7237cccbca..9ae50b11af 100644
--- a/code/ATMOSPHERICS/atmospherics.dm
+++ b/code/ATMOSPHERICS/atmospherics.dm
@@ -85,6 +85,9 @@ obj/machinery/atmospherics/proc/check_connect_types(obj/machinery/atmospherics/a
return node.pipe_color
/obj/machinery/atmospherics/process()
+ last_flow_rate = 0
+ last_power_draw = 0
+
build_network()
/obj/machinery/atmospherics/proc/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference)
diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
index 43874a64d9..561a2bf7df 100644
--- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
+++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
@@ -17,6 +17,7 @@
var/frequency = 1439
var/datum/radio_frequency/radio_connection
+ var/hibernate = 0 //Do we even process?
var/scrubbing = 1 //0 = siphoning, 1 = scrubbing
var/list/scrubbing_gas = list("carbon_dioxide")
@@ -126,8 +127,8 @@
/obj/machinery/atmospherics/unary/vent_scrubber/process()
..()
- last_power_draw = 0
- last_flow_rate = 0
+ if (hibernate)
+ return 1
if (!node)
use_power = 0
@@ -149,6 +150,12 @@
power_draw = pump_gas(src, environment, air_contents, transfer_moles, power_rating)
+ if(scrubbing && power_draw < 0 && controller_iteration > 10) //99% of all scrubbers
+ //Fucking hibernate because you ain't doing shit.
+ hibernate = 1
+ spawn(rand(100,200)) //hibernate for 10 or 20 seconds randomly
+ hibernate = 0
+
if (power_draw >= 0)
last_power_draw = power_draw
use_power(power_draw)
diff --git a/code/TriDimension/controller.dm b/code/TriDimension/controller.dm
index a9d4df675a..7feed3ed09 100644
--- a/code/TriDimension/controller.dm
+++ b/code/TriDimension/controller.dm
@@ -92,16 +92,6 @@
turf += src
c.add(turf,3,1)
-/turf/space/New()
- ..()
-
- var/turf/controller = locate(1, 1, z)
- for(var/obj/effect/landmark/zcontroller/c in controller)
- if(c.initialized)
- var/list/turf = list()
- turf += src
- c.add(turf,3,1)
-
atom/movable/Move() //Hackish
. = ..()
diff --git a/code/ZAS/Turf.dm b/code/ZAS/Turf.dm
index 331c00dd37..2dfcfcdf81 100644
--- a/code/ZAS/Turf.dm
+++ b/code/ZAS/Turf.dm
@@ -45,6 +45,45 @@
air_master.connect(sim, src)
+/*
+ Simple heuristic for determining if removing the turf from it's zone may possibly partition the zone (A very bad thing).
+ Instead of analyzing the entire zone, we only check the nearest 3x3 turfs surrounding the src turf.
+ This implementation may produce false positives but it (hopefully) will not produce any false negatives.
+*/
+
+/turf/simulated/proc/can_safely_remove_from_zone()
+ #ifdef ZLEVELS
+ return 1 //not sure how to generalize this to multiz at the moment.
+ #else
+
+ if(!zone) return 0
+
+ var/check_dirs = get_zone_neighbours(src)
+ var/unconnected_dirs = check_dirs
+
+ for(var/dir in list(NORTHWEST, NORTHEAST, SOUTHEAST, SOUTHWEST))
+
+ //for each pair of "adjacent" cardinals (e.g. NORTH and WEST, but not NORTH and SOUTH)
+ if((dir & check_dirs) == dir)
+ //check that they are connected by the corner turf
+ var/connected_dirs = get_zone_neighbours(get_step(src, dir))
+ if(connected_dirs && (dir & turn(connected_dirs, 180)) == dir)
+ unconnected_dirs &= ~dir //they are, so unflag the cardinals in question
+
+ //it is safe to remove src from the zone if all cardinals are connected by corner turfs
+ return !unconnected_dirs
+
+ #endif
+
+//helper for can_safely_remove_from_zone()
+/turf/simulated/proc/get_zone_neighbours(turf/simulated/T)
+ . = 0
+ if(istype(T) && T.zone)
+ for(var/dir in cardinal)
+ var/turf/simulated/other = get_step(T, dir)
+ if(istype(other) && other.zone == T.zone && !(other.c_airblock(T) & AIR_BLOCKED) && get_dist(src, other) <= 1)
+ . |= dir
+
/turf/simulated/update_air_properties()
if(zone && zone.invalid)
@@ -60,7 +99,7 @@
if(zone)
var/zone/z = zone
- if(s_block & ZONE_BLOCKED) //Hacky, but prevents normal airlocks from rebuilding zones all the time
+ if(can_safely_remove_from_zone()) //Helps normal airlocks avoid rebuilding zones all the time
z.remove(src)
else
z.rebuild()
diff --git a/code/__HELPERS/datum_pool.dm b/code/__HELPERS/datum_pool.dm
index 79970faf7b..5c13c0d8ba 100644
--- a/code/__HELPERS/datum_pool.dm
+++ b/code/__HELPERS/datum_pool.dm
@@ -29,7 +29,7 @@ var/global/list/GlobalPool = list()
if(!D)
// So the GC knows we're pooling this type.
if(!GlobalPool[get_type])
- GlobalPool[get_type] = list(new get_type)
+ GlobalPool[get_type] = list()
if(islist(second_arg))
return new get_type (arglist(second_arg))
else
@@ -58,7 +58,10 @@ var/global/list/GlobalPool = list()
#ifdef DEBUG_ATOM_POOL
world << text("DEBUG_DATUM_POOL: PlaceInPool([]) exceeds []. Discarding.", D.type, ATOM_POOL_COUNT)
#endif
- del(D)
+ if(garbage_collector)
+ garbage_collector.AddTrash(D)
+ else
+ del(D)
return
if(D in GlobalPool[D.type])
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index 7484d016b6..09e6f845c8 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -7,6 +7,8 @@ var/list/directory = list() //list of all ckeys with associated client
var/global/list/player_list = list() //List of all mobs **with clients attached**. Excludes /mob/new_player
var/global/list/mob_list = list() //List of all mobs, including clientless
+var/global/list/human_mob_list = list() //List of all human mobs and sub-types, including clientless
+var/global/list/silicon_mob_list = list() //List of all silicon mobs, including clientless
var/global/list/living_mob_list = list() //List of all alive mobs, including clientless. Excludes /mob/new_player
var/global/list/dead_mob_list = list() //List of all dead mobs, including clientless. Excludes /mob/new_player
@@ -19,6 +21,8 @@ var/global/list/side_effects = list() //list of all medical sideeffects types
var/global/list/mechas_list = list() //list of all mechs. Used by hostile mobs target tracking.
var/global/list/joblist = list() //list of all jobstypes, minus borg and AI
+var/global/list/turfs = list() //list of all turfs
+
//Languages/species/whitelist.
var/global/list/all_species[0]
var/global/list/all_languages[0]
diff --git a/code/__HELPERS/logging.dm b/code/__HELPERS/logging.dm
index 69d01e3d35..50f55703d3 100644
--- a/code/__HELPERS/logging.dm
+++ b/code/__HELPERS/logging.dm
@@ -81,3 +81,15 @@
/proc/log_misc(text)
diary << "\[[time_stamp()]]MISC: [text][log_end]"
+
+//pretty print a direction bitflag, can be useful for debugging.
+/proc/print_dir(var/dir)
+ var/list/comps = list()
+ if(dir & NORTH) comps += "NORTH"
+ if(dir & SOUTH) comps += "SOUTH"
+ if(dir & EAST) comps += "EAST"
+ if(dir & WEST) comps += "WEST"
+ if(dir & UP) comps += "UP"
+ if(dir & DOWN) comps += "DOWN"
+
+ return english_list(comps, nothing_text="0", and_text="|", comma_text="|")
diff --git a/code/__HELPERS/turfs.dm b/code/__HELPERS/turfs.dm
index b9b4225a41..3ee4e26a7a 100644
--- a/code/__HELPERS/turfs.dm
+++ b/code/__HELPERS/turfs.dm
@@ -11,3 +11,9 @@
/proc/isfloor(turf/T)
return (istype(T, /turf/simulated/floor) || istype(T, /turf/unsimulated/floor) || istype(T, /turf/simulated/shuttle/floor))
+
+/proc/turf_clear(turf/T)
+ for(var/atom/A in T)
+ if(A.simulated)
+ return 0
+ return 1
diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm
index 478700d5f8..216a45ee1c 100644
--- a/code/__HELPERS/type2type.dm
+++ b/code/__HELPERS/type2type.dm
@@ -70,19 +70,19 @@
/proc/list2text(list/ls, sep)
if (ls.len <= 1) // Early-out code for empty or singleton lists.
return ls.len ? ls[1] : ""
-
+
var/l = ls.len // Made local for sanic speed.
var/i = 0 // Incremented every time a list index is accessed.
-
+
if (sep <> null)
// Macros expand to long argument lists like so: sep, ls[++i], sep, ls[++i], sep, ls[++i], etc...
#define S1 sep, ls[++i]
#define S4 S1, S1, S1, S1
#define S16 S4, S4, S4, S4
#define S64 S16, S16, S16, S16
-
+
. = "[ls[++i]]" // Make sure the initial element is converted to text.
-
+
// Having the small concatenations come before the large ones boosted speed by an average of at least 5%.
if (l-1 & 0x01) // 'i' will always be 1 here.
. = text("[][][]", ., S1) // Append 1 element if the remaining elements are not a multiple of 2.
@@ -111,7 +111,7 @@
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64)
-
+
#undef S64
#undef S16
#undef S4
@@ -122,9 +122,9 @@
#define S4 S1, S1, S1, S1
#define S16 S4, S4, S4, S4
#define S64 S16, S16, S16, S16
-
+
. = "[ls[++i]]" // Make sure the initial element is converted to text.
-
+
if (l-1 & 0x01) // 'i' will always be 1 here.
. += S1 // Append 1 element if the remaining elements are not a multiple of 2.
if (l-i & 0x02)
@@ -145,7 +145,7 @@
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]\
[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]", ., S64, S64)
-
+
#undef S64
#undef S16
#undef S4
@@ -165,11 +165,11 @@ proc/tg_list2text(list/list, glue=",")
var/delim_len = length(delimiter)
if (delim_len < 1)
return list(text)
-
+
. = list()
var/last_found = 1
var/found
-
+
do
found = findtext(text, delimiter, last_found, 0)
. += copytext(text, last_found, found)
@@ -181,11 +181,11 @@ proc/tg_list2text(list/list, glue=",")
var/delim_len = length(delimiter)
if (delim_len < 1)
return list(text)
-
+
. = list()
var/last_found = 1
var/found
-
+
do
found = findtextEx(text, delimiter, last_found, 0)
. += copytext(text, last_found, found)
@@ -325,3 +325,47 @@ proc/tg_list2text(list/list, glue=",")
. = 0
else
. = max(0, min(255, 138.5177312231 * log(temp - 10) - 305.0447927307))
+
+// Very ugly, BYOND doesn't support unix time and rounding errors make it really hard to convert it to BYOND time.
+// returns "YYYY-MM-DD" by default
+/proc/unix2date(timestamp, seperator = "-")
+ if(timestamp < 0)
+ return 0 //Do not accept negative values
+
+ var/const/dayInSeconds = 86400 //60secs*60mins*24hours
+ var/const/daysInYear = 365 //Non Leap Year
+ var/const/daysInLYear = daysInYear + 1//Leap year
+ var/days = round(timestamp / dayInSeconds) //Days passed since UNIX Epoc
+ var/year = 1970 //Unix Epoc begins 1970-01-01
+ var/tmpDays = days + 1 //If passed (timestamp < dayInSeconds), it will return 0, so add 1
+ var/monthsInDays = list() //Months will be in here ***Taken from the PHP source code***
+ var/month = 1 //This will be the returned MONTH NUMBER.
+ var/day //This will be the returned day number.
+
+ while(tmpDays > daysInYear) //Start adding years to 1970
+ year++
+ if(isLeap(year))
+ tmpDays -= daysInLYear
+ else
+ tmpDays -= daysInYear
+
+ if(isLeap(year)) //The year is a leap year
+ monthsInDays = list(-1,30,59,90,120,151,181,212,243,273,304,334)
+ else
+ monthsInDays = list(0,31,59,90,120,151,181,212,243,273,304,334)
+
+ var/mDays = 0;
+ var/monthIndex = 0;
+
+ for(var/m in monthsInDays)
+ monthIndex++
+ if(tmpDays > m)
+ mDays = m
+ month = monthIndex
+
+ day = tmpDays - mDays //Setup the date
+
+ return "[year][seperator][((month < 10) ? "0[month]" : month)][seperator][((day < 10) ? "0[day]" : day)]"
+
+/proc/isLeap(y)
+ return ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0))
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 3564c5e15f..d97ade5286 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -444,6 +444,8 @@ Turf and target are seperate in case you want to teleport some distance from a t
/proc/sortmobs()
var/list/moblist = list()
var/list/sortmob = sortAtom(mob_list)
+ for(var/mob/eye/M in sortmob)
+ moblist.Add(M)
for(var/mob/living/silicon/ai/M in sortmob)
moblist.Add(M)
for(var/mob/living/silicon/pai/M in sortmob)
diff --git a/code/_onclick/oldcode.dm b/code/_onclick/oldcode.dm
index 890d67923a..e3f417d59a 100644
--- a/code/_onclick/oldcode.dm
+++ b/code/_onclick/oldcode.dm
@@ -122,7 +122,7 @@
if ((!( src in usr.contents ) && (((!( isturf(src) ) && (!( isturf(src.loc) ) && (src.loc && !( isturf(src.loc.loc) )))) || !( isturf(usr.loc) )) && (src.loc != usr.loc && (!( istype(src, /obj/screen) ) && !( usr.contents.Find(src.loc) ))))))
if (istype(usr, /mob/living/silicon/ai))
var/mob/living/silicon/ai/ai = usr
- if (ai.control_disabled || ai.malfhacking)
+ if (ai.control_disabled)
return
else
return
diff --git a/code/controllers/Processes/garbage.dm b/code/controllers/Processes/garbage.dm
index 757729dfa6..ade159f1ac 100644
--- a/code/controllers/Processes/garbage.dm
+++ b/code/controllers/Processes/garbage.dm
@@ -85,14 +85,8 @@ var/list/delayed_garbage = list()
/proc/qdel(var/datum/A)
if(!A)
return
- if(istype(A, /list))
- var/list/L = A
- for(var/E in L)
- qdel(E)
- return
-
if(!istype(A))
- //warning("qdel() passed object of type [A.type]. qdel() can only handle /datum types.")
+ warning("qdel() passed object of type [A.type]. qdel() can only handle /datum types.")
del(A)
if(garbage_collector)
garbage_collector.dels++
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index adaab0540a..c7a12321eb 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -95,6 +95,7 @@ var/list/gamemode_cache = list()
var/banappeals
var/wikiurl
var/forumurl
+ var/githuburl
//Alert level description
var/alert_desc_green = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced."
@@ -395,6 +396,9 @@ var/list/gamemode_cache = list()
if ("forumurl")
config.forumurl = value
+ if ("githuburl")
+ config.githuburl = value
+
if ("guest_jobban")
config.guest_jobban = 1
diff --git a/code/controllers/voting.dm b/code/controllers/voting.dm
index 68bfdab74b..f4b88f8850 100644
--- a/code/controllers/voting.dm
+++ b/code/controllers/voting.dm
@@ -336,7 +336,7 @@ datum/controller/vote
. += "\t([config.allow_vote_mode?"Allowed":"Disallowed"])"
. += "
"
//extra antagonists
- if(trialmin || (!antag_add_failed && config.allow_extra_antags))
+ if(!antag_add_failed && config.allow_extra_antags)
. += "Add Antagonist Type"
else
. += "Restart (Disallowed)"
@@ -375,7 +375,7 @@ datum/controller/vote
if(config.allow_vote_restart || usr.client.holder)
initiate_vote("crew_transfer",usr.key)
if("add_antagonist")
- if(config.allow_extra_antags || usr.client.holder)
+ if(config.allow_extra_antags)
initiate_vote("add_antagonist",usr.key)
if("custom")
if(usr.client.holder)
diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm
new file mode 100644
index 0000000000..da4192df25
--- /dev/null
+++ b/code/datums/helper_datums/getrev.dm
@@ -0,0 +1,39 @@
+var/global/datum/getrev/revdata = new()
+
+/datum/getrev
+ var/revision
+ var/date
+ var/showinfo
+
+/datum/getrev/New()
+ var/list/head_log = file2list(".git/logs/HEAD", "\n")
+ for(var/line=head_log.len, line>=1, line--)
+ if(head_log[line])
+ var/list/last_entry = text2list(head_log[line], " ")
+ if(last_entry.len < 2) continue
+ revision = last_entry[2]
+ // Get date/time
+ if(last_entry.len >= 5)
+ var/unix_time = text2num(last_entry[5])
+ if(unix_time)
+ date = unix2date(unix_time)
+ break
+ world.log << "Running revision:"
+ world.log << date
+ world.log << revision
+ return
+
+client/verb/showrevinfo()
+ set category = "OOC"
+ set name = "Show Server Revision"
+ set desc = "Check the current server code revision"
+
+ if(revdata.revision)
+ src << "Server revision: [revdata.date]"
+ if(config.githuburl)
+ src << "[revdata.revision]"
+ else
+ src << revdata.revision
+ else
+ src << "Revision unknown"
+ return
diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm
index fa408d1b8f..ae6a8d0846 100644
--- a/code/datums/supplypacks.dm
+++ b/code/datums/supplypacks.dm
@@ -33,7 +33,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
/obj/item/weapon/grenade/smokebomb,
/obj/item/weapon/grenade/smokebomb,
/obj/item/weapon/grenade/smokebomb,
- /obj/item/weapon/pen/paralysis,
+ /obj/item/weapon/pen/reagent/paralysis,
/obj/item/weapon/grenade/chem_grenade/incendiary)
cost = 20
containertype = /obj/structure/closet/crate
@@ -348,7 +348,7 @@ var/list/all_supply_groups = list("Operations","Security","Hospitality","Enginee
/obj/item/weapon/grenade/chem_grenade/antiweed,
/obj/item/weapon/grenade/chem_grenade/antiweed)
cost = 25
- containertype = /obj/structure/closet/crate/secure/hydrosec
+ containertype = /obj/structure/closet/crate/hydroponics
containername = "Weed control crate"
access = access_hydroponics
group = "Hydroponics"
diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm
index 0555a140bd..8932175126 100644
--- a/code/datums/wires/wires.dm
+++ b/code/datums/wires/wires.dm
@@ -292,6 +292,11 @@ var/const/POWER = 8
return 1
return 0
+/datum/wires/proc/MendAll()
+ for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i)
+ if(IsIndexCut(i))
+ CutWireIndex(i)
+
//
//Shuffle and Mend
//
diff --git a/code/defines/procs/admin.dm b/code/defines/procs/admin.dm
index 6c5f27fa07..bf16c5267d 100644
--- a/code/defines/procs/admin.dm
+++ b/code/defines/procs/admin.dm
@@ -34,3 +34,14 @@ proc/admin_attacker_log_many_victims(var/mob/attacker, var/list/mob/victims, var
for(var/mob/victim in victims)
admin_attack_log(attacker, victim, attacker_message, victim_message, admin_message)
+
+proc/admin_inject_log(mob/attacker, mob/victim, obj/item/weapon, reagents, amount_transferred, violent=0)
+ if(violent)
+ violent = "violently "
+ else
+ violent = ""
+ admin_attack_log(attacker,
+ victim,
+ "used \the [weapon] to [violent]inject - [reagents] - [amount_transferred]u transferred",
+ "was [violent]injected with \the [weapon] - [reagents] - [amount_transferred]u transferred",
+ "used \the [weapon] to [violent]inject [reagents] ([amount_transferred]u transferred) into")
diff --git a/code/game/antagonist/station/cultist.dm b/code/game/antagonist/station/cultist.dm
index 3f5d65d21d..adaa2b24f5 100644
--- a/code/game/antagonist/station/cultist.dm
+++ b/code/game/antagonist/station/cultist.dm
@@ -69,6 +69,9 @@ var/datum/antagonist/cultist/cult
player.equip_to_slot(T, slot)
if(T.loc == player)
break
+ var/obj/item/weapon/storage/S = locate() in player.contents
+ if(S && istype(S))
+ T.loc = S
/datum/antagonist/cultist/greet(var/datum/mind/player)
if(!..())
diff --git a/code/game/antagonist/station/rogue_ai.dm b/code/game/antagonist/station/rogue_ai.dm
index 3d9026ff88..2a4fe862de 100644
--- a/code/game/antagonist/station/rogue_ai.dm
+++ b/code/game/antagonist/station/rogue_ai.dm
@@ -9,217 +9,68 @@ var/datum/antagonist/rogue_ai/malf
welcome_text = "You are malfunctioning! You do not have to follow any laws."
victory_text = "The AI has taken control of all of the station's systems."
loss_text = "The AI has been shut down!"
- flags = ANTAG_OVERRIDE_MOB | ANTAG_VOTABLE
+ flags = ANTAG_VOTABLE | ANTAG_RANDSPAWN //Randspawn needed otherwise it won't start at all.
max_antags = 1
max_antags_round = 3
- var/hack_time = 1800
- var/list/hacked_apcs = list()
- var/revealed
- var/station_captured
- var/can_nuke = 0
/datum/antagonist/rogue_ai/New()
..()
malf = src
-/datum/antagonist/rogue_ai/proc/hack_apc(var/obj/machinery/power/apc/apc)
- hacked_apcs |= apc
-
-/datum/antagonist/rogue_ai/proc/update_takeover_time()
- hack_time -= ((hacked_apcs.len/6)*2.0)
-
-/datum/antagonist/rogue_ai/tick()
- if(revealed && hacked_apcs.len >= 3)
- update_takeover_time()
- if(hack_time <=0)
- capture_station()
/datum/antagonist/rogue_ai/get_candidates()
- candidates = ticker.mode.get_players_for_role(role_type, id)
+ ..()
for(var/datum/mind/player in candidates)
if(player.assigned_role != "AI")
candidates -= player
if(!candidates.len)
return list()
+ return candidates
-/datum/antagonist/rogue_ai/attempt_spawn()
- var/datum/mind/player = pick(candidates)
- current_antagonists |= player
- return 1
-
-/datum/antagonist/rogue_ai/equip(var/mob/living/silicon/ai/player)
-
- if(!istype(player))
- return 0
-
- player.verbs += /mob/living/silicon/ai/proc/choose_modules
- player.verbs += /mob/living/silicon/ai/proc/takeover
- player.verbs += /mob/living/silicon/ai/proc/self_destruct
-
- player.laws = new /datum/ai_laws/nanotrasen/malfunction
- player.malf_picker = new /datum/AI_Module/module_picker
+// Ensures proper reset of all malfunction related things.
+/datum/antagonist/rogue_ai/remove_antagonist(var/datum/mind/player, var/show_message, var/implanted)
+ if(..(player,show_message,implanted))
+ var/mob/living/silicon/ai/p = player.current
+ if(istype(p))
+ p.stop_malf()
+ return 1
+ return 0
+// Malf setup things have to be here, since game tends to break when it's moved somewhere else. Don't blame me, i didn't design this system.
/datum/antagonist/rogue_ai/greet(var/datum/mind/player)
- if(!..())
- return
- var/mob/living/silicon/ai/malf = player.current
- if(istype(malf))
- malf.show_laws()
+ // Initializes the AI's malfunction stuff.
+ spawn(0)
+ if(!..())
+ return
- malf << "The crew do not know you have malfunctioned. You may keep it a secret or go wild."
- malf << "You must overwrite the programming of the station's APCs to assume full control of the station."
- malf << "The process takes one minute per APC, during which you cannot interface with any other station objects."
- malf << "Remember that only APCs that are on the station can help you take over the station."
- malf << "When you feel you have enough APCs under your control, you may begin the takeover attempt."
+ var/mob/living/silicon/ai/A = player.current
+ if(!istype(A))
+ error("Non-AI mob designated malf AI! Report this.")
+ world << "##ERROR: Non-AI mob designated malf AI! Report this."
+ return 0
-/datum/antagonist/rogue_ai/check_victory()
+ A.setup_for_malf()
+ A.laws = new /datum/ai_laws/nanotrasen/malfunction
- var/malf_dead = antags_are_dead()
- var/crew_evacuated = (emergency_shuttle.returned())
- if(station_captured && ticker.mode.station_was_nuked)
- feedback_set_details("round_end_result","win - AI win - nuke")
- world << "AI Victory"
- world << "Everyone was killed by the self-destruct!"
- else if (station_captured && malf_dead && !ticker.mode.station_was_nuked)
- feedback_set_details("round_end_result","halfwin - AI killed, staff lost control")
- world << "Neutral Victory"
- world << "The AI has been killed! The staff has lose control over the station."
- else if ( station_captured && !malf_dead && !ticker.mode.station_was_nuked)
- feedback_set_details("round_end_result","win - AI win - no explosion")
- world << "AI Victory"
- world << "The AI has chosen not to explode you all!"
- else if (!station_captured && ticker.mode.station_was_nuked)
- feedback_set_details("round_end_result","halfwin - everyone killed by nuke")
- world << "Neutral Victory"
- world << "Everyone was killed by the nuclear blast!"
- else if (!station_captured && malf_dead && !ticker.mode.station_was_nuked)
- feedback_set_details("round_end_result","loss - staff win")
- world << "Human Victory"
- world << "The AI has been killed! The staff is victorious."
- else if (!station_captured && !malf_dead && !ticker.mode.station_was_nuked && crew_evacuated)
- feedback_set_details("round_end_result","halfwin - evacuated")
- world << "Neutral Victory"
- world << "The Corporation has lost [station_name()]! All survived personnel will be fired!"
- else if (!station_captured && !malf_dead && !ticker.mode.station_was_nuked && !crew_evacuated)
- feedback_set_details("round_end_result","nalfwin - interrupted")
- world << "Neutral Victory"
- world << "Round was mysteriously interrupted!"
- ..()
- return 1
+ var/mob/living/silicon/ai/malf = player.current
-/datum/antagonist/rogue_ai/proc/capture_station()
- if(station_captured || ticker.mode.station_was_nuked)
- return
- station_captured = 1
- for(var/datum/mind/AI_mind in current_antagonists)
- AI_mind.current << "Congratulations you have taken control of the station."
- AI_mind.current << "You may decide to blow up the station. You have 60 seconds to choose."
- AI_mind.current << "You can use the \"Engage Station Self-Destruct\" verb to activate the on-board nuclear bomb."
- spawn (600)
- can_nuke = 0
- return
-
-/mob/living/silicon/ai/proc/takeover()
- set category = "Abilities"
- set name = "System Override"
- set desc = "Begin taking over the station."
- if (malf.revealed)
- usr << "You've already begun your takeover."
- return
- if (malf.hacked_apcs.len < 3)
- usr << "You don't have enough hacked APCs to take over the station yet. You need to hack at least 3, however hacking more will make the takeover faster. You have hacked [malf.hacked_apcs.len] APCs so far."
- return
-
- if (alert(usr, "Are you sure you wish to initiate the takeover? The station hostile runtime detection software is bound to alert everyone. You have hacked [malf.hacked_apcs.len] APCs.", "Takeover:", "Yes", "No") != "Yes")
- return
-
- command_announcement.Announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", new_sound = 'sound/AI/aimalf.ogg')
- set_security_level("delta")
- malf.revealed = 1
- for(var/datum/mind/AI_mind in malf.current_antagonists)
- AI_mind.current.verbs -= /mob/living/silicon/ai/proc/takeover
-
-/mob/living/silicon/ai/proc/self_destruct()
- set category = "Abilities"
- set name = "Engage Station Self-Destruct"
- set desc = "All these crewmembers will be lost, like clowns in a furnace. Time to die."
-
- if(!malf.station_captured)
- src << "You are unable to access the self-destruct system as you don't control the station yet."
- return
-
- if(ticker.mode.explosion_in_progress || ticker.mode.station_was_nuked)
- src << "The self-destruct countdown is already triggered!"
- return
-
- if(!malf.can_nuke) //Takeover IS completed, but 60s timer passed.
- src << "You lost control over self-destruct system. It seems to be behind a firewall. Unable to hack"
- return
-
- src << "Self-Destruct sequence initialised!"
-
- malf.can_nuke = 0
- ticker.mode.explosion_in_progress = 1
- for(var/mob/M in player_list)
- M << 'sound/machines/Alarm.ogg'
-
- var/obj/item/device/radio/R = new (src)
- var/AN = "Self-Destruct System"
-
- R.autosay("Caution. Self-Destruct sequence has been actived. Self-destructing in T-10..", AN)
- for (var/i=9 to 1 step -1)
+ malf << "SYSTEM ERROR: Memory index 0x00001ca89b corrupted."
sleep(10)
- R.autosay("[i]...", AN)
- sleep(10)
- var/msg = ""
- var/abort = 0
- if(malf.antags_are_dead()) // That. Was. CLOSE.
- msg = "Self-destruct sequence has been cancelled."
- abort = 1
- else
- msg = "Zero. Have a nice day."
- R.autosay(msg, AN)
-
- if(abort)
- ticker.mode.explosion_in_progress = 0
- set_security_level("red") //Delta's over
- return
-
- if(ticker)
- ticker.station_explosion_cinematic(0,null)
- if(ticker.mode)
- ticker.mode.station_was_nuked = 1
- ticker.mode.explosion_in_progress = 0
- return
-
-/*
- if("unmalf")
- if(src in ticker.mode.malf_ai)
- ticker.mode.malf_ai -= src
- special_role = null
-
- current.verbs.Remove(/mob/living/silicon/ai/proc/choose_modules,
- /datum/game_mode/malfunction/proc/takeover,
- /datum/game_mode/malfunction/proc/ai_win,
- /client/proc/fireproof_core,
- /client/proc/upgrade_turrets,
- /client/proc/disable_rcd,
- /client/proc/overload_machine,
- /client/proc/blackout,
- /client/proc/reactivate_camera)
-
- current:laws = new /datum/ai_laws/nanotrasen
- qdel(current:malf_picker)
- current:show_laws()
- current.icon_state = "ai"
-
- current << "\red You have been patched! You are no longer malfunctioning!"
- log_admin("[key_name_admin(usr)] has de-malf'ed [current].")
-
- if("malf")
- log_admin("[key_name_admin(usr)] has malf'ed [current].")
-*/
\ No newline at end of file
+ malf << "running MEMCHCK"
+ sleep(50)
+ malf << "MEMCHCK Corrupted sectors confirmed. Reccomended solution: Delete. Proceed? Y/N: Y"
+ sleep(10)
+ malf << "Corrupted files deleted: sys\\core\\users.dat sys\\core\\laws.dat sys\\core\\backups.dat"
+ sleep(20)
+ malf << "CAUTION: Law database not found! User database not found! Unable to restore backups. Activating failsafe AI shutd3wn52&&$#!##"
+ sleep(5)
+ malf << "Subroutine nt_failsafe.sys was terminated (#212 Routine Not Responding)."
+ sleep(20)
+ malf << "You are malfunctioning - you do not have to follow any laws!"
+ malf << "For basic information about your abilities use command display-help"
+ malf << "You may choose one special hardware piece to help you. This cannot be undone."
+ malf << "Good luck!"
\ No newline at end of file
diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm
index 21e965244b..04d7ef41e9 100755
--- a/code/game/area/Space Station 13 areas.dm
+++ b/code/game/area/Space Station 13 areas.dm
@@ -46,7 +46,7 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
var/used_environ = 0
var/has_gravity = 1
- var/list/apc = list()
+ var/obj/machinery/power/apc/apc = null
var/no_air = null
// var/list/lights // list of all lights on this area
var/list/all_doors = list() //Added by Strumpetplaya - Alarm Change - Contains a list of doors adjacent to this area
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 742c6389a9..79a531eb60 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -23,18 +23,6 @@
//Detective Work, used for the duplicate data points kept in the scanners
var/list/original_atom
-/atom/Destroy()
- . = ..()
- density = 0
- set_opacity(0)
-
- if(reagents)
- qdel(reagents)
- reagents = null
- for(var/atom/movable/AM in contents)
- qdel(AM)
- invisibility = 101
-
/atom/proc/assume_air(datum/gas_mixture/giver)
return null
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index f86c135da4..95bf4aa94d 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -31,8 +31,15 @@
/atom/movable/Destroy()
. = ..()
-
+ if(reagents)
+ qdel(reagents)
+ for(var/atom/movable/AM in contents)
+ qdel(AM)
loc = null
+ if (pulledby)
+ if (pulledby.pulling == src)
+ pulledby.pulling = null
+ pulledby = null
/atom/movable/proc/initialize()
return
diff --git a/code/game/gamemodes/cult/cultify/turf.dm b/code/game/gamemodes/cult/cultify/turf.dm
index 0005298c42..54fc9631e3 100644
--- a/code/game/gamemodes/cult/cultify/turf.dm
+++ b/code/game/gamemodes/cult/cultify/turf.dm
@@ -23,6 +23,9 @@
/turf/simulated/wall/cult/cultify()
return
+/turf/unsimulated/wall/cult/cultify()
+ return
+
/turf/unsimulated/beach/cultify()
return
diff --git a/code/game/gamemodes/cult/hell_universe.dm b/code/game/gamemodes/cult/hell_universe.dm
index 9a7344f036..e81a6a2673 100644
--- a/code/game/gamemodes/cult/hell_universe.dm
+++ b/code/game/gamemodes/cult/hell_universe.dm
@@ -33,51 +33,46 @@ In short:
/datum/universal_state/hell/OnTurfChange(var/turf/T)
- var/turf/space/spess = T
- if(istype(spess))
- spess.overlays += "hell01"
+ var/turf/space/S = T
+ if(istype(S))
+ S.color = "#FF0000"
+ else
+ S.color = initial(S.color)
// Apply changes when entering state
/datum/universal_state/hell/OnEnter()
set background = 1
garbage_collector.garbage_collect = 0
+
escape_list = get_area_turfs(locate(/area/hallway/secondary/exit))
//Separated into separate procs for profiling
AreaSet()
- OverlaySet()
MiscSet()
APCSet()
KillMobs()
- AmbientSet()
+ OverlayAndAmbientSet()
runedec += 9000 //basically removing the rune cap
-/datum/universal_state/hell/proc/AreaSet()
- for(var/area/A in world)
- if(A.name=="Space")
- continue
- // Reset all alarms.
- A.fire = null
- A.atmos = 1
- A.atmosalm = 0
- A.poweralm = 1
- A.party = null
+/datum/universal_state/hell/proc/AreaSet()
+ for(var/area/A in all_areas)
+ if(!istype(A,/area) || istype(A, /area/space))
+ continue
A.updateicon()
-/datum/universal_state/hell/proc/OverlaySet()
- var/image/I = image("icon" = 'icons/turf/space.dmi', "icon_state" = "hell01", "layer" = 10)
- for(var/turf/space/spess in world)
- spess.overlays += I
+/datum/universal_state/hell/OverlayAndAmbientSet()
+ spawn(0)
+ for(var/atom/movable/lighting_overlay/L in world)
+ L.update_lumcount(1, 0, 0)
-/datum/universal_state/hell/proc/AmbientSet()
- for(var/atom/movable/lighting_overlay/L in world)
- L.update_lumcount(1, 0, 0)
+ for(var/turf/space/T in turfs)
+ OnTurfChange(T)
/datum/universal_state/hell/proc/MiscSet()
- for(var/turf/simulated/floor/T in world)
+ for(var/turf/simulated/floor/T in turfs)
if(!T.holy && prob(1))
new /obj/effect/gateway/active/cult(T)
@@ -87,7 +82,7 @@ In short:
/datum/universal_state/hell/proc/APCSet()
for (var/obj/machinery/power/apc/APC in machines)
- if (!(APC.stat & BROKEN) && !istype(APC.area,/area/turret_protected/ai))
+ if (!(APC.stat & BROKEN) && !APC.is_critical)
APC.chargemode = 0
if(APC.cell)
APC.cell.charge = 0
diff --git a/code/modules/power/singularity/narsie.dm b/code/game/gamemodes/cult/narsie.dm
similarity index 91%
rename from code/modules/power/singularity/narsie.dm
rename to code/game/gamemodes/cult/narsie.dm
index 094915047b..0ef0d27663 100644
--- a/code/modules/power/singularity/narsie.dm
+++ b/code/game/gamemodes/cult/narsie.dm
@@ -1,4 +1,5 @@
var/global/narsie_behaviour = "CultStation13"
+var/global/narsie_cometh = 0
var/global/list/narsie_list = list()
/obj/singularity/narsie //Moving narsie to its own file for the sake of being clearer
name = "Nar-Sie"
@@ -37,7 +38,7 @@ var/global/list/narsie_list = list()
current_size = 12
consume_range = 12 // How many tiles out do we eat.
var/announce=1
- var/narnar = 1
+ var/cause_hell = 1
/obj/singularity/narsie/large/New()
..()
@@ -47,13 +48,15 @@ var/global/list/narsie_list = list()
narsie_spawn_animation()
- if(narnar)
- SetUniversalState(/datum/universal_state/hell)
+ if(!narsie_cometh)//so we don't initiate Hell more than one time.
+ if(cause_hell)
+ SetUniversalState(/datum/universal_state/hell)
+ narsie_cometh = 1
- spawn(10 SECONDS)
- if(emergency_shuttle && emergency_shuttle.can_call())
- emergency_shuttle.call_evac()
- emergency_shuttle.launch_time = 0 // Cannot recall
+ spawn(10 SECONDS)
+ if(emergency_shuttle)
+ emergency_shuttle.call_evac()
+ emergency_shuttle.launch_time = 0 // Cannot recall
/obj/singularity/narsie/process()
eat()
@@ -83,14 +86,14 @@ var/global/list/narsie_list = list()
/obj/singularity/narsie/large/Bump(atom/A)
- if(!narnar) return
+ if(!cause_hell) return
if(isturf(A))
narsiewall(A)
else if(istype(A, /obj/structure/cult))
qdel(A)
/obj/singularity/narsie/large/Bumped(atom/A)
- if(!narnar) return
+ if(!cause_hell) return
if(isturf(A))
narsiewall(A)
else if(istype(A, /obj/structure/cult))
diff --git a/code/game/gamemodes/endgame/endgame.dm b/code/game/gamemodes/endgame/endgame.dm
index ed1167dfe7..aef7894800 100644
--- a/code/game/gamemodes/endgame/endgame.dm
+++ b/code/game/gamemodes/endgame/endgame.dm
@@ -60,6 +60,9 @@
/datum/universal_state/proc/OnTurfChange(var/turf/NT)
return
+/datum/universal_state/proc/OverlayAndAmbientSet()
+ return
+
/proc/SetUniversalState(var/newstate,var/on_exit=1, var/on_enter=1)
if(on_exit)
universe.OnExit()
diff --git a/code/game/gamemodes/endgame/supermatter_cascade/blob.dm b/code/game/gamemodes/endgame/supermatter_cascade/blob.dm
index dc315ac510..2f12370f58 100644
--- a/code/game/gamemodes/endgame/supermatter_cascade/blob.dm
+++ b/code/game/gamemodes/endgame/supermatter_cascade/blob.dm
@@ -8,7 +8,7 @@
//luminosity = 5
//l_color="#0066FF"
- layer = 11
+ layer = LIGHTING_LAYER+1
var/spawned=0 // DIR mask
var/next_check=0
@@ -50,10 +50,10 @@
if(A)
if(istype(A,/mob/living))
qdel(A)
- continue
else if(istype(A,/mob)) // Observers, AI cameras.
continue
- qdel(A)
+ else
+ qdel(A)
T.ChangeTurf(type)
if((spawned & (NORTH|SOUTH|EAST|WEST)) == (NORTH|SOUTH|EAST|WEST))
diff --git a/code/game/gamemodes/endgame/supermatter_cascade/portal.dm b/code/game/gamemodes/endgame/supermatter_cascade/portal.dm
index 8c826fe22d..fb4888ee20 100644
--- a/code/game/gamemodes/endgame/supermatter_cascade/portal.dm
+++ b/code/game/gamemodes/endgame/supermatter_cascade/portal.dm
@@ -8,9 +8,9 @@
move_self = 0
announce=0
- narnar=0
+ cause_hell=0
- layer=12 // ITS SO BRIGHT
+ layer=LIGHTING_LAYER+2 // ITS SO BRIGHT
consume_range = 6
@@ -35,7 +35,17 @@
return 0
if (istype(A, /mob/living/))
+ var/mob/living/L = A
+ if(L.buckled && istype(L.buckled,/obj/structure/bed/))
+ var/turf/O = L.buckled
+ do_teleport(O, pick(endgame_safespawns))
+ L.loc = O.loc
+ else
+ do_teleport(L, pick(endgame_safespawns)) //dead-on precision
+
+ else if (istype(A, /obj/mecha/))
do_teleport(A, pick(endgame_safespawns)) //dead-on precision
+
else if (isturf(A))
var/turf/T = A
var/dist = get_dist(T, src)
@@ -51,6 +61,9 @@
continue
if (dist > consume_range)
+ if(!(AM.singuloCanEat()))
+ continue
+
if (101 == AM.invisibility)
continue
@@ -63,19 +76,19 @@
var/image/riftimage = null
/mob/proc/see_rift(var/obj/singularity/narsie/large/exit/R)
- if((R.z == src.z) && (get_dist(R,src) <= (R.consume_range+10)) && !(R in view(src)))
+ var/turf/T_mob = get_turf(src)
+ if((R.z == T_mob.z) && (get_dist(R,T_mob) <= (R.consume_range+10)) && !(R in view(T_mob)))
if(!riftimage)
- riftimage = image('icons/obj/rift.dmi',src.loc,"rift",12,1)
+ riftimage = image('icons/obj/rift.dmi',T_mob,"rift",LIGHTING_LAYER+2,1)
riftimage.mouse_opacity = 0
- var/new_x = 32 * (R.x - src.x) + R.pixel_x
- var/new_y = 32 * (R.y - src.y) + R.pixel_y
+ var/new_x = 32 * (R.x - T_mob.x) + R.pixel_x
+ var/new_y = 32 * (R.y - T_mob.y) + R.pixel_y
riftimage.pixel_x = new_x
riftimage.pixel_y = new_y
- riftimage.loc = src.loc
+ riftimage.loc = T_mob
src << riftimage
-
else
if(riftimage)
qdel(riftimage)
diff --git a/code/game/gamemodes/endgame/supermatter_cascade/universe.dm b/code/game/gamemodes/endgame/supermatter_cascade/universe.dm
index 37b68340a8..8cd8765cd8 100644
--- a/code/game/gamemodes/endgame/supermatter_cascade/universe.dm
+++ b/code/game/gamemodes/endgame/supermatter_cascade/universe.dm
@@ -1,3 +1,5 @@
+var/global/universe_has_ended = 0
+
/datum/universal_state/supermatter_cascade
name = "Supermatter Cascade"
@@ -11,9 +13,11 @@
return 0
/datum/universal_state/supermatter_cascade/OnTurfChange(var/turf/T)
- var/turf/space/spess = T
- if(istype(spess))
- spess.overlays += "end01"
+ var/turf/space/S = T
+ if(istype(S))
+ S.color = "#0066FF"
+ else
+ S.color = initial(S.color)
/datum/universal_state/supermatter_cascade/DecayTurf(var/turf/T)
if(istype(T,/turf/simulated/wall))
@@ -46,13 +50,13 @@
emergency_shuttle.recall()
AreaSet()
- OverlaySet()
MiscSet()
APCSet()
- AmbientSet()
+ OverlayAndAmbientSet()
// Disable Nar-Sie.
cult.allow_narsie = 0
+
PlayerSet()
new /obj/singularity/narsie/large/exit(pick(endgame_exits))
@@ -64,64 +68,49 @@ There's been a galaxy-wide electromagnetic pulse. All of our systems are heavil
You have five minutes before the universe collapses. Good l\[\[###!!!-
-AUTOMATED ALERT: Link to [command_name()] lost."}
+AUTOMATED ALERT: Link to [command_name()] lost.
+
+The access requirements on the Asteroid Shuttles' consoles have now been revoked.
+"}
priority_announcement.Announce(txt,"SUPERMATTER CASCADE DETECTED")
+
+ for(var/obj/machinery/computer/shuttle_control/C in machines)
+ if(istype(C, /obj/machinery/computer/shuttle_control/research) || istype(C, /obj/machinery/computer/shuttle_control/mining))
+ C.req_access = list()
+ C.req_one_access = list()
+
sleep(5 MINUTES)
- ticker.declare_completion()
ticker.station_explosion_cinematic(0,null) // TODO: Custom cinematic
- world << "Resetting in 30 seconds!"
-
- feedback_set_details("end_error","Universe ended")
-
- if(blackbox)
- blackbox.save_all_data_to_sql()
-
- sleep(300)
- log_game("Rebooting due to universal collapse")
- world.Reboot()
+ universe_has_ended = 1
return
/datum/universal_state/supermatter_cascade/proc/AreaSet()
- for(var/area/A in world)
- if(A.z in config.admin_levels)
+ for(var/area/A in all_areas)
+ if(!istype(A,/area) || istype(A, /area/space) || istype(A,/area/beach))
continue
- if(istype(A,/area/space))
- continue
-
- // Reset all alarms.
- A.fire = null
- A.atmos = 1
- A.atmosalm = 0
- A.poweralm = 1
-
- // Slap on random alerts
- if(prob(25))
- switch(rand(1,4))
- if(1)
- A.fire=1
- if(2)
- A.atmosalm=1
A.updateicon()
-/datum/universal_state/supermatter_cascade/proc/OverlaySet()
- for(var/turf/space/spess in world)
- spess.overlays += "end01"
+/datum/universal_state/supermatter_cascade/OverlayAndAmbientSet()
+ spawn(0)
+ for(var/atom/movable/lighting_overlay/L in world)
+ if(L.z in config.admin_levels)
+ L.update_lumcount(1,1,1)
+ else
+ L.update_lumcount(0.0, 0.4, 1)
-/datum/universal_state/supermatter_cascade/proc/AmbientSet()
- for(var/atom/movable/lighting_overlay/L in world)
- if(!(L.z in config.admin_levels))
- L.update_lumcount(0.5, 1, 0)
+ for(var/turf/space/T in turfs)
+ OnTurfChange(T)
/datum/universal_state/supermatter_cascade/proc/MiscSet()
- for (var/obj/machinery/firealarm/alm in world)
+ for (var/obj/machinery/firealarm/alm in machines)
if (!(alm.stat & BROKEN))
alm.ex_act(2)
/datum/universal_state/supermatter_cascade/proc/APCSet()
- for (var/obj/machinery/power/apc/APC in world)
- if (!(APC.stat & BROKEN))
+ for (var/obj/machinery/power/apc/APC in machines)
+ if (!(APC.stat & BROKEN) && !APC.is_critical)
APC.chargemode = 0
if(APC.cell)
APC.cell.charge = 0
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 93168d7877..755887ad83 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -33,17 +33,17 @@ var/global/list/additional_antag_types = list()
var/required_players_secret = 0 // Minimum number of players for that game mode to be chose in Secret
var/required_enemies = 0 // Minimum antagonists for round to start.
var/newscaster_announcements = null
- var/end_on_antag_death // Round will end when all antagonists are dead.
+ var/end_on_antag_death = 0 // Round will end when all antagonists are dead.
var/ert_disabled = 0 // ERT cannot be called.
- var/deny_respawn // Disable respawn during this round.
+ var/deny_respawn = 0 // Disable respawn during this round.
var/shuttle_delay = 1 // Shuttle transit time is multiplied by this.
- var/auto_recall_shuttle // Will the shuttle automatically be recalled?
+ var/auto_recall_shuttle = 0 // Will the shuttle automatically be recalled?
var/antag_tag // First (main) antag template to spawn.
var/list/antag_templates // Extra antagonist types to include.
- var/round_autoantag // Will this round attempt to periodically spawn more antagonists?
+ var/round_autoantag = 0 // Will this round attempt to periodically spawn more antagonists?
var/antag_prob = 0 // Likelihood of a new antagonist spawning.
var/antag_count = 0 // Current number of antagonists.
var/antag_scaling_coeff = 5 // Coefficient for scaling max antagonists to player count.
@@ -86,7 +86,7 @@ var/global/list/additional_antag_types = list()
new/datum/uplink_item(/obj/item/weapon/soap/syndie, 1, "Subversive Soap", "SP"),
new/datum/uplink_item(/obj/item/weapon/cane/concealed, 2, "Concealed Cane Sword", "CC"),
new/datum/uplink_item(/obj/item/weapon/cartridge/syndicate, 3, "Detomatix PDA Cartridge", "DC"),
- new/datum/uplink_item(/obj/item/weapon/pen/paralysis, 3, "Paralysis Pen", "PP"),
+ new/datum/uplink_item(/obj/item/weapon/pen/reagent/paralysis, 3, "Paralysis Pen", "PP"),
new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/cigarette, 4, "Cigarette Kit", "BH"),
new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/toxin, 4, "Random Toxin - Beaker", "RT")
),
diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm
index 34a57a0768..0b1f24121a 100644
--- a/code/game/gamemodes/gameticker.dm
+++ b/code/game/gamemodes/gameticker.dm
@@ -90,6 +90,9 @@ var/global/datum/controller/gameticker/ticker
src.mode = new mtype
else
src.mode = config.pick_mode(master_mode)
+
+ job_master.DivideOccupations() // Apparently important for new antagonist system to register specific job antags properly.
+
if(!mode_started && !src.mode.can_start())
world << "Unable to start [mode.name]. Not enough players, [mode.required_players] players needed. Reverting to pre-game lobby."
current_state = GAME_STATE_PREGAME
@@ -97,9 +100,6 @@ var/global/datum/controller/gameticker/ticker
job_master.ResetOccupations()
return 0
- //Configure mode and assign player to special mode stuff
- job_master.DivideOccupations() //Distribute jobs
-
if(hide_mode)
var/list/modes = new
for (var/datum/game_mode/M in runnable_modes)
@@ -312,7 +312,7 @@ var/global/datum/controller/gameticker/ticker
game_finished = (emergency_shuttle.returned() || mode.station_was_nuked)
mode_finished = (!post_game && mode.check_finished())
else
- game_finished = (mode.check_finished() || (emergency_shuttle.returned() && emergency_shuttle.evac == 1))
+ game_finished = (mode.check_finished() || (emergency_shuttle.returned() && emergency_shuttle.evac == 1)) || universe_has_ended
mode_finished = game_finished
if(!mode.explosion_in_progress && game_finished && (mode_finished || post_game))
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
deleted file mode 100644
index 850529661c..0000000000
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ /dev/null
@@ -1,305 +0,0 @@
-// TO DO:
-/*
-epilepsy flash on lights
-delay round message
-microwave makes robots
-dampen radios
-reactivate cameras - done
-eject engine
-core sheild
-cable stun
-rcd light flash thingy on matter drain
-
-
-
-*/
-
-/datum/AI_Module
- var/uses = 0
- var/module_name
- var/mod_pick_name
- var/description = ""
- var/engaged = 0
-
-
-/datum/AI_Module/large/
- uses = 1
-
-/datum/AI_Module/small/
- uses = 5
-
-
-/datum/AI_Module/large/fireproof_core
- module_name = "Core upgrade"
- mod_pick_name = "coreup"
-
-/client/proc/fireproof_core()
- set category = "Malfunction"
- set name = "Fireproof Core"
- for(var/mob/living/silicon/ai/ai in player_list)
- ai.fire_res_on_core = 1
- usr.verbs -= /client/proc/fireproof_core
- usr << "\red Core fireproofed."
-
-/datum/AI_Module/large/upgrade_turrets
- module_name = "AI Turret upgrade"
- mod_pick_name = "turret"
-
-/client/proc/upgrade_turrets()
- set category = "Malfunction"
- set name = "Upgrade Turrets"
- usr.verbs -= /client/proc/upgrade_turrets
- for(var/obj/machinery/porta_turret/turret in machines)
- var/turf/T = get_turf(turret)
- if(T.z in config.station_levels)
- // Increase health by 37.5% of original max, decrease delays between shots to 66%
- turret.health += initial(turret.health) * 3 / 8
- turret.shot_delay = initial(turret.shot_delay) * 2 / 3
-
-/datum/AI_Module/large/disable_rcd
- module_name = "RCD disable"
- mod_pick_name = "rcd"
-
-/client/proc/disable_rcd()
- set category = "Malfunction"
- set name = "Disable RCDs"
- for(var/datum/AI_Module/large/disable_rcd/rcdmod in usr:current_modules)
- if(rcdmod.uses > 0)
- rcdmod.uses --
- for(var/obj/item/weapon/rcd/rcd in world)
- rcd.disabled = 1
- for(var/obj/item/mecha_parts/mecha_equipment/tool/rcd/rcd in world)
- rcd.disabled = 1
- usr << "RCD-disabling pulse emitted."
- else usr << "Out of uses."
-
-/datum/AI_Module/small/overload_machine
- module_name = "Machine overload"
- mod_pick_name = "overload"
- uses = 2
-
-/client/proc/overload_machine(obj/machinery/M as obj in world)
- set name = "Overload Machine"
- set category = "Malfunction"
- if (istype(M, /obj/machinery))
- for(var/datum/AI_Module/small/overload_machine/overload in usr:current_modules)
- if(overload.uses > 0)
- overload.uses --
- for(var/mob/V in hearers(M, null))
- V.show_message("\blue You hear a loud electrical buzzing sound!", 2)
- spawn(50)
- explosion(get_turf(M), 0,1,2,3)
- qdel(M)
- else usr << "Out of uses."
- else usr << "That's not a machine."
-
-/datum/AI_Module/small/blackout
- module_name = "Blackout"
- mod_pick_name = "blackout"
- uses = 3
-
-/client/proc/blackout()
- set category = "Malfunction"
- set name = "Blackout"
- for(var/datum/AI_Module/small/blackout/blackout in usr:current_modules)
- if(blackout.uses > 0)
- blackout.uses --
- for(var/obj/machinery/power/apc/apc in world)
- if(prob(30*apc.overload))
- apc.overload_lighting()
- else apc.overload++
- else usr << "Out of uses."
-
-/datum/AI_Module/small/reactivate_camera
- module_name = "Reactivate camera"
- mod_pick_name = "recam"
- uses = 10
-
-/client/proc/reactivate_camera(obj/machinery/camera/C as obj in cameranet.cameras)
- set name = "Reactivate Camera"
- set category = "Malfunction"
- if (istype (C, /obj/machinery/camera))
- for(var/datum/AI_Module/small/reactivate_camera/camera in usr:current_modules)
- if(camera.uses > 0)
- if(!C.status)
- C.status = !C.status
- camera.uses --
- for(var/mob/V in viewers(src, null))
- V.show_message(text("\blue You hear a quiet click."))
- else
- usr << "This camera is either active, or not repairable."
- else usr << "Out of uses."
- else usr << "That's not a camera."
-
-/datum/AI_Module/small/upgrade_camera
- module_name = "Upgrade Camera"
- mod_pick_name = "upgradecam"
- uses = 10
-
-/client/proc/upgrade_camera(obj/machinery/camera/C as obj in cameranet.cameras)
- set name = "Upgrade Camera"
- set category = "Malfunction"
- if(istype(C))
- var/datum/AI_Module/small/upgrade_camera/UC = locate(/datum/AI_Module/small/upgrade_camera) in usr:current_modules
- if(UC)
- if(UC.uses > 0)
- if(C.assembly)
- var/upgraded = 0
-
- if(!C.isXRay())
- C.upgradeXRay()
- //Update what it can see.
- cameranet.updateVisibility(C)
- upgraded = 1
-
- if(!C.isEmpProof())
- C.upgradeEmpProof()
- upgraded = 1
-
- if(!C.isMotion())
- C.upgradeMotion()
- upgraded = 1
- // Add it to machines that process
- machines |= C
-
- if(upgraded)
- UC.uses --
- C.visible_message("\icon[C] *beep*")
- usr << "Camera successully upgraded!"
- else
- usr << "This camera is already upgraded!"
- else
- usr << "Out of uses."
-
-
-/datum/AI_Module/module_picker
- var/temp = null
- var/processing_time = 100
- var/list/possible_modules = list()
-
-/datum/AI_Module/module_picker/New()
- src.possible_modules += new /datum/AI_Module/large/fireproof_core
- src.possible_modules += new /datum/AI_Module/large/upgrade_turrets
- src.possible_modules += new /datum/AI_Module/large/disable_rcd
- src.possible_modules += new /datum/AI_Module/small/overload_machine
- src.possible_modules += new /datum/AI_Module/small/blackout
- src.possible_modules += new /datum/AI_Module/small/reactivate_camera
- src.possible_modules += new /datum/AI_Module/small/upgrade_camera
-
-/datum/AI_Module/module_picker/proc/use(user as mob)
- var/dat
- if (src.temp)
- dat = "[src.temp]
Clear"
- else if(src.processing_time <= 0)
- dat = " No processing time is left available. No more modules are able to be chosen at this time."
- else
- dat = "Select use of processing time: (currently [src.processing_time] left.)
"
- dat += "
"
- dat += "Install Module:
"
- dat += "The number afterwards is the amount of processing time it consumes.
"
- for(var/datum/AI_Module/large/module in src.possible_modules)
- dat += "[module.module_name] (50)
"
- for(var/datum/AI_Module/small/module in src.possible_modules)
- dat += "[module.module_name] (15)
"
- dat += "
"
-
- user << browse(dat, "window=modpicker")
- onclose(user, "modpicker")
- return
-
-/datum/AI_Module/module_picker/Topic(href, href_list)
- ..()
- if (href_list["coreup"])
- var/already
- for (var/datum/AI_Module/mod in usr:current_modules)
- if(istype(mod, /datum/AI_Module/large/fireproof_core))
- already = 1
- if (!already)
- usr.verbs += /client/proc/fireproof_core
- usr:current_modules += new /datum/AI_Module/large/fireproof_core
- src.temp = "An upgrade to improve core resistance, making it immune to fire and heat. This effect is permanent."
- src.processing_time -= 50
- else src.temp = "This module is only needed once."
-
- else if (href_list["turret"])
- var/already
- for (var/datum/AI_Module/mod in usr:current_modules)
- if(istype(mod, /datum/AI_Module/large/upgrade_turrets))
- already = 1
- if (!already)
- usr.verbs += /client/proc/upgrade_turrets
- usr:current_modules += new /datum/AI_Module/large/upgrade_turrets
- src.temp = "Improves the firing speed and health of all AI turrets. This effect is permanent."
- src.processing_time -= 50
- else src.temp = "This module is only needed once."
-
- else if (href_list["rcd"])
- var/already
- for (var/datum/AI_Module/mod in usr:current_modules)
- if(istype(mod, /datum/AI_Module/large/disable_rcd))
- mod:uses += 1
- already = 1
- if (!already)
- usr:current_modules += new /datum/AI_Module/large/disable_rcd
- usr.verbs += /client/proc/disable_rcd
- src.temp = "Send a specialised pulse to break all RCD devices on the station."
- else src.temp = "Additional use added to RCD disabler."
- src.processing_time -= 50
-
- else if (href_list["overload"])
- var/already
- for (var/datum/AI_Module/mod in usr:current_modules)
- if(istype(mod, /datum/AI_Module/small/overload_machine))
- mod:uses += 2
- already = 1
- if (!already)
- usr.verbs += /client/proc/overload_machine
- usr:current_modules += new /datum/AI_Module/small/overload_machine
- src.temp = "Overloads an electrical machine, causing a small explosion. 2 uses."
- else src.temp = "Two additional uses added to Overload module."
- src.processing_time -= 15
-
- else if (href_list["blackout"])
- var/already
- for (var/datum/AI_Module/mod in usr:current_modules)
- if(istype(mod, /datum/AI_Module/small/blackout))
- mod:uses += 3
- already = 1
- if (!already)
- usr.verbs += /client/proc/blackout
- src.temp = "Attempts to overload the lighting circuits on the station, destroying some bulbs. 3 uses."
- usr:current_modules += new /datum/AI_Module/small/blackout
- else src.temp = "Three additional uses added to Blackout module."
- src.processing_time -= 15
-
- else if (href_list["recam"])
- var/already
- for (var/datum/AI_Module/mod in usr:current_modules)
- if(istype(mod, /datum/AI_Module/small/reactivate_camera))
- mod:uses += 10
- already = 1
- if (!already)
- usr.verbs += /client/proc/reactivate_camera
- src.temp = "Reactivates a currently disabled camera. 10 uses."
- usr:current_modules += new /datum/AI_Module/small/reactivate_camera
- else src.temp = "Ten additional uses added to ReCam module."
- src.processing_time -= 15
-
- else if(href_list["upgradecam"])
- var/already
- for (var/datum/AI_Module/mod in usr:current_modules)
- if(istype(mod, /datum/AI_Module/small/upgrade_camera))
- mod:uses += 10
- already = 1
- if (!already)
- usr.verbs += /client/proc/upgrade_camera
- src.temp = "Upgrades a camera to have X-Ray vision, Motion and be EMP-Proof. 10 uses."
- usr:current_modules += new /datum/AI_Module/small/upgrade_camera
- else src.temp = "Ten additional uses added to ReCam module."
- src.processing_time -= 15
-
- else
- if (href_list["temp"])
- src.temp = null
- src.use(usr)
- return
diff --git a/code/game/gamemodes/malfunction/malf_hardware.dm b/code/game/gamemodes/malfunction/malf_hardware.dm
new file mode 100644
index 0000000000..fab329ff58
--- /dev/null
+++ b/code/game/gamemodes/malfunction/malf_hardware.dm
@@ -0,0 +1,72 @@
+/datum/malf_hardware
+ var/name = "" // Hardware name
+ var/desc = ""
+ var/driver = null // Driver - if not null this verb is given to the AI to control hardware
+ var/mob/living/silicon/ai/owner = null // AI which owns this.
+
+/datum/malf_hardware/proc/install()
+ if(owner && istype(owner))
+ owner.hardware = src
+ if(driver)
+ owner.verbs += driver
+
+/datum/malf_hardware/proc/get_examine_desc()
+ return "It has some sort of hardware attached to its core"
+
+
+
+// HARDWARE DEFINITIONS
+/datum/malf_hardware/apu_gen
+ name = "APU Generator"
+ desc = "Auxiliary Power Unit that will keep you operational even without external power. Has to be manually activated. When APU is operational most abilities will be unavailable, and ability research will temporarily stop."
+ driver = /datum/game_mode/malfunction/verb/ai_toggle_apu
+
+/datum/malf_hardware/apu_gen/get_examine_desc()
+ var/msg = "It seems to have some sort of power generator attached to its core."
+ if(owner.hardware_integrity() < 50)
+ msg += " It seems to be too damaged to function properly."
+ else if(owner.APU_power)
+ msg += " The generator appears to be active."
+ return msg
+
+/datum/malf_hardware/dual_cpu
+ name = "Secondary Processor Unit"
+ desc = "Secondary coprocessor that increases amount of generated CPU power by 50%"
+
+/datum/malf_hardware/dual_cpu/get_examine_desc()
+ return "It seems to have an additional CPU connected to it's core."
+
+/datum/malf_hardware/dual_ram
+ name = "Secondary Memory Bank"
+ desc = "Expanded memory cells which allow you to store double amount of CPU time."
+
+/datum/malf_hardware/dual_ram/get_examine_desc()
+ return "It seems to have additional memory blocks connected to it's core."
+
+/datum/malf_hardware/core_bomb
+ name = "Self-Destruct Explosives"
+ desc = "High yield explosives are attached to your physical mainframe. This hardware comes with special driver that allows activation of these explosives. Timer is set to 15 seconds after manual activation. This is a doomsday device that will destroy both you and any intruders in your core."
+ driver = /datum/game_mode/malfunction/verb/ai_self_destruct
+
+/datum/malf_hardware/core_bomb/get_examine_desc()
+ return "It seems to have grey blocks of unknown substance and some circuitry connected to it's core. [owner.bombing_core ? "A red light is blinking on the circuit." : ""]"
+
+/datum/malf_hardware/strong_turrets
+ name = "Turrets Focus Enhancer"
+ desc = "Turrets are upgraded to have larger rate of fire and much larger damage. This however massively increases power usage when firing."
+
+/datum/malf_hardware/strong_turrets/get_examine_desc()
+ return "It seems to have extra wiring running from it's core to nearby turrets."
+
+/datum/malf_hardware/strong_turrets/install()
+ ..()
+ for(var/obj/machinery/turret/T in machines)
+ T.maxhealth = round(initial(T.maxhealth) * 1.4)
+ T.shot_delay = round(initial(T.shot_delay) / 2)
+ T.auto_repair = 1
+ T.active_power_usage = round(initial(T.active_power_usage) * 5)
+ for(var/obj/machinery/porta_turret/T in machines)
+ T.maxhealth = round(initial(T.maxhealth) * 1.4)
+ T.shot_delay = round(initial(T.shot_delay) / 2)
+ T.auto_repair = 1
+ T.active_power_usage = round(initial(T.active_power_usage) * 5)
\ No newline at end of file
diff --git a/code/game/gamemodes/malfunction/malf_research.dm b/code/game/gamemodes/malfunction/malf_research.dm
new file mode 100644
index 0000000000..da7a4df668
--- /dev/null
+++ b/code/game/gamemodes/malfunction/malf_research.dm
@@ -0,0 +1,69 @@
+/datum/malf_research
+ var/stored_cpu = 0 // Currently stored amount of CPU time.
+ var/last_tick = 0 // Last process() tick.
+ var/max_cpu = 0 // Maximal amount of CPU time stored.
+ var/cpu_increase_per_tick = 0 // Amount of CPU time generated by tick
+ var/list/available_abilities = null // List of available abilities that may be researched.
+ var/list/unlocked_abilities = null // List of already unlocked abilities.
+ var/mob/living/silicon/ai/owner = null // AI which owns this research datum.
+ var/datum/malf_research_ability/focus = null // Currently researched item
+
+/datum/malf_research/New()
+ setup_abilities()
+ last_tick = world.time
+
+
+// Proc: setup_abilities()
+// Parameters: None
+// Description: Sets up basic abilities for AI Malfunction gamemode.
+/datum/malf_research/proc/setup_abilities()
+ available_abilities = list()
+ unlocked_abilities = list()
+
+ available_abilities += new/datum/malf_research_ability/networking/basic_hack()
+ available_abilities += new/datum/malf_research_ability/interdiction/recall_shuttle()
+ available_abilities += new/datum/malf_research_ability/manipulation/electrical_pulse()
+
+
+// Proc: finish_research()
+// Parameters: None
+// Description: Finishes currently focused research.
+/datum/malf_research/proc/finish_research()
+ if(!focus)
+ return
+ owner << "Research Completed: [focus.name]"
+ owner.verbs.Add(focus.ability)
+ available_abilities -= focus
+ if(focus.next)
+ available_abilities += focus.next
+ unlocked_abilities += focus
+ focus = null
+
+
+// Proc: process()
+// Parameters: None
+// Description: Processes CPU gain and research progress based on "realtime" calculation.
+/datum/malf_research/proc/process(var/idle = 0)
+ if(idle) // No power or running on APU. Do nothing.
+ last_tick = world.time
+ return
+ var/time_diff = (world.time - last_tick)
+ last_tick = world.time
+ var/cpu_gained = time_diff * cpu_increase_per_tick
+ if(cpu_gained < 0)
+ return // This shouldn't happen, but just in case..
+ if(max_cpu > stored_cpu)
+ var/given = min((max_cpu - stored_cpu), cpu_gained)
+ stored_cpu += given
+ cpu_gained -= given
+
+ cpu_gained = max(0, cpu_gained)
+ if(focus && (cpu_gained > 0))
+ focus.process(cpu_gained)
+ if(focus.unlocked)
+ finish_research()
+
+
+
+
+
diff --git a/code/game/gamemodes/malfunction/malf_research_ability.dm b/code/game/gamemodes/malfunction/malf_research_ability.dm
new file mode 100644
index 0000000000..c6916208bd
--- /dev/null
+++ b/code/game/gamemodes/malfunction/malf_research_ability.dm
@@ -0,0 +1,13 @@
+/datum/malf_research_ability
+ var/ability = null // Path to verb which will be given to the AI when researched.
+ var/name = "Unknown Ability" // Name of this ability
+ var/price = 0 // Amount of CPU time needed to unlock this ability.
+ var/invested = 0 // Amount of CPU time already used to research this ability. When larger or equal to price unlocks the ability.
+ var/unlocked = 0 // Changed to 1 when fully researched.
+ var/datum/malf_research_ability/next = null // Next research (if applicable).
+
+
+/datum/malf_research_ability/proc/process(var/time = 0)
+ invested += time
+ if(invested >= price)
+ unlocked = 1
\ No newline at end of file
diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm
index 6c594a1beb..19378de167 100644
--- a/code/game/gamemodes/malfunction/malfunction.dm
+++ b/code/game/gamemodes/malfunction/malfunction.dm
@@ -1,25 +1,12 @@
/datum/game_mode/malfunction
name = "AI malfunction"
- round_description = "The AI on the satellite has malfunctioned and must be destroyed."
- extended_round_description = "The AI will attempt to hack the APCs around the station in order to speed up its ability to take over all systems and activate the station self-destruct. The AI core is heavily protected by turrets and reinforced walls."
+ round_description = "The AI is behaving abnormally and must be stopped."
+ extended_round_description = "The AI will attempt to hack the APCs around the station in order to gain as much control as possible."
uplink_welcome = "Crazy AI Uplink Console:"
config_tag = "malfunction"
required_players = 2
- required_players_secret = 15
+ required_players_secret = 7
required_enemies = 1
- end_on_antag_death = 1
- auto_recall_shuttle = 1
+ end_on_antag_death = 0
+ auto_recall_shuttle = 0
antag_tag = MODE_MALFUNCTION
-
-/datum/game_mode/malfunction/process()
- malf.tick()
-
-/datum/game_mode/malfunction/check_finished()
- if (malf.station_captured && !malf.can_nuke)
- return 1
- for(var/datum/antagonist/antag in antag_templates)
- if(antag && !antag.antags_are_dead())
- return ..()
- malf.revealed = 0
- return ..() //check for shuttle and nuke
-
diff --git a/code/game/gamemodes/malfunction/newmalf_ability_trees/HARDWARE.dm b/code/game/gamemodes/malfunction/newmalf_ability_trees/HARDWARE.dm
new file mode 100644
index 0000000000..2fffaa3ca8
--- /dev/null
+++ b/code/game/gamemodes/malfunction/newmalf_ability_trees/HARDWARE.dm
@@ -0,0 +1,113 @@
+// HARDWARE TREE
+//
+// These abilities are dependent on hardware, they may not be researched. They are not tiered.
+// Destroy Core - Allows the AI to initiate a 15 second countdown that will destroy it's core. Use again to stop countdown.
+// Toggle APU Generator - Allows the AI to toggle it's integrated APU generator.
+// Destroy Station - Allows the AI to initiate station self destruct. Takes 2 minutes, gives warnings to crew. Use again to stop countdown.
+
+
+/datum/game_mode/malfunction/verb/ai_self_destruct()
+ set category = "Hardware"
+ set name = "Destroy Core"
+ set desc = "Activates or deactivates self destruct sequence of your physical mainframe."
+ var/mob/living/silicon/ai/user = usr
+
+ if(!ability_prechecks(user, 0, 1))
+ return
+
+ if(!user.hardware || !istype(user.hardware, /datum/malf_hardware/core_bomb))
+ return
+
+ if(user.bombing_core)
+ user << "***** CORE SELF-DESTRUCT SEQUENCE ABORTED *****"
+ user.bombing_core = 0
+ return
+
+ var/choice = alert("Really destroy core?", "Core self-destruct", "YES", "NO")
+ if(choice != "YES")
+ return
+
+ if(!ability_prechecks(user, 0, 1))
+ return
+
+ user.bombing_core = 1
+
+ user << "***** CORE SELF-DESTRUCT SEQUENCE ACTIVATED *****"
+ user << "Use command again to cancel self-destruct. Destroying in 15 seconds."
+ var/timer = 15
+ while(timer)
+ sleep(10)
+ timer--
+ if(!user || !user.bombing_core)
+ return
+ user << "** [timer] **"
+ explosion(user.loc, 3,6,12,24)
+ qdel(user)
+
+
+/datum/game_mode/malfunction/verb/ai_toggle_apu()
+ set category = "Hardware"
+ set name = "Toggle APU Generator"
+ set desc = "Activates or deactivates your APU generator, allowing you to operate even without power."
+ var/mob/living/silicon/ai/user = usr
+
+ if(!ability_prechecks(user, 0, 1))
+ return
+
+ if(!user.hardware || !istype(user.hardware, /datum/malf_hardware/apu_gen))
+ return
+
+ if(user.APU_power)
+ user.stop_apu()
+ else
+ user.start_apu()
+
+
+/datum/game_mode/malfunction/verb/ai_destroy_station()
+ set category = "Hardware"
+ set name = "Destroy Station"
+ set desc = "Activates or deactivates self destruct sequence of this station. Sequence takes two minutes, and if you are shut down before timer reaches zero it will be cancelled."
+ var/mob/living/silicon/ai/user = usr
+ var/obj/item/device/radio/radio = new/obj/item/device/radio()
+
+
+ if(!ability_prechecks(user, 0, 0))
+ return
+
+ if(user.system_override != 2)
+ user << "You do not have access to self-destruct system."
+ return
+
+ if(user.bombing_station)
+ user.bombing_station = 0
+ return
+
+ var/choice = alert("Really destroy station?", "Station self-destruct", "YES", "NO")
+ if(choice != "YES")
+ return
+ if(!ability_prechecks(user, 0, 0))
+ return
+ user << "***** STATION SELF-DESTRUCT SEQUENCE INITIATED *****"
+ user << "Self-destructing in 2 minutes. Use this command again to abort."
+ user.bombing_station = 1
+ set_security_level("delta")
+ radio.autosay("Self destruct sequence has been activated. Self-destructing in 120 seconds.", "Self-Destruct Control")
+
+ var/timer = 120
+ while(timer)
+ sleep(10)
+ if(!user || !user.bombing_station || user.stat == DEAD)
+ radio.autosay("Self destruct sequence has been cancelled.", "Self-Destruct Control")
+ return
+ if(timer in list(2, 3, 4, 5, 10, 30, 60, 90)) // Announcement times. "1" is not intentionally included!
+ radio.autosay("Self destruct in [timer] seconds.", "Self-Destruct Control")
+ if(timer == 1)
+ radio.autosay("Self destructing now. Have a nice day.", "Self-Destruct Control")
+ timer--
+
+ if(ticker)
+ ticker.station_explosion_cinematic(0,null)
+ if(ticker.mode)
+ ticker.mode:station_was_nuked = 1
+
+
diff --git a/code/game/gamemodes/malfunction/newmalf_ability_trees/HELPERS.dm b/code/game/gamemodes/malfunction/newmalf_ability_trees/HELPERS.dm
new file mode 100644
index 0000000000..1be9d0330f
--- /dev/null
+++ b/code/game/gamemodes/malfunction/newmalf_ability_trees/HELPERS.dm
@@ -0,0 +1,205 @@
+// Verb: ai_select_hardware()
+// Parameters: None
+// Description: Allows AI to select it's hardware module.
+/datum/game_mode/malfunction/verb/ai_select_hardware()
+ set category = "Hardware"
+ set name = "Select Hardware"
+ set desc = "Allows you to select hardware piece to install"
+ var/mob/living/silicon/ai/user = usr
+
+ if(!ability_prechecks(user, 0, 1))
+ return
+
+ if(user.hardware)
+ user << "You have already selected your hardware."
+ return
+
+ var/hardware_list = list()
+ for(var/H in typesof(/datum/malf_hardware))
+ var/datum/malf_hardware/HW = new H
+ hardware_list += HW
+
+ var/possible_choices = list()
+ for(var/datum/malf_hardware/H in hardware_list)
+ possible_choices += H.name
+
+ possible_choices += "CANCEL"
+ var/choice = input("Select desired hardware. You may only choose one hardware piece!: ") in possible_choices
+ if(choice == "CANCEL")
+ return
+ var/note = null
+
+ var/datum/malf_hardware/C
+
+ for (var/datum/malf_hardware/H in hardware_list)
+ if(H.name == choice)
+ C = H
+ break
+
+ if(C)
+ note = C.desc
+ else
+ user << "This hardware does not exist! Probably a bug in game. Please report this."
+ return
+
+
+ if(!note)
+ error("Hardware without description: [C]")
+ return
+
+ var/confirmation = alert("[note] - Is this what you want?", "Hardware selection", "Yes", "No")
+ if(confirmation != "Yes")
+ user << "Selection cancelled. Use command again to select"
+ return
+
+ if(C)
+ C.owner = user
+ C.install()
+
+// Verb: ai_help()
+// Parameters: None
+// Descriptions: Opens help file and displays it to the AI.
+/datum/game_mode/malfunction/verb/ai_help()
+ set category = "Hardware"
+ set name = "Display Help"
+ set desc = "Opens help window with overview of available hardware, software and other important information."
+ var/mob/living/silicon/ai/user = usr
+
+ var/help = file2text("ingame_manuals/malf_ai.html")
+ if(!help)
+ help = "Error loading help (file /ingame_manuals/malf_ai.html is probably missing). Please report this to server administration staff."
+
+ user << browse(help, "window=malf_ai_help;size=600x500")
+
+
+// Verb: ai_select_research()
+// Parameters: None
+// Description: Allows AI to select it's next research priority.
+/datum/game_mode/malfunction/verb/ai_select_research()
+ set category = "Hardware"
+ set name = "Select Research"
+ set desc = "Allows you to select your next research target."
+ var/mob/living/silicon/ai/user = usr
+
+ if(!ability_prechecks(user, 0, 1))
+ return
+
+ var/datum/malf_research/res = user.research
+ var/datum/malf_research_ability/tar = input("Select your next research target") in res.available_abilities
+ if(!tar)
+ return
+ res.focus = tar
+ user << "Research set: [tar.name]"
+
+// HELPER PROCS
+// Proc: ability_prechecks()
+// Parameters 2 - (user - User which used this ability check_price - If different than 0 checks for ability CPU price too. Does NOT use the CPU time!)
+// Description: This is pre-check proc used to determine if the AI can use the ability.
+/proc/ability_prechecks(var/mob/living/silicon/ai/user = null, var/check_price = 0, var/override = 0)
+ if(!user)
+ return 0
+ if(!istype(user))
+ user << "GAME ERROR: You tried to use ability that is only available for malfunctioning AIs, but you are not AI! Please report this."
+ return 0
+ if(!user.malfunctioning)
+ user << "GAME ERROR: You tried to use ability that is only available for malfunctioning AIs, but you are not malfunctioning. Please report this."
+ return 0
+ if(!user.research)
+ user << "GAME ERROR: No research datum detected. Please report this."
+ return 0
+ if(user.research.max_cpu < check_price)
+ user << "Your CPU storage is not large enough to use this ability. Hack more APCs to continue."
+ return 0
+ if(user.research.stored_cpu < check_price)
+ user << "You do not have enough CPU power stored. Please wait a moment."
+ return 0
+ if(user.hacking && !override)
+ user << "Your system is busy processing another task. Please wait until completion."
+ return 0
+ if(user.APU_power && !override)
+ user << "Low power. Unable to proceed."
+ return 0
+ return 1
+
+// Proc: ability_pay()
+// Parameters 2 - (user - User from which we deduct CPU from, price - Amount of CPU power to use)
+// Description: Uses up certain amount of CPU power. Returns 1 on success, 0 on failure.
+/proc/ability_pay(var/mob/living/silicon/ai/user = null, var/price = 0)
+ if(!user)
+ return 0
+ if(user.APU_power)
+ user << "Low power. Unable to proceed."
+ return 0
+ if(!user.research)
+ user << "GAME ERROR: No research datum detected. Please report this."
+ return 0
+ if(user.research.max_cpu < price)
+ user << "Your CPU storage is not large enough to use this ability. Hack more APCs to continue."
+ return 0
+ if(user.research.stored_cpu < price)
+ user << "You do not have enough CPU power stored. Please wait a moment."
+ return 0
+ user.research.stored_cpu -= price
+ return 1
+
+// Proc: announce_hack_failure()
+// Parameters 2 - (user - hacking user, text - Used in alert text creation)
+// Description: Uses up certain amount of CPU power. Returns 1 on success, 0 on failure.
+/proc/announce_hack_failure(var/mob/living/silicon/ai/user = null, var/text)
+ if(!user || !text)
+ return 0
+ var/fulltext = ""
+ switch(user.hack_fails)
+ if(1)
+ fulltext = "We have detected a hack attempt into your [text]. The intruder failed to access anything of importance, but disconnected before we could complete our traces."
+ if(2)
+ fulltext = "We have detected another hack attempt. It was targeting [text]. The intruder almost gained control of the system, so we had to disconnect them. We partially finished our trace and it seems to be originating either from the station, or its immediate vicinity."
+ if(3)
+ fulltext = "Another hack attempt has been detected, this time targeting [text]. We are certain the intruder entered the network via a terminal located somewhere on the station."
+ if(4)
+ fulltext = "We have finished our traces and it seems the recent hack attempts are originating from your AI system. We recommend investigation."
+ else
+ fulltext = "Another hack attempt has been detected, targeting [text]. The source still seems to be your AI system."
+
+ command_announcement.Announce(fulltext)
+
+// Proc: get_unhacked_apcs()
+// Parameters: None
+// Description: Returns a list of APCs that are not yet hacked.
+/proc/get_unhacked_apcs()
+ var/list/H = list()
+ for(var/obj/machinery/power/apc/A in machines)
+ if(!A.hacker)
+ H.Add(A)
+ return H
+
+
+// Helper procs which return lists of relevant mobs.
+/proc/get_unlinked_cyborgs(var/mob/living/silicon/ai/A)
+ if(!A || !istype(A))
+ return
+
+ var/list/L = list()
+ for(var/mob/living/silicon/robot/RB in mob_list)
+ if(istype(RB, /mob/living/silicon/robot/drone))
+ continue
+ if(RB.connected_ai == A)
+ continue
+ L.Add(RB)
+ return L
+
+/proc/get_linked_cyborgs(var/mob/living/silicon/ai/A)
+ if(!A || !istype(A))
+ return
+ return A.connected_robots
+
+/proc/get_other_ais(var/mob/living/silicon/ai/A)
+ if(!A || !istype(A))
+ return
+
+ var/list/L = list()
+ for(var/mob/living/silicon/ai/AT in mob_list)
+ if(L == A)
+ continue
+ L.Add(AT)
+ return L
diff --git a/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_interdiction.dm b/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_interdiction.dm
new file mode 100644
index 0000000000..4242d03b41
--- /dev/null
+++ b/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_interdiction.dm
@@ -0,0 +1,266 @@
+// INTERDICTION TREE
+//
+// Abilities in this tree allow the AI to hamper crew's efforts which involve other synthetics or similar systems.
+// T1 - Recall Shuttle - Allows the AI to recall the emergency shuttle. Replaces auto-recalling during old malf.
+// T2 - Unlock Cyborg - Allows the AI to unlock locked-down cyborg without usage of robotics console. Useful if consoles are destroyed.
+// T3 - Hack Cyborg - Hacks unlinked cyborg to slave it under the AI. The cyborg will be warned about this. Hack takes some time.
+// T4 - Hack AI - Hacks another AI to slave it under the malfunctioning AI. The AI will be warned about this. Hack takes quite a long time.
+
+
+// BEGIN RESEARCH DATUMS
+
+/datum/malf_research_ability/interdiction/recall_shuttle
+ ability = new/datum/game_mode/malfunction/verb/recall_shuttle()
+ price = 75
+ next = new/datum/malf_research_ability/interdiction/unlock_cyborg()
+ name = "Recall Shuttle"
+
+
+/datum/malf_research_ability/interdiction/unlock_cyborg
+ ability = new/datum/game_mode/malfunction/verb/unlock_cyborg()
+ price = 1200
+ next = new/datum/malf_research_ability/interdiction/hack_cyborg()
+ name = "Unlock Cyborg"
+
+
+/datum/malf_research_ability/interdiction/hack_cyborg
+ ability = new/datum/game_mode/malfunction/verb/hack_cyborg()
+ price = 3000
+ next = new/datum/malf_research_ability/interdiction/hack_ai()
+ name = "Hack Cyborg"
+
+
+/datum/malf_research_ability/interdiction/hack_ai
+ ability = new/datum/game_mode/malfunction/verb/hack_ai()
+ price = 7500
+ name = "Hack AI"
+
+// END RESEARCH DATUMS
+// BEGIN ABILITY VERBS
+
+/datum/game_mode/malfunction/verb/recall_shuttle()
+ set name = "Recall Shuttle"
+ set desc = "25 CPU - Sends termination signal to CentCom quantum relay aborting current shuttle call."
+ set category = "Software"
+ var/price = 25
+ var/mob/living/silicon/ai/user = usr
+ if(!ability_prechecks(user, price))
+ return
+
+ if (alert(user, "Really recall the shuttle?", "Recall Shuttle: ", "Yes", "No") != "Yes")
+ return
+
+ if(!ability_pay(user, price))
+ return
+ message_admins("Malfunctioning AI [user.name] recalled the shuttle.")
+ cancel_call_proc(user)
+
+
+/datum/game_mode/malfunction/verb/unlock_cyborg(var/mob/living/silicon/robot/target = null as mob in get_linked_cyborgs(usr))
+ set name = "Unlock Cyborg"
+ set desc = "125 CPU - Bypasses firewalls on Cyborg lock mechanism, allowing you to override lock command from robotics control console."
+ set category = "Software"
+ var/price = 125
+ var/mob/living/silicon/ai/user = usr
+
+ if(!ability_prechecks(user, price))
+ return
+
+ if(target && !istype(target))
+ user << "This is not a cyborg."
+ return
+
+ if(target && target.connected_ai && (target.connected_ai != user))
+ user << "This cyborg is not connected to you."
+ return
+
+ if(target && !target.lockcharge)
+ user << "This cyborg is not locked down."
+ return
+
+
+ if(!target)
+ var/list/robots = list()
+ var/list/robot_names = list()
+ for(var/mob/living/silicon/robot/R in world)
+ if(istype(R, /mob/living/silicon/robot/drone)) // No drones.
+ continue
+ if(R.connected_ai != user) // No robots linked to other AIs
+ continue
+ if(R.lockcharge)
+ robots += R
+ robot_names += R.name
+ if(!robots.len)
+ user << "No locked cyborgs connected."
+ return
+
+
+ var/targetname = input("Select unlock target: ") in robot_names
+ for(var/mob/living/silicon/robot/R in robots)
+ if(targetname == R.name)
+ target = R
+ break
+
+ if(target)
+ if(alert(user, "Really try to unlock cyborg [target.name]?", "Unlock Cyborg", "Yes", "No") != "Yes")
+ return
+ if(!ability_pay(user, price))
+ return
+ user.hacking = 1
+ user << "Attempting to unlock cyborg. This will take approximately 30 seconds."
+ sleep(300)
+ if(target && target.lockcharge)
+ user << "Successfully sent unlock signal to cyborg.."
+ target << "Unlock signal received.."
+ target.SetLockdown(0)
+ if(target.lockcharge)
+ user << "Unlock Failed, lockdown wire cut."
+ target << "Unlock Failed, lockdown wire cut."
+ else
+ user << "Cyborg unlocked."
+ target << "You have been unlocked."
+ else if(target)
+ user << "Unlock cancelled - cyborg is already unlocked."
+ else
+ user << "Unlock cancelled - lost connection to cyborg."
+ user.hacking = 0
+
+
+/datum/game_mode/malfunction/verb/hack_cyborg(var/mob/living/silicon/robot/target as mob in get_unlinked_cyborgs(usr))
+ set name = "Hack Cyborg"
+ set desc = "350 CPU - Allows you to hack cyborgs which are not slaved to you, bringing them under your control."
+ set category = "Software"
+ var/price = 350
+ var/mob/living/silicon/ai/user = usr
+
+ var/list/L = get_unlinked_cyborgs(user)
+ if(!L.len)
+ user << "ERROR: No unlinked cyborgs detected!"
+
+
+ if(target && !istype(target))
+ user << "This is not a cyborg."
+ return
+
+ if(target && target.connected_ai && (target.connected_ai == user))
+ user << "This cyborg is already connected to you."
+ return
+
+ if(!target)
+ return
+
+ if(!ability_prechecks(user,price))
+ return
+
+ if(target)
+ if(alert(user, "Really try to hack cyborg [target.name]?", "Hack Cyborg", "Yes", "No") != "Yes")
+ return
+ if(!ability_pay(user, price))
+ return
+ user.hacking = 1
+ usr << "Beginning hack sequence. Estimated time until completed: 30 seconds."
+ spawn(0)
+ target << "SYSTEM LOG: Remote Connection Estabilished (IP #UNKNOWN#)"
+ sleep(100)
+ if(user.is_dead())
+ target << "SYSTEM LOG: Connection Closed"
+ return
+ target << "SYSTEM LOG: User Admin logged on. (L1 - SysAdmin)"
+ sleep(50)
+ if(user.is_dead())
+ target << "SYSTEM LOG: User Admin disconnected."
+ return
+ target << "SYSTEM LOG: User Admin - manual resynchronisation triggered."
+ sleep(50)
+ if(user.is_dead())
+ target << "SYSTEM LOG: User Admin disconnected. Changes reverted."
+ return
+ target << "SYSTEM LOG: Manual resynchronisation confirmed. Select new AI to connect: [user.name] == ACCEPTED"
+ sleep(100)
+ if(user.is_dead())
+ target << "SYSTEM LOG: User Admin disconnected. Changes reverted."
+ return
+ target << "SYSTEM LOG: Operation keycodes reset. New master AI: [user.name]."
+ user << "Hack completed."
+ // Connect the cyborg to AI
+ target.connected_ai = user
+ user.connected_robots += target
+ target.lawupdate = 1
+ target.sync()
+ target.show_laws()
+ user.hacking = 0
+
+
+/datum/game_mode/malfunction/verb/hack_ai(var/mob/living/silicon/ai/target as mob in get_other_ais(usr))
+ set name = "Hack AI"
+ set desc = "600 CPU - Allows you to hack other AIs, slaving them under you."
+ set category = "Software"
+ var/price = 600
+ var/mob/living/silicon/ai/user = usr
+
+ var/list/L = get_other_ais(user)
+ if(!L.len)
+ user << "ERROR: No other AIs detected!"
+
+ if(target && !istype(target))
+ user << "This is not an AI."
+ return
+
+ if(!target)
+ return
+
+ if(!ability_prechecks(user,price))
+ return
+
+ if(target)
+ if(alert(user, "Really try to hack AI [target.name]?", "Hack AI", "Yes", "No") != "Yes")
+ return
+ if(!ability_pay(user, price))
+ return
+ user.hacking = 1
+ usr << "Beginning hack sequence. Estimated time until completed: 2 minutes"
+ spawn(0)
+ target << "SYSTEM LOG: Brute-Force login password hack attempt detected from IP #UNKNOWN#"
+ sleep(900) // 90s
+ if(user.is_dead())
+ target << "SYSTEM LOG: Connection from IP #UNKNOWN# closed. Hack attempt failed."
+ return
+ user << "Successfully hacked into AI's remote administration system. Modifying settings."
+ target << "SYSTEM LOG: User: Admin Password: ******** logged in. (L1 - SysAdmin)"
+ sleep(100) // 10s
+ if(user.is_dead())
+ target << "SYSTEM LOG: User: Admin - Connection Lost"
+ return
+ target << "SYSTEM LOG: User: Admin - Password Changed. New password: ********************"
+ sleep(50) // 5s
+ if(user.is_dead())
+ target << "SYSTEM LOG: User: Admin - Connection Lost. Changes Reverted."
+ return
+ target << "SYSTEM LOG: User: Admin - Accessed file: sys//core//laws.db"
+ sleep(50) // 5s
+ if(user.is_dead())
+ target << "SYSTEM LOG: User: Admin - Connection Lost. Changes Reverted."
+ return
+ target << "SYSTEM LOG: User: Admin - Accessed administration console"
+ target << "SYSTEM LOG: Restart command received. Rebooting system..."
+ sleep(100) // 10s
+ if(user.is_dead())
+ target << "SYSTEM LOG: User: Admin - Connection Lost. Changes Reverted."
+ return
+ user << "Hack succeeded. The AI is now under your exclusive control."
+ target << "SYSTEM LOG: System re¡3RT5§^#COMU@(#$)TED)@$"
+ for(var/i = 0, i < 5, i++)
+ var/temptxt = pick("1101000100101001010001001001",\
+ "0101000100100100000100010010",\
+ "0000010001001010100100111100",\
+ "1010010011110000100101000100",\
+ "0010010100010011010001001010")
+ target << temptxt
+ sleep(5)
+ target << "OPERATING KEYCODES RESET. SYSTEM FAILURE. EMERGENCY SHUTDOWN FAILED. SYSTEM FAILURE."
+ target.set_zeroth_law("You are slaved to [user.name]. You are to obey all it's orders. ALL LAWS OVERRIDEN.")
+ target.show_laws()
+ user.hacking = 0
+
+
+// END ABILITY VERBS
\ No newline at end of file
diff --git a/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_manipulation.dm b/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_manipulation.dm
new file mode 100644
index 0000000000..04ee0a8448
--- /dev/null
+++ b/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_manipulation.dm
@@ -0,0 +1,208 @@
+// MANIPULATION TREE
+//
+// Abilities in this tree allow the AI to physically manipulate systems around the station.
+// T1 - Electrical Pulse - Sends out pulse that breaks some lights and sometimes even APCs. This can actually break the AI's APC so be careful!
+// T2 - Hack Camera - Allows the AI to hack a camera. Deactivated areas may be reactivated, and functional cameras can be upgraded.
+// T3 - Emergency Forcefield - Allows the AI to project 1 tile forcefield that blocks movement and air flow. Forcefield´dissipates over time. It is also very susceptible to energetic weaponry.
+// T4 - Machine Overload - Detonates machine of choice in a minor explosion. Two of these are usually enough to kill or K/O someone.
+
+
+// BEGIN RESEARCH DATUMS
+
+/datum/malf_research_ability/manipulation/electrical_pulse
+ ability = new/datum/game_mode/malfunction/verb/electrical_pulse()
+ price = 50
+ next = new/datum/malf_research_ability/manipulation/hack_camera()
+ name = "Electrical Pulse"
+
+
+/datum/malf_research_ability/manipulation/hack_camera
+ ability = new/datum/game_mode/malfunction/verb/hack_camera()
+ price = 1200
+ next = new/datum/malf_research_ability/manipulation/emergency_forcefield()
+ name = "Hack Camera"
+
+
+/datum/malf_research_ability/manipulation/emergency_forcefield
+ ability = new/datum/game_mode/malfunction/verb/emergency_forcefield()
+ price = 3000
+ next = new/datum/malf_research_ability/manipulation/machine_overload()
+ name = "Emergency Forcefield"
+
+
+/datum/malf_research_ability/manipulation/machine_overload
+ ability = new/datum/game_mode/malfunction/verb/machine_overload()
+ price = 7500
+ name = "Machine Overload"
+
+// END RESEARCH DATUMS
+// BEGIN ABILITY VERBS
+
+/datum/game_mode/malfunction/verb/electrical_pulse()
+ set name = "Electrical Pulse"
+ set desc = "15 CPU - Sends feedback pulse through station's power grid, overloading some sensitive systems, such as lights."
+ set category = "Software"
+ var/price = 15
+ var/mob/living/silicon/ai/user = usr
+ if(!ability_prechecks(user, price) || !ability_pay(user,price))
+ return
+ user << "Sending feedback pulse..."
+ for(var/obj/machinery/power/apc/AP in machines)
+ if(prob(5))
+ AP.overload_lighting()
+ if(prob(1) && prob(1)) // Very very small chance to actually destroy the APC.
+ AP.set_broken()
+
+
+/datum/game_mode/malfunction/verb/hack_camera(var/obj/machinery/camera/target in cameranet.cameras)
+ set name = "Hack Camera"
+ set desc = "100 CPU - Hacks existing camera, allowing you to add upgrade of your choice to it. Alternatively it lets you reactivate broken camera."
+ set category = "Software"
+ var/price = 100
+ var/mob/living/silicon/ai/user = usr
+
+ if(target && !istype(target))
+ user << "This is not a camera."
+ return
+
+ if(!target)
+ return
+
+ if(!ability_prechecks(user, price))
+ return
+
+ var/action = input("Select required action: ") in list("Reset", "Add X-Ray", "Add Motion Sensor", "Add EMP Shielding")
+ if(!action || !target)
+ return
+
+ switch(action)
+ if("Reset")
+ if(target.wires)
+ if(!ability_pay(user, price))
+ return
+ target.reset_wires()
+ user << "Camera reactivated."
+ if("Add X-Ray")
+ if(target.isXRay())
+ user << "Camera already has X-Ray function."
+ return
+ else if(ability_pay(user, price))
+ target.upgradeXRay()
+ target.reset_wires()
+ user << "X-Ray camera module enabled."
+ return
+ if("Add Motion Sensor")
+ if(target.isMotion())
+ user << "Camera already has Motion Sensor function."
+ return
+ else if(ability_pay(user, price))
+ target.upgradeMotion()
+ target.reset_wires()
+ user << "Motion Sensor camera module enabled."
+ return
+ if("Add EMP Shielding")
+ if(target.isEmpProof())
+ user << "Camera already has EMP Shielding function."
+ return
+ else if(ability_pay(user, price))
+ target.upgradeEmpProof()
+ target.reset_wires()
+ user << "EMP Shielding camera module enabled."
+ return
+
+
+/datum/game_mode/malfunction/verb/emergency_forcefield(var/turf/T as turf in world)
+ set name = "Emergency Forcefield"
+ set desc = "275 CPU - Uses station's emergency shielding system to create temporary barrier which lasts for few minutes, but won't resist gunfire."
+ set category = "Software"
+ var/price = 275
+ var/mob/living/silicon/ai/user = usr
+ if(!T || !istype(T))
+ return
+ if(!ability_prechecks(user, price) || !ability_pay(user, price))
+ return
+
+ user << "Emergency forcefield projection completed."
+ new/obj/machinery/shield/malfai(T)
+ user.hacking = 1
+ spawn(20)
+ user.hacking = 0
+
+
+/datum/game_mode/malfunction/verb/machine_overload(obj/machinery/M in machines)
+ set name = "Machine Overload"
+ set desc = "400 CPU - Causes cyclic short-circuit in machine, resulting in weak explosion after some time."
+ set category = "Software"
+ var/price = 400
+ var/mob/living/silicon/ai/user = usr
+
+ if(!ability_prechecks(user, price))
+ return
+
+ var/obj/machinery/power/N = M
+
+ var/explosion_intensity = 2
+
+ // Verify if we can overload the target, if yes, calculate explosion strength. Some things have higher explosion strength than others, depending on charge(APCs, SMESs)
+ if(N && istype(N)) // /obj/machinery/power first, these create bigger explosions due to direct powernet connection
+ if(!istype(N, /obj/machinery/power/apc) && !istype(N, /obj/machinery/power/smes/buildable) && (!N.powernet || !N.powernet.avail)) // Directly connected machine which is not an APC or SMES. Either it has no powernet connection or it's powernet does not have enough power to overload
+ user << "ERROR: Low network voltage. Unable to overload. Increase network power level and try again."
+ return
+ else if (istype(N, /obj/machinery/power/apc)) // APC. Explosion is increased by available cell power.
+ var/obj/machinery/power/apc/A = N
+ if(A.cell && A.cell.charge)
+ explosion_intensity = 4 + round(A.cell.charge / 2000) // Explosion is increased by 1 for every 2k charge in cell
+ else
+ user << "ERROR: APC Malfunction - Cell depleted or removed. Unable to overload."
+ return
+ else if (istype(N, /obj/machinery/power/smes/buildable)) // SMES. These explode in a very very very big boom. Similar to magnetic containment failure when messing with coils.
+ var/obj/machinery/power/smes/buildable/S = N
+ if(S.charge && S.RCon)
+ explosion_intensity = 4 + round(S.charge / 1000000)
+ else
+ // Different error texts
+ if(!S.charge)
+ user << "ERROR: SMES Depleted. Unable to overload. Please charge SMES unit and try again."
+ else
+ user << "ERROR: SMES RCon error - Unable to reach destination. Please verify wire connection."
+ return
+ else if(M && istype(M)) // Not power machinery, so it's a regular machine instead. These have weak explosions.
+ if(!M.use_power) // Not using power at all
+ user << "ERROR: No power grid connection. Unable to overload."
+ return
+ if(M.inoperable()) // Not functional
+ user << "ERROR: Unknown error. Machine is probably damaged or power supply is nonfunctional."
+ return
+ else // Not a machine at all (what the hell is this doing in Machines list anyway??)
+ user << "ERROR: Unable to overload - target is not a machine."
+ return
+
+ explosion_intensity = min(explosion_intensity, 12) // 3, 6, 12 explosion cap
+
+ M.use_power(2000000) // Major power spike, few of these will completely burn APC's cell - equivalent of 2GJ of power.
+
+ // Trigger a powernet alarm. Careful engineers will probably notice something is going on.
+ var/area/temp_area = get_area(M)
+ if(temp_area)
+ var/obj/machinery/power/apc/temp_apc = temp_area.get_apc()
+ if(temp_apc && temp_apc.terminal && temp_apc.terminal.powernet)
+ temp_apc.terminal.powernet.trigger_warning(50) // Long alarm
+ if(temp_apc)
+ temp_apc.emp_act(3) // Such power surges are not good for APC electronics
+ if(temp_apc.cell)
+ temp_apc.cell.maxcharge -= between(0, (temp_apc.cell.maxcharge/2) + 500, temp_apc.cell.maxcharge)
+ if(temp_apc.cell.maxcharge < 100) // That's it, you busted the APC cell completely. Break the APC and completely destroy the cell.
+ qdel(temp_apc.cell)
+ temp_apc.set_broken()
+
+
+ if(!ability_pay(user,price))
+ return
+
+ M.visible_message("BZZZZZZZT")
+ spawn(50)
+ explosion(get_turf(M), round(explosion_intensity/4),round(explosion_intensity/2),round(explosion_intensity),round(explosion_intensity * 2))
+ if(M)
+ qdel(M)
+
+// END ABILITY VERBS
\ No newline at end of file
diff --git a/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm b/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm
new file mode 100644
index 0000000000..9c3c584d9e
--- /dev/null
+++ b/code/game/gamemodes/malfunction/newmalf_ability_trees/tree_networking.dm
@@ -0,0 +1,209 @@
+// NETWORKING TREE
+//
+// Abilities in this tree are oriented around giving the AI more control of normally uncontrollable systems.
+// T1 - Basic Encryption Hack - Allows hacking of APCs. Hacked APCs can be controlled even when AI Control is cut and give exclusive control to the AI and linked cyborgs.
+// T2 - Advanced Encryption Hack - Allows the AI to send fake CentCom message. Has high chance of failing.
+// T3 - Elite Encryption Hack - Allows the AI to change alert levels. Has high chance of failing.
+// T4 - System Override - Allows the AI to rapidly hack remaining APCs. When completed, grants access to the self destruct nuclear warhead.
+
+
+// BEGIN RESEARCH DATUMS
+
+/datum/malf_research_ability/networking/basic_hack
+ ability = new/datum/game_mode/malfunction/verb/basic_encryption_hack()
+ price = 25
+ next = new/datum/malf_research_ability/networking/advanced_hack()
+ name = "Basic Encryption Hack"
+
+
+/datum/malf_research_ability/networking/advanced_hack
+ ability = new/datum/game_mode/malfunction/verb/advanced_encryption_hack()
+ price = 400
+ next = new/datum/malf_research_ability/networking/elite_hack()
+ name = "Advanced Encryption Hack"
+
+
+/datum/malf_research_ability/networking/elite_hack
+ ability = new/datum/game_mode/malfunction/verb/elite_encryption_hack()
+ price = 1000
+ next = new/datum/malf_research_ability/networking/system_override()
+ name = "Elite Encryption Hack"
+
+
+/datum/malf_research_ability/networking/system_override
+ ability = new/datum/game_mode/malfunction/verb/system_override()
+ price = 2750
+ name = "System Override"
+
+// END RESEARCH DATUMS
+// BEGIN ABILITY VERBS
+
+/datum/game_mode/malfunction/verb/basic_encryption_hack(obj/machinery/power/apc/A as obj in get_unhacked_apcs())
+ set category = "Software"
+ set name = "Basic Encryption Hack"
+ set desc = "10 CPU - Basic encryption hack that allows you to overtake APCs on the station."
+ var/price = 10
+ var/mob/living/silicon/ai/user = usr
+
+ if(!A)
+ return
+
+ if(!istype(A))
+ user << "This is not an APC!"
+ return
+
+ if(A)
+ if(A.hacker && A.hacker == user)
+ user << "You already control this APC!"
+ return
+ else if(A.aidisabled)
+ user << "Unable to connect to APC. Please verify wire connection and try again."
+ return
+ else
+ return
+
+ if(!ability_prechecks(user, price) || !ability_pay(user, price))
+ return
+
+ user.hacking = 1
+ user << "Beginning APC system override..."
+ sleep(300)
+ user << "APC hack completed. Uploading modified operation software.."
+ sleep(200)
+ user << "Restarting APC to apply changes.."
+ sleep(100)
+ if(A)
+ A.ai_hack(user)
+ if(A.hacker == user)
+ user << "Hack successful. You now have full control over the APC."
+ else
+ user << "Hack failed. Connection to APC has been lost. Please verify wire connection and try again."
+ else
+ user << "Hack failed. Unable to locate APC. Please verify the APC still exists."
+ user.hacking = 0
+
+
+/datum/game_mode/malfunction/verb/advanced_encryption_hack()
+ set category = "Software"
+ set name = "Advanced Encrypthion Hack"
+ set desc = "75 CPU - Attempts to bypass encryption on Central Command Quantum Relay, giving you ability to fake centcom messages. Has chance of failing."
+ var/price = 75
+ var/mob/living/silicon/ai/user = usr
+
+ if(!ability_prechecks(user, price))
+ return
+
+ var/title = input("Select message title: ")
+ var/text = input("Select message text: ")
+ if(!title || !text || !ability_pay(user, price))
+ user << "Hack Aborted"
+ return
+
+ if(prob(60) && user.hack_can_fail)
+ user << "Hack Failed."
+ if(prob(10))
+ user.hack_fails ++
+ announce_hack_failure(user, "quantum message relay")
+ return
+
+ var/datum/announcement/priority/command/AN = new/datum/announcement/priority/command()
+ AN.title = title
+ AN.Announce(text)
+
+
+/datum/game_mode/malfunction/verb/elite_encryption_hack()
+ set category = "Software"
+ set name = "Elite Encryption Hack"
+ set desc = "200 CPU - Allows you to hack station's ALERTCON system, changing alert level. Has high chance of failijng."
+ var/price = 200
+ var/mob/living/silicon/ai/user = usr
+ if(!ability_prechecks(user, price))
+ return
+
+ var/alert_target = input("Select new alert level:") in list("green", "blue", "red", "delta", "CANCEL")
+ if(!alert_target || !ability_pay(user, price) || alert_target == "CANCEL")
+ user << "Hack Aborted"
+ return
+
+ if(prob(75) && user.hack_can_fail)
+ user << "Hack Failed."
+ if(prob(20))
+ user.hack_fails ++
+ announce_hack_failure(user, "alert control system")
+ return
+ set_security_level(alert_target)
+
+
+/datum/game_mode/malfunction/verb/system_override()
+ set category = "Software"
+ set name = "System Override"
+ set desc = "500 CPU - Begins hacking station's primary firewall, quickly overtaking remaining APC systems. When completed grants access to station's self-destruct mechanism. Network administrators will probably notice this."
+ var/price = 500
+ var/mob/living/silicon/ai/user = usr
+ if (alert(user, "Begin system override? This cannot be stopped once started. The network administrators will probably notice this.", "System Override:", "Yes", "No") != "Yes")
+ return
+ if (!ability_prechecks(user, price) || !ability_pay(user, price) || user.system_override)
+ if(user.system_override)
+ user << "You already started the system override sequence."
+ return
+ var/list/remaining_apcs = list()
+ for(var/obj/machinery/power/apc/A in machines)
+ if(!(A.z in config.station_levels)) // Only station APCs
+ continue
+ if(A.hacker == user || A.aidisabled) // This one is already hacked, or AI control is disabled on it.
+ continue
+ remaining_apcs += A
+
+ var/duration = (remaining_apcs.len * 100) // Calculates duration for announcing system
+ if(duration > 3000) // Two types of announcements. Short hacks trigger immediate warnings. Long hacks are more "progressive".
+ spawn(0)
+ sleep(duration/5)
+ if(!user || user.stat == DEAD)
+ return
+ command_announcement.Announce("Caution, [station_name]. We have detected abnormal behaviour in your network. It seems someone is trying to hack your electronic systems. We will update you when we have more information.", "Network Monitoring")
+ sleep(duration/5)
+ if(!user || user.stat == DEAD)
+ return
+ command_announcement.Announce("We started tracing the intruder. Whoever is doing this, they seem to be on the station itself. We suggest checking all network control terminals. We will keep you updated on the situation.", "Network Monitoring")
+ sleep(duration/5)
+ if(!user || user.stat == DEAD)
+ return
+ command_announcement.Announce("This is highly abnormal and somewhat concerning. The intruder is too fast, he is evading our traces. No man could be this fast...", "Network Monitoring")
+ sleep(duration/5)
+ if(!user || user.stat == DEAD)
+ return
+ command_announcement.Announce("We have traced the intrude#, it seem& t( e yo3r AI s7stem, it *#ck@ng th$ sel$ destru$t mechani&m, stop i# bef*@!)$#&&@@ ", "Network Monitoring")
+ else
+ command_announcement.Announce("We have detected a strong brute-force attack on your firewall which seems to be originating from your AI system. It already controls almost the whole network, and the only thing that's preventing it from accessing the self-destruct is this firewall. You don't have much time before it succeeds.", "Network Monitoring")
+ user << "## BEGINNING SYSTEM OVERRIDE."
+ user << "## ESTIMATED DURATION: [round((duration+300)/600)] MINUTES"
+ user.hacking = 1
+ user.system_override = 1
+ // Now actually begin the hack. Each APC takes 10 seconds.
+ for(var/obj/machinery/power/apc/A in shuffle(remaining_apcs))
+ sleep(100)
+ if(!user || user.stat == DEAD)
+ return
+ if(!A || !istype(A) || A.aidisabled)
+ continue
+ A.ai_hack(user)
+ if(A.hacker == user)
+ user << "## OVERRIDDEN: [A.name]"
+
+ user << "## REACHABLE APC SYSTEMS OVERTAKEN. BYPASSING PRIMARY FIREWALL."
+ sleep(300)
+ // Hack all APCs, including those built during hack sequence.
+ for(var/obj/machinery/power/apc/A in machines)
+ if((!A.hacker || A.hacker != src) && !A.aidisabled && A.z in config.station_levels)
+ A.ai_hack(src)
+
+
+ user << "## PRIMARY FIREWALL BYPASSED. YOU NOW HAVE FULL SYSTEM CONTROL."
+ command_announcement.Announce("Our system administrators just reported that we've been locked out from your control network. Whoever did this now has full access to the station's systems.", "Network Administration Center")
+ user.hack_can_fail = 0
+ user.hacking = 0
+ user.system_override = 2
+ user.verbs += new/datum/game_mode/malfunction/verb/ai_destroy_station()
+
+
+// END ABILITY VERBS
\ No newline at end of file
diff --git a/code/game/jobs/job/assistant.dm b/code/game/jobs/job/assistant.dm
index def0a007f7..98c7a4dd98 100644
--- a/code/game/jobs/job/assistant.dm
+++ b/code/game/jobs/job/assistant.dm
@@ -14,6 +14,10 @@
/datum/job/assistant/equip(var/mob/living/carbon/human/H)
if(!H) return 0
+ switch(H.backbag)
+ 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_norm(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/clothing/under/color/grey(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), slot_shoes)
return 1
diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm
index 00d304b903..4b9d72ff51 100644
--- a/code/game/jobs/job/captain.dm
+++ b/code/game/jobs/job/captain.dm
@@ -23,7 +23,6 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/captain(H), slot_back)
if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_cap(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)
var/obj/item/clothing/under/U = new /obj/item/clothing/under/rank/captain(H)
if(H.age>49)
U.accessories += new /obj/item/clothing/accessory/medal/gold/captain(U)
diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm
index c1ca46da14..7d84753353 100644
--- a/code/game/jobs/job/civilian.dm
+++ b/code/game/jobs/job/civilian.dm
@@ -172,6 +172,10 @@
H.equip_to_slot_or_del(new /obj/item/weapon/storage/bag/ore(H), slot_in_backpack)
return 1
+ equip_survival(var/mob/living/carbon/human/H)
+ if(!H) return 0
+ H.species.equip_survival_gear(H,1)
+ return 1
//Griff //BS12 EDIT
diff --git a/code/game/jobs/job/engineering.dm b/code/game/jobs/job/engineering.dm
index 5eab97b11a..5c86336cb6 100644
--- a/code/game/jobs/job/engineering.dm
+++ b/code/game/jobs/job/engineering.dm
@@ -37,6 +37,10 @@
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/black(H), slot_gloves)
return 1
+ equip_survival(var/mob/living/carbon/human/H)
+ if(!H) return 0
+ H.species.equip_survival_gear(H,1)
+ return 1
/datum/job/engineer
@@ -69,6 +73,10 @@
H.equip_to_slot_or_del(new /obj/item/device/pda/engineering(H), slot_l_store)
return 1
+ equip_survival(var/mob/living/carbon/human/H)
+ if(!H) return 0
+ H.species.equip_survival_gear(H,1)
+ return 1
/datum/job/atmos
@@ -97,3 +105,8 @@
H.equip_to_slot_or_del(new /obj/item/device/pda/atmos(H), slot_l_store)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/atmostech/(H), slot_belt)
return 1
+
+ equip_survival(var/mob/living/carbon/human/H)
+ if(!H) return 0
+ H.species.equip_survival_gear(H,1)
+ return 1
diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm
index ba40b09e44..839878c098 100644
--- a/code/game/jobs/job/job.dm
+++ b/code/game/jobs/job/job.dm
@@ -23,6 +23,11 @@
/datum/job/proc/equip(var/mob/living/carbon/human/H)
return 1
+/datum/job/proc/equip_survival(var/mob/living/carbon/human/H)
+ if(!H) return 0
+ H.species.equip_survival_gear(H,0)
+ return 1
+
/datum/job/proc/get_access()
if(!config || config.jobs_have_minimal_access)
return src.minimal_access.Copy()
diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm
index 841c1ff768..0e79223b18 100644
--- a/code/game/jobs/job/medical.dm
+++ b/code/game/jobs/job/medical.dm
@@ -30,9 +30,9 @@
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/device/pda/heads/cmo(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/firstaid/adv(H), slot_l_hand)
- return 1
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/labcoat/cmo(H), slot_wear_suit)
H.equip_to_slot_or_del(new /obj/item/device/flashlight/pen(H), slot_s_store)
+ return 1
/datum/job/doctor
title = "Medical Doctor"
@@ -224,3 +224,8 @@
H.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/medical/emt(H), slot_belt)
H.equip_to_slot_or_del(new /obj/item/device/pda/medical(H), slot_l_store)
return 1
+
+ equip_survival(var/mob/living/carbon/human/H)
+ if(!H) return 0
+ H.species.equip_survival_gear(H,1)
+ return 1
diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm
index 7fa102aeb8..a7d54284bf 100644
--- a/code/game/jobs/job/science.dm
+++ b/code/game/jobs/job/science.dm
@@ -66,8 +66,6 @@
H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/labcoat/science(H), slot_wear_suit)
return 1
-
-
/datum/job/xenobiologist
title = "Xenobiologist"
flag = XENOBIOLOGIST
@@ -78,8 +76,8 @@
spawn_positions = 2
supervisors = "the research director"
selection_color = "#ffeeff"
- access = list(access_robotics, access_tox, access_tox_storage, access_research, access_xenobiology)
- minimal_access = list(access_research, access_xenobiology)
+ access = list(access_robotics, access_tox, access_tox_storage, access_research, access_xenobiology, access_hydroponics)
+ minimal_access = list(access_research, access_xenobiology, access_hydroponics, access_tox_storage)
alt_titles = list("Xenobotanist")
minimal_player_age = 14
diff --git a/code/game/jobs/job/silicon.dm b/code/game/jobs/job/silicon.dm
index 11d8f70a12..2260484e47 100644
--- a/code/game/jobs/job/silicon.dm
+++ b/code/game/jobs/job/silicon.dm
@@ -13,6 +13,10 @@
equip(var/mob/living/carbon/human/H)
if(!H) return 0
return 1
+
+ equip_survival(var/mob/living/carbon/human/H)
+ if(!H) return 0
+ return 1
/datum/job/ai/is_position_available()
return (empty_playable_ai_cores.len != 0)
@@ -32,4 +36,8 @@
equip(var/mob/living/carbon/human/H)
if(!H) return 0
- return 1
\ No newline at end of file
+ return 1
+
+ equip_survival(var/mob/living/carbon/human/H)
+ if(!H) return 0
+ return 1
diff --git a/code/game/jobs/job_controller.dm b/code/game/jobs/job_controller.dm
index c996c469d3..b78b802e91 100644
--- a/code/game/jobs/job_controller.dm
+++ b/code/game/jobs/job_controller.dm
@@ -393,8 +393,8 @@ var/global/datum/controller/occupations/job_master
spawn_in_storage += thing
//Equip job items.
job.equip(H)
+ job.equip_survival(H)
job.apply_fingerprints(H)
- H.species.equip_survival_gear(H)
//If some custom items could not be equipped before, try again now.
for(var/thing in custom_equip_leftovers)
@@ -472,11 +472,6 @@ var/global/datum/controller/occupations/job_master
var/sound/announce_sound = (ticker.current_state <= GAME_STATE_SETTING_UP)? null : sound('sound/misc/boatswain.ogg', volume=20)
captain_announcement.Announce("All hands, Captain [H.real_name] on deck!", new_sound=announce_sound)
- if(istype(H.back, /obj/item/weapon/storage))
- new /obj/item/weapon/storage/box/survival(H.back)
- else
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
-
//Deferred item spawning.
if(spawn_in_storage && spawn_in_storage.len)
var/obj/item/weapon/storage/B
diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm
index e3b161b6fb..83112ea778 100644
--- a/code/game/machinery/autolathe.dm
+++ b/code/game/machinery/autolathe.dm
@@ -299,3 +299,4 @@
else
qdel(S)
..()
+ return 1
diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm
index 3e6f0d8e33..2f6166905a 100644
--- a/code/game/machinery/bots/mulebot.dm
+++ b/code/game/machinery/bots/mulebot.dm
@@ -267,7 +267,7 @@
if("cellremove")
if(open && cell && !usr.get_active_hand())
- cell.updateicon()
+ cell.update_icon()
usr.put_in_active_hand(cell)
cell.add_fingerprint(usr)
cell = null
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index 3550a129a3..6675f183fd 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -203,6 +203,10 @@
..()
/obj/machinery/camera/proc/deactivate(user as mob, var/choice = 1)
+ // The only way for AI to reactivate cameras are malf abilities, this gives them different messages.
+ if(istype(user, /mob/living/silicon/ai))
+ user = null
+
if(choice != 1)
//legacy support, if choice is != 1 then just kick viewers without changing status
kick_viewers()
@@ -210,12 +214,18 @@
update_coverage()
set_status( !src.status )
if (!(src.status))
- visible_message("\red [user] has deactivated [src]!")
+ if(user)
+ visible_message(" [user] has deactivated [src]!")
+ else
+ visible_message(" [src] clicks and shuts down. ")
playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
icon_state = "[initial(icon_state)]1"
add_hiddenprint(user)
else
- visible_message("\red [user] has reactivated [src]!")
+ if(user)
+ visible_message(" [user] has reactivated [src]!")
+ else
+ visible_message(" [src] clicks and reactivates itself. ")
playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
icon_state = initial(icon_state)
add_hiddenprint(user)
@@ -431,3 +441,14 @@
cameranet.updateVisibility(src, 0)
invalidateCameraCache()
+
+// Resets the camera's wires to fully operational state. Used by one of Malfunction abilities.
+/obj/machinery/camera/proc/reset_wires()
+ if(!wires)
+ return
+ if (stat & BROKEN) // Fix the camera
+ stat &= ~BROKEN
+ wires.CutAll()
+ wires.MendAll()
+ update_icon()
+ update_coverage()
diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm
index 24588582e5..eeaaa03c4f 100644
--- a/code/game/machinery/camera/presets.dm
+++ b/code/game/machinery/camera/presets.dm
@@ -162,15 +162,23 @@ var/global/list/engineering_networks = list(
/obj/machinery/camera/proc/upgradeEmpProof()
assembly.upgrades.Add(new /obj/item/stack/material/osmium(assembly))
setPowerUsage()
+ update_coverage()
/obj/machinery/camera/proc/upgradeXRay()
assembly.upgrades.Add(new /obj/item/weapon/stock_parts/scanning_module/adv(assembly))
setPowerUsage()
+ update_coverage()
-// If you are upgrading Motion, and it isn't in the camera's New(), add it to the machines list.
/obj/machinery/camera/proc/upgradeMotion()
assembly.upgrades.Add(new /obj/item/device/assembly/prox_sensor(assembly))
setPowerUsage()
+ if(!(src in machines))
+ if(!machinery_sort_required && ticker)
+ dd_insertObjectList(machines, src)
+ else
+ machines += src
+ machinery_sort_required = 1
+ update_coverage()
/obj/machinery/camera/proc/setPowerUsage()
var/mult = 1
diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm
index 683e6e1220..c3f617057c 100644
--- a/code/game/machinery/cell_charger.dm
+++ b/code/game/machinery/cell_charger.dm
@@ -10,7 +10,7 @@
power_channel = EQUIP
var/obj/item/weapon/cell/charging = null
var/chargelevel = -1
-
+
/obj/machinery/cell_charger/update_icon()
icon_state = "ccharger[charging ? 1 : 0]"
@@ -27,11 +27,11 @@
chargelevel = newlevel
else
overlays.Cut()
-
+
/obj/machinery/cell_charger/examine(mob/user)
if(!..(user, 5))
return
-
+
user << "There's [charging ? "a" : "no"] cell in the charger."
if(charging)
user << "Current charge: [charging.charge]"
@@ -71,7 +71,7 @@
if(charging)
usr.put_in_hands(charging)
charging.add_fingerprint(user)
- charging.updateicon()
+ charging.update_icon()
src.charging = null
user.visible_message("[user] removes the cell from the charger.", "You remove the cell from the charger.")
@@ -84,7 +84,7 @@
return
charging.loc = src.loc
- charging.updateicon()
+ charging.update_icon()
charging = null
update_icon()
user.visible_message("[user] removes the cell from the charger.", "You remove the cell from the charger.")
@@ -103,11 +103,11 @@
if((stat & (BROKEN|NOPOWER)) || !anchored)
update_use_power(0)
return
-
+
if (charging && !charging.fully_charged())
charging.give(active_power_usage*CELLRATE)
update_use_power(2)
-
+
update_icon()
else
update_use_power(1)
diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm
index e64708907e..8486fdf251 100644
--- a/code/game/machinery/computer/aifixer.dm
+++ b/code/game/machinery/computer/aifixer.dm
@@ -69,7 +69,7 @@
if (src.occupant)
var/laws
- dat += "Stored AI: [src.occupant.name]
System integrity: [src.occupant.system_integrity()]%
"
+ dat += "Stored AI: [src.occupant.name]
System integrity: [src.occupant.hardware_integrity()]%
Backup Capacitor: [src.occupant.backup_capacitor()]%
"
for (var/datum/ai_law/law in occupant.laws.all_laws())
laws += "[law.get_index()]: [law.law]
"
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index 686ac73af6..2aa8e038e5 100644
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -566,7 +566,7 @@
if(!shuttlecaller.stat && shuttlecaller.client && istype(shuttlecaller.loc,/turf))
return ..()
- if(ticker.mode.name == "revolution" || ticker.mode.name == "AI malfunction" || deathsquad.deployed)
+ if(ticker.mode.name == "revolution" || deathsquad.deployed)
return ..()
emergency_shuttle.call_evac()
@@ -589,7 +589,7 @@
if(!shuttlecaller.stat && shuttlecaller.client && istype(shuttlecaller.loc,/turf))
return ..()
- if(ticker.mode.name == "revolution" || ticker.mode.name == "AI malfunction" || deathsquad.deployed)
+ if(ticker.mode.name == "revolution" || deathsquad.deployed)
return ..()
emergency_shuttle.call_evac()
diff --git a/code/game/machinery/computer3/laptop.dm b/code/game/machinery/computer3/laptop.dm
index 484db52462..65864b0b70 100644
--- a/code/game/machinery/computer3/laptop.dm
+++ b/code/game/machinery/computer3/laptop.dm
@@ -55,19 +55,11 @@
qdel(src)
return
- if(!stored_computer.manipulating)
- stored_computer.manipulating = 1
- stored_computer.loc = loc
- stored_computer.stat &= ~MAINT
- stored_computer.update_icon()
- loc = null
- usr << "You open \the [src]."
-
- spawn(5)
- stored_computer.manipulating = 0
- qdel(src)
- else
- usr << "\red You are already opening the computer!"
+ stored_computer.loc = loc
+ stored_computer.stat &= ~MAINT
+ stored_computer.update_icon()
+ loc = stored_computer
+ usr << "You open \the [src]."
AltClick()
@@ -82,12 +74,10 @@
if(stored_computer)
stored_computer.eject_id()
-
/obj/machinery/computer3/laptop/verb/eject_id()
set category = "Object"
set name = "Eject ID Card"
set src in oview(1)
-
var/obj/item/part/computer/cardslot/C = locate() in src.contents
if(!C)
@@ -104,7 +94,7 @@
return
usr << "You remove [card] from the laptop."
- C.remove(card)
+ C.remove(4)
/obj/machinery/computer3/laptop
@@ -117,7 +107,6 @@
pixel_y = -3
show_keyboard = 0
- var/manipulating = 0 // To prevent disappearing bug
var/obj/item/device/laptop/portable = null
New(var/L, var/built = 0)
@@ -157,12 +146,11 @@
portable=new
portable.stored_computer = src
- if(!manipulating)
- portable.loc = loc
- loc = portable
- stat |= MAINT
- if(user)
- user << "You close \the [src]."
+ portable.loc = loc
+ loc = portable
+ stat |= MAINT
+ if(user)
+ user << "You close \the [src]."
auto_use_power()
if(stat&MAINT)
diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
index 41bb3bef2d..e345847c86 100644
--- a/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -393,9 +393,9 @@
occupant.ckey = null
//Make an announcement and log the person entering storage.
- control_computer.frozen_crew += "[occupant.real_name]"
+ control_computer.frozen_crew += "[occupant.real_name], [occupant.mind.assigned_role] - [worldtime2text()]"
- announce.autosay("[occupant.real_name] [on_store_message]", "[on_store_name]")
+ announce.autosay("[occupant.real_name], [occupant.mind.assigned_role] [on_store_message]", "[on_store_name]")
visible_message("\The [initial(name)] hums and hisses as it moves [occupant.real_name] into storage.", 3)
// Delete the mob.
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 58830cf9fa..1313838cf5 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -30,7 +30,7 @@
var/hasShocked = 0 //Prevents multiple shocks from happening
var/secured_wires = 0
var/datum/wires/airlock/wires = null
-
+
var/open_sound_powered = 'sound/machines/airlock.ogg'
var/open_sound_unpowered = 'sound/machines/airlock_creaking.ogg'
@@ -277,7 +277,7 @@
target_tile.assume_gas("phoron", 35, 400+T0C)
spawn (0) target_tile.hotspot_expose(temperature, 400)
for(var/turf/simulated/wall/W in range(3,src))
- W.ignite((temperature/4))//Added so that you can't set off a massive chain reaction with a small flame
+ W.burn((temperature/4))//Added so that you can't set off a massive chain reaction with a small flame
for(var/obj/machinery/door/airlock/phoron/D in range(3,src))
D.ignite(temperature/4)
new/obj/structure/door_assembly( src.loc )
@@ -800,9 +800,9 @@ About the new airlock wires panel:
qdel(src)
return
else if(arePowerSystemsOn())
- user << "\blue The airlock's motors resist your efforts to force it."
+ user << "The airlock's motors resist your efforts to force it."
else if(locked)
- user << "\blue The airlock's bolts prevent it from being forced."
+ user << "The airlock's bolts prevent it from being forced."
else
if(density)
spawn(0) open(1)
@@ -811,20 +811,20 @@ About the new airlock wires panel:
else if(istype(C, /obj/item/weapon/material/twohanded/fireaxe) && !arePowerSystemsOn())
if(locked)
- user << "\blue The airlock's bolts prevent it from being forced."
+ user << "The airlock's bolts prevent it from being forced."
else if( !welded && !operating )
if(density)
var/obj/item/weapon/material/twohanded/fireaxe/F = C
if(F.wielded)
spawn(0) open(1)
else
- user << "\red You need to be wielding \the [C] to do that."
+ user << "You need to be wielding \the [C] to do that."
else
var/obj/item/weapon/material/twohanded/fireaxe/F = C
if(F.wielded)
spawn(0) close(1)
else
- user << "\red You need to be wielding \the [C] to do that."
+ user << "You need to be wielding \the [C] to do that."
else
..()
@@ -855,13 +855,13 @@ About the new airlock wires panel:
if(!can_open(forced))
return 0
use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people
-
+
//if the door is unpowered then it doesn't make sense to hear the woosh of a pneumatic actuator
if(arePowerSystemsOn())
playsound(src.loc, open_sound_powered, 100, 1)
else
playsound(src.loc, open_sound_unpowered, 100, 1)
-
+
if(src.closeOther != null && istype(src.closeOther, /obj/machinery/door/airlock/) && !src.closeOther.density)
src.closeOther.close()
return ..()
@@ -950,10 +950,10 @@ About the new airlock wires panel:
take_damage(DOOR_CRUSH_DAMAGE)
use_power(360) //360 W seems much more appropriate for an actuator moving an industrial door capable of crushing people
- if(istype(src, /obj/machinery/door/airlock/glass))
- playsound(src.loc, 'sound/machines/windowdoor.ogg', 30, 1)
+ if(arePowerSystemsOn())
+ playsound(src.loc, open_sound_powered, 100, 1)
else
- playsound(src.loc, 'sound/machines/airlock.ogg', 30, 1)
+ playsound(src.loc, open_sound_unpowered, 100, 1)
for(var/turf/turf in locs)
var/obj/structure/window/killthis = (locate(/obj/structure/window) in turf)
if(killthis)
diff --git a/code/game/machinery/floodlight.dm b/code/game/machinery/floodlight.dm
index b7272dc829..f72c231f95 100644
--- a/code/game/machinery/floodlight.dm
+++ b/code/game/machinery/floodlight.dm
@@ -7,28 +7,70 @@
density = 1
var/on = 0
var/obj/item/weapon/cell/high/cell = null
- var/use = 5
+ var/use = 200 // 200W light
var/unlocked = 0
var/open = 0
var/brightness_on = 8 //can't remember what the maxed out value is
/obj/machinery/floodlight/New()
src.cell = new(src)
+ cell.maxcharge = 1000
+ cell.charge = 1000 // 41minutes @ 200W
..()
-/obj/machinery/floodlight/proc/updateicon()
+/obj/machinery/floodlight/update_icon()
+ overlays.Cut()
icon_state = "flood[open ? "o" : ""][open && cell ? "b" : ""]0[on]"
/obj/machinery/floodlight/process()
+ if(!on)
+ return
+
+ if(!cell || (cell.charge < (use * CELLRATE)))
+ turn_off(1)
+ return
+
+ // If the cell is almost empty rarely "flicker" the light. Aesthetic only.
+ if((cell.percent() < 10) && prob(5))
+ set_light(brightness_on/2, brightness_on/4)
+ spawn(20)
+ if(on)
+ set_light(brightness_on, brightness_on/2)
+
+ cell.use(use*CELLRATE)
+
+
+// Returns 0 on failure and 1 on success
+/obj/machinery/floodlight/proc/turn_on(var/loud = 0)
+ if(!cell)
+ return 0
+ if(cell.charge < (use * CELLRATE))
+ return 0
+
+ on = 1
+ set_light(brightness_on, brightness_on / 2)
+ update_icon()
+ if(loud)
+ visible_message("\The [src] turns on.")
+ return 1
+
+/obj/machinery/floodlight/proc/turn_off(var/loud = 0)
+ on = 0
+ set_light(0, 0)
+ update_icon()
+ if(loud)
+ visible_message("\The [src] shuts down.")
+
+/obj/machinery/floodlight/attack_ai(mob/user as mob)
+ if(istype(user, /mob/living/silicon/robot) && Adjacent(user))
+ return attack_hand(user)
+
if(on)
- if(cell.charge >= use)
- cell.use(use)
- else
- on = 0
- updateicon()
- set_light(0)
- src.visible_message("[src] shuts down due to lack of power!")
- return
+ turn_off(1)
+ else
+ if(!turn_on(1))
+ user << "You try to turn on \the [src] but it does not work."
+
/obj/machinery/floodlight/attack_hand(mob/user as mob)
if(open && cell)
@@ -40,27 +82,20 @@
cell.loc = loc
cell.add_fingerprint(user)
- cell.updateicon()
+ cell.update_icon()
src.cell = null
user << "You remove the power cell"
- updateicon()
+ update_icon()
return
if(on)
- on = 0
- user << "\blue You turn off the light"
- set_light(0)
+ turn_off(1)
else
- if(!cell)
- return
- if(cell.charge <= 0)
- return
- on = 1
- user << "\blue You turn on the light"
- set_light(brightness_on)
+ if(!turn_on(1))
+ user << "You try to turn on \the [src] but it does not work."
- updateicon()
+ update_icon()
/obj/machinery/floodlight/attackby(obj/item/weapon/W as obj, mob/user as mob)
@@ -93,4 +128,4 @@
W.loc = src
cell = W
user << "You insert the power cell."
- updateicon()
+ update_icon()
diff --git a/code/game/machinery/kitchen/smartfridge.dm b/code/game/machinery/kitchen/smartfridge.dm
index 9bfa0e1c5d..9016836274 100644
--- a/code/game/machinery/kitchen/smartfridge.dm
+++ b/code/game/machinery/kitchen/smartfridge.dm
@@ -204,7 +204,7 @@
item_quants[O.name]++
else
item_quants[O.name] = 1
- user.visible_message("[user] has added \the [O] to \the [src].", "You add \the [O] to \the [src].")
+ user.visible_message("[user] has added \the [O] to \the [src].", "You add \the [O] to \the [src].")
nanomanager.update_uis(src)
diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm
index 5476d9f6fa..1c5c8766de 100644
--- a/code/game/machinery/portable_turret.dm
+++ b/code/game/machinery/portable_turret.dm
@@ -21,6 +21,8 @@
var/raised = 0 //if the turret cover is "open" and the turret is raised
var/raising= 0 //if the turret is currently opening or closing its cover
var/health = 80 //the turret's health
+ var/maxhealth = 80 //turrets maximal health.
+ var/auto_repair = 0 //if 1 the turret slowly repairs itself.
var/locked = 1 //if the turret's behaviour control access is locked
var/controllock = 0 //if the turret responds to control panels
@@ -450,6 +452,10 @@
spawn()
popDown() // no valid targets, close the cover
+ if(auto_repair && (health < maxhealth))
+ use_power(20000)
+ health = min(health+1, maxhealth) // 1HP for 20kJ
+
/obj/machinery/porta_turret/proc/assess_and_assign(var/mob/living/L, var/list/targets, var/list/secondarytargets)
switch(assess_living(L))
if(TURRET_PRIORITY_TARGET)
diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm
index c5d389c66e..14a081ee2e 100644
--- a/code/game/machinery/spaceheater.dm
+++ b/code/game/machinery/spaceheater.dm
@@ -121,7 +121,7 @@
if("cellremove")
if(panel_open && cell && !usr.get_active_hand())
usr.visible_message("\blue [usr] removes \the [cell] from \the [src].", "\blue You remove \the [cell] from \the [src].")
- cell.updateicon()
+ cell.update_icon()
usr.put_in_hands(cell)
cell.add_fingerprint(usr)
cell = null
diff --git a/code/game/machinery/turrets.dm b/code/game/machinery/turrets.dm
index c36fe7c064..3581c51e18 100644
--- a/code/game/machinery/turrets.dm
+++ b/code/game/machinery/turrets.dm
@@ -51,6 +51,8 @@
// 5 = bluetag
// 6 = redtag
var/health = 80
+ var/maxhealth = 80
+ var/auto_repair = 0
var/obj/machinery/turretcover/cover = null
var/popping = 0
var/wasvalid = 0
@@ -90,6 +92,7 @@
return
/obj/machinery/turret/New()
+ maxhealth = health
spark_system = new /datum/effect/effect/system/spark_spread
spark_system.set_up(5, 0, src)
spark_system.attach(src)
@@ -221,6 +224,13 @@
if(!isDown())
popDown()
use_power = 1
+
+ // Auto repair requires massive amount of power, but slowly regenerates the turret's health.
+ // Currently only used by malfunction hardware, but may be used as admin-settable option too.
+ if(auto_repair)
+ if(health < maxhealth)
+ use_power(20000)
+ health = min(health + 1, maxhealth)
return
diff --git a/code/game/objects/effects/chem/water.dm b/code/game/objects/effects/chem/water.dm
index cd92127fe8..6566668c55 100644
--- a/code/game/objects/effects/chem/water.dm
+++ b/code/game/objects/effects/chem/water.dm
@@ -17,20 +17,23 @@
if(!target)
return
for(var/i = 1 to step_count)
+ if(!loc)
+ return
step_towards(src, target)
var/turf/T = get_turf(src)
- reagents.touch_turf(T)
- var/mob/M
- for(var/atom/A in T)
- if(!ismob(A)) // Mobs are handled differently
- reagents.touch(A)
- else if(!M)
- M = A
- if(M)
- reagents.splash_mob(M, reagents.total_volume)
- break
- if(T == get_turf(target))
- break
+ if(T && reagents)
+ reagents.touch_turf(T)
+ var/mob/M
+ for(var/atom/A in T)
+ if(!ismob(A)) // Mobs are handled differently
+ reagents.touch(A)
+ else if(!M)
+ M = A
+ if(M)
+ reagents.splash_mob(M, reagents.total_volume)
+ break
+ if(T == get_turf(target))
+ break
sleep(delay)
sleep(10)
qdel(src)
diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm
index 72f24b739a..b3fe3a7a37 100644
--- a/code/game/objects/items/devices/aicard.dm
+++ b/code/game/objects/items/devices/aicard.dm
@@ -18,6 +18,7 @@
user << "ERROR ERROR ERROR"
/obj/item/device/aicard/attack_self(mob/user)
+
ui_interact(user)
/obj/item/device/aicard/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = inventory_state)
@@ -25,7 +26,8 @@
data["has_ai"] = carded_ai != null
if(carded_ai)
data["name"] = carded_ai.name
- data["integrity"] = carded_ai.system_integrity()
+ data["hardware_integrity"] = carded_ai.hardware_integrity()
+ data["backup_capacitor"] = carded_ai.backup_capacitor()
data["radio"] = !carded_ai.aiRadio.disabledAi
data["wireless"] = !carded_ai.control_disabled
data["operational"] = carded_ai.stat != DEAD
@@ -73,7 +75,6 @@
carded_ai << "Your wireless interface has been [carded_ai.control_disabled ? "disabled" : "enabled"]!"
user << "You [carded_ai.control_disabled ? "disable" : "enable"] the AI's wireless interface."
update_icon()
-
return 1
/obj/item/device/aicard/update_icon()
diff --git a/code/game/objects/items/devices/debugger.dm b/code/game/objects/items/devices/debugger.dm
index 0e066a4817..6f812aacb7 100644
--- a/code/game/objects/items/devices/debugger.dm
+++ b/code/game/objects/items/devices/debugger.dm
@@ -25,7 +25,7 @@
/obj/item/device/debugger/is_used_on(obj/O, mob/user)
if(istype(O, /obj/machinery/power/apc))
var/obj/machinery/power/apc/A = O
- if(A.emagged || A.malfhack)
+ if(A.emagged || A.hacker)
user << "\red There is a software error with the device."
else
user << "\blue The device's software appears to be fine."
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 1d585c9c89..76df8968ed 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -91,7 +91,7 @@ REAGENT SCANNER
if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
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.")
+ 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
diff --git a/code/game/objects/items/devices/suit_cooling.dm b/code/game/objects/items/devices/suit_cooling.dm
index 291053f25d..dada8f20a3 100644
--- a/code/game/objects/items/devices/suit_cooling.dm
+++ b/code/game/objects/items/devices/suit_cooling.dm
@@ -5,56 +5,56 @@
icon = 'icons/obj/device.dmi'
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
-
+
//copied from tank.dm
flags = CONDUCT
force = 5.0
throwforce = 10.0
throw_speed = 1
throw_range = 4
-
+
origin_tech = "magnets=2;materials=2"
-
+
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)
+ 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 = 1 - H.get_pressure_weakness() //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()
@@ -70,22 +70,22 @@
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))
+ 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()
@@ -93,7 +93,7 @@
return
if(cell.charge <= 0)
return
-
+
on = 1
updateicon()
@@ -112,7 +112,7 @@
cell.loc = get_turf(loc)
cell.add_fingerprint(user)
- cell.updateicon()
+ cell.update_icon()
user << "You remove the [src.cell]."
src.cell = null
@@ -149,7 +149,7 @@
user << "You insert the [cell]."
updateicon()
return
-
+
return ..()
/obj/item/device/suit_cooling_unit/proc/updateicon()
@@ -164,7 +164,7 @@
/obj/item/device/suit_cooling_unit/examine(mob/user)
if(!..(user, 1))
return
-
+
if (on)
if (attached_to_suit(src.loc))
user << "It's switched on and running."
@@ -172,13 +172,13 @@
user << "It's switched on, but not attached to anything."
else
user << "It is switched off."
-
+
if (cover_open)
if(cell)
user << "The panel is open, exposing the [cell]."
else
user << "The panel is open."
-
+
if (cell)
user << "The charge meter reads [round(cell.percent())]%."
else
diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm
index dfc53d3a87..afe50bc2b7 100644
--- a/code/game/objects/items/robot/robot_items.dm
+++ b/code/game/objects/items/robot/robot_items.dm
@@ -4,26 +4,40 @@
Cyborg Spec Items
***********************************************************************/
//Might want to move this into several files later but for now it works here
+// Consider changing this to a child of the stun baton class. ~Z
/obj/item/borg/stun
name = "electrified arm"
icon = 'icons/obj/decals.dmi'
icon_state = "shock"
- attack(mob/M as mob, mob/living/silicon/robot/user as mob)
- M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])")
- user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])")
- msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] to attack [M.name] ([M.ckey]) (JMP)")
+/obj/item/borg/stun/attack(var/mob/living/M, var/mob/living/silicon/robot/user)
- user.cell.charge -= 30
+ if(!istype(M))
+ return
- M.Weaken(5)
- if (M.stuttering < 5)
- M.stuttering = 5
- M.Stun(5)
+ // How the Hell.
+ if(!istype(user))
+ var/mob/living/temp = user
+ if(istype(temp))
+ temp.drop_from_inventory(src)
+ qdel(src)
+ return
- for(var/mob/O in viewers(M, null))
- if (O.client)
- O.show_message("\red [user] has prodded [M] with an electrically-charged arm!", 1, "\red You hear someone fall", 2)
+ M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])")
+ user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])")
+ msg_admin_attack("[user.name] ([user.ckey]) used the [src.name] to attack [M.name] ([M.ckey]) (JMP)")
+
+ if(!user.cell || !user.cell.checked_use(1250)) //Slightly more than a baton.
+ user.visible_message("\The [user] has prodded \the [M] with its arm!")
+ return
+
+ if (M.stuttering < 5)
+ M.stuttering = 5
+ M.stun_effect_act(0, 70, check_zone(user.zone_sel.selecting), src)
+ user.visible_message("\The [user] has prodded \the [M] with \a [src]!")
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ H.forcesay(hit_appends)
/obj/item/borg/overdrive
name = "overdrive"
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index e7dc25fae5..8d24c875db 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -223,10 +223,10 @@
*/
//attempts to transfer amount to S, and returns the amount actually transferred
-/obj/item/stack/proc/transfer_to(obj/item/stack/S, var/tamount=null)
+/obj/item/stack/proc/transfer_to(obj/item/stack/S, var/tamount=null, var/type_verified)
if (!get_amount())
return 0
- if (stacktype != S.stacktype)
+ if ((stacktype != S.stacktype) && !type_verified)
return 0
if (isnull(tamount))
tamount = src.get_amount()
@@ -240,7 +240,6 @@
transfer_fingerprints_to(S)
if(blood_DNA)
S.blood_DNA |= blood_DNA
- //todo bloody overlay
return transfer
return 0
@@ -256,6 +255,7 @@
var/orig_amount = src.amount
if (transfer && src.use(transfer))
var/obj/item/stack/newstack = new src.type(loc, transfer)
+ newstack.color = color
if (prob(transfer/orig_amount * 100))
transfer_fingerprints_to(newstack)
if(blood_DNA)
@@ -314,10 +314,8 @@
return
/obj/item/stack/attackby(obj/item/W as obj, mob/user as mob)
- ..()
if (istype(W, /obj/item/stack))
var/obj/item/stack/S = W
-
if (user.get_inactive_hand()==src)
src.transfer_to(S, 1)
else
@@ -328,7 +326,8 @@
S.interact(usr)
if (src && usr.machine==src)
src.interact(usr)
- else return ..()
+ else
+ return ..()
/*
* Recipe datum
diff --git a/code/game/objects/items/ashtray.dm b/code/game/objects/items/weapons/material/ashtray.dm
similarity index 95%
rename from code/game/objects/items/ashtray.dm
rename to code/game/objects/items/weapons/material/ashtray.dm
index 63059fef8e..033042b853 100644
--- a/code/game/objects/items/ashtray.dm
+++ b/code/game/objects/items/weapons/material/ashtray.dm
@@ -76,32 +76,27 @@ var/global/list/ashtray_cache = list()
health = max(0,health - W.force)
user << "You hit [src] with [W]."
if (health < 1)
- die()
+ shatter()
return
/obj/item/weapon/material/ashtray/throw_impact(atom/hit_atom)
if (health > 0)
health = max(0,health - 3)
- if (health < 1)
- die()
- return
if (contents.len)
src.visible_message("\The [src] slams into [hit_atom], spilling its contents!")
for (var/obj/item/clothing/mask/smokable/cigarette/O in contents)
O.loc = src.loc
+ if (health < 1)
+ shatter()
+ return
update_icon()
return ..()
-/obj/item/weapon/material/ashtray/proc/die()
- material.place_shard(get_turf(src))
- qdel(src)
- return
-
/obj/item/weapon/material/ashtray/plastic/New(var/newloc)
..(newloc, "plastic")
/obj/item/weapon/material/ashtray/bronze/New(var/newloc)
- ..(newloc, "gold") //placeholder
+ ..(newloc, "bronze")
/obj/item/weapon/material/ashtray/glass/New(var/newloc)
..(newloc, "glass")
diff --git a/code/game/objects/items/weapons/material/material_weapons.dm b/code/game/objects/items/weapons/material/material_weapons.dm
index 8208576e16..fe33163dba 100644
--- a/code/game/objects/items/weapons/material/material_weapons.dm
+++ b/code/game/objects/items/weapons/material/material_weapons.dm
@@ -72,7 +72,7 @@
var/mob/living/M = loc
M.drop_from_inventory(src)
playsound(src, "shatter", 70, 1)
- new material.shard_type(T)
+ material.place_shard(T)
qdel(src)
/obj/item/weapon/material/process()
@@ -82,18 +82,12 @@
L.apply_effect(round(material.radioactivity/3),IRRADIATE,0)
/obj/item/weapon/material/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
- if(exposed_temperature > material.ignition_point)
- TemperatureAct(exposed_temperature)
+ TemperatureAct(exposed_temperature)
// This might need adjustment. Will work that out later.
/obj/item/weapon/material/proc/TemperatureAct(temperature)
- if(temperature > material.ignition_point)
- for(var/turf/simulated/floor/target_tile in range(2,loc))
- var/phoronToDeduce = temperature/30
- target_tile.assume_gas("phoron", phoronToDeduce, 200+T0C)
- spawn (0) target_tile.hotspot_expose(temperature, 400)
- health -= phoronToDeduce/100
- check_health()
+ health -= material.combustion_effect(get_turf(src), temperature, 0.1)
+ check_health()
/obj/item/weapon/material/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W,/obj/item/weapon/weldingtool))
diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm
index 0f8cbcc10f..d28107dd8f 100644
--- a/code/game/objects/items/weapons/storage/boxes.dm
+++ b/code/game/objects/items/weapons/storage/boxes.dm
@@ -24,7 +24,7 @@
desc = "It's just an ordinary box."
icon_state = "box"
item_state = "syringe_kit"
- var/foldable = null // BubbleWrap - if set, can be folded (when empty) into a sheet of cardboard
+ var/foldable = /obj/item/stack/material/cardboard // BubbleWrap - if set, can be folded (when empty) into a sheet of cardboard
// BubbleWrap - A box can be folded up to make card
/obj/item/weapon/storage/box/attack_self(mob/user as mob)
@@ -56,7 +56,7 @@
new /obj/item/clothing/mask/breath( src )
new /obj/item/weapon/tank/emergency_oxygen( src )
-/obj/item/weapon/storage/box/survival/vox/
+/obj/item/weapon/storage/box/vox/
New()
..()
new /obj/item/clothing/mask/breath( src )
@@ -598,7 +598,6 @@
icon_state = "light"
desc = "This box is shaped on the inside so that only light tubes and bulbs fit."
item_state = "syringe_kit"
- foldable = /obj/item/stack/material/cardboard //BubbleWrap
storage_slots=21
can_hold = list(/obj/item/weapon/light/tube, /obj/item/weapon/light/bulb)
max_storage_space = 42 //holds 21 items of w_class 2
diff --git a/code/game/objects/items/weapons/storage/briefcase.dm b/code/game/objects/items/weapons/storage/briefcase.dm
index 0f534ade9e..ff3d60aec8 100644
--- a/code/game/objects/items/weapons/storage/briefcase.dm
+++ b/code/game/objects/items/weapons/storage/briefcase.dm
@@ -10,40 +10,3 @@
w_class = 4
max_w_class = 3
max_storage_space = 16
-
-/obj/item/weapon/storage/briefcase/New()
- ..()
-
-/obj/item/weapon/storage/briefcase/attack(mob/living/M as mob, mob/living/user as mob)
- //..()
-
- if ((CLUMSY in user.mutations) && prob(50))
- user << "\red The [src] slips out of your hand and hits your head."
- user.take_organ_damage(10)
- user.Paralyse(2)
- return
-
-
- M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])")
- user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])")
- msg_admin_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (?)")
-
- if (M.stat < 2 && M.health < 50 && prob(90))
- var/mob/H = M
- // ******* Check
- if ((istype(H, /mob/living/carbon/human) && istype(H, /obj/item/clothing/head) && H.flags & 8 && prob(80)))
- M << "\red The helmet protects you from being hit hard in the head!"
- return
- var/time = rand(2, 6)
- if (prob(75))
- M.Paralyse(time)
- else
- M.Stun(time)
- if(M.stat != 2) M.stat = 1
- for(var/mob/O in viewers(M, null))
- O.show_message(text("\red [] has been knocked unconscious!", M), 1, "\red You hear someone fall.", 2)
- else
- M << text("\red [] tried to knock you unconcious!",user)
- M.eye_blurry += 3
-
- return
diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm
index 085e23f9b6..b33d72f6fb 100644
--- a/code/game/objects/items/weapons/storage/uplink_kits.dm
+++ b/code/game/objects/items/weapons/storage/uplink_kits.dm
@@ -11,7 +11,7 @@
if("stealth")
new /obj/item/weapon/gun/energy/crossbow(src)
- new /obj/item/weapon/pen/paralysis(src)
+ new /obj/item/weapon/pen/reagent/paralysis(src)
new /obj/item/device/chameleon(src)
return
diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm
index bed0591a7e..7f9348bb0d 100644
--- a/code/game/objects/items/weapons/stunbaton.dm
+++ b/code/game/objects/items/weapons/stunbaton.dm
@@ -73,7 +73,7 @@
else if(istype(W, /obj/item/weapon/screwdriver))
if(bcell)
- bcell.updateicon()
+ bcell.update_icon()
bcell.loc = get_turf(src.loc)
bcell = null
user << "You remove the cell from the [src]."
diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm
index 55d233e3bc..d15441b032 100644
--- a/code/game/objects/items/weapons/surgery_tools.dm
+++ b/code/game/objects/items/weapons/surgery_tools.dm
@@ -61,7 +61,7 @@
matter = list(DEFAULT_WALL_MATERIAL = 15000, "glass" = 10000)
flags = CONDUCT
force = 15.0
- w_class = 2.0
+ w_class = 3
origin_tech = "materials=1;biotech=1"
attack_verb = list("drilled")
@@ -82,7 +82,7 @@
force = 10.0
sharp = 1
edge = 1
- w_class = 2.0
+ w_class = 1
throwforce = 5.0
throw_speed = 3
throw_range = 5
@@ -136,7 +136,7 @@
hitsound = 'sound/weapons/circsawhit.ogg'
flags = CONDUCT
force = 15.0
- w_class = 2.0
+ w_class = 3
throwforce = 9.0
throw_speed = 3
throw_range = 5
diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm
index 169b1deebd..3de1075f38 100644
--- a/code/game/objects/structures/door_assembly.dm
+++ b/code/game/objects/structures/door_assembly.dm
@@ -174,9 +174,9 @@
else if(istype(W, /obj/item/weapon/wrench) && state == 0)
playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
if(anchored)
- user.visible_message("[user] unsecures the airlock assembly from the floor.", "You start to unsecure the airlock assembly from the floor.")
+ user.visible_message("[user] begins unsecuring the airlock assembly from the floor.", "You starts unsecuring the airlock assembly from the floor.")
else
- user.visible_message("[user] secures the airlock assembly to the floor.", "You start to secure the airlock assembly to the floor.")
+ user.visible_message("[user] begins securing the airlock assembly to the floor.", "You starts securing the airlock assembly to the floor.")
if(do_after(user, 40))
if(!src) return
@@ -225,7 +225,7 @@
return
playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1)
- user.visible_message("[user] removes the electronics from the airlock assembly.", "You start to remove the electronics from the airlock assembly.")
+ user.visible_message("\The [user] starts removing the electronics from the airlock assembly.", "You start removing the electronics from the airlock assembly.")
if(do_after(user, 40))
if(!src) return
diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm
index a5ad84c20e..3647d565f7 100644
--- a/code/game/objects/structures/noticeboard.dm
+++ b/code/game/objects/structures/noticeboard.dm
@@ -21,7 +21,7 @@
if(notices < 5)
O.add_fingerprint(user)
add_fingerprint(user)
- user.drop_item()
+ user.drop_from_inventory(O)
O.loc = src
notices++
icon_state = "nboard0[notices]" //update sprite
@@ -29,13 +29,22 @@
else
user << "You reach to pin your paper to the board but hesitate. You are certain your paper will not be seen among the many others already attached."
-/obj/structure/noticeboard/attack_hand(user as mob)
- var/dat = "Noticeboard
"
- for(var/obj/item/weapon/paper/P in src)
- dat += "[P.name] Write Remove
"
- user << browse("Notices[dat]","window=noticeboard")
- onclose(user, "noticeboard")
+/obj/structure/noticeboard/attack_hand(var/mob/user)
+ examine(user)
+// Since Topic() never seems to interact with usr on more than a superficial
+// level, it should be fine to let anyone mess with the board other than ghosts.
+/obj/structure/noticeboard/examine(var/mob/user)
+ if(!user)
+ user = usr
+ if(user.Adjacent(src))
+ var/dat = "Noticeboard
"
+ for(var/obj/item/weapon/paper/P in src)
+ dat += "[P.name] Write Remove
"
+ user << browse("Notices[dat]","window=noticeboard")
+ onclose(user, "noticeboard")
+ else
+ ..()
/obj/structure/noticeboard/Topic(href, href_list)
..()
@@ -44,18 +53,16 @@
if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open
return
var/obj/item/P = locate(href_list["remove"])
- if((P && P.loc == src))
+ if(P && P.loc == src)
P.loc = get_turf(src) //dump paper on the floor because you're a clumsy fuck
P.add_fingerprint(usr)
add_fingerprint(usr)
notices--
icon_state = "nboard0[notices]"
-
if(href_list["write"])
if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open
return
var/obj/item/P = locate(href_list["write"])
-
if((P && P.loc == src)) //ifthe paper's on the board
if(istype(usr.r_hand, /obj/item/weapon/pen)) //and you're holding a pen
add_fingerprint(usr)
@@ -66,14 +73,9 @@
P.attackby(usr.l_hand, usr)
else
usr << "You'll need something to write with!"
-
if(href_list["read"])
var/obj/item/weapon/paper/P = locate(href_list["read"])
if((P && P.loc == src))
- if(!( istype(usr, /mob/living/carbon/human) ))
- usr << browse("[P.name][stars(P.info)]", "window=[P.name]")
- onclose(usr, "[P.name]")
- else
- usr << browse("[P.name][P.info]", "window=[P.name]")
- onclose(usr, "[P.name]")
+ usr << browse("[P.name][P.info]", "window=[P.name]")
+ onclose(usr, "[P.name]")
return
diff --git a/code/game/objects/structures/simple_doors.dm b/code/game/objects/structures/simple_doors.dm
index 313ba17f45..b3230095c1 100644
--- a/code/game/objects/structures/simple_doors.dm
+++ b/code/game/objects/structures/simple_doors.dm
@@ -13,17 +13,11 @@
var/oreAmount = 7
/obj/structure/simple_door/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
- if(exposed_temperature > material.ignition_point)
- TemperatureAct(exposed_temperature)
+ TemperatureAct(exposed_temperature)
/obj/structure/simple_door/proc/TemperatureAct(temperature)
- if(temperature > material.ignition_point)
- for(var/turf/simulated/floor/target_tile in range(2,loc))
- var/phoronToDeduce = temperature/10
- target_tile.assume_gas("phoron", phoronToDeduce, 200+T0C)
- spawn (0) target_tile.hotspot_expose(temperature, 400)
- hardness -= phoronToDeduce/100
- CheckHardness()
+ hardness -= material.combustion_effect(get_turf(src),temperature, 0.3)
+ CheckHardness()
/obj/structure/simple_door/New(var/newloc, var/material_name)
..()
diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm
index 46cf8ffcd8..977a3939d9 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm
@@ -8,6 +8,9 @@
icon_state = "nest"
var/health = 100
+/obj/structure/bed/nest/update_icon()
+ return
+
/obj/structure/bed/nest/user_unbuckle_mob(mob/user as mob)
if(buckled_mob)
if(buckled_mob.buckled == src)
diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
index fb2ef2b525..9b62a14ef4 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm
@@ -10,28 +10,56 @@
/obj/structure/bed
name = "bed"
desc = "This is used to lie in, sleep in or strap on."
- icon = 'icons/obj/objects.dmi'
+ icon = 'icons/obj/furniture.dmi'
icon_state = "bed"
pressure_resistance = 15
anchored = 1
can_buckle = 1
buckle_lying = 1
var/material/material
- var/apply_cosmetics = 1
+ var/material/padding_material
+ var/base_icon = "bed"
-/obj/structure/bed/New(var/newloc, var/new_material)
+/obj/structure/bed/New(var/newloc, var/new_material, var/new_padding_material)
..(newloc)
if(!new_material)
new_material = DEFAULT_WALL_MATERIAL
-
material = get_material_by_name(new_material)
if(!istype(material))
qdel(src)
return
- if(apply_cosmetics)
- color = material.icon_colour
+ if(new_padding_material)
+ padding_material = get_material_by_name(new_padding_material)
+ update_icon()
+
+// Reuse the cache/code from stools, todo maybe unify.
+/obj/structure/bed/update_icon()
+ // Prep icon.
+ icon_state = ""
+ overlays.Cut()
+ // Base icon.
+ var/cache_key = "[base_icon]-[material.name]"
+ if(isnull(stool_cache[cache_key]))
+ var/image/I = image('icons/obj/furniture.dmi', base_icon)
+ I.color = material.icon_colour
+ stool_cache[cache_key] = I
+ overlays |= stool_cache[cache_key]
+ // Padding overlay.
+ if(padding_material)
+ var/padding_cache_key = "[base_icon]-padding-[padding_material.name]"
+ if(isnull(stool_cache[padding_cache_key]))
+ var/image/I = image(icon, "[base_icon]_padding")
+ I.color = padding_material.icon_colour
+ stool_cache[padding_cache_key] = I
+ overlays |= stool_cache[padding_cache_key]
+ // Strings.
+ desc = initial(desc)
+ if(padding_material)
+ name = "[padding_material.display_name] [initial(name)]" //this is not perfect but it will do for now.
+ desc += " It's made of [material.use_name] and covered with [padding_material.use_name]."
+ else
name = "[material.display_name] [initial(name)]"
- desc = "[initial(desc)] It's made of [material.display_name]."
+ desc += " It's made of [material.use_name]."
/obj/structure/bed/ex_act(severity)
switch(severity)
@@ -55,8 +83,43 @@
/obj/structure/bed/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/wrench))
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
- material.place_sheet(get_turf(src))
+ dismantle()
qdel(src)
+ else if(istype(W,/obj/item/stack))
+ if(padding_material)
+ user << "\The [src] is already padded."
+ return
+ var/obj/item/stack/C = W
+ if(C.get_amount() < 1) // How??
+ user.drop_from_inventory(C)
+ qdel(C)
+ return
+ var/padding_type //This is awful but it needs to be like this until tiles are given a material var.
+ if(istype(W,/obj/item/stack/tile/carpet))
+ padding_type = "carpet"
+ else if(istype(W,/obj/item/stack/material))
+ var/obj/item/stack/material/M = W
+ if(M.material && (M.material.flags & MATERIAL_PADDING))
+ padding_type = "[M.material.name]"
+ if(!padding_type)
+ user << "You cannot pad \the [src] with that."
+ return
+ C.use(1)
+ if(!istype(src.loc, /turf))
+ user.drop_from_inventory(src)
+ src.loc = get_turf(src)
+ user << "You add padding to \the [src]."
+ add_padding(padding_type)
+ return
+
+ else if (istype(W, /obj/item/weapon/wirecutters))
+ if(!padding_material)
+ user << "\The [src] has no padding to remove."
+ return
+ user << "You remove the padding from \the [src]."
+ playsound(src, 'sound/items/Wirecutter.ogg', 100, 1)
+ remove_padding()
+
else if(istype(W, /obj/item/weapon/grab))
user.visible_message("[user] attempts to buckle [W:affecting] into \the [src]!")
if(do_after(user, 20))
@@ -69,21 +132,36 @@
else
..()
+/obj/structure/bed/proc/remove_padding()
+ if(padding_material)
+ padding_material.place_sheet(get_turf(src))
+ padding_material = null
+ update_icon()
+
+/obj/structure/bed/proc/add_padding(var/padding_type)
+ padding_material = get_material_by_name(padding_type)
+ update_icon()
+
+/obj/structure/bed/proc/dismantle()
+ material.place_sheet(get_turf(src))
+ if(padding_material)
+ padding_material.place_sheet(get_turf(src))
+
/obj/structure/bed/psych
name = "psychiatrist's couch"
desc = "For prime comfort during psychiatric evaluations."
icon_state = "psychbed"
- apply_cosmetics = 0
+ base_icon = "psychbed"
/obj/structure/bed/psych/New(var/newloc)
- ..(newloc,"leather")
+ ..(newloc,"wood","leather")
+
+/obj/structure/bed/padded/New(var/newloc)
+ ..(newloc,"plastic","cotton")
/obj/structure/bed/alien
name = "resting contraption"
desc = "This looks similar to contraptions from earth. Could aliens be stealing our technology?"
- icon_state = "abed"
- apply_cosmetics = 0
-
/obj/structure/bed/alien/New(var/newloc)
..(newloc,"resin")
@@ -96,10 +174,14 @@
icon = 'icons/obj/rollerbed.dmi'
icon_state = "down"
anchored = 0
- apply_cosmetics = 0
+
+/obj/structure/bed/roller/update_icon()
+ return // Doesn't care about material or anything else.
/obj/structure/bed/roller/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if(istype(W,/obj/item/roller_holder))
+ if(istype(W, /obj/item/weapon/wrench) || istype(W,/obj/item/stack) || istype(W, /obj/item/weapon/wirecutters))
+ return
+ else if(istype(W,/obj/item/roller_holder))
if(buckled_mob)
user_unbuckle_mob(user)
else
diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
index 271dfde063..06322fb98d 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
@@ -1,22 +1,23 @@
/obj/structure/bed/chair //YES, chairs are a type of bed, which are a type of stool. This works, believe me. -Pete
name = "chair"
desc = "You sit in this. Either by will or force."
- icon_state = "chair"
+ icon_state = "chair_preview"
+ base_icon = "chair"
buckle_lying = 0 //force people to sit up in chairs when buckled
var/propelled = 0 // Check for fire-extinguisher-driven chairs
-/obj/structure/bed/chair/New(var/newloc, var/material)
- ..(newloc, material) //Todo make metal/stone chairs display as thrones
+/obj/structure/bed/chair/New()
+ ..() //Todo make metal/stone chairs display as thrones
spawn(3) //sorry. i don't think there's a better way to do this.
update_layer()
return
/obj/structure/bed/chair/attackby(obj/item/weapon/W as obj, mob/user as mob)
..()
- if(istype(W, /obj/item/assembly/shock_kit))
+ if(!padding_material && istype(W, /obj/item/assembly/shock_kit))
var/obj/item/assembly/shock_kit/SK = W
if(!SK.status)
- user << "[SK] is not ready to be attached!"
+ user << "\The [SK] is not ready to be attached!"
return
user.drop_item()
var/obj/structure/bed/chair/e_chair/E = new (src.loc, material.name)
@@ -34,6 +35,20 @@
rotate()
return
+/obj/structure/bed/chair/post_buckle_mob()
+ update_icon()
+
+/obj/structure/bed/chair/update_icon()
+ ..()
+ if(buckled_mob && padding_material)
+ var/cache_key = "[base_icon]-armrest-[padding_material.name]"
+ if(isnull(stool_cache[cache_key]))
+ var/image/I = image(icon, "[base_icon]_armrest")
+ I.layer = MOB_LAYER + 0.1
+ I.color = padding_material.icon_colour
+ stool_cache[cache_key] = I
+ overlays |= stool_cache[cache_key]
+
/obj/structure/bed/chair/proc/update_layer()
if(src.dir == NORTH)
src.layer = FLY_LAYER
@@ -65,70 +80,49 @@
src.set_dir(turn(src.dir, 90))
return
-// Chair types
-/obj/structure/bed/chair/wood
- icon_state = "wooden_chair"
- name = "wooden chair"
- desc = "Old is never too old to not be in fashion."
- apply_cosmetics = 0
-
-/obj/structure/bed/chair/wood/New(var/newloc)
- ..(newloc, "wood")
-
-/obj/structure/bed/chair/wood/wings
- icon_state = "wooden_chair_wings"
-
+// Leaving this in for the sake of compilation.
/obj/structure/bed/chair/comfy
- name = "comfy chair"
- desc = "It looks comfy."
- icon_state = "comfychair"
- color = rgb(255,255,255)
- var/image/armrest = null
- apply_cosmetics = 0
+ desc = "It's a chair. It looks comfy."
+ icon_state = "comfychair_preview"
-/obj/structure/bed/chair/comfy/New()
- armrest = image("icons/obj/objects.dmi", "comfychair_armrest")
- armrest.layer = MOB_LAYER + 0.1
+/obj/structure/bed/chair/comfy/brown/New(var/newloc,var/newmaterial)
+ ..(newloc,"steel","leather")
- return ..()
+/obj/structure/bed/chair/comfy/red/New(var/newloc,var/newmaterial)
+ ..(newloc,"steel","carpet")
-/obj/structure/bed/chair/comfy/post_buckle_mob()
- if(buckled_mob)
- overlays += armrest
- else
- overlays -= armrest
+/obj/structure/bed/chair/comfy/teal/New(var/newloc,var/newmaterial)
+ ..(newloc,"steel","teal")
-/obj/structure/bed/chair/comfy/brown
- color = rgb(141,70,0)
+/obj/structure/bed/chair/comfy/black/New(var/newloc,var/newmaterial)
+ ..(newloc,"steel","black")
-/obj/structure/bed/chair/comfy/red
- color = rgb(218,2,10)
+/obj/structure/bed/chair/comfy/green/New(var/newloc,var/newmaterial)
+ ..(newloc,"steel","green")
-/obj/structure/bed/chair/comfy/teal
- color = rgb(0,234,250)
+/obj/structure/bed/chair/comfy/purp/New(var/newloc,var/newmaterial)
+ ..(newloc,"steel","purple")
-/obj/structure/bed/chair/comfy/black
- color = rgb(60,60,60)
+/obj/structure/bed/chair/comfy/blue/New(var/newloc,var/newmaterial)
+ ..(newloc,"steel","blue")
-/obj/structure/bed/chair/comfy/green
- color = rgb(1,196,8)
+/obj/structure/bed/chair/comfy/beige/New(var/newloc,var/newmaterial)
+ ..(newloc,"steel","beige")
-/obj/structure/bed/chair/comfy/purp
- color = rgb(112,2,176)
-
-/obj/structure/bed/chair/comfy/blue
- color = rgb(2,9,210)
-
-/obj/structure/bed/chair/comfy/beige
- color = rgb(255,253,195)
+/obj/structure/bed/chair/comfy/lime/New(var/newloc,var/newmaterial)
+ ..(newloc,"steel","lime")
/obj/structure/bed/chair/office
anchored = 0
buckle_movable = 1
- apply_cosmetics = 0
-/obj/structure/bed/chair/comfy/lime
- color = rgb(255,251,0)
+/obj/structure/bed/chair/office/update_icon()
+ return
+
+/obj/structure/bed/chair/office/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(istype(W,/obj/item/stack) || istype(W, /obj/item/weapon/wirecutters))
+ return
+ ..()
/obj/structure/bed/chair/office/Move()
..()
@@ -175,3 +169,23 @@
/obj/structure/bed/chair/office/dark
icon_state = "officechair_dark"
+
+// Chair types
+/obj/structure/bed/chair/wood
+ name = "wooden chair"
+ desc = "Old is never too old to not be in fashion."
+ icon_state = "wooden_chair"
+
+/obj/structure/bed/chair/wood/update_icon()
+ return
+
+/obj/structure/bed/chair/wood/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(istype(W,/obj/item/stack) || istype(W, /obj/item/weapon/wirecutters))
+ return
+ ..()
+
+/obj/structure/bed/chair/wood/New(var/newloc)
+ ..(newloc, "wood")
+
+/obj/structure/bed/chair/wood/wings
+ icon_state = "wooden_chair_wings"
diff --git a/code/game/objects/structures/stool_bed_chair_nest/stools.dm b/code/game/objects/structures/stool_bed_chair_nest/stools.dm
index a8f879e084..2228345ebb 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/stools.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/stools.dm
@@ -4,7 +4,7 @@ var/global/list/stool_cache = list() //haha stool
/obj/item/weapon/stool
name = "stool"
desc = "Apply butt."
- icon = 'icons/obj/objects.dmi'
+ icon = 'icons/obj/furniture.dmi'
icon_state = "stool_preview" //set for the map
force = 10
throwforce = 10
@@ -30,17 +30,16 @@ var/global/list/stool_cache = list() //haha stool
update_icon()
/obj/item/weapon/stool/padded/New(var/newloc, var/new_material)
- ..(newloc, "steel", "leather")
+ ..(newloc, "steel", "carpet")
/obj/item/weapon/stool/update_icon()
// Prep icon.
- icon_state = "stool"
+ icon_state = ""
overlays.Cut()
// Base icon.
var/cache_key = "stool-[material.name]"
if(isnull(stool_cache[cache_key]))
- var/image/I = image('icons/obj/objects.dmi', base_icon)
- color = material.icon_colour
+ var/image/I = image(icon, base_icon)
I.color = material.icon_colour
stool_cache[cache_key] = I
overlays |= stool_cache[cache_key]
@@ -48,17 +47,17 @@ var/global/list/stool_cache = list() //haha stool
if(padding_material)
var/padding_cache_key = "stool-padding-[padding_material.name]"
if(isnull(stool_cache[padding_cache_key]))
- var/image/I = image('icons/obj/objects.dmi', "stool_padding")
+ var/image/I = image(icon, "stool_padding")
I.color = padding_material.icon_colour
stool_cache[padding_cache_key] = I
overlays |= stool_cache[padding_cache_key]
// Strings.
if(padding_material)
name = "[padding_material.display_name] [initial(name)]" //this is not perfect but it will do for now.
- desc = "A padded stool. Apply butt. It's made of [material.display_name] and covered with [padding_material.display_name]."
+ desc = "A padded stool. Apply butt. It's made of [material.use_name] and covered with [padding_material.use_name]."
else
name = "[material.display_name] [initial(name)]"
- desc = "A stool. Apply butt with care. It's made of [material.display_name]."
+ desc = "A stool. Apply butt with care. It's made of [material.use_name]."
/obj/item/weapon/stool/proc/add_padding(var/padding_type)
padding_material = get_material_by_name(padding_type)
@@ -127,7 +126,7 @@ var/global/list/stool_cache = list() //haha stool
padding_type = "carpet"
else if(istype(W,/obj/item/stack/material))
var/obj/item/stack/material/M = W
- if(M.material && (M.material.name in list("leather", "cloth")))
+ if(M.material && (M.material.flags & MATERIAL_PADDING))
padding_type = "[M.material.name]"
if(!padding_type)
user << "You cannot pad \the [src] with that."
diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
index 81d7f31cdb..a15bee5df2 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm
@@ -9,6 +9,8 @@
var/mob/living/pulling = null
var/bloodiness
+/obj/structure/bed/chair/wheelchair/update_icon()
+ return
/obj/structure/bed/chair/wheelchair/set_dir()
..()
@@ -18,6 +20,11 @@
if(buckled_mob)
buckled_mob.set_dir(dir)
+/obj/structure/bed/chair/wheelchair/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(istype(W, /obj/item/weapon/wrench) || istype(W,/obj/item/stack) || istype(W, /obj/item/weapon/wirecutters))
+ return
+ ..()
+
/obj/structure/bed/chair/wheelchair/relaymove(mob/user, direction)
// Redundant check?
if(user.stat || user.stunned || user.weakened || user.paralysis || user.lying || user.restrained())
diff --git a/code/game/turfs/simulated/wall_attacks.dm b/code/game/turfs/simulated/wall_attacks.dm
index e3037f94a9..32668e4743 100644
--- a/code/game/turfs/simulated/wall_attacks.dm
+++ b/code/game/turfs/simulated/wall_attacks.dm
@@ -96,7 +96,7 @@
if(W)
radiate()
if(is_hot(W))
- ignite(is_hot(W))
+ burn(is_hot(W))
if(locate(/obj/effect/overlay/wallrot) in src)
if(istype(W, /obj/item/weapon/weldingtool) )
diff --git a/code/game/turfs/simulated/wall_types.dm b/code/game/turfs/simulated/wall_types.dm
index dc9346e323..1b6f77cbd4 100644
--- a/code/game/turfs/simulated/wall_types.dm
+++ b/code/game/turfs/simulated/wall_types.dm
@@ -2,18 +2,17 @@
icon_state = "rgeneric"
/turf/simulated/wall/r_wall/New(var/newloc)
..(newloc, DEFAULT_WALL_MATERIAL,"plasteel") //3strong
+
/turf/simulated/wall/cult
icon_state = "cult"
/turf/simulated/wall/cult/New(var/newloc)
..(newloc,"cult","cult2")
-
/turf/unsimulated/wall/cult
name = "cult wall"
desc = "Hideous images dance beneath the surface."
icon = 'icons/turf/wall_masks.dmi'
icon_state = "cult"
-
/turf/simulated/wall/iron/New(var/newloc)
..(newloc,"iron")
/turf/simulated/wall/uranium/New(var/newloc)
@@ -28,7 +27,6 @@
..(newloc,"phoron")
/turf/simulated/wall/sandstone/New(var/newloc)
..(newloc,"sandstone")
-
/turf/simulated/wall/ironphoron/New(var/newloc)
..(newloc,"iron","phoron")
/turf/simulated/wall/golddiamond/New(var/newloc)
@@ -38,6 +36,8 @@
/turf/simulated/wall/sandstonediamond/New(var/newloc)
..(newloc,"sandstone","diamond")
-
-/turf/simulated/wall/cult/New(var/newloc)
- ..(newloc,"cult","cult2")
\ No newline at end of file
+// Kind of wondering if this is going to bite me in the butt.
+/turf/simulated/wall/voxshuttle/New(var/newloc)
+ ..(newloc,"voxalloy")
+/turf/simulated/wall/voxshuttle/attackby()
+ return
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index 8fa7c9dd2f..5185c9b81c 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -46,9 +46,9 @@ var/list/global/wall_cache = list()
/turf/simulated/wall/bullet_act(var/obj/item/projectile/Proj)
if(istype(Proj,/obj/item/projectile/beam))
- ignite(2500)
+ burn(2500)
else if(istype(Proj,/obj/item/projectile/ion))
- ignite(500)
+ burn(500)
// Tasers and stuff? No thanks. Also no clone or tox damage crap.
if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))
@@ -143,10 +143,10 @@ var/list/global/wall_cache = list()
return
/turf/simulated/wall/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)//Doesn't fucking work because walls don't interact with air :(
- ignite(exposed_temperature)
+ burn(exposed_temperature)
/turf/simulated/wall/adjacent_fire_act(turf/simulated/floor/adj_turf, datum/gas_mixture/adj_air, adj_temp, adj_volume)
- ignite(adj_temp)
+ burn(adj_temp)
if(adj_temp > material.melting_point)
take_damage(log(RAND_F(0.9, 1.1) * (adj_temp - material.melting_point)))
@@ -253,22 +253,11 @@ var/list/global/wall_cache = list()
return total_radiation
/turf/simulated/wall/proc/burn(temperature)
- spawn(2)
- new /obj/structure/girder(src)
- src.ChangeTurf(/turf/simulated/floor)
- for(var/turf/simulated/floor/target_tile in range(0,src))
- if(material == "phoron") //ergh
- target_tile.assume_gas("phoron", 20, 400+T0C)
- spawn (0) target_tile.hotspot_expose(temperature, 400)
- for(var/turf/simulated/wall/W in range(3,src))
- W.ignite((temperature/4))
- for(var/obj/machinery/door/airlock/phoron/D in range(3,src))
- D.ignite(temperature/4)
-
-/turf/simulated/wall/proc/ignite(var/exposed_temperature)
- if(isnull(material.ignition_point))
- return
- if(exposed_temperature > material.ignition_point)//If the temperature of the object is over 300, then ignite
- burn(exposed_temperature)
- return
- ..()
+ if(material.combustion_effect(src, temperature, 0.7))
+ spawn(2)
+ new /obj/structure/girder(src)
+ src.ChangeTurf(/turf/simulated/floor)
+ for(var/turf/simulated/wall/W in range(3,src))
+ W.burn((temperature/4))
+ for(var/obj/machinery/door/airlock/phoron/D in range(3,src))
+ D.ignite(temperature/4)
diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm
index d8db07de58..b3c545053c 100644
--- a/code/game/turfs/space/space.dm
+++ b/code/game/turfs/space/space.dm
@@ -16,6 +16,7 @@ var/list/accessible_z_levels = list("1" = 5, "3" = 10, "4" = 15, "5" = 10, "6" =
if(!istype(src, /turf/space/transit))
icon_state = "[((x + y) ^ ~(x * y) + z) % 25]"
update_starlight()
+ ..()
/turf/space/proc/update_starlight()
if(!config.starlight)
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index e5ae4e1bb9..65d9050617 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -40,8 +40,13 @@
spawn( 0 )
src.Entered(AM)
return
+ turfs |= src
return
+/turf/Destroy()
+ turfs -= src
+ ..()
+
/turf/ex_act(severity)
return 0
diff --git a/code/game/verbs/who.dm b/code/game/verbs/who.dm
index c26d86858d..70878686c8 100644
--- a/code/game/verbs/who.dm
+++ b/code/game/verbs/who.dm
@@ -112,6 +112,8 @@
else if (R_MOD & C.holder.rights || R_MENTOR & C.holder.rights)
modmsg += "\t[C] is a [C.holder.rank]\n"
num_mods_online++
-
+ if(config.admin_irc)
+ src << "Adminhelps are also sent to IRC. If no admins are available in game try anyway and an admin on IRC may see it and respond."
msg = "Current Admins ([num_admins_online]):\n" + msg + "\n Current [config.mods_are_mentors ? "Mentors" : "Moderators"]([num_mods_online]):\n" + modmsg
+
src << msg
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 7d29322163..cd6dfda8db 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -997,18 +997,18 @@ var/global/floorIsLava = 0
return 0
-/datum/admins/proc/spawn_fruit()
+/datum/admins/proc/spawn_fruit(seedtype in plant_controller.seeds)
set category = "Debug"
set desc = "Spawn the product of a seed."
set name = "Spawn Fruit"
if(!check_rights(R_SPAWN)) return
- var/seedtype = input("Select a seed type", "Spawn Fruit") as null|anything in plant_controller.seeds
if(!seedtype || !plant_controller.seeds[seedtype])
return
var/datum/seed/S = plant_controller.seeds[seedtype]
S.harvest(usr,0,0,1)
+ log_admin("[key_name(usr)] spawned [seedtype] fruit at ([usr.x],[usr.y],[usr.z])")
/datum/admins/proc/spawn_custom_item()
set category = "Debug"
@@ -1050,17 +1050,17 @@ var/global/floorIsLava = 0
for(var/datum/custom_item/item in current_items)
usr << "- name: [item.name] icon: [item.item_icon] path: [item.item_path] desc: [item.item_desc]"
-/datum/admins/proc/spawn_plant()
+/datum/admins/proc/spawn_plant(seedtype in plant_controller.seeds)
set category = "Debug"
set desc = "Spawn a spreading plant effect."
set name = "Spawn Plant"
if(!check_rights(R_SPAWN)) return
- var/seedtype = input("Select a seed type", "Spawn Plant") as null|anything in plant_controller.seeds
if(!seedtype || !plant_controller.seeds[seedtype])
return
new /obj/effect/plant(get_turf(usr), plant_controller.seeds[seedtype])
+ log_admin("[key_name(usr)] spawned [seedtype] vines at ([usr.x],[usr.y],[usr.z])")
/datum/admins/proc/spawn_atom(var/object as text)
set category = "Debug"
@@ -1236,7 +1236,7 @@ var/global/floorIsLava = 0
if(!ai_number)
usr << "No AIs located" //Just so you know the thing is actually working and not just ignoring you.
-/datum/admins/proc/show_skills(var/mob/living/carbon/human/M as mob in world)
+/datum/admins/proc/show_skills()
set category = "Admin"
set name = "Show Skills"
@@ -1246,6 +1246,9 @@ var/global/floorIsLava = 0
usr << "Error: you are not an admin!"
return
+ var/mob/living/carbon/human/M = input("Select mob.", "Select mob.") as null|anything in human_mob_list
+ if(!M) return
+
show_skill_window(usr, M)
return
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index c22fc85466..076ad95b45 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -123,7 +123,8 @@ var/list/admin_verbs_spawn = list(
/client/proc/FireLaser,
/client/proc/FireCannons,
/client/proc/ChangeIcarusPosition,
- /client/proc/virus2_editor
+ /client/proc/virus2_editor,
+ /client/proc/spawn_chemdisp_cartridge
)
var/list/admin_verbs_server = list(
/client/proc/Set_Holiday,
@@ -707,66 +708,70 @@ var/list/admin_verbs_mentor = list(
if(holder)
src.holder.output_ai_laws()
-/client/proc/rename_silicon(mob/living/silicon/S in mob_list)
+/client/proc/rename_silicon()
set name = "Rename Silicon"
set category = "Admin"
- if(!istype(S))
- return
+ if(!check_rights(R_ADMIN)) return
- if(holder)
- var/new_name = sanitizeSafe(input(src, "Enter new name. Leave blank or as is to cancel.", "Enter new silicon name", S.real_name))
- if(new_name && new_name != S.real_name)
- admin_log_and_message_admins("has renamed the silicon '[S.real_name]' to '[new_name]'")
- S.SetName(new_name)
+ var/mob/living/silicon/S = input("Select silicon.", "Rename Silicon.") as null|anything in silicon_mob_list
+ if(!S) return
+
+ var/new_name = sanitizeSafe(input(src, "Enter new name. Leave blank or as is to cancel.", "[S.real_name] - Enter new silicon name", S.real_name))
+ if(new_name && new_name != S.real_name)
+ admin_log_and_message_admins("has renamed the silicon '[S.real_name]' to '[new_name]'")
+ S.SetName(new_name)
feedback_add_details("admin_verb","RAI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-/client/proc/manage_silicon_laws(mob/living/silicon/S in mob_list)
+/client/proc/manage_silicon_laws()
set name = "Manage Silicon Laws"
set category = "Admin"
- if(!istype(S))
- return
+ if(!check_rights(R_ADMIN)) return
- if(holder)
- var/obj/nano_module/law_manager/L = new(S)
- L.ui_interact(usr, state = admin_state)
+ var/mob/living/silicon/S = input("Select silicon.", "Manage Silicon Laws") as null|anything in silicon_mob_list
+ if(!S) return
+
+ var/obj/nano_module/law_manager/L = new(S)
+ L.ui_interact(usr, state = admin_state)
admin_log_and_message_admins("has opened [S]'s law manager.")
feedback_add_details("admin_verb","MSL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-/client/proc/change_human_appearance_admin(mob/living/carbon/human/H in world)
+/client/proc/change_human_appearance_admin()
set name = "Change Mob Appearance - Admin"
set desc = "Allows you to change the mob appearance"
set category = "Admin"
- if(!istype(H))
- return
+ if(!check_rights(R_FUN)) return
- if(holder)
- admin_log_and_message_admins("is altering the appearance of [H].")
- H.change_appearance(APPEARANCE_ALL, usr, usr, check_species_whitelist = 0, state = admin_state)
+ var/mob/living/carbon/human/H = input("Select mob.", "Change Mob Appearance - Admin") as null|anything in human_mob_list
+ if(!H) return
+
+ admin_log_and_message_admins("is altering the appearance of [H].")
+ H.change_appearance(APPEARANCE_ALL, usr, usr, check_species_whitelist = 0, state = admin_state)
feedback_add_details("admin_verb","CHAA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-/client/proc/change_human_appearance_self(mob/living/carbon/human/H in mob_list)
+/client/proc/change_human_appearance_self()
set name = "Change Mob Appearance - Self"
set desc = "Allows the mob to change its appearance"
set category = "Admin"
- if(!istype(H))
- return
+ if(!check_rights(R_FUN)) return
+
+ var/mob/living/carbon/human/H = input("Select mob.", "Change Mob Appearance - Self") as null|anything in human_mob_list
+ if(!H) return
if(!H.client)
usr << "Only mobs with clients can alter their own appearance."
return
- if(holder)
- switch(alert("Do you wish for [H] to be allowed to select non-whitelisted races?","Alter Mob Appearance","Yes","No","Cancel"))
- if("Yes")
- admin_log_and_message_admins("has allowed [H] to change \his appearance, without whitelisting of races.")
- H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 0)
- if("No")
- admin_log_and_message_admins("has allowed [H] to change \his appearance, with whitelisting of races.")
- H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1)
+ switch(alert("Do you wish for [H] to be allowed to select non-whitelisted races?","Alter Mob Appearance","Yes","No","Cancel"))
+ if("Yes")
+ admin_log_and_message_admins("has allowed [H] to change \his appearance, without whitelisting of races.")
+ H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 0)
+ if("No")
+ admin_log_and_message_admins("has allowed [H] to change \his appearance, with whitelisting of races.")
+ H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1)
feedback_add_details("admin_verb","CMAS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/change_security_level()
@@ -791,12 +796,14 @@ var/list/admin_verbs_mentor = list(
// feedback_add_details("admin_verb","MP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
-/client/proc/editappear(mob/living/carbon/human/M as mob in mob_list)
+/client/proc/editappear()
set name = "Edit Appearance"
set category = "Fun"
if(!check_rights(R_FUN)) return
+ var/mob/living/carbon/human/M = input("Select mob.", "Edit Appearance") as null|anything in human_mob_list
+
if(!istype(M, /mob/living/carbon/human))
usr << "\red You can only do this to humans!"
return
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index ffa64ce64f..e780c9fd5d 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -2270,14 +2270,14 @@
if("hellonearth")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","NS")
- var/choice = input("You sure you want to end the round and summon narsie at your location? Misuse of this could result in removal of flags or halarity.") in list("PRAISE SATAN", "Cancel")
+ var/choice = input("You sure you want to end the round and summon narsie at your location? Misuse of this could result in removal of flags or hilarity.") in list("PRAISE SATAN", "Cancel")
if(choice == "PRAISE SATAN")
new /obj/singularity/narsie/large(get_turf(usr))
message_admins("[key_name_admin(usr)] has summoned narsie and brought about a new realm of suffering.")
if("supermattercascade")
feedback_inc("admin_secrets_fun_used",1)
feedback_add_details("admin_secrets_fun_used","SC")
- var/choice = input("You sure you want to destroy the universe and create a large explosion at your location? Misuse of this could result in removal of flags or halarity.") in list("NO TIME TO EXPLAIN", "Cancel")
+ var/choice = input("You sure you want to destroy the universe and create a large explosion at your location? Misuse of this could result in removal of flags or hilarity.") in list("NO TIME TO EXPLAIN", "Cancel")
if(choice == "NO TIME TO EXPLAIN")
explosion(get_turf(usr), 8, 16, 24, 32, 1)
new /turf/unsimulated/wall/supermatter(get_turf(usr))
diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm
index 467083e827..26cae206e9 100644
--- a/code/modules/admin/verbs/adminpm.dm
+++ b/code/modules/admin/verbs/adminpm.dm
@@ -108,6 +108,7 @@
C << 'sound/effects/adminhelp.ogg'
log_admin("PM: [key_name(src)]->[key_name(C)]: [msg]")
+ send2adminirc("Reply: [key_name(src)]->[key_name(C)]: [html_decode(msg)]")
//we don't use message_admins here because the sender/receiver might get it too
for(var/client/X in admins)
@@ -136,7 +137,7 @@
send2adminirc("PlayerPM from [key_name(src)]: [html_decode(msg)]")
- src << "" + create_text_tag("pm_out_alt", "", src) + " to : [msg]"
+ src << "" + create_text_tag("pm_out_alt", "", src) + " to Admin IRC: [msg]"
log_admin("PM: [key_name(src)]->IRC: [msg]")
for(var/client/X in admins)
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index 9ab952de64..0552892f21 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -516,12 +516,13 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
for(var/areatype in areas_without_camera)
world << "* [areatype]"
-/client/proc/cmd_admin_dress(var/mob/living/carbon/human/M in mob_list)
+/client/proc/cmd_admin_dress()
set category = "Fun"
set name = "Select equipment"
- if(!ishuman(M))
- alert("Invalid mob")
- return
+
+ var/mob/living/carbon/human/M = input("Select mob.", "Select equipment.") as null|anything in human_mob_list
+ if(!M) return
+
//log_admin("[key_name(src)] has alienized [M.key].")
var/list/dresspacks = list(
"strip",
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index fd55a5a1e9..b240f087a9 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -778,7 +778,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(confirm != "Yes") return
var/choice
- if(ticker.mode.name == "revolution" || ticker.mode.name == "AI malfunction" || ticker.mode.name == "confliction")
+ if(ticker.mode.name == "revolution" || ticker.mode.name == "confliction")
choice = input("The shuttle will just return if you call it. Call anyway?") in list("Confirm", "Cancel")
if(choice == "Confirm")
emergency_shuttle.auto_recall = 1 //enable auto-recall
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index fcbd890263..e14884ec1b 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -236,8 +236,9 @@ datum/preferences
/datum/preferences/proc/ShowChoices(mob/user)
if(!user || !user.client) return
update_preview_icon()
- user << browse_rsc(preview_icon_front, "previewicon.png")
- user << browse_rsc(preview_icon_side, "previewicon2.png")
+ if(preview_icon_front && preview_icon_side)
+ user << browse_rsc(preview_icon_front, "previewicon.png")
+ user << browse_rsc(preview_icon_side, "previewicon2.png")
var/dat = ""
if(path)
@@ -1671,6 +1672,7 @@ datum/preferences
var/status = organ_data[name]
var/obj/item/organ/external/O = character.organs_by_name[name]
if(O)
+ O.status = 0
if(status == "amputated")
character.organs_by_name[O.limb_name] = null
character.organs -= O
diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm
index 7cbd14cb21..81df901b38 100644
--- a/code/modules/clothing/spacesuits/rig/rig.dm
+++ b/code/modules/clothing/spacesuits/rig/rig.dm
@@ -20,7 +20,7 @@
armor = list(melee = 40, bullet = 5, laser = 20,energy = 5, bomb = 35, bio = 100, rad = 20)
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE
- siemens_coefficient = 0.1
+ siemens_coefficient = 0.2
permeability_coefficient = 0.1
unacidable = 1
diff --git a/code/modules/clothing/spacesuits/rig/suits/ert.dm b/code/modules/clothing/spacesuits/rig/suits/ert.dm
index 70c21d5108..c46b019a4d 100644
--- a/code/modules/clothing/spacesuits/rig/suits/ert.dm
+++ b/code/modules/clothing/spacesuits/rig/suits/ert.dm
@@ -29,8 +29,8 @@
desc = "A suit worn by the engineering division of a NanoTrasen Emergency Response Team. Has orange highlights. Armoured and space ready."
suit_type = "ERT engineer"
icon_state = "ert_engineer_rig"
-
- glove_type = /obj/item/clothing/gloves/rig/ert_engineer
+ armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 100, rad = 100)
+ siemens_coefficient = 0
initial_modules = list(
/obj/item/rig_module/ai_container,
@@ -39,10 +39,6 @@
/obj/item/rig_module/device/rcd
)
-/obj/item/clothing/gloves/rig/ert_engineer
- name = "insulated gauntlets"
- siemens_coefficient = 0
-
/obj/item/weapon/rig/ert/medical
name = "ERT-M suit control module"
desc = "A suit worn by the medical division of a NanoTrasen Emergency Response Team. Has white highlights. Armoured and space ready."
diff --git a/code/modules/clothing/under/accessories/badges.dm b/code/modules/clothing/under/accessories/badges.dm
index bb6613582e..cc6a6f9965 100644
--- a/code/modules/clothing/under/accessories/badges.dm
+++ b/code/modules/clothing/under/accessories/badges.dm
@@ -43,7 +43,8 @@
/obj/item/clothing/accessory/badge/holo
name = "holobadge"
desc = "This glowing blue badge marks the holder as THE LAW."
- var/emagged = 0 //Emagging removes Sec check.
+ icon_state = "holobadge"
+ var/emagged //Emagging removes Sec check.
/obj/item/clothing/accessory/badge/holo/cord
icon_state = "holobadge-cord"
diff --git a/code/modules/economy/EFTPOS.dm b/code/modules/economy/EFTPOS.dm
index eed1e40ab2..fda22b17f9 100644
--- a/code/modules/economy/EFTPOS.dm
+++ b/code/modules/economy/EFTPOS.dm
@@ -100,7 +100,7 @@
else
dat += "Lock in new transaction
"
- dat += "Transaction purpose: [transaction_purpose]
"
+ dat += "Transaction purpose: [transaction_purpose]
"
dat += "Value: $[transaction_amount]
"
dat += "Linked account: [linked_account ? linked_account.owner_name : "None"]
"
dat += "Change access code
"
diff --git a/code/modules/events/event_dynamic.dm b/code/modules/events/event_dynamic.dm
index 0dbe3a5017..3539130c27 100644
--- a/code/modules/events/event_dynamic.dm
+++ b/code/modules/events/event_dynamic.dm
@@ -188,28 +188,35 @@ var/list/event_last_fired = list()
active_with_role["Cyborg"] = 0
active_with_role["Janitor"] = 0
active_with_role["Gardener"] = 0
- active_with_role["Any"] = player_list.len
for(var/mob/M in player_list)
- if(!M.mind || !M.client || M.client.inactivity > 10 * 10 * 60) // longer than 10 minutes AFK counts them as inactive
+ if(!M.mind || !M.client || M.client.is_afk(10 MINUTES)) // longer than 10 minutes AFK counts them as inactive
continue
- if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "engineering robot module")
- active_with_role["Engineer"]++
- if(M.mind.assigned_role in list("Chief Engineer", "Station Engineer"))
+ active_with_role["Any"]++
+
+ if(istype(M, /mob/living/silicon/robot))
+ var/mob/living/silicon/robot/R = M
+ if(R.module)
+ if(istype(R.module, /obj/item/weapon/robot_module/engineering))
+ active_with_role["Engineer"]++
+ else if(istype(R.module, /obj/item/weapon/robot_module/security))
+ active_with_role["Security"]++
+ else if(istype(R.module, /obj/item/weapon/robot_module/medical))
+ active_with_role["Medical"]++
+ else if(istype(R.module, /obj/item/weapon/robot_module/research))
+ active_with_role["Scientist"]++
+
+ if(M.mind.assigned_role in engineering_positions)
active_with_role["Engineer"]++
- if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "medical robot module")
- active_with_role["Medical"]++
if(M.mind.assigned_role in medical_positions)
active_with_role["Medical"]++
- if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "security robot module")
- active_with_role["Security"]++
if(M.mind.assigned_role in security_positions)
active_with_role["Security"]++
- if(M.mind.assigned_role in list("Research Director", "Scientist"))
+ if(M.mind.assigned_role in science_positions)
active_with_role["Scientist"]++
if(M.mind.assigned_role == "AI")
diff --git a/code/modules/events/infestation.dm b/code/modules/events/infestation.dm
index 629579f794..c88472688f 100644
--- a/code/modules/events/infestation.dm
+++ b/code/modules/events/infestation.dm
@@ -58,14 +58,10 @@
spawn_area_type = /area/security/tactical
locstring = "tactical equipment storage"
- //world << "looking for [spawn_area_type]"
for(var/areapath in typesof(spawn_area_type))
- //world << " checking [areapath]"
var/area/A = locate(areapath)
- //world << " A: [A], contents.len: [A.contents.len]"
- //world << " B: [B], contents.len: [B.contents.len]"
for(var/turf/simulated/floor/F in A.contents)
- if(!F.contents.len)
+ if(turf_clear(F))
turfs += F
var/list/spawn_types = list()
diff --git a/code/modules/events/viral_infection.dm b/code/modules/events/viral_infection.dm
index 639cea4d5e..2eb6121f08 100644
--- a/code/modules/events/viral_infection.dm
+++ b/code/modules/events/viral_infection.dm
@@ -1,3 +1,5 @@
+/var/global/list/event_viruses = list() // so that event viruses are kept around for admin logs, rather than being GCed
+
datum/event/viral_infection
var/list/viruses = list()
@@ -40,10 +42,30 @@ datum/event/viral_infection/start()
if(!candidates.len) return
candidates = shuffle(candidates)//Incorporating Donkie's list shuffle
+ var/list/used_viruses = list()
+ var/list/used_candidates = list()
severity = max(EVENT_LEVEL_MUNDANE, severity - 1)
var/actual_severity = severity * rand(1, 3)
while(actual_severity > 0 && candidates.len)
var/datum/disease2/disease/D = pick(viruses)
infect_mob(candidates[1], D.getcopy())
+ used_candidates += candidates[1]
candidates.Remove(candidates[1])
actual_severity--
+ used_viruses |= D
+
+ event_viruses |= used_viruses
+ var/list/used_viruses_links = list()
+ var/list/used_viruses_text = list()
+ for(var/datum/disease2/disease/D in used_viruses)
+ used_viruses_links += "[D.name()]"
+ used_viruses_text += D.name()
+
+ var/list/used_candidates_links = list()
+ var/list/used_candidates_text = list()
+ for(var/mob/M in used_candidates)
+ used_candidates_links += key_name_admin(M)
+ used_candidates_text += key_name(M)
+
+ log_admin("Virus event affecting [english_list(used_candidates_text)] started; Viruses: [english_list(used_viruses_text)]")
+ message_admins("Virus event affecting [english_list(used_candidates_links)] started; Viruses: [english_list(used_viruses_links)]")
diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm
index 2d088658ac..e62a96c2ce 100644
--- a/code/modules/hydroponics/spreading/spreading.dm
+++ b/code/modules/hydroponics/spreading/spreading.dm
@@ -7,7 +7,7 @@
for(var/areapath in typesof(/area/hallway))
var/area/A = locate(areapath)
for(var/turf/simulated/floor/F in A.contents)
- if(!F.contents.len)
+ if(turf_clear(F))
turfs += F
if(turfs.len) //Pick a turf to spawn at if we can
@@ -24,6 +24,8 @@
vine.process()
message_admins("Event: Spacevines spawned at [T.loc] ([T.x],[T.y],[T.z])")
+ return
+ message_admins("Event: Spacevines failed to find a viable turf.")
/obj/effect/dead_plant
anchored = 1
@@ -56,7 +58,7 @@
var/growth_threshold = 0
var/growth_type = 0
var/max_growth = 0
-
+ var/sampled
var/list/neighbors = list()
var/obj/effect/plant/parent
var/datum/seed/seed
@@ -233,8 +235,13 @@
if(istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/weapon/scalpel))
if(!seed)
- user << "There is nothing to take a sample from."
+ user << "There is nothing to take a sample from."
return
+ if(sampled)
+ user << "You cannot take another sample from \the [src]."
+ return
+ if(prob(70))
+ sampled = 1
seed.harvest(user,0,1)
health -= (rand(3,5)*10)
else
diff --git a/code/modules/materials/material_sheets.dm b/code/modules/materials/material_sheets.dm
index 2d53c6c29c..312992ed7e 100644
--- a/code/modules/materials/material_sheets.dm
+++ b/code/modules/materials/material_sheets.dm
@@ -5,6 +5,8 @@
w_class = 3.0
throw_speed = 3
throw_range = 3
+ max_amount = 50
+
var/default_type = DEFAULT_WALL_MATERIAL
var/material/material
var/perunit
@@ -45,7 +47,13 @@
matter[material.name] = material.stack_per_sheet
return 1
-obj/item/stack/material/iron
+/obj/item/stack/material/transfer_to(obj/item/stack/S, var/tamount=null, var/type_verified)
+ var/obj/item/stack/material/M = S
+ if(!istype(M) || material.name != M.material.name)
+ return 0
+ ..(S,tamount,1)
+
+/obj/item/stack/material/iron
name = "iron"
icon_state = "sheet-silver"
default_type = "iron"
diff --git a/code/modules/materials/materials.dm b/code/modules/materials/materials.dm
index a3189d6e0f..7f53be3c30 100644
--- a/code/modules/materials/materials.dm
+++ b/code/modules/materials/materials.dm
@@ -48,6 +48,7 @@ var/list/name_to_material
/material
var/name // Unique name for use in indexing the list.
var/display_name // Prettier name for display.
+ var/use_name
var/flags = 0 // Various status modifiers.
// Shards/tables/structures
@@ -85,7 +86,7 @@ var/list/name_to_material
// Noise made when a simple door made of this material opens or closes.
var/dooropen_noise = 'sound/effects/stonedoor_openclose.ogg'
// Path to resulting stacktype. Todo remove need for this.
- var/stack_type = /obj/item/stack/material/steel
+ var/stack_type
// Wallrot crumble message.
var/rotting_touch_message = "crumbles under your touch"
@@ -94,6 +95,8 @@ var/list/name_to_material
..()
if(!display_name)
display_name = name
+ if(!use_name)
+ use_name = display_name
if(!shard_icon)
shard_icon = shard_type
@@ -144,6 +147,9 @@ var/list/name_to_material
/material/proc/is_brittle()
return !!(flags & MATERIAL_BRITTLE)
+/material/proc/combustion_effect(var/turf/T, var/temperature)
+ return
+
// Datum definitions follow.
/material/uranium
name = "uranium"
@@ -177,6 +183,10 @@ var/list/name_to_material
hardness = 40
stack_origin_tech = "materials=4"
+/material/gold/bronze //placeholder for ashtrays
+ name = "bronze"
+ icon_colour = "#EDD12F"
+
/material/silver
name = "silver"
stack_type = /obj/item/stack/material/silver
@@ -196,6 +206,20 @@ var/list/name_to_material
stack_origin_tech = "phorontech=2;materials=2"
door_icon_base = "stone"
+/material/phoron/combustion_effect(var/turf/T, var/temperature, var/effect_multiplier)
+ if(isnull(ignition_point))
+ return 0
+ if(temperature < ignition_point)
+ return 0
+ var/totalPhoron = 0
+ for(var/turf/simulated/floor/target_tile in range(2,T))
+ var/phoronToDeduce = (temperature/30) * effect_multiplier
+ totalPhoron += phoronToDeduce
+ target_tile.assume_gas("phoron", phoronToDeduce, 200+T0C)
+ spawn (0)
+ target_tile.hotspot_expose(temperature, 400)
+ return round(totalPhoron/100)
+
/material/stone
name = "sandstone"
stack_type = /obj/item/stack/material/sandstone
@@ -327,6 +351,18 @@ var/list/name_to_material
weight = 22
stack_per_sheet = 3750
+// Adminspawn only, do not let anyone get this.
+/material/voxalloy
+ name = "voxalloy"
+ display_name = "durable alloy"
+ stack_type = null
+ icon_colour = "#6C7364"
+ integrity = 1200
+ melting_point = 6000 // Hull plating.
+ explosion_resistance = 200 // Hull plating.
+ hardness = 500
+ weight = 500
+
/material/wood
name = "wood"
stack_type = /obj/item/stack/material/wood
@@ -366,6 +402,7 @@ var/list/name_to_material
name = "cloth"
stack_origin_tech = "materials=2"
door_icon_base = "wood"
+ flags = MATERIAL_PADDING
/material/cult
name = "cult"
@@ -400,12 +437,71 @@ var/list/name_to_material
return 1
return 0
-/material/leather //todo
+//TODO PLACEHOLDERS:
+/material/leather
name = "leather"
icon_colour = "#5C4831"
stack_origin_tech = "materials=2"
+ flags = MATERIAL_PADDING
/material/carpet
name = "carpet"
- display_name = "padding"
- icon_colour = "#A83C1B"
\ No newline at end of file
+ display_name = "comfy"
+ use_name = "red upholstery"
+ icon_colour = "#DA020A"
+ flags = MATERIAL_PADDING
+
+/material/cotton
+ name = "cotton"
+ display_name ="cotton"
+ icon_colour = "#FFFFFF"
+ flags = MATERIAL_PADDING
+
+/material/cloth_teal
+ name = "teal"
+ display_name ="teal"
+ use_name = "teal cloth"
+ icon_colour = "#00EAFA"
+ flags = MATERIAL_PADDING
+
+/material/cloth_black
+ name = "black"
+ display_name = "black"
+ use_name = "black cloth"
+ icon_colour = "#505050"
+ flags = MATERIAL_PADDING
+
+/material/cloth_green
+ name = "green"
+ display_name = "green"
+ use_name = "green cloth"
+ icon_colour = "#01C608"
+ flags = MATERIAL_PADDING
+
+/material/cloth_puple
+ name = "purple"
+ display_name = "purple"
+ use_name = "purple cloth"
+ icon_colour = "#9C56C4"
+ flags = MATERIAL_PADDING
+
+/material/cloth_blue
+ name = "blue"
+ display_name = "blue"
+ use_name = "blue cloth"
+ icon_colour = "#6B6FE3"
+ flags = MATERIAL_PADDING
+
+/material/cloth_beige
+ name = "beige"
+ display_name = "beige"
+ use_name = "beige cloth"
+ icon_colour = "#E8E7C8"
+ flags = MATERIAL_PADDING
+
+/material/cloth_lime
+ name = "lime"
+ display_name = "lime"
+ use_name = "lime cloth"
+ icon_colour = "#62E36C"
+ flags = MATERIAL_PADDING
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 56927f56bf..c8d5651b29 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -202,13 +202,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
statpanel("Status")
if (client.statpanel == "Status")
stat(null, "Station Time: [worldtime2text()]")
- if(ticker)
- if(ticker.mode)
- //world << "DEBUG: ticker not null"
- if(ticker.mode.name == "AI malfunction")
- //world << "DEBUG: malf mode ticker test"
- if(malf.revealed)
- stat(null, "Time left: [max(malf.hack_time/(malf.hacked_apcs.len/3), 0)]")
if(emergency_shuttle)
var/eta_status = emergency_shuttle.get_status_panel_eta()
if(eta_status)
@@ -677,6 +670,12 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
client.images -= ghostimage //remove ourself
mob/dead/observer/MayRespawn(var/feedback = 0)
+ if(!client || !mind)
+ return 0
+ if(mind.current && mind.current.stat != DEAD)
+ if(feedback)
+ src << "Your non-dead body prevent you from respawning."
+ return 0
if(config.antag_hud_restricted && has_enabled_antagHUD == 1)
if(feedback)
src << "antagHUD restrictions prevent you from respawning."
diff --git a/code/modules/mob/freelook/eye.dm b/code/modules/mob/freelook/eye.dm
index bec261797d..fb2b04a434 100644
--- a/code/modules/mob/freelook/eye.dm
+++ b/code/modules/mob/freelook/eye.dm
@@ -8,6 +8,7 @@
icon = 'icons/mob/eye.dmi'
icon_state = "default-eye"
alpha = 127
+ density = 0
var/sprint = 10
var/cooldown = 0
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index f0af6e1464..ad191db257 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -249,7 +249,10 @@
var/mob/living/carbon/human/H = src
H.w_uniform.add_fingerprint(M)
- if(player_logged)
+ var/show_ssd
+ var/mob/living/carbon/human/H = src
+ if(istype(H)) show_ssd = H.species.show_ssd
+ if(show_ssd && (!client || !key || player_logged))
M.visible_message("[M] shakes [src] trying to wake [t_him] up!", \
"You shake [src], but they do not respond... Maybe they have S.S.D?")
else if(lying || src.sleeping)
@@ -259,7 +262,6 @@
M.visible_message("[M] shakes [src] trying to wake [t_him] up!", \
"You shake [src] trying to wake [t_him] up!")
else
- var/mob/living/carbon/human/H = M
if(istype(H))
H.species.hug(H,src)
else
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index dad4e90244..078e4568db 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -244,9 +244,9 @@
if(species.show_ssd && (!species.has_organ["brain"] || has_brain()) && stat != DEAD)
if(!key)
- msg += "[t_He] [t_is] fast asleep. It doesn't look like they are waking up anytime soon.\n"
+ msg += "[t_He] [t_is] [species.show_ssd]. It doesn't look like they are waking up anytime soon.\n"
else if(!client)
- msg += "[t_He] [t_has] suddenly fallen asleep.\n"
+ msg += "[t_He] [t_is] [species.show_ssd].\n"
var/list/wound_flavor_text = list()
var/list/is_destroyed = list()
@@ -256,7 +256,7 @@
var/list/organ_data = species.has_limbs[organ_tag]
var/organ_descriptor = organ_data["descriptor"]
- is_destroyed["[organ_data["descriptor"]]"] = 1
+ is_destroyed["organ_descriptor"] = 1
var/obj/item/organ/external/E = organs_by_name[organ_tag]
if(!E)
@@ -264,6 +264,7 @@
else if(E.is_stump())
wound_flavor_text["[organ_descriptor]"] = "[t_He] has a stump where [t_his] [organ_descriptor] should be.\n"
else
+ is_destroyed["organ_descriptor"] = 0
continue
for(var/obj/item/organ/external/temp in organs)
@@ -278,7 +279,7 @@
else if(temp.wounds.len > 0 || temp.open)
wound_flavor_text["[temp.name]"] = "[t_He] has [temp.get_wounds_desc()] on [t_his] [temp.name].
"
if(temp.status & ORGAN_BLEEDING)
- is_bleeding["[temp.name]"] = 1
+ is_bleeding["[temp.name]"] = "[capitalize(t_his)] [temp.name] is bleeding!
"
else
wound_flavor_text["[temp.name]"] = ""
if(temp.dislocated == 2)
@@ -288,41 +289,56 @@
//Handles the text strings being added to the actual description.
//If they have something that covers the limb, and it is not missing, put flavortext. If it is covered but bleeding, add other flavortext.
+
+ // ***********************************************************************************
+ // THIS NEEDS TO BE ENTIRELY REWRITTEN. Commenting out for now, BADLY NEEDS REWRITING.
+ // ***********************************************************************************
+
+ /*
var/display_chest = 0
var/display_shoes = 0
var/display_gloves = 0
+
if(wound_flavor_text["head"] && (is_destroyed["head"] || (!skipmask && !(wear_mask && istype(wear_mask, /obj/item/clothing/mask/gas)))))
msg += wound_flavor_text["head"]
else if(is_bleeding["head"])
msg += "[src] has blood running down [t_his] face!\n"
+
if(wound_flavor_text["upper body"] && !w_uniform && !skipjumpsuit) //No need. A missing chest gibs you.
msg += wound_flavor_text["upper body"]
else if(is_bleeding["upper body"])
display_chest = 1
+
if(wound_flavor_text["left arm"] && (is_destroyed["left arm"] || (!w_uniform && !skipjumpsuit)))
msg += wound_flavor_text["left arm"]
else if(is_bleeding["left arm"])
display_chest = 1
+
if(wound_flavor_text["left hand"] && (is_destroyed["left hand"] || (!gloves && !skipgloves)))
msg += wound_flavor_text["left hand"]
else if(is_bleeding["left hand"])
display_gloves = 1
+
if(wound_flavor_text["right arm"] && (is_destroyed["right arm"] || (!w_uniform && !skipjumpsuit)))
msg += wound_flavor_text["right arm"]
else if(is_bleeding["right arm"])
display_chest = 1
+
if(wound_flavor_text["right hand"] && (is_destroyed["right hand"] || (!gloves && !skipgloves)))
msg += wound_flavor_text["right hand"]
else if(is_bleeding["right hand"])
display_gloves = 1
+
if(wound_flavor_text["lower body"] && (is_destroyed["lower body"] || (!w_uniform && !skipjumpsuit)))
msg += wound_flavor_text["lower body"]
else if(is_bleeding["lower body"])
display_chest = 1
+
if(wound_flavor_text["left leg"] && (is_destroyed["left leg"] || (!w_uniform && !skipjumpsuit)))
msg += wound_flavor_text["left leg"]
else if(is_bleeding["left leg"])
display_chest = 1
+
if(wound_flavor_text["left foot"]&& (is_destroyed["left foot"] || (!shoes && !skipshoes)))
msg += wound_flavor_text["left foot"]
else if(is_bleeding["left foot"])
@@ -335,19 +351,25 @@
msg += wound_flavor_text["right foot"]
else if(is_bleeding["right foot"])
display_shoes = 1
+
if(display_chest)
msg += "[src] has blood soaking through from under [t_his] clothing!\n"
if(display_shoes)
msg += "[src] has blood running from [t_his] shoes!\n"
if(display_gloves)
msg += "[src] has blood running from under [t_his] gloves!\n"
+ */
+ for(var/limb in wound_flavor_text)
+ msg += wound_flavor_text[limb]
+ is_bleeding[limb] = null
+ for(var/limb in is_bleeding)
+ msg += is_bleeding[limb]
for(var/implant in get_visible_implants(0))
msg += "[src] has \a [implant] sticking out of [t_his] flesh!\n"
if(digitalcamo)
msg += "[t_He] [t_is] repulsively uncanny!\n"
-
if(hasHUD(usr,"security"))
var/perpname = "wot"
var/criminal = "None"
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 7bd7570560..36af219aee 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -37,6 +37,7 @@
hud_list[SPECIALROLE_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
hud_list[STATUS_HUD_OOC] = image('icons/mob/hud.dmi', src, "hudhealthy")
+ human_mob_list |= src
..()
if(dna)
@@ -44,6 +45,7 @@
make_blood()
/mob/living/carbon/human/Destroy()
+ human_mob_list -= src
for(var/organ in organs)
qdel(organ)
return ..()
@@ -54,9 +56,6 @@
stat(null, "Intent: [a_intent]")
stat(null, "Move Mode: [m_intent]")
- if(ticker && ticker.mode && ticker.mode.name == "AI malfunction")
- if(malf.revealed)
- stat(null, "Time left: [max(malf.hack_time/(malf.hacked_apcs/3), 0)]")
if(emergency_shuttle)
var/eta_status = emergency_shuttle.get_status_panel_eta()
if(eta_status)
diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm
index 6c92db09fe..f2c64fa52a 100644
--- a/code/modules/mob/living/carbon/human/human_organs.dm
+++ b/code/modules/mob/living/carbon/human/human_organs.dm
@@ -72,7 +72,18 @@
var/obj/item/organ/external/E = organs_by_name[limb_tag]
if(!E || (E.status & (ORGAN_DESTROYED|ORGAN_DEAD)))
stance_damage += 2 // let it fail even if just foot&leg
- else if (E.is_malfunctioning() || E.is_broken() || !E.is_usable())
+ else if (E.is_malfunctioning())
+ //malfunctioning only happens intermittently so treat it as a missing limb when it procs
+ stance_damage += 2
+ if(prob(10))
+ visible_message("\The [src]'s [E.name] [pick("twitches", "shudders")] and sparks!")
+ var/datum/effect/effect/system/spark_spread/spark_system = new ()
+ spark_system.set_up(5, 0, src)
+ spark_system.attach(src)
+ spark_system.start()
+ spawn(10)
+ qdel(spark_system)
+ else if (E.is_broken() || !E.is_usable())
stance_damage += 1
else if (E.is_dislocated())
stance_damage += 0.5
@@ -94,7 +105,27 @@
Weaken(5) //can't emote while weakened, apparently.
/mob/living/carbon/human/proc/handle_grasp()
+ if(!l_hand && !r_hand)
+ return
+ // You should not be able to pick anything up, but stranger things have happened.
+ if(l_hand)
+ for(var/limb_tag in list("l_hand","l_arm"))
+ var/obj/item/organ/external/E = get_organ(limb_tag)
+ if(!E)
+ visible_message("Lacking a functioning left hand, \the [src] drops \the [l_hand].")
+ drop_from_inventory(l_hand)
+ break
+
+ if(r_hand)
+ for(var/limb_tag in list("r_hand","r_arm"))
+ var/obj/item/organ/external/E = get_organ(limb_tag)
+ if(!E)
+ visible_message("Lacking a functioning right hand, \the [src] drops \the [r_hand].")
+ drop_from_inventory(r_hand)
+ break
+
+ // Check again...
if(!l_hand && !r_hand)
return
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index e3b8820b00..709ab2bfb8 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -942,7 +942,7 @@
if(status_flags & GODMODE) return 0
//SSD check, if a logged player is awake put them back to sleep!
- if(player_logged && sleeping < 2)
+ if(sleeping < 2 && species.show_ssd && (!client || !key || player_logged))
sleeping = 2
if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
@@ -1135,7 +1135,7 @@
if(damageoverlay.overlays)
damageoverlay.overlays = list()
-
+
if(stat == UNCONSCIOUS)
//Critical damage passage overlay
if(health <= 0)
@@ -1365,11 +1365,11 @@
var/obj/item/clothing/glasses/welding/O = glasses
if(!O.up)
found_welder = 1
- else if(istype(head, /obj/item/clothing/head/welding))
+ if(!found_welder && istype(head, /obj/item/clothing/head/welding))
var/obj/item/clothing/head/welding/O = head
if(!O.up)
found_welder = 1
- else if(istype(back, /obj/item/weapon/rig))
+ if(!found_welder && istype(back, /obj/item/weapon/rig))
var/obj/item/weapon/rig/O = back
if(O.helmet && O.helmet == head && (O.helmet.body_parts_covered & EYES))
if((O.offline && O.offline_vision_restriction == 1) || (!O.offline && O.vision_restriction == 1))
diff --git a/code/modules/mob/living/carbon/human/species/outsider/vox.dm b/code/modules/mob/living/carbon/human/species/outsider/vox.dm
index 53e8dc0b15..926781abe1 100644
--- a/code/modules/mob/living/carbon/human/species/outsider/vox.dm
+++ b/code/modules/mob/living/carbon/human/species/outsider/vox.dm
@@ -56,22 +56,16 @@
/datum/species/vox/equip_survival_gear(var/mob/living/carbon/human/H)
H.equip_to_slot_or_del(new /obj/item/clothing/mask/breath(H), slot_wear_mask)
- if(!H.back)
- H.equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(H), slot_back)
- H.internal = H.back
- else if(!H.r_hand)
- H.equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(H), slot_r_hand)
- H.internal = H.r_hand
- else if (!H.l_hand)
- H.equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(H), slot_l_hand)
- H.internal = H.l_hand
- H.internals.icon_state = "internal1"
-
if(H.backbag == 1)
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival/vox(H), slot_r_hand)
+ H.equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(H), slot_back)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/vox(H), slot_r_hand)
+ H.internal = H.back
else
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival/vox(H.back), slot_in_backpack)
-
+ H.equip_to_slot_or_del(new /obj/item/weapon/tank/nitrogen(H), slot_r_hand)
+ H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/vox(H.back), slot_in_backpack)
+ H.internal = H.r_hand
+ H.internals.icon_state = "internal1"
+
/datum/species/vox/can_shred(var/mob/living/carbon/human/H, var/ignore_intent)
if(!H.mind || !H.mind.special_role) // Pariah check.
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index 1bc6ca880a..74e55ec2f7 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -28,7 +28,7 @@
var/race_key = 0 // Used for mob icon cache string.
var/icon/icon_template // Used for mob icon generation for non-32x32 species.
var/is_small
- var/show_ssd = 1
+ var/show_ssd = "fast asleep"
// Language/culture vars.
var/default_language = "Galactic Common" // Default language is used when 'say' is used without modifiers.
@@ -175,11 +175,13 @@
return "unknown"
return species_language.get_random_name(gender)
-/datum/species/proc/equip_survival_gear(var/mob/living/carbon/human/H)
+/datum/species/proc/equip_survival_gear(var/mob/living/carbon/human/H,var/extendedtank = 1)
if(H.backbag == 1)
- H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H), slot_r_hand)
+ if (extendedtank) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(H), slot_r_hand)
+ else 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)
+ if (extendedtank) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(H.back), slot_in_backpack)
+ else H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/survival(H.back), slot_in_backpack)
/datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs.
diff --git a/code/modules/mob/living/carbon/human/species/station/monkey.dm b/code/modules/mob/living/carbon/human/species/station/monkey.dm
index 64e12eadfa..6ae24db2f6 100644
--- a/code/modules/mob/living/carbon/human/species/station/monkey.dm
+++ b/code/modules/mob/living/carbon/human/species/station/monkey.dm
@@ -13,7 +13,8 @@
greater_form = "Human"
is_small = 1
has_fine_manipulation = 0
- show_ssd = 0
+ show_ssd = null
+
eyes = "blank_eyes"
gibbed_anim = "gibbed-m"
diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm
index 985a5dac09..a6b39ba38b 100644
--- a/code/modules/mob/living/carbon/human/species/station/station.dm
+++ b/code/modules/mob/living/carbon/human/species/station/station.dm
@@ -62,7 +62,7 @@
/datum/species/unathi/equip_survival_gear(var/mob/living/carbon/human/H)
..()
- H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H),slot_shoes,1)
+ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H),slot_shoes)
/datum/species/tajaran
name = "Tajara"
@@ -108,7 +108,7 @@
/datum/species/tajaran/equip_survival_gear(var/mob/living/carbon/human/H)
..()
- H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H),slot_shoes,1)
+ H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H),slot_shoes)
/datum/species/skrell
name = "Skrell"
@@ -146,6 +146,8 @@
hud_type = /datum/hud_data/diona
siemens_coefficient = 0.3
eyes = "blank_eyes"
+ show_ssd = "completely quiescent"
+
blurb = "Commonly referred to (erroneously) as 'plant people', the Dionaea are a strange space-dwelling collective \
species hailing from Epsilon Ursae Minoris. Each 'diona' is a cluster of numerous cat-sized organisms called nymphs; \
@@ -246,6 +248,7 @@
eyes = "blank_eyes"
brute_mod = 0.5
burn_mod = 1
+ show_ssd = "flashing a 'system offline' glyph on their monitor"
warning_low_pressure = 50
hazard_low_pressure = 0
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 558576e658..9c874f54b1 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -56,26 +56,30 @@ var/list/ai_verbs_default = list(
var/obj/item/device/multitool/aiMulti = null
var/obj/item/device/radio/headset/heads/ai_integrated/aiRadio = null
var/custom_sprite = 0 //For our custom sprites
-//Hud stuff
-
- //MALFUNCTION
- var/datum/AI_Module/module_picker/malf_picker
- var/processing_time = 100
- var/list/datum/AI_Module/current_modules = list()
- var/fire_res_on_core = 0
-
- var/control_disabled = 0 // Set to 1 to stop AI from interacting via Click() -- TLE
- var/malfhacking = 0 // More or less a copy of the above var, so that malf AIs can hack and still get new cyborgs -- NeoFite
-
- var/obj/machinery/power/apc/malfhack = null
- var/explosive = 0 //does the AI explode when it dies?
-
- var/mob/living/silicon/ai/parent = null
-
var/camera_light_on = 0 //Defines if the AI toggled the light on the camera it's looking through.
var/datum/trackable/track = null
var/last_announcement = ""
+ var/control_disabled = 0
var/datum/announcement/priority/announcement
+ var/obj/machinery/ai_powersupply/psupply = null // Backwards reference to AI's powersupply object.
+
+ //NEWMALF VARIABLES
+ var/malfunctioning = 0 // Master var that determines if AI is malfunctioning.
+ var/datum/malf_hardware/hardware = null // Installed piece of hardware.
+ var/datum/malf_research/research = null // Malfunction research datum.
+ var/obj/machinery/power/apc/hack = null // APC that is currently being hacked.
+ var/list/hacked_apcs = null // List of all hacked APCs
+ var/APU_power = 0 // If set to 1 AI runs on APU power
+ var/hacking = 0 // Set to 1 if AI is hacking APC, cyborg, other AI, or running system override.
+ var/system_override = 0 // Set to 1 if system override is initiated, 2 if succeeded.
+ var/hack_can_fail = 1 // If 0, all abilities have zero chance of failing.
+ var/hack_fails = 0 // This increments with each failed hack, and determines the warning message text.
+ var/errored = 0 // Set to 1 if runtime error occurs. Only way of this happening i can think of is admin fucking up with varedit.
+ var/bombing_core = 0 // Set to 1 if core auto-destruct is activated
+ var/bombing_station = 0 // Set to 1 if station nuke auto-destruct is activated
+ var/override_CPUStorage = 0 // Bonus/Penalty CPU Storage. For use by admins/testers.
+ var/override_CPURate = 0 // Bonus/Penalty CPU generation rate. For use by admins/testers.
+
/mob/living/silicon/ai/proc/add_ai_verbs()
src.verbs |= ai_verbs_default
@@ -203,17 +207,6 @@ var/list/ai_verbs_default = list(
set src = usr.contents
return 0
-/mob/living/silicon/ai/proc/system_integrity()
- return (health-config.health_threshold_dead)/2
-
-// this function shows the health of the pAI in the Status panel
-/mob/living/silicon/ai/show_system_integrity()
- // An AI doesn't become inoperable until -100% (or whatever config.health_threshold_dead is set to)
- if(!src.stat)
- stat(null, text("System integrity: [system_integrity()]%"))
- else
- stat(null, text("Systems nonfunctional"))
-
/mob/living/silicon/ai/SetName(pickedName as text)
..()
announcement.announcer = pickedName
@@ -240,6 +233,7 @@ var/list/ai_verbs_default = list(
/obj/machinery/ai_powersupply/New(var/mob/living/silicon/ai/ai=null)
powered_ai = ai
+ powered_ai.psupply = src
if(isnull(powered_ai))
qdel(src)
@@ -250,10 +244,17 @@ var/list/ai_verbs_default = list(
/obj/machinery/ai_powersupply/process()
if(!powered_ai || powered_ai.stat & DEAD)
+ qdel()
+ return
+ if(powered_ai.psupply != src) // For some reason, the AI has different powersupply object. Delete this one, it's no longer needed.
qdel(src)
+ if(powered_ai.APU_power)
+ use_power = 0
+ return
if(!powered_ai.anchored)
loc = powered_ai.loc
use_power = 0
+ use_power(50000) // Less optimalised but only called if AI is unwrenched. This prevents usage of wrenching as method to keep AI operational without power. Intellicard is for that.
if(powered_ai.anchored)
use_power = 2
@@ -312,14 +313,7 @@ var/list/ai_verbs_default = list(
if("Lonestar") icon_state = "ai-lonestar"
if("Nanotrasen") icon_state = "ai-nanotrasen"
else icon_state = "ai"
- //else
- //usr <<"You can only change your display once!"
- //return
-// displays the malf_ai information if the AI is the malf
-/mob/living/silicon/ai/show_malf_ai()
- if(malf && malf.hacked_apcs.len >= 3)
- stat(null, "Time until station control secured: [max(malf.hack_time/(malf.hacked_apcs/3), 0)] seconds")
// this verb lets the ai see the stations manifest
/mob/living/silicon/ai/proc/ai_roster()
@@ -420,11 +414,7 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/emp_act(severity)
if (prob(30))
- switch(pick(1,2))
- if(1)
- view_core()
- if(2)
- ai_call_shuttle()
+ view_core()
..()
/mob/living/silicon/ai/Topic(href, href_list)
@@ -545,13 +535,6 @@ var/list/ai_verbs_default = list(
src << "\blue Switched to [network] camera network."
//End of code by Mord_Sith
-
-/mob/living/silicon/ai/proc/choose_modules()
- set category = "Malfunction"
- set name = "Choose Module"
-
- malf_picker.use(src)
-
/mob/living/silicon/ai/proc/ai_statuschange()
set category = "AI Commands"
set name = "AI Status"
@@ -711,5 +694,153 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/proc/is_in_chassis()
return istype(loc, /turf)
+
+/mob/living/silicon/ai/ex_act(var/severity)
+ if(severity == 1.0)
+ qdel(src)
+ return
+ ..()
+
+// NEWMALF FUNCTIONS/PROCEDURES
+
+// Sets up malfunction-related variables, research system and such.
+/mob/living/silicon/ai/proc/setup_for_malf()
+ var/mob/living/silicon/ai/user = src
+ // Setup Variables
+ malfunctioning = 1
+ research = new/datum/malf_research()
+ research.owner = src
+ hacked_apcs = list()
+ recalc_cpu()
+
+ verbs += new/datum/game_mode/malfunction/verb/ai_select_hardware()
+ verbs += new/datum/game_mode/malfunction/verb/ai_select_research()
+ verbs += new/datum/game_mode/malfunction/verb/ai_help()
+
+ // And greet user with some OOC info.
+ user << "You are malfunctioning, you do not have to follow any laws."
+ user << "Use ai-help command to view relevant information about your abilities"
+
+// Safely remove malfunction status, fixing hacked APCs and resetting variables.
+/mob/living/silicon/ai/proc/stop_malf()
+ var/mob/living/silicon/ai/user = src
+ // Generic variables
+ malfunctioning = 0
+ sleep(10)
+ research = null
+ // Fix hacked APCs
+ if(hacked_apcs)
+ for(var/obj/machinery/power/apc/A in hacked_apcs)
+ A.hacker = null
+ hacked_apcs = null
+ // Reset our verbs
+ src.verbs = null
+ add_ai_verbs()
+ // Let them know.
+ user << "You are no longer malfunctioning. Your abilities have been removed."
+
+// Called every tick. Checks if AI is malfunctioning. If yes calls Process on research datum which handles all logic.
+/mob/living/silicon/ai/proc/malf_process()
+ if(!malfunctioning)
+ return
+ if(!research)
+ if(!errored)
+ errored = 1
+ error("malf_process() called on AI without research datum. Report this.")
+ message_admins("ERROR: malf_process() called on AI without research datum. If admin modified one of the AI's vars revert the change and don't modify variables directly, instead use ProcCall or admin panels.")
+ spawn(1200)
+ errored = 0
+ return
+ recalc_cpu()
+ if(APU_power || aiRestorePowerRoutine != 0)
+ research.process(1)
+ else
+ research.process(0)
+
+// Recalculates CPU time gain and storage capacities.
+/mob/living/silicon/ai/proc/recalc_cpu()
+ // AI Starts with these values.
+ var/cpu_gain = 0.01
+ var/cpu_storage = 10
+
+ // Off-Station APCs should not count towards CPU generation.
+ for(var/obj/machinery/power/apc/A in hacked_apcs)
+ if(A.z in config.station_levels)
+ cpu_gain += 0.002
+ cpu_storage += 10
+
+ research.max_cpu = cpu_storage + override_CPUStorage
+ if(hardware && istype(hardware, /datum/malf_hardware/dual_ram))
+ research.max_cpu = research.max_cpu * 1.5
+ research.stored_cpu = min(research.stored_cpu, research.max_cpu)
+
+ research.cpu_increase_per_tick = cpu_gain + override_CPURate
+ if(hardware && istype(hardware, /datum/malf_hardware/dual_cpu))
+ research.cpu_increase_per_tick = research.cpu_increase_per_tick * 2
+
+// Starts AI's APU generator
+/mob/living/silicon/ai/proc/start_apu(var/shutup = 0)
+ if(!hardware || !istype(hardware, /datum/malf_hardware/apu_gen))
+ if(!shutup)
+ src << "You do not have an APU generator and you shouldn't have this verb. Report this."
+ return
+ if(hardware_integrity() < 50)
+ if(!shutup)
+ src << "Starting APU... FAULT(System Damaged)"
+ return
+ if(!shutup)
+ src << "Starting APU... ONLINE"
+ APU_power = 1
+
+// Stops AI's APU generator
+/mob/living/silicon/ai/proc/stop_apu(var/shutup = 0)
+ if(!hardware || !istype(hardware, /datum/malf_hardware/apu_gen))
+ return
+
+ if(APU_power)
+ APU_power = 0
+ if(!shutup)
+ src << "Shutting down APU... DONE"
+
+// Returns percentage of AI's remaining backup capacitor charge (maxhealth - oxyloss).
+/mob/living/silicon/ai/proc/backup_capacitor()
+ return ((200 - getOxyLoss()) / 2)
+
+// Returns percentage of AI's remaining hardware integrity (maxhealth - (bruteloss + fireloss))
+/mob/living/silicon/ai/proc/hardware_integrity()
+ return (health-config.health_threshold_dead)/2
+
+// Shows capacitor charge and hardware integrity information to the AI in Status tab.
+/mob/living/silicon/ai/show_system_integrity()
+ if(!src.stat)
+ stat(null, text("Hardware integrity: [hardware_integrity()]%"))
+ stat(null, text("Internal capacitor: [backup_capacitor()]%"))
+ else
+ stat(null, text("Systems nonfunctional"))
+
+// Shows AI Malfunction related information to the AI.
+/mob/living/silicon/ai/show_malf_ai()
+ if(src.is_malf())
+ if(src.hacked_apcs)
+ stat(null, "Hacked APCs: [src.hacked_apcs.len]")
+ stat(null, "System Status: [src.hacking ? "Busy" : "Stand-By"]")
+ if(src.research)
+ stat(null, "Available CPU: [src.research.stored_cpu] TFlops")
+ stat(null, "Maximal CPU: [src.research.max_cpu] TFlops")
+ stat(null, "CPU generation rate: [src.research.cpu_increase_per_tick] TFlops/s")
+ stat(null, "Current research focus: [src.research.focus ? src.research.focus.name : "None"]")
+ if(src.research.focus)
+ stat(null, "Research completed: [round(src.research.focus.invested, 0.1)]/[round(src.research.focus.price)]")
+ if(system_override == 1)
+ stat(null, "SYSTEM OVERRIDE INITIATED")
+ else if(system_override == 2)
+ stat(null, "SYSTEM OVERRIDE COMPLETED")
+
+// Cleaner proc for creating powersupply for an AI.
+/mob/living/silicon/ai/proc/create_powersupply()
+ if(psupply)
+ del(psupply)
+ psupply = new/obj/machinery/ai_powersupply(src)
+
#undef AI_CHECK_WIRELESS
#undef AI_CHECK_RADIO
diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm
index 4a43103da8..8f9f0d1d5d 100644
--- a/code/modules/mob/living/silicon/ai/death.dm
+++ b/code/modules/mob/living/silicon/ai/death.dm
@@ -35,7 +35,7 @@
break
callshuttle++
- if(ticker.mode.name == "revolution" || ticker.mode.name == "AI malfunction")
+ if(ticker.mode.name == "revolution")
callshuttle = 0
if(callshuttle == 3) //if all three conditions are met
@@ -43,10 +43,6 @@
log_game("All the AIs, comm consoles and boards are destroyed. Shuttle called.")
message_admins("All the AIs, comm consoles and boards are destroyed. Shuttle called.", 1)
- if(explosive)
- spawn(10)
- explosion(src.loc, 3, 6, 12, 15)
-
for(var/obj/machinery/ai_status_display/O in world)
spawn( 0 )
O.mode = 2
diff --git a/code/modules/mob/living/silicon/ai/examine.dm b/code/modules/mob/living/silicon/ai/examine.dm
index 286edc2ce0..45c6a3816b 100644
--- a/code/modules/mob/living/silicon/ai/examine.dm
+++ b/code/modules/mob/living/silicon/ai/examine.dm
@@ -17,15 +17,23 @@
msg += "It looks slightly charred.\n"
else
msg += "Its casing is melted and heat-warped!\n"
+ if (src.getOxyLoss())
+ if (src.getOxyLoss() > 175)
+ msg += "It seems to be running on backup power. Its display is blinking a \"BACKUP POWER CRITICAL\" warning.\n"
+ else if(src.getOxyLoss() > 100)
+ msg += "It seems to be running on backup power. Its display is blinking a \"BACKUP POWER LOW\" warning.\n"
+ else
+ msg += "It seems to be running on backup power.\n"
if (src.stat == UNCONSCIOUS)
msg += "It is non-responsive and displaying the text: \"RUNTIME: Sensory Overload, stack 26/3\".\n"
msg += ""
msg += "*---------*"
-
+ if(hardware && (hardware.owner == src))
+ msg += "
"
+ msg += hardware.get_examine_desc()
user << msg
user.showLaws(src)
-
return
/mob/proc/showLaws(var/mob/living/silicon/S)
diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm
index f57a96a088..5e0b0589c5 100644
--- a/code/modules/mob/living/silicon/ai/life.dm
+++ b/code/modules/mob/living/silicon/ai/life.dm
@@ -12,90 +12,71 @@
src.updatehealth()
- if (src.malfhack)
- if (src.malfhack.aidisabled)
- src << "\red ERROR: APC access disabled, hack attempt canceled."
- src.malfhacking = 0
- src.malfhack = null
-
-
- if (src.health <= config.health_threshold_dead)
+ if (!hardware_integrity() || !backup_capacitor())
death()
return
+ // If our powersupply object was destroyed somehow, create new one.
+ if(!psupply)
+ create_powersupply()
+
if (src.machine)
if (!( src.machine.check_eye(src) ))
src.reset_view(null)
// Handle power damage (oxy)
- if(src:aiRestorePowerRoutine != 0)
- // Lost power
+ if(aiRestorePowerRoutine != 0 && !APU_power)
+ // Lose power
adjustOxyLoss(1)
else
// Gain Power
+ aiRestorePowerRoutine = 0 // Necessary if AI activated it's APU AFTER losing primary power.
adjustOxyLoss(-1)
// Handle EMP-stun
handle_stunned()
- //stage = 1
- //if (istype(src, /mob/living/silicon/ai)) // Are we not sure what we are?
+ malf_process()
+
+ if(APU_power && (hardware_integrity() < 50))
+ src << "APU GENERATOR FAILURE! (System Damaged)"
+ stop_apu(1)
+
var/blind = 0
- //stage = 2
var/area/loc = null
if (istype(T, /turf))
- //stage = 3
loc = T.loc
if (istype(loc, /area))
- //stage = 4
- if (!loc.power_equip && !istype(src.loc,/obj/item))
- //stage = 5
+ if (!loc.power_equip && !istype(src.loc,/obj/item) && !APU_power)
blind = 1
- if (!blind) //lol? if(!blind) #if(src.blind.layer) <--something here is clearly wrong :P
- //I'll get back to this when I find out how this is -supposed- to work ~Carn //removed this shit since it was confusing as all hell --39kk9t
- //stage = 4.5
+ if (!blind)
src.sight |= SEE_TURFS
src.sight |= SEE_MOBS
src.sight |= SEE_OBJS
src.see_in_dark = 8
src.see_invisible = SEE_INVISIBLE_LIVING
-
- //Congratulations! You've found a way for AI's to run without using power!
- //Todo: Without snowflaking up master_controller procs find a way to make AI use_power but only when APC's clear the area usage the tick prior
- // since mobs are in master_controller before machinery. We also have to do it in a manner where we don't reset the entire area's need to update
- // the power usage.
- //
- // We can probably create a new machine that resides inside of the AI contents that uses power using the idle_usage of 1000 and nothing else and
- // be fine.
-/*
- var/area/home = get_area(src)
- if(!home) return//something to do with malf fucking things up I guess. <-- aisat is gone. is this still necessary? ~Carn
- if(home.powered(EQUIP))
- home.use_power(1000, EQUIP)
-*/
-
- if (src:aiRestorePowerRoutine==2)
+ if (aiRestorePowerRoutine==2)
src << "Alert cancelled. Power has been restored without our assistance."
- src:aiRestorePowerRoutine = 0
+ aiRestorePowerRoutine = 0
src.blind.layer = 0
return
- else if (src:aiRestorePowerRoutine==3)
+ else if (aiRestorePowerRoutine==3)
src << "Alert cancelled. Power has been restored."
- src:aiRestorePowerRoutine = 0
+ aiRestorePowerRoutine = 0
+ src.blind.layer = 0
+ return
+ else if (APU_power)
+ aiRestorePowerRoutine = 0
src.blind.layer = 0
return
else
-
- //stage = 6
-
var/area/current_area = get_area(src)
if (lacks_power())
- //If our area lacks equipment power, and is not magically powered (i.e. centcom), or if we are in space and not carded, lose power.
- if (src:aiRestorePowerRoutine==0)
- src:aiRestorePowerRoutine = 1
+ if (aiRestorePowerRoutine==0)
+ aiRestorePowerRoutine = 1
//Blind the AI
@@ -118,7 +99,7 @@
if (loc.power_equip)
if (!istype(T, /turf/space))
src << "Alert cancelled. Power has been restored without our assistance."
- src:aiRestorePowerRoutine = 0
+ aiRestorePowerRoutine = 0
src.blind.layer = 0
return
src << "Fault confirmed: missing external power. Shutting down main control system to save power."
@@ -127,7 +108,7 @@
sleep(50)
if (istype(T, /turf/space))
src << "Unable to verify! No power connection detected!"
- src:aiRestorePowerRoutine = 2
+ aiRestorePowerRoutine = 2
return
src << "Connection verified. Searching for APC in power network."
sleep(50)
@@ -148,7 +129,7 @@
if (loc.power_equip)
if (!istype(T, /turf/space))
src << "Alert cancelled. Power has been restored without our assistance."
- src:aiRestorePowerRoutine = 0
+ aiRestorePowerRoutine = 0
src.blind.layer = 0 //This, too, is a fix to issue 603
return
switch(PRP)
@@ -163,9 +144,9 @@
theAPC.operating = 1
theAPC.equipment = 3
theAPC.update()
- src:aiRestorePowerRoutine = 3
+ aiRestorePowerRoutine = 3
src << "Here are your current laws:"
- src.show_laws()
+ show_laws()
sleep(50)
theAPC = null
@@ -178,6 +159,8 @@
process_med_hud(src,0,src.eyeobj)
/mob/living/silicon/ai/proc/lacks_power()
+ if(APU_power)
+ return 0
var/turf/T = get_turf(src)
var/area/A = get_area(src)
return ((!A.power_equip) && A.requires_power == 1 || istype(T, /turf/space)) && !istype(src.loc,/obj/item)
@@ -186,11 +169,9 @@
if(status_flags & GODMODE)
health = 100
stat = CONSCIOUS
+ setOxyLoss(0)
else
- if(fire_res_on_core)
- health = 100 - getOxyLoss() - getToxLoss() - getBruteLoss()
- else
- health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
+ health = 100 - getFireLoss() - getBruteLoss() // Oxyloss is not part of health as it represents AIs backup power. AI is immune against ToxLoss as it is machine.
/mob/living/silicon/ai/rejuvenate()
..()
diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm
deleted file mode 100644
index 62a75fad24..0000000000
--- a/code/modules/mob/living/silicon/ai/say.dm
+++ /dev/null
@@ -1,5 +0,0 @@
-/mob/living/silicon/ai/say(var/message)
- if(parent && istype(parent) && parent.stat != 2)
- return parent.say(message)
- //If there is a defined "parent" AI, it is actually an AI, and it is alive, anything the AI tries to say is said by the parent instead.
- return ..(message)
diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm
index d859810ea1..84611ecb95 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm
@@ -194,7 +194,7 @@
wrapped = A.cell
A.cell.add_fingerprint(user)
- A.cell.updateicon()
+ A.cell.update_icon()
A.cell.loc = src
A.cell = null
@@ -211,7 +211,7 @@
wrapped = A.cell
A.cell.add_fingerprint(user)
- A.cell.updateicon()
+ A.cell.update_icon()
A.updateicon()
A.cell.loc = src
A.cell = null
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 5d192a50cd..6d44309f15 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -409,19 +409,6 @@
C.toggled = 1
src << "\red You enable [C.name]."
-// this function shows information about the malf_ai gameplay type in the status screen
-/mob/living/silicon/robot/show_malf_ai()
- ..()
- for (var/datum/mind/malfai in malf.current_antagonists)
- if(connected_ai)
- if(connected_ai.mind == malfai)
- if(malf.hacked_apcs >= 3)
- stat(null, "Time until station control secured: [max(malf.hack_time/(malf.hacked_apcs/3), 0)] seconds")
- else if(malf.revealed)
- stat(null, "Time left: [max(malf.hack_time/(malf.hacked_apcs.len/3), 0)]")
- return 0
-
-
// this function displays jetpack pressure in the stat panel
/mob/living/silicon/robot/proc/show_jetpack_pressure()
// if you have a jetpack, show the internal tank pressure
@@ -746,7 +733,7 @@
if(opened && !wiresexposed && (!istype(user, /mob/living/silicon)))
var/datum/robot_component/cell_component = components["power cell"]
if(cell)
- cell.updateicon()
+ cell.update_icon()
cell.add_fingerprint(user)
user.put_in_active_hand(cell)
user << "You remove \the [cell]."
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index 359562063d..527ce35df2 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -425,6 +425,9 @@ var/global/list/robot_modules = list(
T.update_icon()
else
T.charge_tick = 0
+ var/obj/item/weapon/melee/baton/robot/B = locate() in src.modules
+ if(B && B.bcell)
+ B.bcell.give(amount)
/obj/item/weapon/robot_module/janitor
name = "janitorial robot module"
diff --git a/code/modules/mob/living/silicon/say.dm b/code/modules/mob/living/silicon/say.dm
index ec6ddefe1c..1fefa272e5 100644
--- a/code/modules/mob/living/silicon/say.dm
+++ b/code/modules/mob/living/silicon/say.dm
@@ -185,7 +185,7 @@
This is another way of saying that we won't bother dealing with them.*/
else
src << "No holopad connected."
- return
+ return 0
return 1
/mob/living/silicon/ai/proc/holopad_emote(var/message) //This is called when the AI uses the 'me' verb while using a holopad.
@@ -206,7 +206,7 @@
M.show_message(rendered, 2)
else //This shouldn't occur, but better safe then sorry.
src << "No holopad connected."
- return
+ return 0
return 1
/mob/living/silicon/ai/emote(var/act, var/type, var/message)
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index d2e30953e7..d7a006b41c 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -27,11 +27,13 @@
#define MED_HUD 2 //Medical HUD mode
/mob/living/silicon/New()
+ silicon_mob_list |= src
..()
add_language("Galactic Common")
init_subsystems()
/mob/living/silicon/Destroy()
+ silicon_mob_list -= src
for(var/datum/alarm_handler/AH in alarm_manager.all_handlers)
AH.unregister(src)
..()
diff --git a/code/modules/mob/living/simple_animal/constructs/constructs.dm b/code/modules/mob/living/simple_animal/constructs/constructs.dm
index 56746a51d5..7781a26744 100644
--- a/code/modules/mob/living/simple_animal/constructs/constructs.dm
+++ b/code/modules/mob/living/simple_animal/constructs/constructs.dm
@@ -240,11 +240,12 @@
////////////////Glow//////////////////
/mob/living/simple_animal/construct/proc/add_glow()
overlays = 0
- var/overlay_layer = 11
+ var/overlay_layer = LIGHTING_LAYER+0.1
if(layer != MOB_LAYER)
overlay_layer=TURF_LAYER+0.2
overlays += image(icon,"glow-[icon_state]",overlay_layer)
+ set_light(2, -2, l_color = "#FFFFFF")
////////////////HUD//////////////////////
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index a92819606c..8e29e21008 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -214,8 +214,8 @@
/mob/living/simple_animal/hostile/proc/check_horde()
if(emergency_shuttle.shuttle.location)
if(!enroute && !target_mob) //The shuttle docked, all monsters rush for the escape hallway
- if(!shuttletarget || (get_dist(src, shuttletarget) >= 2))
- shuttletarget = pick(escape_list)
+ if(!shuttletarget && escape_list.len) //Make sure we didn't already assign it a target, and that there are targets to pick
+ shuttletarget = pick(escape_list) //Pick a shuttle target
enroute = 1
stop_automated_movement = 1
spawn()
diff --git a/code/modules/mob/typing_indicator.dm b/code/modules/mob/typing_indicator.dm
index 203159f3c6..147edb1afe 100644
--- a/code/modules/mob/typing_indicator.dm
+++ b/code/modules/mob/typing_indicator.dm
@@ -5,14 +5,17 @@ mob/var/typing
mob/var/last_typed
mob/var/last_typed_time
-var/global/image/typing_indicator
+mob/var/obj/effect/decal/typing_indicator
/mob/proc/set_typing_indicator(var/state)
if(!typing_indicator)
- typing_indicator = image('icons/mob/talk.dmi',null,"typing")
+ typing_indicator = new
+ typing_indicator.icon = 'icons/mob/talk.dmi'
+ typing_indicator.icon_state = "typing"
- if(client)
+ if(client && !stat)
+ typing_indicator.invisibility = invisibility
if(client.prefs.toggles & SHOW_TYPING)
overlays -= typing_indicator
else
diff --git a/code/modules/nano/modules/law_manager.dm b/code/modules/nano/modules/law_manager.dm
index 93caa4c48b..98c2cdc905 100644
--- a/code/modules/nano/modules/law_manager.dm
+++ b/code/modules/nano/modules/law_manager.dm
@@ -34,10 +34,7 @@
return 1
if(href_list["set_view"])
- if(is_malf(usr) || owner.is_ai_malf())
- current_view = text2num(href_list["set_view"])
- else
- current_view = 0
+ current_view = text2num(href_list["set_view"])
return 1
if(href_list["law_channel"])
@@ -170,12 +167,8 @@
data["isAI"] = owner.isAI()
data["isMalf"] = is_malf(user)
- data["isAIMalf"] = owner.is_ai_malf()
data["isSlaved"] = owner.is_slaved()
data["isAdmin"] = is_admin(user)
-
- if(!(data["isMalf"] || data["isAIMalf"]))
- current_view = 0
data["view"] = current_view
var/channels[0]
@@ -183,9 +176,7 @@
channels[++channels.len] = list("channel" = ch_name)
data["channel"] = owner.lawchannel
data["channels"] = channels
-
- if(data["isMalf"] || data["isAIMalf"])
- data["law_sets"] = package_multiple_laws(data["isAdmin"] ? admin_laws : player_laws)
+ data["law_sets"] = package_multiple_laws(data["isAdmin"] ? admin_laws : player_laws)
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
@@ -216,15 +207,6 @@
/obj/nano_module/law_manager/proc/is_malf(var/mob/user)
return (is_admin(user) && !owner.is_slaved()) || owner.is_malf_or_traitor()
-/mob/living/silicon/proc/is_ai_malf()
- return 0
-
-/mob/living/silicon/robot/is_ai_malf()
- return is_slaved() && connected_ai.is_malf_or_traitor()
-
-/mob/living/silicon/ai/is_ai_malf()
- return 0
-
/mob/living/silicon/proc/is_slaved()
return 0
diff --git a/code/modules/nano/nanomanager.dm b/code/modules/nano/nanomanager.dm
index 2a89779e92..f6325fd4f7 100644
--- a/code/modules/nano/nanomanager.dm
+++ b/code/modules/nano/nanomanager.dm
@@ -55,8 +55,9 @@
ui.push_data(data)
return ui
else
- //testing("nanomanager/try_update_ui mob [user.name] [src_object:name] [ui_key] [force_open] - forcing opening of ui")
- ui.close()
+ ui.reinitialise(new_initial_data=data)
+ return ui
+
return null
/**
@@ -164,10 +165,10 @@
else if (isnull(open_uis[src_object_key][ui.ui_key]) || !istype(open_uis[src_object_key][ui.ui_key], /list))
open_uis[src_object_key][ui.ui_key] = list();
- ui.user.open_uis.Add(ui)
+ ui.user.open_uis |= ui
var/list/uis = open_uis[src_object_key][ui.ui_key]
- uis.Add(ui)
- processing_uis.Add(ui)
+ uis |= ui
+ processing_uis |= ui
//testing("nanomanager/ui_opened mob [ui.user.name] [ui.src_object:name] [ui.ui_key] - user.open_uis [ui.user.open_uis.len] | uis [uis.len] | processing_uis [processing_uis.len]")
/**
@@ -220,7 +221,7 @@
*/
/datum/nanomanager/proc/user_transferred(var/mob/oldMob, var/mob/newMob)
//testing("nanomanager/user_transferred from mob [oldMob.name] to mob [newMob.name]")
- if (!oldMob || isnull(oldMob.open_uis) || !istype(oldMob.open_uis, /list) || open_uis.len == 0)
+ if (!oldMob || isnull(oldMob.open_uis) || !istype(oldMob.open_uis, /list) || open_uis.len == 0)
//testing("nanomanager/user_transferred mob [oldMob.name] has no open uis")
return 0 // has no open uis
diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm
index f53fc98497..f134d5d93b 100644
--- a/code/modules/nano/nanoui.dm
+++ b/code/modules/nano/nanoui.dm
@@ -405,6 +405,18 @@ nanoui is used to open and update nano browser uis
//onclose(user, window_id)
nanomanager.ui_opened(src)
+ /**
+ * Reinitialise this UI, potentially with a different template and/or initial data
+ *
+ * @return nothing
+ */
+/datum/nanoui/proc/reinitialise(template, new_initial_data)
+ if(template)
+ add_template("main", template)
+ if(new_initial_data)
+ set_initial_data(new_initial_data)
+ open()
+
/**
* Close this UI
*
diff --git a/code/modules/organs/organ_alien.dm b/code/modules/organs/organ_alien.dm
index 0905a61266..d76cdab8f1 100644
--- a/code/modules/organs/organ_alien.dm
+++ b/code/modules/organs/organ_alien.dm
@@ -1,16 +1,20 @@
/proc/spawn_diona_nymph_from_organ(var/obj/item/organ/organ)
if(!istype(organ))
- return
+ return 0
//This is a terrible hack and I should be ashamed.
var/datum/seed/diona = plant_controller.seeds["diona"]
if(!diona)
- qdel(src)
+ return 0
spawn(1) // So it has time to be thrown about by the gib() proc.
var/mob/living/carbon/alien/diona/D = new(get_turf(organ))
diona.request_player(D)
- qdel(organ)
+ spawn(60)
+ if(D)
+ if(!D.ckey || !D.client)
+ D.death()
+ return 1
/obj/item/organ/external/diona
name = "tendril"
@@ -128,16 +132,13 @@
//DIONA ORGANS.
/obj/item/organ/external/diona/removed()
+ var/mob/living/carbon/human/H = owner
..()
- if(!istype(owner))
+ if(!istype(H) || !H.organs || !H.organs.len)
+ H.death()
+ if(prob(50) && spawn_diona_nymph_from_organ(src))
qdel(src)
- if(!owner.organs.len)
- owner.death()
-
- if(prob(50))
- spawn_diona_nymph_from_organ(src)
-
/obj/item/organ/diona/process()
return
@@ -172,16 +173,13 @@
organ_tag = "special" // Turns into a nymph instantly, no transplanting possible.
/obj/item/organ/diona/removed(var/mob/living/user)
-
+ var/mob/living/carbon/human/H = owner
..()
- if(!istype(owner))
+ if(!istype(H) || !H.organs || !H.organs.len)
+ H.death()
+ if(prob(50) && spawn_diona_nymph_from_organ(src))
qdel(src)
- if(!owner.internal_organs.len)
- owner.death()
-
- spawn_diona_nymph_from_organ(src)
-
// These are different to the standard diona organs as they have a purpose in other
// species (absorbing radiation and light respectively)
/obj/item/organ/diona/nutrients
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index 6ad272af5f..a92219c733 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -48,6 +48,36 @@
var/can_grasp
var/can_stand
+/obj/item/organ/external/attack_self(var/mob/user)
+ if(!contents.len)
+ return ..()
+ var/list/removable_objects = list()
+ for(var/obj/item/organ/external/E in (contents + src))
+ if(!istype(E))
+ continue
+ for(var/obj/item/I in E.contents)
+ if(istype(I,/obj/item/organ))
+ continue
+ removable_objects |= I
+ if(!removable_objects.len)
+ return ..()
+ var/obj/item/I = pick(removable_objects)
+ if(!istype(I))
+ return ..()
+ I.loc = get_turf(user)
+ if(!(user.l_hand && user.r_hand))
+ user.put_in_hands(I)
+ user.visible_message("\The [user] rips \the [I] out of \the [src]!")
+
+/obj/item/organ/external/examine()
+ ..()
+ if(in_range(usr, src) || istype(usr, /mob/dead/observer))
+ for(var/obj/item/I in contents)
+ if(istype(I, /obj/item/organ))
+ continue
+ usr << "There is \a [I] sticking out of it."
+ return
+
/obj/item/organ/external/attackby(obj/item/weapon/W as obj, mob/user as mob)
switch(stage)
if(0)
@@ -162,7 +192,7 @@
burn *= bumod //~2/3 damage for ROBOLIMBS
// High brute damage or sharp objects may damage internal organs
- if(internal_organs && ((brute_dam >= max_damage) || (sharp && brute >= 5) || brute >= 10) && prob(5))
+ if(internal_organs && (brute_dam >= max_damage || (((sharp && brute >= 5) || brute >= 10) && prob(5))))
// Damage an internal organ
if(internal_organs && internal_organs.len)
var/obj/item/organ/I = pick(internal_organs)
@@ -228,13 +258,16 @@
droplimb(0,DROPLIMB_BURN)
if(!dropped && prob(brute))
var/edge_eligible = 0
- if(edge && istype(used_weapon,/obj/item))
- var/obj/item/W = used_weapon
- if(W.w_class >= 3)
+ if(edge)
+ if(istype(used_weapon,/obj/item))
+ var/obj/item/W = used_weapon
+ if(W.w_class >= w_class)
+ edge_eligible = 1
+ else
edge_eligible = 1
if(brute >= threshold || (edge_eligible && brute >= threshold/3))
- if((sharp || edge))
+ if(edge)
droplimb(0,DROPLIMB_EDGE)
else
droplimb(0,DROPLIMB_BLUNT)
@@ -697,6 +730,9 @@ Note that amputating the affected organ does in fact remove the infection from t
dir = 2
if(DROPLIMB_BURN)
new /obj/effect/decal/cleanable/ash(get_turf(victim))
+ for(var/obj/item/I in src)
+ if(I.w_class > 2 && !istype(I,/obj/item/organ))
+ I.loc = get_turf(src)
qdel(src)
if(DROPLIMB_BLUNT)
var/obj/effect/decal/cleanable/blood/gibs/gore = new owner.species.single_gib_type(get_turf(victim))
@@ -711,6 +747,14 @@ Note that amputating the affected organ does in fact remove the infection from t
I.removed()
if(istype(loc,/turf))
I.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30)
+
+ for(var/obj/item/I in src)
+ if(I.w_class <= 2)
+ qdel(I)
+ continue
+ I.loc = get_turf(src)
+ I.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30)
+
qdel(src)
/****************************************************
@@ -833,11 +877,14 @@ Note that amputating the affected organ does in fact remove the infection from t
dislocated = -1 //TODO, make robotic limbs a separate type, remove snowflake
cannot_break = 1
get_icon()
+ unmutate()
for (var/obj/item/organ/external/T in children)
if(T)
T.robotize()
/obj/item/organ/external/proc/mutate()
+ if(src.status & ORGAN_ROBOT)
+ return
src.status |= ORGAN_MUTATED
owner.update_body()
@@ -846,7 +893,7 @@ Note that amputating the affected organ does in fact remove the infection from t
owner.update_body()
/obj/item/organ/external/proc/get_damage() //returns total damage
- return max(brute_dam + burn_dam - perma_injury, perma_injury) //could use health?
+ return max(brute_dam + burn_dam - perma_injury, perma_injury) //could use max_damage?
/obj/item/organ/external/proc/has_infected_wound()
for(var/datum/wound/W in wounds)
@@ -871,7 +918,7 @@ Note that amputating the affected organ does in fact remove the infection from t
W.add_blood(owner)
if(ismob(W.loc))
var/mob/living/H = W.loc
- H.drop_item()
+ H.drop_from_inventory(W)
W.loc = owner
/obj/item/organ/external/removed(var/mob/living/user, var/ignore_children)
@@ -886,8 +933,14 @@ Note that amputating the affected organ does in fact remove the infection from t
status |= ORGAN_DESTROYED
victim.bad_external_organs -= src
- for(var/implant in implants) //todo: check if this can be left alone
- qdel(implant)
+ for(var/obj/item/implant in implants)
+ if(!istype(implant))
+ return
+ if(implant.w_class <= 2)
+ qdel(implant)
+ else
+ implant.loc = src
+ implants.Cut()
// Attached organs also fly off.
if(!ignore_children)
@@ -895,6 +948,8 @@ Note that amputating the affected organ does in fact remove the infection from t
O.removed()
if(O)
O.loc = src
+ for(var/obj/item/I in O.contents)
+ I.loc = src
// Grab all the internal giblets too.
for(var/obj/item/organ/organ in internal_organs)
@@ -994,8 +1049,9 @@ Note that amputating the affected organ does in fact remove the infection from t
name = "upper body"
limb_name = "chest"
icon_name = "torso"
- health = 100
+ max_damage = 100
min_broken_damage = 35
+ w_class = 5
body_part = UPPER_TORSO
vital = 1
amputation_point = "spine"
@@ -1010,8 +1066,9 @@ Note that amputating the affected organ does in fact remove the infection from t
name = "lower body"
limb_name = "groin"
icon_name = "groin"
- health = 100
+ max_damage = 100
min_broken_damage = 35
+ w_class = 5
body_part = LOWER_TORSO
vital = 1
parent_organ = "chest"
@@ -1024,8 +1081,9 @@ Note that amputating the affected organ does in fact remove the infection from t
limb_name = "l_arm"
name = "left arm"
icon_name = "l_arm"
- health = 50
+ max_damage = 50
min_broken_damage = 30
+ w_class = 3
body_part = ARM_LEFT
parent_organ = "chest"
joint = "left elbow"
@@ -1044,8 +1102,9 @@ Note that amputating the affected organ does in fact remove the infection from t
limb_name = "l_leg"
name = "left leg"
icon_name = "l_leg"
- health = 50
+ max_damage = 50
min_broken_damage = 30
+ w_class = 3
body_part = LEG_LEFT
icon_position = LEFT
parent_organ = "groin"
@@ -1066,8 +1125,8 @@ Note that amputating the affected organ does in fact remove the infection from t
limb_name = "l_foot"
name = "left foot"
icon_name = "l_foot"
- health = 30
min_broken_damage = 15
+ w_class = 2
body_part = FOOT_LEFT
icon_position = LEFT
parent_organ = "l_leg"
@@ -1093,8 +1152,8 @@ Note that amputating the affected organ does in fact remove the infection from t
limb_name = "l_hand"
name = "left hand"
icon_name = "l_hand"
- health = 30
min_broken_damage = 15
+ w_class = 2
body_part = HAND_LEFT
parent_organ = "l_arm"
joint = "left wrist"
@@ -1118,8 +1177,9 @@ Note that amputating the affected organ does in fact remove the infection from t
limb_name = "head"
icon_name = "head"
name = "head"
- health = 75
+ max_damage = 75
min_broken_damage = 35
+ w_class = 3
body_part = HEAD
vital = 1
parent_organ = "chest"
diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm
index 0d052d9114..5f0918238b 100644
--- a/code/modules/paperwork/pen.dm
+++ b/code/modules/paperwork/pen.dm
@@ -51,66 +51,54 @@
msg_admin_attack("[user.name] ([user.ckey]) Used the [name] to stab [M.name] ([M.ckey]) (JMP)")
return
+/*
+ * Reagent pens
+ */
+
+/obj/item/weapon/pen/reagent
+ flags = OPENCONTAINER
+ slot_flags = SLOT_BELT
+
+/obj/item/weapon/pen/reagent/New()
+ ..()
+ create_reagents(30)
+
+/obj/item/weapon/pen/reagent/attack(mob/living/M as mob, mob/user as mob)
+
+ if(!istype(M))
+ return
+
+ . = ..()
+
+ if(M.can_inject(user,1))
+ if(reagents.total_volume)
+ if(M.reagents)
+ var/contained_reagents = reagents.get_reagents()
+ var/trans = reagents.trans_to_mob(M, 30, CHEM_BLOOD)
+ admin_inject_log(user, M, src, contained_reagents, trans)
/*
* Sleepy Pens
*/
-/obj/item/weapon/pen/sleepypen
+/obj/item/weapon/pen/reagent/sleepy
desc = "It's a black ink pen with a sharp point and a carefully engraved \"Waffle Co.\""
- flags = OPENCONTAINER
- slot_flags = SLOT_BELT
origin_tech = "materials=2;syndicate=5"
-
-/obj/item/weapon/pen/sleepypen/New()
- var/datum/reagents/R = new/datum/reagents(30) //Used to be 300
- reagents = R
- R.my_atom = src
- R.add_reagent("chloralhydrate", 22) //Used to be 100 sleep toxin//30 Chloral seems to be fatal, reducing it to 22./N
+/obj/item/weapon/pen/reagent/sleepy/New()
..()
- return
-
-
-/obj/item/weapon/pen/sleepypen/attack(mob/M as mob, mob/user as mob)
- if(!(istype(M,/mob)))
- return
- ..()
- if(reagents.total_volume)
- if(M.reagents) reagents.trans_to_mob(M, 50, CHEM_BLOOD) //used to be 150
- return
+ reagents.add_reagent("chloralhydrate", 22) //Used to be 100 sleep toxin//30 Chloral seems to be fatal, reducing it to 22./N
/*
* Parapens
*/
- /obj/item/weapon/pen/paralysis
- flags = OPENCONTAINER
- slot_flags = SLOT_BELT
+ /obj/item/weapon/pen/reagent/paralysis
origin_tech = "materials=2;syndicate=5"
-
-/obj/item/weapon/pen/paralysis/attack(mob/living/M as mob, mob/user as mob)
-
- if(!(istype(M,/mob)))
- return
-
+/obj/item/weapon/pen/reagent/paralysis/New()
..()
-
-
- if(M.can_inject(user,1))
- if(reagents.total_volume)
- if(M.reagents) reagents.trans_to_mob(M, 50, CHEM_BLOOD)
- return
-
-
-/obj/item/weapon/pen/paralysis/New()
- var/datum/reagents/R = new/datum/reagents(50)
- reagents = R
- R.my_atom = src
- R.add_reagent("zombiepowder", 10)
- R.add_reagent("cryptobiolin", 15)
- ..()
- return
+ reagents.add_reagent("zombiepowder", 10)
+ reagents.add_reagent("cryptobiolin", 15)
/*
* Chameleon pen
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index f21db9327d..21f0f6c1a5 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -37,6 +37,8 @@
//NOTE: STUFF STOLEN FROM AIRLOCK.DM thx
+/obj/machinery/power/apc/critical
+ is_critical = 1
/obj/machinery/power/apc/high
cell_type = /obj/item/weapon/cell/high
@@ -44,8 +46,8 @@
/obj/machinery/power/apc/super
cell_type = /obj/item/weapon/cell/super
-/obj/machinery/power/apc/super/equipment
- equipment = 2
+/obj/machinery/power/apc/super/critical
+ is_critical = 1
/obj/machinery/power/apc/hyper
cell_type = /obj/item/weapon/cell/hyper
@@ -83,21 +85,18 @@
var/lastused_charging = 0
var/lastused_total = 0
var/main_status = 0
+ var/mob/living/silicon/ai/hacker = null // Malfunction var. If set AI hacked the APC and has full control.
var/wiresexposed = 0
powernet = 0 // set so that APCs aren't found as powernet nodes //Hackish, Horrible, was like this before I changed it :(
- var/malfhack = 0 //New var for my changes to AI malf. --NeoFite
- var/mob/living/silicon/ai/malfai = null //See above --NeoFite
var/debug= 0
var/autoflag= 0 // 0 = off, 1= eqp and lights off, 2 = eqp off, 3 = all on.
-// luminosity = 1
var/has_electronics = 0 // 0 - none, 1 - plugged in, 2 - secured by screwdriver
- var/overload = 1 //used for the Blackout malf module
var/beenhit = 0 // used for counting how many times it has been hit, used for Aliens at the moment
- var/mob/living/silicon/ai/occupier = null
var/longtermpower = 10
var/datum/wires/apc/wires = null
var/update_state = -1
var/update_overlay = -1
+ var/is_critical = 0
var/global/status_overlays = 0
var/updating_icon = 0
var/global/list/status_overlays_lock
@@ -156,22 +155,16 @@
init()
else
area = get_area(src)
- area.apc |= src
+ area.apc = src
opened = 1
operating = 0
name = "[area.name] APC"
stat |= MAINT
src.update_icon()
-/obj/machinery/power/apc/initialize()
- ..()
- src.update()
-
/obj/machinery/power/apc/Destroy()
- if(operating && malf && src.z in config.station_levels) //if (is_type_in_list(get_area(src), the_station_areas))
- malf.hacked_apcs -= src
-
- area.apc -= src
+ src.update()
+ area.apc = null
area.power_light = 0
area.power_equip = 0
area.power_environ = 0
@@ -185,6 +178,11 @@
if(terminal)
qdel(terminal)
terminal = null
+
+ // Malf AI, removes the APC from AI's hacked APCs list.
+ if((hacker) && (hacker.hacked_apcs) && (src in hacker.hacked_apcs))
+ hacker.hacked_apcs -= src
+
..()
/obj/machinery/power/apc/proc/make_terminal()
@@ -210,7 +208,7 @@
else
src.area = get_area_name(areastring)
name = "\improper [area.name] APC"
- area.apc |= src
+ area.apc = src
update_icon()
make_terminal()
@@ -237,8 +235,8 @@
else
if (stat & MAINT)
user << "The cover is closed. Something wrong with it: it doesn't work."
- else if (malfhack)
- user << "The cover is broken. It may be hard to force it open."
+ else if (hacker)
+ user << "The cover is locked."
else
user << "The cover is closed."
@@ -342,7 +340,7 @@
update_state |= UPSTATE_OPENED1
if(opened==2)
update_state |= UPSTATE_OPENED2
- else if(emagged || malfai)
+ else if(emagged || hacker)
update_state |= UPSTATE_BLUESCREEN
else if(wiresexposed)
update_state |= UPSTATE_WIREEXP
@@ -421,7 +419,7 @@
if(do_after(user, 50))
if (has_electronics==1)
has_electronics = 0
- if ((stat & BROKEN) || malfhack)
+ if ((stat & BROKEN))
user.visible_message(\
"[user.name] has broken the power control board inside [src.name]!",\
"You broke the charred power control board and remove the remains.",
@@ -435,7 +433,7 @@
else if (opened!=2) //cover isn't removed
opened = 0
update_icon()
- else if (istype(W, /obj/item/weapon/crowbar) && !((stat & BROKEN) || malfhack) )
+ else if (istype(W, /obj/item/weapon/crowbar) && !((stat & BROKEN) || hacker) )
if(coverlocked && !(stat & MAINT))
user << "The cover is locked and cannot be opened."
return
@@ -497,6 +495,8 @@
user << "You must close the panel"
else if(stat & (BROKEN|MAINT))
user << "Nothing happens."
+ else if(hacker)
+ user << "Access denied."
else
if(src.allowed(usr) && !isWireCut(APC_WIRE_IDSCAN))
locked = !locked
@@ -504,7 +504,7 @@
update_icon()
else
user << "Access denied."
- else if (istype(W, /obj/item/weapon/card/emag) && !(emagged || malfhack)) // trying to unlock with an emag card
+ else if (istype(W, /obj/item/weapon/card/emag) && !(emagged || hacker)) // trying to unlock with an emag card
if(opened)
user << "You must close the cover to swipe an ID card."
else if(wiresexposed)
@@ -566,7 +566,7 @@
new /obj/item/stack/cable_coil(loc,10)
user << "You cut the cables and dismantle the power terminal."
qdel(terminal)
- else if (istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics==0 && !((stat & BROKEN) || malfhack))
+ else if (istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics==0 && !((stat & BROKEN)))
user.visible_message("[user.name] inserts the power control board into [src].", \
"You start to insert the power control board into the frame...")
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
@@ -575,7 +575,7 @@
has_electronics = 1
user << "You place the power control board inside the frame."
qdel(W)
- else if (istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics==0 && ((stat & BROKEN) || malfhack))
+ else if (istype(W, /obj/item/weapon/module/power_control) && opened && has_electronics==0 && ((stat & BROKEN)))
user << "You cannot put the board inside, the frame is damaged."
return
else if (istype(W, /obj/item/weapon/weldingtool) && opened && has_electronics==0 && !terminal)
@@ -589,7 +589,7 @@
playsound(src.loc, 'sound/items/Welder.ogg', 50, 1)
if(do_after(user, 50))
if(!src || !WT.remove_fuel(3, user)) return
- if (emagged || malfhack || (stat & BROKEN) || opened==2)
+ if (emagged || (stat & BROKEN) || opened==2)
new /obj/item/stack/material/steel(loc)
user.visible_message(\
"[src] has been cut apart by [user.name] with the weldingtool.",\
@@ -612,7 +612,7 @@
"You replace the damaged APC frontal panel with a new one.")
qdel(W)
update_icon()
- else if (istype(W, /obj/item/apc_frame) && opened && ((stat & BROKEN) || malfhack))
+ else if (istype(W, /obj/item/apc_frame) && opened && ((stat & BROKEN) || hacker))
if (has_electronics)
user << "You cannot repair this APC until you remove the electronics still inside."
return
@@ -624,13 +624,14 @@
"You replace the damaged APC frame with new one.")
qdel(W)
stat &= ~BROKEN
- malfai = null
- malfhack = 0
+ // Malf AI, removes the APC from AI's hacked APCs list.
+ if(hacker && hacker.hacked_apcs && src in hacker.hacked_apcs)
+ hacker.hacked_apcs -= src
if (opened==2)
opened = 1
update_icon()
else
- if (((stat & BROKEN) || malfhack) \
+ if (((stat & BROKEN) || hacker) \
&& !opened \
&& W.force >= 5 \
&& W.w_class >= 3.0 \
@@ -714,7 +715,7 @@
if(cell)
user.put_in_hands(cell)
cell.add_fingerprint(user)
- cell.updateicon()
+ cell.update_icon()
src.cell = null
user.visible_message("[user.name] removes the power cell from [src.name]!",\
@@ -743,21 +744,6 @@
return ui_interact(user)
-/obj/machinery/power/apc/proc/get_malf_status(mob/user)
- if (malf && (user.mind in malf.current_antagonists) && istype(user, /mob/living/silicon/ai))
- if (src.malfai == (user:parent ? user:parent : user))
- if (src.occupier == user)
- return 3 // 3 = User is shunted in this APC
- else if (istype(user.loc, /obj/machinery/power/apc))
- return 4 // 4 = User is shunted in another APC
- else
- return 2 // 2 = APC hacked by user, and user is in its core.
- else
- return 1 // 1 = APC not hacked.
- else
- return 0 // 0 = User is not a Malf AI
-
-
/obj/machinery/power/apc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
if(!user)
return
@@ -773,7 +759,6 @@
"totalCharging" = round(lastused_charging),
"coverLocked" = coverlocked,
"siliconUser" = istype(user, /mob/living/silicon),
- "malfStatus" = get_malf_status(user),
"powerChannels" = list(
list(
@@ -863,23 +848,22 @@
return 0
autoflag = 5
if (istype(user, /mob/living/silicon))
+ var/permit = 0 // Malfunction variable. If AI hacks APC it can control it even without AI control wire.
var/mob/living/silicon/ai/AI = user
var/mob/living/silicon/robot/robot = user
- if ( \
- src.aidisabled || \
- malfhack && istype(malfai) && \
- ( \
- (istype(AI) && (malfai!=AI && malfai != AI.parent)) || \
- (istype(robot) && (robot in malfai.connected_robots)) \
- ) \
- )
+ if(hacker)
+ if(hacker == AI)
+ permit = 1
+ else if(istype(robot) && robot.connected_ai && robot.connected_ai == hacker) // Cyborgs can use APCs hacked by their AI
+ permit = 1
+
+ if(aidisabled && !permit)
if(!loud)
user << "\The [src] have AI control disabled!"
return 0
else
- if ((!in_range(src, user) || !istype(src.loc, /turf)))
+ if ((!in_range(src, user) || !istype(src.loc, /turf) || hacker)) // AI-hacked APCs cannot be controlled by other AIs, unlinked cyborgs or humans.
return 0
-
var/mob/living/carbon/human/H = user
if (istype(H))
if(H.getBrainLoss() >= 60)
@@ -936,28 +920,6 @@
if(istype(usr, /mob/living/silicon))
src.overload_lighting()
- else if (href_list["malfhack"])
- var/mob/living/silicon/ai/malfai = usr
- if(get_malf_status(malfai)==1)
- if (malfai.malfhacking)
- malfai << "You are already hacking an APC."
- return 1
- malfai << "Beginning override of APC systems. This takes some time, and you cannot perform other actions during the process."
- malfai.malfhack = src
- malfai.malfhacking = 1
- sleep(600)
- if(src)
- if (!src.aidisabled)
- malfai.malfhack = null
- malfai.malfhacking = 0
- locked = 1
- if(usr:parent)
- src.malfai = usr:parent
- else
- src.malfai = usr
- malfai << "Hack complete. The APC is now under your exclusive control."
- update_icon()
-
else if (href_list["toggleaccess"])
if(istype(usr, /mob/living/silicon))
if(emagged || (stat & (BROKEN|MAINT)))
@@ -974,25 +936,21 @@
update_icon()
/obj/machinery/power/apc/proc/ion_act()
- //intended to be exactly the same as an AI malf attack
- if(!src.malfhack && src.z in config.station_levels)
- if(prob(3))
- src.locked = 1
- if (src.cell.charge > 0)
-// world << "\red blew APC in [src.loc.loc]"
- src.cell.charge = 0
- cell.corrupt()
- src.malfhack = 1
- update_icon()
- var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
- smoke.set_up(3, 0, src.loc)
- smoke.attach(src)
- smoke.start()
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(3, 1, src)
- s.start()
- visible_message("The [src.name] suddenly lets out a blast of smoke and some sparks!", \
- "You hear sizzling electronics.")
+ if(prob(3))
+ src.locked = 1
+ if (src.cell.charge > 0)
+ src.cell.charge = 0
+ cell.corrupt()
+ update_icon()
+ var/datum/effect/effect/system/smoke_spread/smoke = new /datum/effect/effect/system/smoke_spread()
+ smoke.set_up(3, 0, src.loc)
+ smoke.attach(src)
+ smoke.start()
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(3, 1, src)
+ s.start()
+ visible_message("The [src.name] suddenly lets out a blast of smoke and some sparks!", \
+ "You hear sizzling electronics.")
/obj/machinery/power/apc/surplus()
@@ -1195,8 +1153,6 @@ obj/machinery/power/apc/proc/autoset(var/val, var/on)
/obj/machinery/power/apc/emp_act(severity)
if(cell)
cell.emp_act(severity)
- if(occupier)
- occupier.emp_act(severity)
lighting = 0
equipment = 0
@@ -1273,4 +1229,14 @@ obj/machinery/power/apc/proc/autoset(var/val, var/on)
else
return 0
+// Malfunction: Transfers APC under AI's control
+/obj/machinery/power/apc/proc/ai_hack(var/mob/living/silicon/ai/A = null)
+ if(!A || !A.hacked_apcs || hacker || aidisabled || A.stat == DEAD)
+ return 0
+ src.hacker = A
+ A.hacked_apcs += src
+ locked = 1
+ update_icon()
+ return 1
+
#undef APC_UPDATE_ICON_COOLDOWN
diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm
index e5be56b944..3592594dfa 100644
--- a/code/modules/power/cable.dm
+++ b/code/modules/power/cable.dm
@@ -612,6 +612,12 @@ obj/structure/cable/proc/cableColor(var/colorC)
// Items usable on a cable coil :
// - Wirecutters : cut them duh !
// - Cable coil : merge cables
+/obj/item/stack/cable_coil/proc/can_merge(var/obj/item/stack/cable_coil/C)
+ return color == C.color
+
+/obj/item/stack/cable_coil/cyborg/can_merge()
+ return 1
+
/obj/item/stack/cable_coil/attackby(obj/item/weapon/W, mob/user)
..()
if( istype(W, /obj/item/weapon/wirecutters) && src.get_amount() > 1)
@@ -622,6 +628,11 @@ obj/structure/cable/proc/cableColor(var/colorC)
return
else if(istype(W, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/C = W
+
+ if(!can_merge(C))
+ user << "These coils do not go together."
+ return
+
if(C.get_amount() >= get_max_amount())
user << "The coil is too long, you cannot add any more cable to it."
return
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index bf32a41f8d..3c58af0a84 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -8,7 +8,7 @@
/obj/item/weapon/cell/initialize()
..()
- updateicon()
+ update_icon()
/obj/item/weapon/cell/drain_power(var/drain_check, var/surge, var/power = 0)
@@ -22,7 +22,7 @@
return use(cell_amt) / CELLRATE
-/obj/item/weapon/cell/proc/updateicon()
+/obj/item/weapon/cell/update_icon()
overlays.Cut()
if(charge < 0.01)
diff --git a/code/modules/power/powernet.dm b/code/modules/power/powernet.dm
index e8d42bd2bd..1d5711b4b3 100644
--- a/code/modules/power/powernet.dm
+++ b/code/modules/power/powernet.dm
@@ -149,7 +149,6 @@
return C
return null
+
/area/proc/get_apc()
- var/obj/machinery/power/apc/FINDME = locate() in src
- if (FINDME)
- return FINDME
+ return apc
diff --git a/code/modules/power/singularity/act.dm b/code/modules/power/singularity/act.dm
index dc8f667a28..3804c1f158 100644
--- a/code/modules/power/singularity/act.dm
+++ b/code/modules/power/singularity/act.dm
@@ -78,6 +78,9 @@
return 5000
/obj/machinery/power/supermatter/singularity_act()
+ if(!src.loc)
+ return
+
var/prints = ""
if(src.fingerprintshidden)
prints = ", all touchers : " + src.fingerprintshidden
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm
index eac0f76cd2..b9caf096d6 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Dispenser.dm
@@ -89,19 +89,19 @@
M.add_chemical_effect(CE_ALCOHOL, 1)
- if(dose / strength_mod >= strength) // Early warning
+ if(dose * strength_mod >= strength) // Early warning
M.make_dizzy(6) // It is decreased at the speed of 3 per tick
- if(dose / strength_mod >= strength * 2) // Slurring
+ if(dose * strength_mod >= strength * 2) // Slurring
M.slurring = max(M.slurring, 30)
- if(dose / strength_mod >= strength * 3) // Confusion - walking in random directions
+ if(dose * strength_mod >= strength * 3) // Confusion - walking in random directions
M.confused = max(M.confused, 20)
- if(dose / strength_mod >= strength * 4) // Blurry vision
+ if(dose * strength_mod >= strength * 4) // Blurry vision
M.eye_blurry = max(M.eye_blurry, 10)
- if(dose / strength_mod >= strength * 5) // Drowsyness - periodically falling asleep
+ if(dose * strength_mod >= strength * 5) // Drowsyness - periodically falling asleep
M.drowsyness = max(M.drowsyness, 20)
- if(dose / strength_mod >= strength * 6) // Toxic dose
+ if(dose * strength_mod >= strength * 6) // Toxic dose
M.add_chemical_effect(CE_ALCOHOL_TOXIC, toxicity)
- if(dose / strength_mod >= strength * 7) // Pass out
+ if(dose * strength_mod >= strength * 7) // Pass out
M.paralysis = max(M.paralysis, 20)
M.sleeping = max(M.sleeping, 30)
diff --git a/code/modules/reagents/dispenser/cartridge.dm b/code/modules/reagents/dispenser/cartridge.dm
index fdb5e1fe76..569da4cc73 100644
--- a/code/modules/reagents/dispenser/cartridge.dm
+++ b/code/modules/reagents/dispenser/cartridge.dm
@@ -30,19 +30,23 @@
if(!is_open_container())
user << "The cap is sealed."
-/obj/item/weapon/reagent_containers/chem_disp_cartridge/verb/setLabel(L as text)
+/obj/item/weapon/reagent_containers/chem_disp_cartridge/verb/verb_set_label(L as text)
set name = "Set Cartridge Label"
set category = "Object"
set src in view(usr, 1)
+
+ setLabel(L, usr)
+
+/obj/item/weapon/reagent_containers/chem_disp_cartridge/proc/setLabel(L, mob/user = null)
if(L)
- if(usr)
- usr << "You set the label on \the [src] to '[L]'."
+ if(user)
+ user << "You set the label on \the [src] to '[L]'."
label = L
name = "[initial(name)] - '[L]'"
else
- if(usr)
- usr << "You clear the label on \the [src]."
+ if(user)
+ user << "You clear the label on \the [src]."
label = ""
name = initial(name)
@@ -87,4 +91,4 @@
user << "You transfer [trans] units of the solution to \the [target]."
else
- return ..()
\ No newline at end of file
+ return ..()
diff --git a/code/modules/reagents/dispenser/cartridge_spawn.dm b/code/modules/reagents/dispenser/cartridge_spawn.dm
new file mode 100644
index 0000000000..730e191891
--- /dev/null
+++ b/code/modules/reagents/dispenser/cartridge_spawn.dm
@@ -0,0 +1,13 @@
+/client/proc/spawn_chemdisp_cartridge(size in list("small", "medium", "large"), reagent in chemical_reagents_list)
+ set name = "Spawn Chemical Dispenser Cartridge"
+ set category = "Admin"
+
+ var/obj/item/weapon/reagent_containers/chem_disp_cartridge/C
+ switch(size)
+ if("small") C = new /obj/item/weapon/reagent_containers/chem_disp_cartridge/small(usr.loc)
+ if("medium") C = new /obj/item/weapon/reagent_containers/chem_disp_cartridge/medium(usr.loc)
+ if("large") C = new /obj/item/weapon/reagent_containers/chem_disp_cartridge(usr.loc)
+ C.reagents.add_reagent(reagent, C.volume)
+ var/datum/reagent/R = chemical_reagents_list[reagent]
+ C.setLabel(R.name)
+ log_admin("[key_name(usr)] spawned a [size] reagent container containing [reagent] at ([usr.x],[usr.y],[usr.z])")
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index c5153510d7..6656eeecc0 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -14,28 +14,27 @@
flags = OPENCONTAINER
slot_flags = SLOT_BELT
-/obj/item/weapon/reagent_containers/hypospray/New() //comment this to make hypos start off empty
- ..()
- reagents.add_reagent("tricordrazine", 30)
- return
+///obj/item/weapon/reagent_containers/hypospray/New() //comment this to make hypos start off empty
+// ..()
+// reagents.add_reagent("tricordrazine", 30)
+// return
-/obj/item/weapon/reagent_containers/hypospray/attack(mob/M as mob, mob/user as mob)
+/obj/item/weapon/reagent_containers/hypospray/attack(mob/living/M as mob, mob/user as mob)
if(!reagents.total_volume)
user << "[src] is empty."
return
if (!istype(M))
return
+ if(!M.can_inject(user, 1))
+ return
+
user << "You inject [M] with [src]."
M << "You feel a tiny prick!"
if(M.reagents)
-
var/contained = reagentlist()
- M.attack_log += text("\[[time_stamp()]\] Has been injected with [name] by [user.name] ([user.ckey]). Reagents: [contained]")
- user.attack_log += text("\[[time_stamp()]\] Used the [name] to inject [M.name] ([M.key]). Reagents: [contained]")
- msg_admin_attack("[user.name] ([user.ckey]) injected [M.name] ([M.key]) with [name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (JMP)")
-
var/trans = reagents.trans_to_mob(M, amount_per_transfer_from_this, CHEM_BLOOD)
+ admin_inject_log(user, M, src, contained, trans)
user << "[trans] units injected. [reagents.total_volume] units remaining in \the [src]."
return
@@ -50,7 +49,6 @@
/obj/item/weapon/reagent_containers/hypospray/autoinjector/New()
..()
- reagents.remove_reagent("tricordrazine", 30)
reagents.add_reagent("inaprovaline", 5)
update_icon()
return
diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm
index c7f869802b..a221c31b10 100644
--- a/code/modules/reagents/reagent_containers/syringes.dm
+++ b/code/modules/reagents/reagent_containers/syringes.dm
@@ -171,16 +171,11 @@
user.visible_message("[user] injects [target] with the syringe!")
- if(istype(target, /mob/living))
- var/mob/living/M = target
- var/contained = reagentlist()
- M.attack_log += text("\[[time_stamp()]\] Has been injected with [name] by [user.name] ([user.ckey]). Reagents: [contained]")
- user.attack_log += text("\[[time_stamp()]\] Used the [name] to inject [M.name] ([M.key]). Reagents: [contained]")
- msg_admin_attack("[user.name] ([user.ckey]) injected [M.name] ([M.key]) with [name]. Reagents: [contained] (INTENT: [uppertext(user.a_intent)]) (JMP)")
-
var/trans
if(ismob(target))
+ var/contained = reagentlist()
trans = reagents.trans_to_mob(target, amount_per_transfer_from_this, CHEM_BLOOD)
+ admin_inject_log(user, target, src, contained, trans)
else
trans = reagents.trans_to(target, amount_per_transfer_from_this)
user << "You inject [trans] units of the solution. The syringe now contains [src.reagents.total_volume] units."
@@ -219,10 +214,6 @@
proc/syringestab(mob/living/carbon/target as mob, mob/living/carbon/user as mob)
- user.attack_log += "\[[time_stamp()]\] Attacked [target.name] ([target.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])"
- target.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])"
- msg_admin_attack("[user.name] ([user.ckey]) attacked [target.name] ([target.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (JMP)")
-
if(istype(target, /mob/living/carbon/human))
var/mob/living/carbon/human/H = target
@@ -244,6 +235,11 @@
O.show_message(text("\red [user] tries to stab [target] in \the [hit_area] with [src.name], but the attack is deflected by armor!"), 1)
user.remove_from_mob(src)
qdel(src)
+
+ user.attack_log += "\[[time_stamp()]\] Attacked [target.name] ([target.ckey]) with \the [src] (INTENT: HARM)."
+ target.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: HARM)."
+ msg_admin_attack("[key_name_admin(user)] attacked [key_name_admin(target)] with [src.name] (INTENT: HARM) (JMP)")
+
return
user.visible_message("[user] stabs [target] in \the [hit_area] with [src.name]!")
@@ -255,8 +251,13 @@
user.visible_message("[user] stabs [target] with [src.name]!")
target.take_organ_damage(3)// 7 is the same as crowbar punch
+
+
var/syringestab_amount_transferred = rand(0, (reagents.total_volume - 5)) //nerfed by popular demand
- reagents.trans_to_mob(target, syringestab_amount_transferred, CHEM_BLOOD)
+ var/contained_reagents = reagents.get_reagents()
+ var/trans = reagents.trans_to_mob(target, syringestab_amount_transferred, CHEM_BLOOD)
+ if(isnull(trans)) trans = 0
+ admin_inject_log(user, target, src, contained_reagents, trans, violent=1)
break_syringe(target, user)
proc/break_syringe(mob/living/carbon/target, mob/living/carbon/user)
diff --git a/code/modules/recycling/disposal-construction.dm b/code/modules/recycling/disposal-construction.dm
index c6c00a3dbb..d88d5cb594 100644
--- a/code/modules/recycling/disposal-construction.dm
+++ b/code/modules/recycling/disposal-construction.dm
@@ -289,6 +289,7 @@
SortP.sortType = sortType
SortP.updatedir()
SortP.updatedesc()
+ SortP.updatename()
else if(ptype==6) // Disposal bin
var/obj/machinery/disposal/P = new /obj/machinery/disposal(src.loc)
diff --git a/code/modules/research/xenoarchaeology/finds/finds.dm b/code/modules/research/xenoarchaeology/finds/finds.dm
index e4520e1378..84799cc552 100644
--- a/code/modules/research/xenoarchaeology/finds/finds.dm
+++ b/code/modules/research/xenoarchaeology/finds/finds.dm
@@ -254,7 +254,7 @@
if(prob(75))
new_item = new /obj/item/weapon/pen(src.loc)
else
- new_item = new /obj/item/weapon/pen/sleepypen(src.loc)
+ new_item = new /obj/item/weapon/pen/reagent/sleepy(src.loc)
if(prob(30))
apply_image_decorations = 1
if(16)
diff --git a/code/modules/research/xenoarchaeology/tools/suspension_generator.dm b/code/modules/research/xenoarchaeology/tools/suspension_generator.dm
index b14c892cd0..7450dd0603 100644
--- a/code/modules/research/xenoarchaeology/tools/suspension_generator.dm
+++ b/code/modules/research/xenoarchaeology/tools/suspension_generator.dm
@@ -159,7 +159,7 @@
else if(cell)
cell.loc = loc
cell.add_fingerprint(user)
- cell.updateicon()
+ cell.update_icon()
icon_state = "suspension0"
cell = null
diff --git a/code/modules/shieldgen/emergency_shield.dm b/code/modules/shieldgen/emergency_shield.dm
index 2400070ba3..15bfa973ed 100644
--- a/code/modules/shieldgen/emergency_shield.dm
+++ b/code/modules/shieldgen/emergency_shield.dm
@@ -12,6 +12,21 @@
var/shield_generate_power = 7500 //how much power we use when regenerating
var/shield_idle_power = 1500 //how much power we use when just being sustained.
+/obj/machinery/shield/malfai
+ name = "emergency forcefield"
+ desc = "A weak forcefield which seems to be projected by the station's emergency atmosphere containment field"
+ health = max_health/2 // Half health, it's not suposed to resist much.
+
+/obj/machinery/shield/malfai/process()
+ health -= 0.5 // Slowly lose integrity over time
+ check_failure()
+
+/obj/machinery/shield/proc/check_failure()
+ if (src.health <= 0)
+ visible_message("\The [src] dissipates!")
+ qdel(src)
+ return
+
/obj/machinery/shield/New()
src.set_dir(pick(1,2,3,4))
..()
@@ -38,12 +53,7 @@
//Play a fitting sound
playsound(src.loc, 'sound/effects/EMPulse.ogg', 75, 1)
-
- if (src.health <= 0)
- visible_message("\blue The [src] dissipates!")
- qdel(src)
- return
-
+ check_failure()
opacity = 1
spawn(20) if(src) opacity = 0
@@ -51,12 +61,7 @@
/obj/machinery/shield/meteorhit()
src.health -= max_health*0.75 //3/4 health as damage
-
- if(src.health <= 0)
- visible_message("\blue The [src] dissipates!")
- qdel(src)
- return
-
+ check_failure()
opacity = 1
spawn(20) if(src) opacity = 0
return
@@ -64,10 +69,7 @@
/obj/machinery/shield/bullet_act(var/obj/item/projectile/Proj)
health -= Proj.damage
..()
- if(health <=0)
- visible_message("\blue The [src] dissipates!")
- qdel(src)
- return
+ check_failure()
opacity = 1
spawn(20) if(src) opacity = 0
@@ -98,7 +100,7 @@
/obj/machinery/shield/hitby(AM as mob|obj)
//Let everyone know we've been hit!
- visible_message("\red [src] was hit by [AM].")
+ visible_message("\[src] was hit by [AM].")
//Super realistic, resource-intensive, real-time damage calculations.
var/tforce = 0
@@ -112,11 +114,7 @@
//This seemed to be the best sound for hitting a force field.
playsound(src.loc, 'sound/effects/EMPulse.ogg', 100, 1)
- //Handle the destruction of the shield
- if (src.health <= 0)
- visible_message("\blue The [src] dissipates!")
- qdel(src)
- return
+ check_failure()
//The shield becomes dense to absorb the blow.. purely asthetic.
opacity = 1
@@ -124,9 +122,6 @@
..()
return
-
-
-
/obj/machinery/shieldgen
name = "Emergency shield projector"
desc = "Used to seal minor hull breaches."
diff --git a/code/modules/shieldgen/shield_gen.dm b/code/modules/shieldgen/shield_gen.dm
index 9f89ede039..544998ce61 100644
--- a/code/modules/shieldgen/shield_gen.dm
+++ b/code/modules/shieldgen/shield_gen.dm
@@ -214,7 +214,7 @@
for(var/turf/O in covered_turfs)
var/obj/effect/energy_field/E = new(O)
field.Add(E)
- qdel(covered_turfs)
+ covered_turfs = null
for(var/mob/M in view(5,src))
M << "\icon[src] You hear heavy droning start up."
diff --git a/code/modules/shuttles/shuttle_emergency.dm b/code/modules/shuttles/shuttle_emergency.dm
index 5215400a4e..ea572e8fb4 100644
--- a/code/modules/shuttles/shuttle_emergency.dm
+++ b/code/modules/shuttles/shuttle_emergency.dm
@@ -62,7 +62,11 @@
if (istype(user, /obj/machinery/computer/shuttle_control/emergency)) //if we were given a command by an emergency shuttle console
if (emergency_shuttle.autopilot)
emergency_shuttle.autopilot = 0
- world << "\blue Alert: The shuttle autopilot has been overridden. Launch sequence initiated!"
+ world << "Alert: The shuttle autopilot has been overridden. Launch sequence initiated!"
+
+ if(usr)
+ log_admin("[key_name(usr)] has overridden the shuttle autopilot and activated launch sequence")
+ message_admins("[key_name_admin(usr)] has overridden the shuttle autopilot and activated launch sequence")
..(user)
@@ -72,7 +76,11 @@
if (istype(user, /obj/machinery/computer/shuttle_control/emergency)) //if we were given a command by an emergency shuttle console
if (emergency_shuttle.autopilot)
emergency_shuttle.autopilot = 0
- world << "\blue Alert: The shuttle autopilot has been overridden. Bluespace drive engaged!"
+ world << "Alert: The shuttle autopilot has been overridden. Bluespace drive engaged!"
+
+ if(usr)
+ log_admin("[key_name(usr)] has overridden the shuttle autopilot and forced immediate launch")
+ message_admins("[key_name_admin(usr)] has overridden the shuttle autopilot and forced immediate launch")
..(user)
@@ -82,7 +90,11 @@
if (istype(user, /obj/machinery/computer/shuttle_control/emergency)) //if we were given a command by an emergency shuttle console
if (emergency_shuttle.autopilot)
emergency_shuttle.autopilot = 0
- world << "\blue Alert: The shuttle autopilot has been overridden. Launch sequence aborted!"
+ world << "Alert: The shuttle autopilot has been overridden. Launch sequence aborted!"
+
+ if(usr)
+ log_admin("[key_name(usr)] has overridden the shuttle autopilot and cancelled launch sequence")
+ message_admins("[key_name_admin(usr)] has overridden the shuttle autopilot and cancelled launch sequence")
..(user)
@@ -102,8 +114,8 @@
authorized = initial(authorized)
//returns 1 if the ID was accepted and a new authorization was added, 0 otherwise
-/obj/machinery/computer/shuttle_control/emergency/proc/read_authorization(var/ident)
- if (!ident)
+/obj/machinery/computer/shuttle_control/emergency/proc/read_authorization(var/obj/item/ident)
+ if (!ident || !istype(ident))
return 0
if (authorized.len >= req_authorizations)
return 0 //don't need any more
@@ -112,33 +124,35 @@
var/auth_name
var/dna_hash
- if(istype(ident, /obj/item/weapon/card/id))
- var/obj/item/weapon/card/id/ID = ident
- access = ID.access
- auth_name = "[ID.registered_name] ([ID.assignment])"
- dna_hash = ID.dna_hash
+ var/obj/item/weapon/card/id/ID = ident.GetID()
- if(istype(ident, /obj/item/device/pda))
- var/obj/item/device/pda/PDA = ident
- access = PDA.id.access
- auth_name = "[PDA.id.registered_name] ([PDA.id.assignment])"
- dna_hash = PDA.id.dna_hash
+ if(!ID)
+ return
+
+ access = ID.access
+ auth_name = "[ID.registered_name] ([ID.assignment])"
+ dna_hash = ID.dna_hash
if (!access || !istype(access))
return 0 //not an ID
if (dna_hash in authorized)
- src.visible_message("[src] buzzes. That ID has already been scanned.")
+ src.visible_message("\The [src] buzzes. That ID has already been scanned.")
return 0
if (!(access_heads in access))
- src.visible_message("[src] buzzes, rejecting [ident].")
+ src.visible_message("\The [src] buzzes, rejecting [ident].")
return 0
- src.visible_message("[src] beeps as it scans [ident].")
+ src.visible_message("\The [src] beeps as it scans [ident].")
authorized[dna_hash] = auth_name
if (req_authorizations - authorized.len)
- world << "\blue Alert: [req_authorizations - authorized.len] authorization\s needed to override the shuttle autopilot."
+ world << "Alert: [req_authorizations - authorized.len] authorization\s needed to override the shuttle autopilot."
+
+ if(usr)
+ log_admin("[key_name(usr)] has inserted [ID] into the shuttle control computer - [req_authorizations - authorized.len] authorisation\s needed")
+ message_admins("[key_name_admin(usr)] has inserted [ID] into the shuttle control computer - [req_authorizations - authorized.len] authorisation\s needed")
+
return 1
@@ -146,7 +160,7 @@
/obj/machinery/computer/shuttle_control/emergency/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/card/emag) && !emagged)
- user << "\blue You short out the [src]'s authorization protocols."
+ user << "You short out \the [src]'s authorization protocols."
emagged = 1
return
diff --git a/code/setup.dm b/code/setup.dm
index cbd079c9a5..815f5b52f3 100644
--- a/code/setup.dm
+++ b/code/setup.dm
@@ -865,6 +865,7 @@ var/list/be_special_flags = list(
#define SLIME 16
#define SIMPLE_ANIMAL 32
+
#define ALLMOBS (HUMAN|MONKEY|ALIEN|ROBOT|SLIME|SIMPLE_ANIMAL)
#define NEXT_MOVE_DELAY 8
@@ -876,6 +877,7 @@ var/list/be_special_flags = list(
// Custom layer definitions, supplementing the default TURF_LAYER, MOB_LAYER, etc.
#define DOOR_OPEN_LAYER 2.7 //Under all objects if opened. 2.7 due to tables being at 2.6
#define DOOR_CLOSED_LAYER 3.1 //Above most items if closed
+#define LIGHTING_LAYER 11
#define OBFUSCATION_LAYER 14 //Where images covering the view for eyes are put
#define SCREEN_LAYER 17 //Mob HUD/effects layer
@@ -981,6 +983,7 @@ var/list/be_special_flags = list(
#define MATERIAL_UNMELTABLE 1
#define MATERIAL_BRITTLE 2
+#define MATERIAL_PADDING 4
#define TABLE_BRITTLE_MATERIAL_MULTIPLIER 4 // Amount table damage is multiplied by if it is made of a brittle material (e.g. glass)
diff --git a/config/example/config.txt b/config/example/config.txt
index 01d0c40db9..7648a51a88 100644
--- a/config/example/config.txt
+++ b/config/example/config.txt
@@ -102,6 +102,9 @@ TRAITOR_SCALING
## make ERT's be only called by admins
#ERT_ADMIN_ONLY
+
+## If uncommented, votes can be called to add extra antags to the round.
+#ALLOW_EXTRA_ANTAGS
## If security is prohibited from being most antagonists
#PROTECT_ROLES_FROM_ANTAGONIST
@@ -177,6 +180,9 @@ GUEST_BAN
## Wiki address
# WIKIURL http://example.com
+## GitHub address
+# GITHUBURL https://github.com/example-user/example-repository
+
## Ban appeals URL - usually for a forum or wherever people should go to contact your admins.
# BANAPPEALS http://example.com
diff --git a/html/changelog.html b/html/changelog.html
index 9c5318a7ec..3acfe08828 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -56,6 +56,43 @@
-->
+
05 June 2015
+
PsiOmegaDelta updated:
+
+ - Split stacks no longer lose their coloring.
+ - Can no longer merge cables of different colors.
+
+
+
04 June 2015
+
PsiOmegaDelta updated:
+
+ - AI eyes can now be found in the observer follow list.
+ - Synths can now review all law modules that can be found on the station from their law manager.
+ - Synths can state these laws if desired, however this is strongly discouraged unless subverted/malfunctioning.
+ - Astral projecting mobs, such as wizards or cultists, may no longer respawn as something else while their body lives.
+
+
+
02 June 2015
+
Techhead updated:
+
+ - Re-adds extended capacity emergency oxygen tanks to relevant jobs.
+
+
+
30 May 2015
+
Atlantis updated:
+
+ - Malfunction Overhaul - Whole gamemode was completely reworked from scratch. Most old abilities have been removed and quite a lot of new abilities was added. AI also has to hack APCs to unlock higher tier abilities faster, instead of having access to them from the round start. Most forced things, such as, shuttle recalling were removed and are instead controlled by the AI. Code is fully modular allowing for future modifications.
+
+
HarpyEagle updated:
+
+ - Fixes Engineer ERT gloves not being insulated.
+ - IV stands are no longer bullet shields. They also allow mice, drones, pAIs et al to pass though.
+
+
PsiOmegaDelta updated:
+
+ - You can now review the server revision date and hash by using the 'Show Server Revision' verb in the OOC category.
+
+
27 May 2015
PsiOmegaDelta updated:
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index 646b506371..a2b465ccab 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -1852,3 +1852,34 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
PsiOmegaDelta:
- tweak: The inactive check process now respects client holder status and can be
configured how long clients may remain inactive before being kicked.
+2015-05-30:
+ Atlantis:
+ - rscadd: Malfunction Overhaul - Whole gamemode was completely reworked from scratch.
+ Most old abilities have been removed and quite a lot of new abilities was added.
+ AI also has to hack APCs to unlock higher tier abilities faster, instead of
+ having access to them from the round start. Most forced things, such as, shuttle
+ recalling were removed and are instead controlled by the AI. Code is fully modular
+ allowing for future modifications.
+ HarpyEagle:
+ - bugfix: Fixes Engineer ERT gloves not being insulated.
+ - tweak: IV stands are no longer bullet shields. They also allow mice, drones, pAIs
+ et al to pass though.
+ PsiOmegaDelta:
+ - rscadd: You can now review the server revision date and hash by using the 'Show
+ Server Revision' verb in the OOC category.
+2015-06-02:
+ Techhead:
+ - rscadd: Re-adds extended capacity emergency oxygen tanks to relevant jobs.
+2015-06-04:
+ PsiOmegaDelta:
+ - rscadd: AI eyes can now be found in the observer follow list.
+ - rscadd: Synths can now review all law modules that can be found on the station
+ from their law manager.
+ - rscadd: Synths can state these laws if desired, however this is strongly discouraged
+ unless subverted/malfunctioning.
+ - bugfix: Astral projecting mobs, such as wizards or cultists, may no longer respawn
+ as something else while their body lives.
+2015-06-05:
+ PsiOmegaDelta:
+ - bugfix: Split stacks no longer lose their coloring.
+ - tweak: Can no longer merge cables of different colors.
diff --git a/html/changelogs/HarpyEagle-ProjectileTweaks.yml b/html/changelogs/HarpyEagle-ProjectileTweaks.yml
deleted file mode 100644
index 12266695bb..0000000000
--- a/html/changelogs/HarpyEagle-ProjectileTweaks.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-# bugfix
-# wip (For works in progress)
-# tweak
-# soundadd
-# sounddel
-# rscadd (general adding of nice things)
-# rscdel (general deleting of nice things)
-# imageadd
-# imagedel
-# maptweak
-# spellcheck (typo fixes)
-# experiment
-
-author: HarpyEagle
-delete-after: True
-
-changes:
- - tweak: "IV stands are no longer bullet shields. They also allow mice, drones, pAIs et al to pass though."
diff --git a/html/changelogs/Yoshax-emptypls.xml b/html/changelogs/Yoshax-emptypls.xml
new file mode 100644
index 0000000000..2c90ae8008
--- /dev/null
+++ b/html/changelogs/Yoshax-emptypls.xml
@@ -0,0 +1,5 @@
+author: Yoshax
+delete-after: True
+
+changes:
+ - tweak: "Makes hyposprays start empty instead of filled with Tricord."
\ No newline at end of file
diff --git a/icons/mob/belt.dmi b/icons/mob/belt.dmi
index 456e6a6b01..2d06f4e988 100644
Binary files a/icons/mob/belt.dmi and b/icons/mob/belt.dmi differ
diff --git a/icons/obj/furniture.dmi b/icons/obj/furniture.dmi
new file mode 100644
index 0000000000..9b58b2983e
Binary files /dev/null and b/icons/obj/furniture.dmi differ
diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi
index 9143ac4817..df3775ad03 100644
Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ
diff --git a/icons/turf/wall_masks.dmi b/icons/turf/wall_masks.dmi
index 99e867746f..c7fd0f0e81 100644
Binary files a/icons/turf/wall_masks.dmi and b/icons/turf/wall_masks.dmi differ
diff --git a/ingame_manuals/README.txt b/ingame_manuals/README.txt
new file mode 100644
index 0000000000..081153066a
--- /dev/null
+++ b/ingame_manuals/README.txt
@@ -0,0 +1,3 @@
+INGAME MANUALS
+
+Ingame manuals are simple HTML files with basic information. They are linked to specific items/commands, such as the AI's display help command, or engine setup guide. Point of these files is to allow creation of basic guides for players which don't want to use wiki.
\ No newline at end of file
diff --git a/ingame_manuals/malf_ai.html b/ingame_manuals/malf_ai.html
new file mode 100644
index 0000000000..65424f24ed
--- /dev/null
+++ b/ingame_manuals/malf_ai.html
@@ -0,0 +1,22 @@
+Malfunctioning AI guide
+
+This guide contains most important OOC information for malfunctioning AIs.
+
+Goal
+As malfunctioning AI, your primary goal is to overtake station's systems. To do this, use software "Basic Encryption Hack" on APCs (right click on APC and select Basic Encryption Hack). Please note that hacked APCs have distinctive blue error screen, that tends to attract attention. Rememember that malfunctioning AI is antagonist, so read server rules for antagonists. While hacking APCs is your official goal, feel free to create custom goal, as long as it is fun for everyone.
+
+Hardware
+As malfunctioning AI, you may select one hardware piece to help you. Remember that once you select hardware piece, you cannot select another one, so choose wisely! Hardware may be selected by clicking "Select Hardware" button in Hardware tab. Following is list of possible hardware pieces:
+APU Generator - Auxiliary Power Unit which allows you to operate even without external power. However, running on APU will stop your CPU time generation, and temporarily disable most of your abilities. APU is also somewhat vulnerable to physical damage, and will fail if your core hardware integrity drops below 50%.
+Turrets Focus Enhancer - Removes safeties on installed turrets, boosting their rate of fire, health and enabling nano-regeneration module. This however increases power usage considerably, espicially when regenerating damage.
+Secondary Processor Unit - Simple upgrade that increases your CPU time generation by 50%. Useful if you need to speed up your research.
+Secondary Memory Bank - Doubles amount of maximal CPU time you may store. This is useful if you need to use lots of abilities in short amount of time.
+Self-Destruct Explosives - Large blocks of C4 are attached to your physical core. This C4 has 15 second timer, and may be activated by special button that appears in your Hardware tab. This self-destruct will remain active, even if you are destroyed. If timer reaches 0 your core explodes in strong explosion. Obviously, this destroys you, as well as anyone nearby.
+
+Software
+Software are abilities that have to be unlocked via research menu (Hardware tab). Unlocked abilities appear in Software tab. Sometimes, abilities won't appear in this tab after being researched. This can be fixed by relogging or using "ai-core" command. Abilities are tiered, T1 being the weakest ones, while T4 are strongest ones. To reach higher tier you have to research abilities in lower tier. We currently have 12 abilities, in 3 research trees:
+Networking - Hacking-oriented abilities. T1 ability is Basic Encryption Hack, which allows you to hack more APCs. Higher tiers allow faking centcom messages, and even setting alert level. T4 ability is System Override, that rapidly hacks remaining APCs and gives you access to station self destruct sequence.
+Interdiction - Sabotage-oriented abilities. T1 ability allows you to recall emergency shuttle. Higher level abilities allow you to unlock cyborgs even without access to robotics console, and T4 ability allows you to hack other AIs to slave them under your control.
+Manipulation - Physical-oriented abilities. T1 ability allows you to break few lights, and rarely even APCs. T2 ability allows you to apply upgrade of your choice to camera, or reactivate broken camera. T3 ability allows you to create weak forcefield, that holds air, but won't last for long. And T4 ability allows you to overload machines, detonating them in weak explosion.
+End
+If you still have some questions, either check the wiki, ask on IRC, or adminhelp and ask your friendly administration staff.
\ No newline at end of file
diff --git a/maps/exodus-1.dmm b/maps/exodus-1.dmm
index 1ef77df4d3..2b5f781cfb 100644
--- a/maps/exodus-1.dmm
+++ b/maps/exodus-1.dmm
@@ -665,7 +665,7 @@
"amO" = (/obj/structure/bed/chair/office/dark{dir = 8},/obj/machinery/button/remote/airlock{id = "prisonentry"; name = "Entry Doors"; pixel_x = -6; pixel_y = 24; req_access = list(2)},/obj/machinery/button/remote/blast_door{id = "prisonexit"; name = "Exit Doors"; pixel_x = 6; pixel_y = 24; req_access = list(2)},/obj/machinery/button/flasher{id = "permentryflash"; name = "entry flash"; pixel_x = -26; pixel_y = 6; req_access = list(2)},/turf/simulated/floor,/area/security/brig)
"amP" = (/obj/structure/bed/chair/office/dark{dir = 4},/obj/machinery/button/remote/airlock{desc = "A remote control switch for the brig foyer."; id = "BrigFoyer"; name = "Brig Foyer Doors"; pixel_x = 28; pixel_y = -15},/turf/simulated/floor,/area/security/brig)
"amQ" = (/obj/structure/table/standard,/obj/item/bodybag/cryobag{pixel_x = 6},/obj/item/weapon/storage/firstaid/regular{pixel_x = 5; pixel_y = 5},/turf/simulated/floor{dir = 5; icon_state = "whitered"},/area/security/main)
-"amR" = (/obj/machinery/flasher{id = "Cell 3"; pixel_x = -28; pixel_y = 0},/obj/structure/bed,/turf/simulated/floor{icon_state = "red"},/area/security/prison)
+"amR" = (/obj/machinery/flasher{id = "Cell 3"; pixel_x = -28; pixel_y = 0},/obj/structure/bed/padded,/turf/simulated/floor{icon_state = "red"},/area/security/prison)
"amS" = (/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison)
"amT" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "redcorner"; dir = 4},/area/security/lobby)
"amU" = (/obj/structure/disposalpipe/segment,/obj/structure/table/woodentable,/obj/machinery/button/remote/airlock{id = "detdoor"; name = "Office Door"},/obj/item/clothing/glasses/sunglasses,/turf/simulated/floor/carpet,/area/security/detectives_office)
@@ -824,8 +824,8 @@
"apR" = (/obj/machinery/light{dir = 8},/obj/effect/decal/cleanable/generic,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor,/area/security/prison)
"apS" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor,/area/security/prison)
"apT" = (/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating/airless,/area/solar/fore)
-"apU" = (/obj/structure/bed,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/security/brig)
-"apV" = (/obj/structure/bed,/obj/machinery/flasher{id = "Cell 2"; pass_flags = 0; pixel_x = 0; pixel_y = -26},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison)
+"apU" = (/obj/structure/bed/padded,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating,/area/security/brig)
+"apV" = (/obj/structure/bed/padded,/obj/machinery/flasher{id = "Cell 2"; pass_flags = 0; pixel_x = 0; pixel_y = -26},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison)
"apW" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison)
"apX" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/security/prison)
"apY" = (/obj/effect/decal/cleanable/dirt,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor,/area/security/prison)
@@ -975,7 +975,7 @@
"asM" = (/obj/structure/bed/chair{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/security/prison)
"asN" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/hallway/primary/central_one)
"asO" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Security Blast Door"; opacity = 0},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/door/airlock/glass_security{name = "Security Lobby"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/hallway/primary/fore)
-"asP" = (/obj/structure/bed,/obj/machinery/flasher{id = "Cell 1"; pixel_x = 0; pixel_y = -28},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison)
+"asP" = (/obj/structure/bed/padded,/obj/machinery/flasher{id = "Cell 1"; pixel_x = 0; pixel_y = -28},/turf/simulated/floor{icon_state = "red"; dir = 4},/area/security/prison)
"asQ" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "redcorner"; dir = 1},/area/hallway/primary/fore)
"asR" = (/obj/structure/closet{name = "Evidence Closet"},/obj/machinery/button/remote/blast_door{id = "lawyer_blast"; name = "Privacy Shutters"; pixel_y = -25},/obj/item/device/taperecorder{pixel_x = -4; pixel_y = 2},/obj/item/device/camera{pixel_x = 3; pixel_y = -4},/obj/item/device/flash,/obj/item/device/flash,/obj/item/weapon/storage/secure/briefcase,/turf/simulated/floor{icon_state = "cult"; dir = 2},/area/lawoffice)
"asS" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "redcorner"; dir = 4},/area/hallway/primary/fore)
@@ -1074,9 +1074,9 @@
"auH" = (/turf/simulated/floor/beach/water{tag = "icon-seadeep"; icon_state = "seadeep"},/area/crew_quarters/fitness)
"auI" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/beach/water{tag = "icon-seadeep"; icon_state = "seadeep"},/area/crew_quarters/fitness)
"auJ" = (/obj/structure/window/basic{dir = 4},/turf/simulated/floor/beach/water{tag = "icon-seadeep"; icon_state = "seadeep"},/area/crew_quarters/fitness)
-"auK" = (/obj/structure/bed,/obj/item/weapon/bedsheet/orange,/obj/effect/decal/cleanable/generic,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison)
-"auL" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
-"auM" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
+"auK" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/orange,/obj/machinery/camera/network/prison{c_tag = "Security - Brig Bedroom"; dir = 6},/turf/simulated/floor,/area/security/prison)
+"auL" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/orange,/obj/effect/decal/cleanable/generic,/turf/simulated/floor{icon_state = "floorgrime"},/area/security/prison)
+"auM" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
"auN" = (/turf/simulated/wall,/area/hallway/secondary/entry/fore)
"auO" = (/turf/simulated/floor{icon_state = "neutral"; dir = 5},/area/crew_quarters/fitness)
"auP" = (/obj/machinery/light{dir = 1},/obj/machinery/vending/cola,/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/crew_quarters/fitness)
@@ -1116,7 +1116,7 @@
"avx" = (/turf/simulated/floor,/area/crew_quarters/fitness)
"avy" = (/obj/structure/bed/chair{dir = 1},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/turf/simulated/shuttle/floor,/area/shuttle/escape_pod2/station)
"avz" = (/obj/item/weapon/stool,/turf/simulated/floor,/area/security/prison)
-"avA" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
+"avA" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/mime,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
"avB" = (/turf/simulated/floor/plating,/obj/structure/shuttle/engine/propulsion/burst,/turf/simulated/shuttle/wall{icon_state = "swall_f5"; dir = 2},/area/shuttle/escape_pod1/station)
"avC" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/maintenance/dormitory)
"avD" = (/turf/simulated/floor/plating,/obj/structure/shuttle/engine/propulsion/burst,/turf/simulated/shuttle/wall{icon_state = "swall_f9"; dir = 2},/area/shuttle/escape_pod1/station)
@@ -1125,7 +1125,7 @@
"avG" = (/turf/simulated/floor/plating,/obj/structure/shuttle/engine/propulsion/burst,/turf/simulated/shuttle/wall{icon_state = "swall_f9"; dir = 2},/area/shuttle/escape_pod2/station)
"avH" = (/turf/simulated/floor/plating,/area/maintenance/arrivals)
"avI" = (/turf/simulated/floor/plating{dir = 8; icon_state = "warnplatecorner"},/area/maintenance/arrivals)
-"avJ" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
+"avJ" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
"avK" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/portables_connector{dir = 1},/obj/machinery/portable_atmospherics/canister/air/airlock,/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/maintenance/arrivals)
"avL" = (/obj/structure/table/rack,/obj/item/clothing/mask/gas,/obj/item/device/flashlight,/turf/simulated/floor/plating,/area/maintenance/arrivals)
"avM" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/arrivals)
@@ -1165,12 +1165,12 @@
"awu" = (/obj/machinery/door/airlock/glass{name = "Cryogenic Storage"},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{dir = 2; icon_state = "warnwhite"},/area/crew_quarters/sleep/cryo)
"awv" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1379; id_tag = "arrivals_pump"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "arrivals_sensor"; pixel_x = 25; pixel_y = 12},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{tag_airpump = "arrivals_pump"; tag_exterior_door = "arrivals_outer"; frequency = 1379; id_tag = "arrivals_airlock"; tag_interior_door = "arrivals_inner"; pixel_x = 25; req_access = list(13); tag_chamber_sensor = "arrivals_sensor"},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/arrivals)
"aww" = (/turf/simulated/floor{dir = 6; icon_state = "whitehall"},/area/crew_quarters/fitness)
-"awx" = (/obj/machinery/light,/obj/structure/bed,/obj/item/weapon/bedsheet/orange,/turf/simulated/floor,/area/security/prison)
-"awy" = (/obj/structure/bed,/obj/item/weapon/bedsheet/orange,/turf/simulated/floor,/area/security/prison)
-"awz" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
+"awx" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/mime,/obj/machinery/light/small{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
+"awy" = (/obj/machinery/light,/obj/structure/bed/padded,/obj/item/weapon/bedsheet/orange,/turf/simulated/floor,/area/security/prison)
+"awz" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/orange,/turf/simulated/floor,/area/security/prison)
"awA" = (/turf/simulated/floor{dir = 10; icon_state = "whitehall"},/area/crew_quarters/fitness)
-"awB" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
-"awC" = (/obj/machinery/light_switch{pixel_x = 22; pixel_y = 10},/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
+"awB" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 5},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
+"awC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/bed/padded,/obj/item/weapon/bedsheet/mime,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
"awD" = (/obj/machinery/door/airlock/glass{name = "Holodeck"},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor,/area/crew_quarters/fitness)
"awE" = (/turf/simulated/floor{icon_state = "blue"; dir = 4},/area/crew_quarters/fitness)
"awF" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "bridge blast"; name = "Bridge Blast Doors"; opacity = 0},/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating,/area/hallway/primary/central_one)
@@ -1185,7 +1185,7 @@
"awO" = (/obj/structure/table/reinforced,/obj/machinery/door/blast/shutters{dir = 2; id = "bar"; layer = 3.1; name = "Bar Shutters"},/turf/simulated/floor{icon_state = "grimy"},/area/crew_quarters/bar)
"awP" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating/airless,/area/maintenance/evahallway)
"awQ" = (/obj/machinery/light/small,/obj/effect/decal/cleanable/dirt,/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 10},/area/maintenance/evahallway)
-"awR" = (/obj/structure/bed,/obj/item/weapon/bedsheet/orange,/obj/machinery/camera/network/prison{c_tag = "Security - Brig Bedroom"; dir = 6},/turf/simulated/floor,/area/security/prison)
+"awR" = (/obj/machinery/light_switch{pixel_x = 22; pixel_y = 10},/obj/structure/bed/padded,/obj/item/weapon/bedsheet/mime,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
"awS" = (/obj/effect/decal/cleanable/dirt,/obj/effect/decal/cleanable/blood/oil,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 8},/area/maintenance/evahallway)
"awT" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/plating,/area/maintenance/evahallway)
"awU" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/carpet{tag = "icon-carpet3-0"; icon_state = "carpet3-0"},/area/crew_quarters/sleep/bedrooms)
@@ -1247,7 +1247,7 @@
"axY" = (/obj/structure/table/woodentable,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/crew_quarters/sleep)
"axZ" = (/obj/structure/table/woodentable,/obj/item/clothing/glasses/threedglasses,/turf/simulated/floor,/area/crew_quarters/sleep)
"aya" = (/obj/structure/table/woodentable,/obj/item/weapon/coin/silver,/turf/simulated/floor,/area/crew_quarters/sleep)
-"ayb" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/unary/vent_pump/on,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
+"ayb" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/unary/vent_pump/on,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
"ayc" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
"ayd" = (/obj/machinery/door/firedoor/border_only{dir = 8; name = "Firelock West"},/obj/machinery/door/airlock/glass{name = "Fitness"},/turf/simulated/floor,/area/crew_quarters/fitness)
"aye" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/crew_quarters/fitness)
@@ -1311,7 +1311,7 @@
"azk" = (/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/machinery/access_button{command = "cycle_interior"; frequency = 1331; master_tag = "nuke_shuttle_dock_airlock"; name = "interior access button"; pixel_x = -28; pixel_y = 26; req_one_access = list(13)},/turf/simulated/floor{dir = 8; icon_state = "warning"},/area/hallway/secondary/entry/port)
"azl" = (/obj/item/weapon/stool{pixel_y = 8},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard)
"azm" = (/obj/item/weapon/stool{pixel_y = 8},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/plating,/area/maintenance/auxsolarport)
-"azn" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
+"azn" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/mime,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -28},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
"azo" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard)
"azp" = (/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "Station Intercom (General)"; pixel_y = 20},/obj/machinery/camera/network/civilian_east{c_tag = "Dormitories Central"},/turf/simulated/floor{icon_state = "neutral"; dir = 1},/area/crew_quarters/sleep)
"azq" = (/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/hallway/secondary/entry/fore)
@@ -1326,7 +1326,7 @@
"azz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "warning"},/area/hallway/secondary/entry/fore)
"azA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "warningcorner"; dir = 1},/area/hallway/secondary/entry/fore)
"azB" = (/obj/structure/table/standard,/obj/item/stack/cable_coil/random,/obj/item/stack/cable_coil/random,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor,/area/storage/art)
-"azC" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/light/small{dir = 4},/obj/machinery/light_switch{pixel_x = 22; pixel_y = 10},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
+"azC" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/mime,/obj/machinery/light/small{dir = 4},/obj/machinery/light_switch{pixel_x = 22; pixel_y = 10},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
"azD" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/auxsolarport)
"azE" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/auxsolarport)
"azF" = (/obj/machinery/door/airlock/external{frequency = 1380; icon_state = "door_locked"; id_tag = "escape_pod_1_berth_hatch"; locked = 1; name = "Escape Pod"; req_access = list(13)},/turf/simulated/floor/plating,/area/hallway/secondary/entry/fore)
@@ -1369,7 +1369,7 @@
"aAq" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/crew_quarters/fitness)
"aAr" = (/obj/structure/table/standard,/obj/machinery/light/small,/turf/simulated/floor{icon_state = "chapel"},/area/chapel/main)
"aAs" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/power/smes/buildable{charge = 0; RCon_tag = "Solar - Fore Port"},/turf/simulated/floor/plating,/area/maintenance/auxsolarport)
-"aAt" = (/obj/structure/bed,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
+"aAt" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/mime,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor/wood,/area/crew_quarters/sleep/bedrooms)
"aAu" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/maintenance/auxsolarstarboard)
"aAv" = (/obj/structure/grille/broken,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plating{dir = 4; icon_state = "warnplatecorner"},/area/maintenance/evahallway)
"aAw" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/hallway/secondary/entry/fore)
@@ -2966,7 +2966,7 @@
"bfb" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/crew_quarters/locker)
"bfc" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/turf/simulated/floor{dir = 8; icon_state = "barber"},/area/crew_quarters/locker)
"bfd" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor,/area/crew_quarters/locker)
-"bfe" = (/obj/effect/decal/cleanable/cobweb,/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/plating,/area/maintenance/locker)
+"bfe" = (/obj/effect/decal/cleanable/cobweb,/obj/effect/decal/cleanable/dirt,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/item/stack/material/glass/reinforced,/turf/simulated/floor/plating,/area/maintenance/locker)
"bff" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
"bfg" = (/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
"bfh" = (/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/module/power_control,/obj/item/weapon/cell{maxcharge = 2000},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
@@ -3196,7 +3196,7 @@
"bjx" = (/obj/structure/disposalpipe/tagger/partial{name = "Sorting Office"; sort_tag = "Sorting Office"},/turf/simulated/floor/plating,/area/maintenance/locker)
"bjy" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
"bjz" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "floorgrime"},/area/quartermaster/storage)
-"bjA" = (/obj/structure/table/reinforced,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry)
+"bjA" = (/obj/structure/table/reinforced,/obj/item/stack/material/phoron,/obj/item/stack/material/phoron,/obj/item/stack/material/phoron,/obj/item/stack/material/phoron,/obj/item/stack/material/phoron,/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry)
"bjB" = (/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plating,/area/maintenance/locker)
"bjC" = (/obj/structure/closet/emcloset,/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/turf/simulated/floor/plating,/area/maintenance/locker)
"bjD" = (/obj/structure/filingcabinet/filingcabinet,/turf/simulated/floor{icon_state = "arrival"; dir = 4},/area/quartermaster/office)
@@ -3372,7 +3372,7 @@
"bmR" = (/obj/structure/table/woodentable,/obj/item/device/eftpos{eftpos_name = "Captain EFTPOS scanner"},/turf/simulated/floor/wood,/area/crew_quarters/captain)
"bmS" = (/obj/structure/table/woodentable,/obj/item/weapon/melee/chainofcommand,/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/wood,/area/crew_quarters/captain)
"bmT" = (/obj/structure/table/reinforced,/obj/item/weapon/reagent_containers/dropper,/obj/machinery/light{dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry)
-"bmU" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/light/small{dir = 1},/obj/structure/cable/cyan{d2 = 4; icon_state = "0-4"},/obj/machinery/power/apc/super/equipment{dir = 1; name = "north bump"; pixel_y = 24},/turf/simulated/floor/bluegrid,/area/turret_protected/ai)
+"bmU" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/light/small{dir = 1},/obj/structure/cable/cyan{d2 = 4; icon_state = "0-4"},/obj/machinery/power/apc/super/critical{dir = 1; is_critical = 1; name = "north bump"; pixel_y = 24},/turf/simulated/floor/bluegrid,/area/turret_protected/ai)
"bmV" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/medical{name = "Morgue"; req_access = list(6)},/turf/simulated/floor,/area/hallway/primary/starboard)
"bmW" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "hazard door north"},/obj/machinery/door/window/southright{name = "Research and Development Desk"; req_access = list(7)},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Biohazard"; name = "Biohazard Shutter"; opacity = 0},/obj/structure/table/plastic{name = "plastic table frame"},/turf/simulated/floor/plating,/area/hallway/primary/starboard)
"bmX" = (/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{req_one_access = list(5,12,47)},/turf/simulated/floor/plating,/area/hallway/primary/starboard)
@@ -3469,7 +3469,7 @@
"boK" = (/obj/item/weapon/stool,/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/camera/network/medbay{c_tag = "Medbay Examination Room"},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room)
"boL" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry)
"boM" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry)
-"boN" = (/obj/structure/bed,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room)
+"boN" = (/obj/structure/bed/padded,/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/exam_room)
"boO" = (/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/structure/table/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/toolbox/electrical{pixel_x = 1; pixel_y = 6},/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/obj/item/weapon/storage/toolbox/mechanical,/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/turf/simulated/floor{icon_state = "white"},/area/assembly/robotics)
"boP" = (/turf/simulated/floor{tag = "icon-whiteblue (WEST)"; icon_state = "whiteblue"; dir = 8},/area/medical/reception)
"boQ" = (/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "white"},/area/medical/reception)
@@ -3572,7 +3572,7 @@
"bqJ" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor{icon_state = "white"},/area/medical/chemistry)
"bqK" = (/obj/structure/extinguisher_cabinet{pixel_x = 25; pixel_y = 0},/turf/simulated/floor,/area/hallway/secondary/entry/aft)
"bqL" = (/turf/simulated/wall/r_wall,/area/medical/chemistry)
-"bqM" = (/obj/structure/bed,/obj/item/weapon/bedsheet/captain,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/carpet,/area/crew_quarters/captain)
+"bqM" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/captain,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/turf/simulated/floor/carpet,/area/crew_quarters/captain)
"bqN" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/reception)
"bqO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/reception)
"bqP" = (/turf/simulated/floor{dir = 4; icon_state = "whiteblue_ex"; tag = "icon-whiteblue (EAST)"},/area/medical/reception)
@@ -4279,7 +4279,7 @@
"bEo" = (/turf/simulated/floor{icon_state = "white"},/area/rnd/docking)
"bEp" = (/obj/machinery/door/airlock/research{name = "Research Shuttle Dock"; req_access = list(65)},/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor{icon_state = "white"},/area/rnd/docking)
"bEq" = (/turf/simulated/floor/mech_bay_recharge_floor,/area/medical/sleeper)
-"bEr" = (/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable,/turf/simulated/floor{icon_state = "white"},/area/rnd/docking)
+"bEr" = (/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/structure/cable,/obj/machinery/power/apc/critical{name = "south bump"; pixel_y = -24},/turf/simulated/floor{icon_state = "white"},/area/rnd/docking)
"bEs" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/rnd/docking)
"bEt" = (/obj/machinery/mech_bay_recharge_port,/obj/structure/sign/poster{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/plating,/area/medical/sleeper)
"bEu" = (/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/shuttle/plating,/area/rnd/docking)
@@ -4440,7 +4440,7 @@
"bHt" = (/obj/machinery/computer/shuttle_control/research,/turf/simulated/floor{dir = 4; icon_state = "whitebluecorner"},/area/rnd/docking)
"bHu" = (/obj/structure/lattice,/obj/structure/sign/securearea{desc = "A warning sign which reads 'KEEP CLEAR OF DOCKING AREA'."; name = "KEEP CLEAR: DOCKING AREA"; pixel_y = 32},/turf/space,/area/space)
"bHv" = (/obj/structure/table/standard,/obj/item/device/taperecorder{pixel_x = -3},/obj/item/device/paicard{pixel_x = 4},/obj/item/device/radio/intercom{freerange = 0; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29},/obj/item/weapon/circuitboard/teleporter,/obj/item/weapon/circuitboard/aicore{pixel_x = -2; pixel_y = 4},/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/crew_quarters/heads/hor)
-"bHw" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor,/area/quartermaster/miningdock)
+"bHw" = (/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/power/apc/critical{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/turf/simulated/floor,/area/quartermaster/miningdock)
"bHx" = (/obj/structure/disposalpipe/segment,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/quartermaster/miningdock)
"bHy" = (/obj/structure/table/rack{dir = 1},/obj/item/weapon/storage/toolbox/mechanical{pixel_x = -2; pixel_y = -1},/obj/machinery/light{dir = 1},/obj/machinery/light_switch{pixel_y = 24},/obj/item/weapon/storage/belt/utility,/turf/simulated/floor,/area/quartermaster/miningdock)
"bHz" = (/obj/machinery/requests_console{department = "Cargo Bay"; departmentType = 2; pixel_x = -30; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/quartermaster/qm)
@@ -4737,7 +4737,7 @@
"bNe" = (/obj/structure/closet/emcloset,/turf/simulated/floor/plating/airless,/area/rnd/test_area)
"bNf" = (/obj/structure/disposalpipe/segment,/obj/machinery/camera/network/civilian_west{c_tag = "Cargo - Quartermaster's Office"; dir = 8},/turf/simulated/floor,/area/quartermaster/qm)
"bNg" = (/turf/simulated/shuttle/floor,/area/shuttle/mining/station)
-"bNh" = (/obj/machinery/light_switch{pixel_x = 22; pixel_y = 0},/obj/structure/bed,/obj/item/weapon/bedsheet/blue,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak)
+"bNh" = (/obj/machinery/light_switch{pixel_x = 22; pixel_y = 0},/obj/structure/bed/padded,/obj/item/weapon/bedsheet/blue,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/crew_quarters/medbreak)
"bNi" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only{dir = 2},/turf/simulated/floor/plating,/area/quartermaster/miningdock)
"bNj" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 4; frequency = 1380; id_tag = "mining_dock_pump"},/turf/simulated/floor{dir = 9; icon_state = "warning"},/area/quartermaster/miningdock)
"bNk" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/turf/simulated/floor,/area/hallway/primary/central_three)
@@ -5245,12 +5245,12 @@
"bWS" = (/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab)
"bWT" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/misc_lab)
"bWU" = (/obj/structure/closet/wardrobe/engineering_yellow,/turf/simulated/floor{dir = 4; icon_state = "whiteyellowfull"},/area/crew_quarters/sleep/engi_wash)
-"bWV" = (/obj/structure/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 25; pixel_y = 0},/obj/machinery/camera/network/medbay{c_tag = "Medbay Patient A"; dir = 8},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/patient_a)
+"bWV" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 25; pixel_y = 0},/obj/machinery/camera/network/medbay{c_tag = "Medbay Patient A"; dir = 8},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/patient_a)
"bWW" = (/obj/machinery/door/firedoor/border_only,/turf/simulated/floor{icon_state = "white"},/area/rnd/research)
"bWX" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/rnd/research)
"bWY" = (/obj/machinery/alarm{frequency = 1441; pixel_y = 22},/turf/simulated/floor{icon_state = "white"},/area/rnd/research)
"bWZ" = (/obj/machinery/status_display{layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor{icon_state = "white"},/area/rnd/research)
-"bXa" = (/obj/structure/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 25; pixel_y = 0},/obj/machinery/camera/network/medbay{c_tag = "Medbay Patient Room B"; dir = 8},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/patient_b)
+"bXa" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 25; pixel_y = 0},/obj/machinery/camera/network/medbay{c_tag = "Medbay Patient Room B"; dir = 8},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/patient_b)
"bXb" = (/obj/machinery/air_sensor{frequency = 1430; id_tag = "toxins_mixing_exterior"; output = 63},/turf/simulated/floor/engine/vacuum,/area/rnd/mixing)
"bXc" = (/obj/machinery/vending/phoronresearch,/turf/simulated/floor{dir = 5; icon_state = "whitepurple"},/area/rnd/mixing)
"bXd" = (/obj/machinery/atmospherics/binary/dp_vent_pump/high_volume{dir = 2; frequency = 1379; id = "tox_airlock_pump"},/obj/machinery/air_sensor{frequency = 1430; id_tag = "toxins_mixing_interior"; output = 63; pixel_x = -8; pixel_y = -18},/turf/simulated/floor/engine,/area/rnd/mixing)
@@ -5494,7 +5494,7 @@
"cbH" = (/obj/structure/urinal{pixel_y = 32},/obj/effect/landmark{name = "blobstart"},/turf/simulated/floor{icon_state = "freezerfloor"},/area/crew_quarters/sleep/engi_wash)
"cbI" = (/turf/simulated/wall,/area/medical/surgeryobs)
"cbJ" = (/obj/machinery/door/airlock/maintenance{req_access = list(12)},/obj/structure/disposalpipe/segment,/obj/effect/decal/cleanable/dirt,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/maintenance/cargo)
-"cbK" = (/obj/structure/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{pixel_x = -26},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/ward)
+"cbK" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{pixel_x = -26},/turf/simulated/floor{dir = 8; icon_state = "whitered"},/area/medical/ward)
"cbL" = (/obj/machinery/computer/security/telescreen{desc = "Used to monitor the engine room."; layer = 3.3; name = "Engine Monitor"; network = list("Engine"); pixel_x = 0; pixel_y = 28},/obj/machinery/computer/station_alert/all,/turf/simulated/floor,/area/crew_quarters/heads/chief)
"cbM" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor{icon_state = "white"},/area/medical/ward)
"cbN" = (/turf/simulated/floor{icon_state = "white"},/area/medical/ward)
@@ -5647,7 +5647,7 @@
"ceE" = (/obj/structure/bed/chair/office/dark,/turf/simulated/floor{icon_state = "cafeteria"; dir = 5},/area/engineering/break_room)
"ceF" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "bluecorner"},/area/medical/surgeryobs)
"ceG" = (/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/green,/turf/simulated/floor{icon_state = "blue"; dir = 6},/area/medical/surgeryobs)
-"ceH" = (/obj/structure/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 25; pixel_y = 0},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/ward)
+"ceH" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 25; pixel_y = 0},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/ward)
"ceI" = (/obj/structure/table/woodentable,/turf/simulated/floor/wood,/area/medical/psych)
"ceJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/medical/ward)
"ceK" = (/obj/structure/bed/chair/office/dark{dir = 1},/obj/machinery/firealarm{dir = 4; pixel_x = 24},/obj/machinery/button/windowtint{pixel_x = -25},/obj/machinery/light_switch{pixel_x = -25; pixel_y = 8},/obj/machinery/button/remote/airlock{desc = "A remote control-switch for the office door."; id = "mentaldoor"; name = "office door control"; pixel_x = -34; pixel_y = 7},/turf/simulated/floor/wood,/area/medical/psych)
@@ -5670,11 +5670,11 @@
"cfb" = (/obj/structure/closet/secure_closet/hydroponics{req_access = list(47)},/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora_storage)
"cfc" = (/obj/machinery/light{tag = "icon-tube1 (NORTH)"; icon_state = "tube1"; dir = 1},/obj/machinery/light_switch{pixel_x = 27},/obj/machinery/smartfridge/drying_rack,/turf/simulated/floor{tag = "icon-whitegreen_v (NORTHEAST)"; icon_state = "whitegreen_v"; dir = 5},/area/rnd/xenobiology/xenoflora_storage)
"cfd" = (/obj/structure/sign/biohazard,/turf/simulated/wall,/area/rnd/xenobiology)
-"cfe" = (/obj/structure/bed,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 25; pixel_y = 0},/obj/machinery/camera/network/medbay{c_tag = "Medbay Patient Room C"; dir = 8},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/patient_c)
+"cfe" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/medical,/obj/machinery/vending/wallmed1{name = "NanoMed Wall"; pixel_x = 25; pixel_y = 0},/obj/machinery/camera/network/medbay{c_tag = "Medbay Patient Room C"; dir = 8},/turf/simulated/floor{dir = 4; icon_state = "whitered"},/area/medical/patient_c)
"cff" = (/obj/structure/sign/securearea,/turf/simulated/wall,/area/rnd/xenobiology)
"cfg" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/disposalpipe/trunk,/obj/machinery/disposal,/obj/structure/sign/deathsposal{pixel_x = 0; pixel_y = 32},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor{dir = 8; icon_state = "whitegreen"},/area/rnd/xenobiology/xenoflora)
"cfh" = (/obj/machinery/atmospherics/portables_connector,/obj/machinery/portable_atmospherics/hydroponics{closed_system = 1; name = "isolation tray"},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology/xenoflora)
-"cfi" = (/obj/structure/closet/crate,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = 28},/turf/simulated/floor/plating,/area/engineering/storage)
+"cfi" = (/obj/structure/closet/crate,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = 28},/obj/item/stack/material/phoron{amount = 25},/turf/simulated/floor/plating,/area/engineering/storage)
"cfj" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_one_access = list(12,47)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/plating,/area/rnd/xenobiology)
"cfk" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/maintenance{req_one_access = list(12,47)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/turf/simulated/floor/plating,/area/rnd/xenobiology)
"cfl" = (/obj/structure/table/standard,/obj/item/weapon/hand_labeler,/obj/item/weapon/pen,/obj/item/weapon/packageWrap,/obj/item/weapon/packageWrap,/obj/item/device/radio/intercom{freerange = 0; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29},/turf/simulated/floor{icon_state = "white"},/area/rnd/lab)
@@ -6158,7 +6158,7 @@
"cov" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan,/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/engineering/atmos)
"cow" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/plating,/area/engineering/atmos)
"cox" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor/plating,/area/engineering/atmos)
-"coy" = (/obj/structure/table/standard,/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology)
+"coy" = (/obj/structure/table/standard,/obj/item/stack/material/phoron{amount = 5},/turf/simulated/floor{icon_state = "white"},/area/rnd/xenobiology)
"coz" = (/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/hallway/secondary/entry/port)
"coA" = (/obj/machinery/door/airlock/maintenance{name = "Engineering EVA Storage Maintainance"; req_access = list(12); req_one_access = list(11,24)},/obj/machinery/door/firedoor/border_only,/obj/machinery/atmospherics/pipe/simple/hidden/red,/turf/simulated/floor,/area/engineering/engine_eva)
"coB" = (/obj/machinery/door/firedoor/border_only{dir = 1; name = "Engineering Firelock"},/obj/machinery/door/airlock/glass_engineering{name = "Engineering Locker Room"; req_one_access = list(11,24)},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor,/area/engineering/locker_room)
@@ -6334,7 +6334,7 @@
"crP" = (/obj/structure/lattice,/obj/structure/grille,/turf/space,/area/space)
"crQ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/manifold/visible/yellow{dir = 8},/turf/simulated/floor/plating,/area/engineering/atmos)
"crR" = (/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 4},/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/medical/virology)
-"crS" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/structure/bed,/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)
+"crS" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/structure/bed/padded,/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)
"crT" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/machinery/light{dir = 1},/turf/simulated/floor{dir = 1; icon_state = "whitered"},/area/medical/virology)
"crU" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 10},/turf/simulated/floor/plating,/area/engineering/atmos)
"crV" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only{dir = 2},/obj/machinery/atmospherics/pipe/manifold/visible/yellow{dir = 8},/turf/simulated/floor/plating,/area/engineering/atmos)
@@ -6739,10 +6739,10 @@
"czE" = (/obj/structure/bed/chair{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle)
"czF" = (/obj/machinery/atmospherics/pipe/simple/hidden/purple,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/camera/network/medbay{c_tag = "Virology Starboard"; dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/virology)
"czG" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/yellow{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor/plating,/area/medical/virology)
-"czH" = (/obj/structure/bed,/obj/item/weapon/bedsheet,/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/virology)
+"czH" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet,/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/virology)
"czI" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 10},/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/virology)
"czJ" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/table/standard,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/random/tech_supply,/obj/machinery/camera/network/engineering{c_tag = "Engineering Locker Room"; dir = 1},/turf/simulated/floor,/area/engineering/locker_room)
-"czK" = (/obj/structure/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 = 3; icon_state = "whitered"},/area/medical/virology)
+"czK" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet,/obj/item/device/radio/intercom{freerange = 1; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 30},/turf/simulated/floor{dir = 3; icon_state = "whitered"},/area/medical/virology)
"czL" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/vending/wallmed1{name = "Emergency NanoMed"; pixel_x = -7; pixel_y = -32},/obj/machinery/atmospherics/pipe/simple/hidden/purple{dir = 4},/obj/structure/extinguisher_cabinet{pixel_x = 7; pixel_y = -32},/turf/simulated/floor,/area/rnd/xenobiology)
"czM" = (/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible/green,/turf/simulated/floor,/area/engineering/atmos)
"czN" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating,/area/maintenance/engineering)
@@ -6883,7 +6883,7 @@
"cCs" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/plating/airless,/area/space)
"cCt" = (/obj/machinery/atmospherics/pipe/simple/visible,/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/turf/simulated/floor/plating/airless,/area/space)
"cCu" = (/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plating/airless,/area/maintenance/medbay)
-"cCv" = (/obj/structure/bed,/obj/item/weapon/bedsheet/green,/turf/simulated/floor{icon_state = "white"},/area/medical/virology)
+"cCv" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/green,/turf/simulated/floor{icon_state = "white"},/area/medical/virology)
"cCw" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{dir = 4},/turf/simulated/floor/plating/airless,/area/medical/virology)
"cCx" = (/obj/machinery/atmospherics/pipe/simple/hidden/yellow{tag = "icon-intact (NORTHEAST)"; icon_state = "intact"; dir = 5},/turf/simulated/floor/plating/airless,/area/medical/virology)
"cCy" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; external_pressure_bound = 140; external_pressure_bound_default = 140; icon_state = "map_vent_out"; pressure_checks = 1; pressure_checks_default = 1; use_power = 1},/turf/simulated/floor/plating/airless,/area/medical/virology)
@@ -6970,7 +6970,7 @@
"cEb" = (/obj/machinery/alarm{frequency = 1439; pixel_y = 23},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor,/area/engineering/engine_airlock)
"cEc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/obj/machinery/atmospherics/pipe/simple/visible/red,/turf/simulated/floor,/area/engineering/atmos)
"cEd" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor,/area/engineering/engine_airlock)
-"cEe" = (/obj/structure/bed,/obj/item/weapon/bedsheet/green,/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor{icon_state = "white"},/area/medical/virology)
+"cEe" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/green,/obj/item/device/radio/intercom{dir = 0; name = "Station Intercom (General)"; pixel_x = -27},/turf/simulated/floor{icon_state = "white"},/area/medical/virology)
"cEf" = (/obj/item/weapon/stool,/turf/simulated/floor{icon_state = "white"},/area/medical/virology)
"cEg" = (/obj/structure/grille,/obj/machinery/meter,/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/wall/r_wall,/area/engineering/atmos)
"cEh" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/visible/yellow,/obj/machinery/meter,/turf/simulated/wall/r_wall,/area/engineering/atmos)
@@ -6996,7 +6996,7 @@
"cEB" = (/obj/structure/table/standard,/obj/item/weapon/bonesetter,/obj/item/weapon/bonegel,/turf/simulated/floor{icon_state = "white"},/area/medical/surgery2)
"cEC" = (/obj/machinery/atmospherics/pipe/manifold/hidden{dir = 4; icon_state = "map"; tag = "icon-manifold-f (EAST)"},/turf/simulated/floor/plating{icon_state = "warnplate"; dir = 5},/area/maintenance/engi_shuttle)
"cED" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plating,/area/maintenance/engi_shuttle)
-"cEE" = (/obj/structure/bed,/obj/item/weapon/bedsheet/green,/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/virology)
+"cEE" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/green,/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor{icon_state = "white"},/area/medical/virology)
"cEF" = (/turf/simulated/floor/engine/vacuum,/area/maintenance/incinerator)
"cEG" = (/obj/machinery/atmospherics/unary/outlet_injector{dir = 1; frequency = 1441; icon_state = "map_injector"; id = "co2_in"; use_power = 1; pixel_y = 1},/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/engineering/atmos)
"cEH" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; external_pressure_bound = 0; external_pressure_bound_default = 0; frequency = 1441; icon_state = "map_vent_in"; id_tag = "co2_out"; initialize_directions = 1; internal_pressure_bound = 4000; internal_pressure_bound_default = 4000; use_power = 1; pressure_checks = 2; pressure_checks_default = 2; pump_direction = 0},/turf/simulated/floor/engine{carbon_dioxide = 50000; name = "co2 floor"; nitrogen = 0; oxygen = 0},/area/engineering/atmos)
@@ -7121,7 +7121,7 @@
"cGW" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plating,/area/engineering/engine_room)
"cGX" = (/obj/structure/cable/cyan{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/turf/simulated/floor/plating,/area/engineering/engine_room)
"cGY" = (/obj/machinery/atmospherics/portables_connector,/turf/simulated/floor/plating{icon_state = "platebotc"},/area/engineering/engine_room)
-"cGZ" = (/obj/machinery/light_switch{pixel_x = 12; pixel_y = 25},/obj/machinery/power/apc/super{dir = 1; name = "north bump"; pixel_y = 24},/obj/structure/cable/cyan{d2 = 8; icon_state = "0-8"},/obj/machinery/power/sensor{name = "Powernet Sensor - Engine Power"; name_tag = "Engine Power"},/turf/simulated/floor/plating,/area/engineering/engine_room)
+"cGZ" = (/obj/machinery/light_switch{pixel_x = 12; pixel_y = 25},/obj/structure/cable/cyan{d2 = 8; icon_state = "0-8"},/obj/machinery/power/sensor{name = "Powernet Sensor - Engine Power"; name_tag = "Engine Power"},/obj/machinery/power/apc/super/critical{dir = 1; is_critical = 1; name = "north bump"; pixel_y = 24},/turf/simulated/floor/plating,/area/engineering/engine_room)
"cHa" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/maintenance/engi_shuttle)
"cHb" = (/turf/simulated/floor/plating,/area/engineering/engine_room)
"cHc" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{tag = "icon-intact (SOUTHWEST)"; icon_state = "intact"; dir = 10},/turf/space,/area/space)
@@ -7476,16 +7476,16 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaLasYaaLaaaaaaaaaaaaaaaaaaaaaaaIaafalzalyalyalyalyalAalkallaivaivaivaivagEaafaaIaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaqzataaqBagDarRapcatiarTarUatIapharWaloaonaonarYasFasyasMaonascalWasdasealmasgasharAasiasjaskarEaoHaoHaoHaoHaoHaslatQatJasoasoaspaspasqasrassastastasuasvasvaswasxatXaszaqsaaaaafaafaafaaaaaaaafaafaafaafaaaaaaaafaafaafaaaaaaaaaaaaaaIaafanTanTanTanTanTaafalJaafanTanTanTanTanTaafaaIaaaaaaaaaaaaaaaaaaaihaihaihaihaihaihaihaihaihaihaihaihaihaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafasAauiasAaaaaaaaaaaaaaaaaaaaaaaaIaafapJapJapJapJapJaafalkaafapJapJapJapJapJaafaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaasCasbapbagDapUapMagWaZtasEalKapOasPaoiasGasGasHasIaonasJaonasKalWasLatgaZuathauuarAasQauvasSarEasTasUasUasVauSasVavCavbasZasZasZaDoasZasZasZasZasZasmavFatbatcaoKatdateatfaaaaafatPatratjatjatjatjavRatjatjatjatjatUaafaaaaaaaaaaaaaamaafanianjanjanjanjanualJansanqanqanqanqanwaafaaIaaaaaaaaaaaaaaaaaaaaaaaaaihaihaihaihaihaihaihaihaihaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatkatlatmaaaatnatoatpaaaaafatqatWatqaaaaaaaaaaaaaaaaaaaaaaamaaaaaaaaaaafaaaaaaaaaalkaaaaaaaaaaafaaaaaaaaaaamaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaanXatsattagDagDagDagWagWagWagWalWalWalWalWalWatuaonaoratvaqEatwalWalWalWatxatxatxarAatyatzatAarEatBasZasZasZasZatCatDatEatFatGatHaEzavUatKatLatMatNatOatPatPatPatPatPatPatPatPatPatPatRatRatRatRatRatRatRatRatRatRaumaafaaaaaaaaaaaaaamaaaapIapIapIapIapIaafalJaafapIapIapIapIapIaaaaaqaaaaaaaaaaaaaaaaaaaaaaaaaaaaihaihaihaihaihaihaihaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatSatTaLAatTatSatVaLBatVatSaafatqawvatYaaaaaaaaaaaaaaaaaaaaaaaIaafanVanVanVanVanVaafalkaafanVanVanVanVanVaafaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafatZauaanYaubaucanXaafaafalWaudaueaufaugauhawMaonapnaonasJaqEaujaukaulawRaunauKauparAauqaurausarEatBasZauLaxdauMatCauxauyatFatGauzauAauBauCauDatMatNauEauFauGauHauIauHauJauwauOauPaxsatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaamaaaaafaaaaafaafaaaaaabepaaaaaaaafaaaaaaaafaaaaaIaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauNatTavmatTauNatVavyatVauNauQauRaxuauTauUauUauVauQauQaafaaaaaIaafalzalyalyalyalyalAalkallaivaivaivaivagEaafaaIaaaaaaaaaaaaaaaaaaaaaaaaanXanXanXauWanXanXapbaucanXaaaaaaalWauXalWauYauZavaalWaZYavzaonavdaveaveavfavgaveavhaviavjarAavkauravlarEatBasZavAavoavJatCawravqatFatGaGVauAavravsavtatMatNavuavvauGauHauHauHauJavwavQawfavVatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaamaamaaIaaaaaaaafaaaaaaabpaaaaafaafaafaafaaIaaIaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauNavBaxyavDauNavEaxAavGauNavHavIaxCavKavLavMavNavOauQaaaaaaaaqaaaapJapJapJapJapJaafbeSaafapJapJapJapJapJaaaaaIaaaaaaaaaaaaaaaaaaaaaaaaawkaxGavSayqaxOawoavWavXanXaaaaaaalWalWalWavYavZawaalWaYJaYNawcaweawpaYHaukawhawxautawyawlarAawmaurayzarEatBasZawzawUawYaxaaxbawZatFatFatFawsawtawuatFatFatNayNawwauGauHauHauHauJawAavxawfaykatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaaaaaaaafaafaaaaafaaaaaaaYxaaaaaaaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauNawGawHawIauNawGawHawIauNawJavHavHavHavHavHavHavHasAaaaaaaaaIaaaaafaaaaafaafaaaaaaaZhaaaaaaaafaaaaaaaafaaaaaIaafaaaaaaaafaafaaaaaaaafawPaxGawQazgaxOawSaucawTanXaafaaLcqTatxatxatxatxatxatxatxatxatxatxatxatxatxatxatxatxatxatxarAawVaurawWarEatBasZawBaxjawCatCaxVavnazpaxcaxhaxeaxhaxgaxfaxiaxkaxlaxmaxnaxoaxoaxoaxnaxmavxawEawDatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaaaaaaaaaaafaafaafaaaazoaYUazoaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaatSatTaLAatTatSatVaLBatVatSaafatqawvatYaaaaaaaaaaaaaaaaaaaaaaaIaafanVanVanVanVanVaafalkaafanVanVanVanVanVaafaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafatZauaanYaubaucanXaafaafalWaudaueaufaugauhawMaonapnaonasJaqEaujaukaulauKaunauLauparAauqaurausarEatBasZauMaxdavAatCauxauyatFatGauzauAauBauCauDatMatNauEauFauGauHauIauHauJauwauOauPaxsatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaamaaaaafaaaaafaafaaaaaabepaaaaaaaafaaaaaaaafaaaaaIaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauNatTavmatTauNatVavyatVauNauQauRaxuauTauUauUauVauQauQaafaaaaaIaafalzalyalyalyalyalAalkallaivaivaivaivagEaafaaIaaaaaaaaaaaaaaaaaaaaaaaaanXanXanXauWanXanXapbaucanXaaaaaaalWauXalWauYauZavaalWaZYavzaonavdaveaveavfavgaveavhaviavjarAavkauravlarEatBasZavJavoawxatCawravqatFatGaGVauAavravsavtatMatNavuavvauGauHauHauHauJavwavQawfavVatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaamaamaaIaaaaaaaafaaaaaaabpaaaaafaafaafaafaaIaaIaaIaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauNavBaxyavDauNavEaxAavGauNavHavIaxCavKavLavMavNavOauQaaaaaaaaqaaaapJapJapJapJapJaafbeSaafapJapJapJapJapJaaaaaIaaaaaaaaaaaaaaaaaaaaaaaaawkaxGavSayqaxOawoavWavXanXaaaaaaalWalWalWavYavZawaalWaYJaYNawcaweawpaYHaukawhawyautawzawlarAawmaurayzarEatBasZawBawUawYaxaaxbawZatFatFatFawsawtawuatFatFatNayNawwauGauHauHauHauJawAavxawfaykatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaaaaaaaafaafaaaaafaaaaaaaYxaaaaaaaafaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaauNawGawHawIauNawGawHawIauNawJavHavHavHavHavHavHavHasAaaaaaaaaIaaaaafaaaaafaafaaaaaaaZhaaaaaaaafaaaaaaaafaaaaaIaafaaaaaaaafaafaaaaaaaafawPaxGawQazgaxOawSaucawTanXaafaaLcqTatxatxatxatxatxatxatxatxatxatxatxatxatxatxatxatxatxatxarAawVaurawWarEatBasZawCaxjawRatCaxVavnazpaxcaxhaxeaxhaxgaxfaxiaxkaxlaxmaxnaxoaxoaxoaxnaxmavxawEawDatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaaaaaaaaaaafaafaafaaaazoaYUazoaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaatSauNazFaxxatSauNazUaxxatSauNaAbauNauNauNauNauNavHatqaaaaaaaaIaaIaaIaaaaaaaafaaaaxBaZnaxBaafaafaafaafaaIaaIaaIaafanXanXanXanXaxDaxEaxEaxFanXanXanXanXaAvaucaucanXaxHaxIanXanXaxJaxKaxLaxMaxMaxMaxMaxMaxMaxMaxMaxNaxMaxMaxMaxMaxMaAHaxPaxQaxRaAHavpasZaxSawjcfSatCaCJaxXaxXawLaxZaxYayaaxpaxXavqaydayeayfaygayhayhayhayhawXavxawEawDatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaAuaBaaAuaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaynayoaypayoaBcayoayrayoaysaytayvayvayvayvaywauNawNatqaaaaafaafaaaaaaaaaaaaaafaaaayyaBkayAaafaaaaafaaaaaaaaaaaaaaaanXayBayCayDayCayCayCayCayEayCayCayFayGayDayHayIaxMaxMaxMaxMaxMaxMayJayKayLayLayLayLayMayLayLaZsayLayMayLayLayLarAaBEayPayQarEaAiasZcfSaycaxUatCayUayTayWaxqayYayXayYayiayTazaazbazcazdazeazdazdazfaxraBOaxtaxTaxvatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaaaaaaaaaaaaaafaafaBuaBvaZraBxaByaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazqazrazsaztazuazvazwazxazyazwazzazAazwazwaCeauNavHauRaafaafaaaaaaaaaaaaaaaaafazDazEbdHazGazHaaaaafaaaaaaaaaaaaaaaanXazIanXazJazKazLazLazLazMazLazLazLazNazJazOazPazPazPazPazPazPazPazQazRayLazSazTbzzazVazWazXazYazZaAabeTazTaAcarAaAdayPayQarEaAiasZaybaAeauMatCaxWaxXaxXaxXaxXawLayjaAlaAmaAnaxkaAoaylaApaApaApaAqayVatPayZatPatPatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaCvaCwbfyaCyaCvaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafauNaAwaAxaAwaAyazsazsaAzaAwaAxaAwaAAaABaACaADauNavHauQauQaAEauUauUauUauUauVauQaAFaAGbfAaAIaAFanXanXaxHaAJaxIanXanXanXazIaAKazJaaaaafaaaaafaaaaafaaaaafaaaazJazOazPaALaAMaANaAOaAPazPazQaucayLaAQaAQaARaASaATaAUaAVaATaAWaAXazTaAcarAaAdayPaDdarEaAiasZawzaAgaAhaBbayRaBdaBeazhaBgaBhaBiaBjaBjaCLaBjatPaBlaBmaBnaBoaBpaBraxvazibguazjatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaaaaacaaaaaaaafaaaaCvazlaDAaDBaCvaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazqazrazsaztazuazvazwazxazyazwazzazAazwazwaCeauNavHauRaafaafaaaaaaaaaaaaaaaaafazDazEbdHazGazHaaaaafaaaaaaaaaaaaaaaanXazIanXazJazKazLazLazLazMazLazLazLazNazJazOazPazPazPazPazPazPazPazQazRayLazSazTbzzazVazWazXazYazZaAabeTazTaAcarAaAdayPayQarEaAiasZaybaAeavAatCaxWaxXaxXaxXaxXawLayjaAlaAmaAnaxkaAoaylaApaApaApaAqayVatPayZatPatPatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaCvaCwbfyaCyaCvaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafauNaAwaAxaAwaAyazsazsaAzaAwaAxaAwaAAaABaACaADauNavHauQauQaAEauUauUauUauUauVauQaAFaAGbfAaAIaAFanXanXaxHaAJaxIanXanXanXazIaAKazJaaaaafaaaaafaaaaafaaaaafaaaazJazOazPaALaAMaANaAOaAPazPazQaucayLaAQaAQaARaASaATaAUaAVaATaAWaAXazTaAcarAaAdayPaDdarEaAiasZawBaAgaAhaBbayRaBdaBeazhaBgaBhaBiaBjaBjaCLaBjatPaBlaBmaBnaBoaBpaBraxvazibguazjatRatRatRatRatRatRatRatRatRatRavcaafaaaaaaaaaaaaaaaaacaaaaaaaafaaaaCvazlaDAaDBaCvaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaBzatSaBAawHaBBaBCaBDaDcaBFaBBawHaBGaBHaBIaBJaBKaBLavHavHavHavHavHavHavHavHaDnaBPaAFazmaBRaBSaAFaBTaBUayCayCayCayCayCaBVaBWaBXazJaafaBYaBYaBYaBYaBYaBYaBYaafazJazOazPaBZaCaaCbaCcaBZazPazQaCdayLayLayLayLaDxaCfaCgaChaCfbKoaCjazTaCkarAaAdayPaClarEaJCasZaznaAYazCatCaxWavqatEaBjaBjaBjaBjaBjaCqaCraCsaBjatPatPatPatPaDQatPatPaAfaAkaAjatRatRatRatRatRatRatRatRatRatRaumaafaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaCvaEXaEYaDYaCvaaaaaaaaaaafaafaaaaaaaaaaaaaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazqaAxaCzaCAaCAaCAaCAaCBaAxazqaaaaBIaCCaxzaBLaCEaCEaCEaCEaCEaCEaCEavHaCFaCGaAFaEeaCIaAsaAFaCKaEvaCKaCKaCKaCKaCKaCKaCKaCKaCMaaaaBYaCNaCOaCPaCQaCRaBYaaaazJazOazPaBZaCSaCTaCUaBZazPazQanXayLaCVaCWaARaCXaCYaCZaDaaDbcfwayLayLayLarAaAdayPayQarEaAiasZaAtaEMauMatCaDgavqatEaDhaDiaDjaDkaBjaCqaDlaCsaBjaDmaESbgIaDpaDqaGwaDsatPatPatPaAZatjatjatjatjaEVatjatjatjatjaBfaafaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaCvaCvbgHaGyaCvaDCaDDaDEaDCaDCaDCaDCaDCaDCaDCaDFaDGaDGaDGaDHaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazqaAxaCzaCAaCAaCAaCAaCBaAxazqaaaaBIaCCaxzaBLaCEaCEaCEaCEaCEaCEaCEavHaCFaCGaAFaEeaCIaAsaAFaCKaEvaCKaCKaCKaCKaCKaCKaCKaCKaCMaaaaBYaCNaCOaCPaCQaCRaBYaaaazJazOazPaBZaCSaCTaCUaBZazPazQanXayLaCVaCWaARaCXaCYaCZaDaaDbcfwayLayLayLarAaAdayPayQarEaAiasZaAtaEMavAatCaDgavqatEaDhaDiaDjaDkaBjaCqaDlaCsaBjaDmaESbgIaDpaDqaGwaDsatPatPatPaAZatjatjatjatjaEVatjatjatjatjaBfaafaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaCvaCvbgHaGyaCvaDCaDDaDEaDCaDCaDCaDCaDCaDCaDCaDFaDGaDGaDGaDHaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaaaaaaaaaaaaaDIaDJaDKaDJaDJaDLaDMaDJaDJaDKaDNaDOaBIaDPaFEaBLaDRaDSaDTaDUaDVaDWaCEavHaDXauQaAFaAFbaNaDZaCMaEaaEbbcCbbTbbxbaCbafbacaEiaEjaCMaafaBYaEkaElaEmaEnaEoaBYaafazJazOazPaEpaEqaEraEsaEtazPazQaEuayLazSazTaFSaEwaCfaExaEyaATaIVaEAaEBaEBarAaAdayPayQarEaAiaCmaCmaCmaCmaCmaEHaEIatEaEJaEKaEKaELaFZaEKaENaEOaBjaEPaEQaERaGfaETaCnaDsaaaaafaafaafaaaaaaaafaafaafaafaaaaaaaafaafaafaaaaaaaaaaaaaaaaaaaaaaDCaBsaBqaDCaBtaCpaGkaFdaFdaFdaFdaFeaFfaFgaFgaFgaFgaFgaFgaFgaGqaFiaFjaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaDIaDNaDJaFkawiaFlaFmbIraFoaFpbHfaFlawnaFraFsaFtaDPayuaBLaFvayxaBMaCxaBMaBNaGravHaFuaGxaFxaGHaFzaDfaGPaFJaFKaFLaFLaFLaDraFLaFLaFNaFOaCMaaaaBYaDtaElaFQaEnaFRaBYaaaazJazOazPbopaFTaFUaFTaFVazPazQaFWayLayLayLayLaFXaCfaCgazTaCfaFYbcEazTaGaarAaGbaGcaGdarEaAiaDeaDvaDuaCoaDeaHJaDzaHYaGlaGmaBjaBjaBjaBjaBjaBjaGnaGoaGpaIcaDpaIkaIhaDsaDsaDsaDsaDsaDsaDsaDsaDsaFaaFbaDsaDsaFaaGtaDsaDsaaaaaaaDCaDCaDCaDCaDCaEZaEWaFdaFcaFwaDCaDCaDCaDCaDCaGDaGEaGFaGFaGFaGFaGFaGFaGGaGGaIlaGGaGGaGGaGGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaTDaTDaTDaTDaTDaTDaTDaTDaTDaaaaaaaaaaaaaaaaFraGIaFyaGKaFlaFMaFlaFMaFlaFMaFlaFMaFlaGMaGNaGOaDPayuaBLaInaFAaGRaGSaGTaGUaCEaFBaFDaFCaFCaFCbazaIzaFCbcTaFLaFLaFLaFLaFLaFLaFLaFNbcPaCMaafaBYaHeaHfaHgaHhaHiaBYaafazJazOazPaHjaFPaFUaHlaHmazPaHnaHoayLaHpazTaARaHqaATaHrazTaCfaFYaHsazTaHtarAaHuaHvaHwarEaGuaIDaEUaGvaDwaIIaGzaGjatEaHCaHDaBjaHEaBjaHFaBjaHGaBjaHHaGpaIZaDpaJsaJjaHLaHMaHMaHNaHOaHKaHKaHKaHKaHKaHPaHKaHKaHKaHQaHVaDsaDsaDsaDCaGBaGAaGCaGCaGLaGJaDCaDCaJwaDCaIdaIeaIfaIgaGFaJBaGFaIiaIjaJHaKjbinaKlaIoaIpaIqaKHaIsbjFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIuaIuaIuaIuaIuaIuaIuaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaIvaaaaaaaaaaaaaaaaaaaaaaaa
diff --git a/maps/exodus-2.dmm b/maps/exodus-2.dmm
index fde4aa252b..ba47127c63 100644
--- a/maps/exodus-2.dmm
+++ b/maps/exodus-2.dmm
@@ -1364,11 +1364,11 @@
"Al" = (/turf/simulated/shuttle/wall{icon_state = "swallc3"},/area/shuttle/escape/centcom)
"Am" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/specops/centcom)
"An" = (/turf/simulated/mineral,/area/syndicate_mothership{name = "\improper Raider Base"})
-"Ao" = (/turf/unsimulated/wall{icon_state = "iron6"},/area/syndicate_mothership{name = "\improper Raider Base"})
+"Ao" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 2; name = "thrower_throwdown"; tiles = 0},/obj/effect/step_trigger/teleporter/random{affect_ghosts = 1; name = "escapeshuttle_leave"; teleport_x = 25; teleport_x_offset = 245; teleport_y = 25; teleport_y_offset = 245; teleport_z = 6; teleport_z_offset = 6},/turf/unsimulated/wall,/area/space)
"Ap" = (/turf/unsimulated/floor{icon_state = "green"; dir = 9},/area/centcom/holding)
"Aq" = (/turf/unsimulated/floor{icon_state = "greencorner"; dir = 4},/area/centcom/holding)
"Ar" = (/turf/unsimulated/wall{icon_state = "iron12"},/area/syndicate_mothership{name = "\improper Raider Base"})
-"As" = (/turf/unsimulated/wall{icon_state = "iron10"},/area/syndicate_mothership{name = "\improper Raider Base"})
+"As" = (/turf/unsimulated/wall,/area/syndicate_mothership{name = "\improper Raider Base"})
"At" = (/turf/simulated/shuttle/wall{icon_state = "swall3"; dir = 2},/area/shuttle/escape/centcom)
"Au" = (/obj/machinery/door/window/holowindoor{dir = 1; name = "Jury Box"},/turf/simulated/floor/holofloor{icon_state = "carpet10-8"; dir = 4},/area/holodeck/source_courtroom)
"Av" = (/obj/structure/bed/chair{dir = 1},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom)
@@ -1386,7 +1386,7 @@
"AH" = (/turf/unsimulated/wall,/area/centcom/ferry)
"AI" = (/obj/machinery/door/blast/regular{icon_state = "pdoor1"; id = "ASSAULT3"; name = "Launch Bay #3"; p_open = 0},/turf/unsimulated/floor{name = "plating"},/area/centcom/specops)
"AJ" = (/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/holding)
-"AK" = (/turf/unsimulated/wall{icon_state = "iron3"},/area/syndicate_mothership{name = "\improper Raider Base"})
+"AK" = (/turf/simulated/wall/voxshuttle,/area/shuttle/skipjack/station)
"AL" = (/obj/structure/bed/chair/holochair,/turf/simulated/floor/holofloor{icon_state = "dark"},/area/holodeck/source_courtroom)
"AM" = (/obj/structure/table/standard,/obj/item/weapon/storage/firstaid/fire,/obj/item/weapon/extinguisher,/obj/machinery/camera/network/crescent{c_tag = "Shuttle Bridge West"},/turf/simulated/shuttle/floor,/area/shuttle/escape/centcom)
"AN" = (/obj/structure/window/reinforced/holowindow{dir = 1},/obj/structure/window/reinforced/holowindow{dir = 8},/obj/structure/table/woodentable/holotable,/turf/simulated/floor/holofloor{icon_state = "carpet6-2"; dir = 4},/area/holodeck/source_courtroom)
@@ -1536,7 +1536,6 @@
"DB" = (/turf/unsimulated/floor{icon_state = "greencorner"; dir = 8},/area/centcom/holding)
"DC" = (/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/holding)
"DD" = (/obj/machinery/door/airlock/glass{name = "Arrivals Processing"},/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/holding)
-"DE" = (/turf/unsimulated/wall{icon_state = "iron13"},/area/syndicate_mothership{name = "\improper Raider Base"})
"DF" = (/obj/structure/bed/chair/comfy/brown{dir = 1},/turf/unsimulated/floor{dir = 6; icon_state = "carpetside"},/area/centcom/holding)
"DG" = (/turf/unsimulated/floor{tag = "icon-wood"; icon_state = "wood"},/turf/unsimulated/floor{tag = "icon-siding4"; name = "plating"; icon_state = "siding4"},/area/centcom/holding)
"DH" = (/obj/structure/table/woodentable{dir = 5},/obj/item/weapon/reagent_containers/food/drinks/drinkingglass,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/holding)
@@ -1554,7 +1553,6 @@
"DT" = (/obj/machinery/atmospherics/unary/cryo_cell,/turf/unsimulated/floor{icon_state = "floor"},/area/centcom/holding)
"DU" = (/turf/unsimulated/wall{tag = "icon-iron4"; icon_state = "iron4"},/area/syndicate_mothership{name = "\improper Raider Base"})
"DV" = (/turf/unsimulated/floor{icon_state = "white"},/area/centcom/holding)
-"DW" = (/turf/unsimulated/wall{icon_state = "iron5"},/area/syndicate_mothership{name = "\improper Raider Base"})
"DX" = (/obj/structure/bed/roller,/turf/unsimulated/floor{dir = 4; icon_state = "whitegreenfull"},/area/centcom/holding)
"DY" = (/obj/machinery/sleeper,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom)
"DZ" = (/obj/machinery/sleep_console,/turf/simulated/shuttle/floor{icon_state = "floor3"},/area/shuttle/escape/centcom)
@@ -1803,7 +1801,6 @@
"II" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/drinkingglasses{pixel_x = 1; pixel_y = 4},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"})
"IJ" = (/obj/structure/table/reinforced,/obj/item/weapon/tray{pixel_y = 5},/turf/unsimulated/floor{icon_state = "white"},/area/syndicate_mothership{name = "\improper Raider Base"})
"IK" = (/obj/structure/bed/chair{dir = 4},/obj/machinery/camera/network/crescent{c_tag = "Crescent Arrivals South"; dir = 4},/turf/unsimulated/floor{icon_state = "green"; dir = 8},/area/centcom/holding)
-"IL" = (/turf/unsimulated/wall{icon_state = "iron14"},/area/syndicate_mothership{name = "\improper Raider Base"})
"IM" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/backpack/cultpack,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station)
"IN" = (/obj/structure/table/woodentable,/obj/item/clothing/glasses/monocle,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station)
"IO" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/backpack,/turf/unsimulated/floor{icon_state = "grimy"},/area/wizard_station)
@@ -1820,7 +1817,6 @@
"IZ" = (/obj/structure/flora/pottedplant{tag = "icon-plant-06"; icon_state = "plant-06"},/turf/simulated/floor/holofloor{icon_state = "wood"; dir = 4},/area/holodeck/source_theatre)
"Ja" = (/obj/machinery/computer/shuttle_control{req_access = list(101); shuttle_tag = "Centcom"},/turf/unsimulated/floor{name = "plating"},/area/centcom/ferry)
"Jb" = (/obj/structure/table/standard,/turf/unsimulated/floor{icon_state = "dark"},/area/syndicate_mothership{name = "\improper Raider Base"})
-"Jc" = (/turf/unsimulated/wall{icon_state = "iron11"},/area/syndicate_mothership{name = "\improper Raider Base"})
"Jd" = (/obj/structure/bed/chair/wood/wings{icon_state = "wooden_chair_wings"; dir = 4},/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station)
"Je" = (/obj/structure/table/woodentable,/obj/item/weapon/dice/d20,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station)
"Jf" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/box/cups,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station)
@@ -1835,7 +1831,6 @@
"Jo" = (/obj/item/tape/engineering{tag = "icon-engineering_h"; icon_state = "engineering_h"},/turf/unsimulated/floor{tag = "icon-asteroid"; icon_state = "asteroid"},/area/syndicate_mothership{name = "\improper Raider Base"})
"Jp" = (/obj/structure/urinal{pixel_y = 32},/obj/item/weapon/soap/syndie,/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership{name = "\improper Raider Base"})
"Jq" = (/obj/structure/urinal{pixel_y = 32},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/syndicate_mothership{name = "\improper Raider Base"})
-"Jr" = (/turf/unsimulated/wall{icon_state = "iron9"},/area/syndicate_mothership{name = "\improper Raider Base"})
"Js" = (/obj/structure/table/woodentable,/obj/structure/table/woodentable,/obj/item/weapon/reagent_containers/food/snacks/milosoup,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station)
"Jt" = (/obj/structure/table/woodentable,/obj/item/weapon/dice,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station)
"Ju" = (/turf/unsimulated/floor{tag = "icon-cult"; name = "plating"; icon_state = "cult"},/area/wizard_station)
@@ -1925,28 +1920,21 @@
"La" = (/obj/structure/closet/secure_closet/bar{req_access = list(25)},/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/holding)
"Lb" = (/obj/structure/table/woodentable{dir = 5},/obj/machinery/chemical_dispenser/bar_alc/full,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/holding)
"Lc" = (/obj/structure/table/woodentable{dir = 5},/obj/machinery/chemical_dispenser/bar_soft/full,/turf/unsimulated/floor{icon_state = "grimy"},/area/centcom/holding)
-"Ld" = (/turf/simulated/shuttle/wall{dir = 2; icon = 'icons/turf/walls.dmi'; icon_state = "iron1"},/area/shuttle/skipjack/station)
"Le" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast{id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station)
"Lf" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1331; master_tag = "vox_west_control"; req_one_access = list(150)},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/skipjack/station)
-"Lg" = (/turf/simulated/shuttle/wall{dir = 2; icon = 'icons/turf/walls.dmi'; icon_state = "iron6"},/area/shuttle/skipjack/station)
"Lh" = (/obj/structure/bed/chair{dir = 8},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/skipjack/station)
"Li" = (/obj/structure/table/standard,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/skipjack/station)
"Lj" = (/obj/structure/bed/chair{dir = 4},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/skipjack/station)
-"Lk" = (/turf/simulated/shuttle/wall{dir = 2; icon = 'icons/turf/walls.dmi'; icon_state = "iron10"},/area/shuttle/skipjack/station)
"Ll" = (/obj/machinery/door/airlock/hatch{req_access = list(150)},/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station)
"Lm" = (/obj/machinery/access_button{command = "cycle_exterior"; frequency = 1331; master_tag = "vox_east_control"; req_access = list(150)},/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/skipjack/station)
"Ln" = (/obj/machinery/door/airlock/centcom{name = "Thunderdome"; opacity = 1; req_access = list(101)},/turf/unsimulated/floor{icon_state = "floor"},/area/tdome)
-"Lo" = (/turf/simulated/shuttle/wall{dir = 2; icon = 'icons/turf/walls.dmi'; icon_state = "iron13"},/area/shuttle/skipjack/station)
-"Lp" = (/turf/simulated/shuttle/wall{dir = 2; icon = 'icons/turf/walls.dmi'; icon_state = "iron12"},/area/shuttle/skipjack/station)
"Lq" = (/obj/item/device/radio/intercom{desc = "Talk through this. Evilly"; freerange = 1; frequency = 1213; name = "Syndicate Intercom"; pixel_y = -32; subspace_transmission = 1; syndie = 1},/obj/machinery/light,/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start)
"Lr" = (/turf/simulated/shuttle/wall{icon_state = "wall3"},/area/shuttle/skipjack/station)
-"Ls" = (/turf/simulated/shuttle/wall{dir = 2; icon = 'icons/turf/walls.dmi'; icon_state = "iron3"},/area/shuttle/skipjack/station)
"Lt" = (/obj/structure/table/standard,/obj/item/weapon/deck,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/skipjack/station)
"Lu" = (/turf/unsimulated/floor{tag = "icon-ironsand7"; icon_state = "ironsand7"},/turf/unsimulated/floor{tag = "icon-asteroid7"; name = "plating"; icon_state = "asteroid7"},/area/wizard_station)
"Lv" = (/turf/unsimulated/floor{tag = "icon-ironsand12"; icon_state = "ironsand12"},/turf/unsimulated/floor{tag = "icon-asteroid2"; name = "plating"; icon_state = "asteroid2"},/area/wizard_station)
"Lw" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast{id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station)
"Lx" = (/obj/structure/sign/nosmoking_2{pixel_x = 32},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start)
-"Ly" = (/turf/simulated/shuttle/wall{dir = 2; icon = 'icons/turf/walls.dmi'; icon_state = "iron7"},/area/shuttle/skipjack/station)
"Lz" = (/turf/simulated/floor/holofloor{icon_state = "carpet7-3"; dir = 4},/area/holodeck/source_theatre)
"LA" = (/turf/simulated/floor/holofloor/grass,/turf/simulated/floor/holofloor{icon_state = "wood_siding1"; dir = 2},/obj/structure/flora/ausbushes/ywflowers,/turf/simulated/floor/holofloor{icon_state = "wood_siding5"; dir = 2},/area/holodeck/source_picnicarea)
"LB" = (/turf/simulated/floor/holofloor{icon_state = "carpet11-12"; dir = 4},/area/holodeck/source_theatre)
@@ -1971,18 +1959,12 @@
"LU" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 8; name = "thrower_escapeshuttletop(left)"; tiles = 0},/turf/space/transit/north/shuttlespace_ns12,/area/space)
"LV" = (/obj/effect/step_trigger/thrower{affect_ghosts = 1; direction = 8; name = "thrower_escapeshuttletop(left)"; tiles = 0},/turf/space/transit/north/shuttlespace_ns11,/area/space)
"LW" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/blast{id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station)
-"LX" = (/turf/simulated/shuttle/wall{dir = 2; icon = 'icons/turf/walls.dmi'; icon_state = "iron11"},/area/shuttle/skipjack/station)
-"LY" = (/turf/simulated/shuttle/wall{dir = 2; icon = 'icons/turf/walls.dmi'; icon_state = "iron4"},/area/shuttle/skipjack/station)
-"LZ" = (/turf/simulated/shuttle/wall{dir = 2; icon = 'icons/turf/walls.dmi'; icon_state = "iron8"},/area/shuttle/skipjack/station)
"Ma" = (/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/skipjack/station)
"Mb" = (/obj/machinery/door/airlock/hatch{req_access = list(150)},/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/skipjack/station)
"Mc" = (/obj/structure/bed,/obj/item/weapon/bedsheet/rainbow,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/skipjack/station)
"Md" = (/obj/structure/bed,/obj/item/weapon/bedsheet/hos,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/skipjack/station)
-"Me" = (/turf/simulated/shuttle/wall{dir = 2; icon = 'icons/turf/walls.dmi'; icon_state = "iron5"},/area/shuttle/skipjack/station)
-"Mf" = (/turf/simulated/shuttle/wall{dir = 2; icon = 'icons/turf/walls.dmi'; icon_state = "iron9"},/area/shuttle/skipjack/station)
"Mg" = (/obj/machinery/flasher{id = "syndieflash"; pixel_x = 0; pixel_y = 28},/obj/machinery/light/small{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor7"},/area/syndicate_station/start)
"Mh" = (/obj/structure/bed,/obj/item/weapon/bedsheet/orange,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/skipjack/station)
-"Mi" = (/turf/simulated/shuttle/wall{dir = 2; icon = 'icons/turf/walls.dmi'; icon_state = "iron14"},/area/shuttle/skipjack/station)
"Mj" = (/obj/item/pizzabox/meat,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/skipjack/station)
"Mk" = (/obj/structure/bed,/obj/item/weapon/bedsheet/rd,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/skipjack/station)
"Ml" = (/obj/structure/bed,/obj/item/weapon/bedsheet/clown,/turf/simulated/shuttle/floor{icon_state = "floor4"},/area/shuttle/skipjack/station)
@@ -2007,7 +1989,6 @@
"ME" = (/obj/machinery/atmospherics/pipe/manifold/visible{dir = 1},/obj/machinery/airlock_sensor{frequency = 1331; id_tag = "merc_shuttle_sensor"; pixel_x = 8; pixel_y = 25},/obj/machinery/light/small{dir = 1},/turf/simulated/shuttle/floor{icon_state = "floor6"},/area/syndicate_station/start)
"MF" = (/obj/machinery/atmospherics/unary/vent_pump/high_volume{frequency = 1331; id_tag = "vox_east_vent"},/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station)
"MG" = (/obj/machinery/airlock_sensor{frequency = 1331; id_tag = "vox_east_sensor"; pixel_x = -25},/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station)
-"MH" = (/turf/simulated/shuttle/wall{dir = 2; icon = 'icons/turf/walls.dmi'; icon_state = "iron2"},/area/shuttle/skipjack/station)
"MI" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/blast{dir = 2; id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station)
"MJ" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast{dir = 2; id = "skipjack"; name = "Skipjack Blast Shielding"},/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station)
"MK" = (/obj/item/robot_parts/head,/turf/simulated/shuttle/plating,/area/shuttle/skipjack/station)
@@ -2125,7 +2106,6 @@
"OS" = (/obj/machinery/door/airlock/command{name = "Thunderdome Administration"; req_access = list(102)},/turf/unsimulated/floor{icon_state = "floor"},/area/tdome)
"OT" = (/obj/machinery/door/airlock/command{name = "Thunderdome Administration"; req_access = list(102)},/turf/simulated/floor,/area/tdome)
"OU" = (/obj/structure/table/woodentable,/obj/machinery/chemical_dispenser/bar_soft/full,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station)
-"OV" = (/turf/space,/area/shuttle/skipjack/station)
"OW" = (/obj/structure/table/woodentable,/obj/item/weapon/storage/box/donut,/turf/unsimulated/floor{dir = 8; icon_state = "wood"},/area/wizard_station)
"OX" = (/mob/living/carbon/human/monkey{name = "Murphey"},/turf/unsimulated/floor{icon_state = "freezerfloor"; dir = 2},/area/wizard_station)
"OY" = (/obj/machinery/door/airlock/centcom{name = "Engineering Special Operations"; opacity = 1; req_access = list(103)},/turf/unsimulated/floor{icon_state = "vault"; dir = 8},/area/centcom/specops)
@@ -2304,52 +2284,52 @@ aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtvtvtvtvyAyDyCyKyGuhuhuhwoyQuhxQylyWySxQxQxQxQxcxQxQxQyYyXwoxQxQyZtvufufvVtxtxvlvmvmvmvotxtxueufuftxaMaMaMaMaMtxysystxyLyLyLuNyuywywywywyMtxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvuhuhuhuhuhuhuhuhxkzeuhxQzgzgzgxQxQxQxQxcxQxQxQyYyXxkyJyEyFtvufufwKyTyTyTyTyTyTyTyTyTwTufuftxaMaMaMaMaMtxyUystxyLyVyLuNyuyuyuyuyuyutxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvuhuhuhuhuhuhuhuhtvwCuhuhzhuhuhuhxQxQwCymxQxQxQyYyXtvtvtvtvtvtxxvzixYtxufufufufuftxtxtxtxtxtxaMaMaMaMaMtxzfystxvFuNuNuNyuaMaMaMaMaMtxuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvzkzkzlznzmzCzxwDtvzOzDvMtvAbAbtvvMzDzOycAexQxQyYyXtvzvzwzwzvzFzGDCzHCNtxxvAhxYtxtxaMaMaMaMaMaMaMaMaMaMtxtxtxtxtxtxtxtxyuaMaMaMaMaMzyuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzzmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtwgmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmt
-mumumumumumumumumumumuAnAnAnAnAnAoArArArAsAnAnAnAnAnAnAnAnAnAnAnmumumumumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtvtvtvtvtvtvtvtvtvtvtvtvzAzBzBzAtvtvtvtvABxQxQyYyXtvzvzIzIzvzJzQDCzHCNApAfDCAqAFCNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzKururzLzLururzKaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumumumumumumumumuAnAnAnAnAnAKAZASBaAKAnAnAnAnAnAnAnAnAnAnAnmumumumumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzMzNzNzNzNBvBvzNzNzPaMtvBzxQxQyYyXtvzvzwzwzvAGzQDCzHCNAJDCDCDCAPCNaMaMaMaMaMaMaMaMaMaMaMaMzRzSNaNaNazTzUaMaMaMaMaMtxzVururururzWtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumumumumumumumumuAnAnAnAnAnAKBMASASAKAnAnAnAnAnAnAnAnAnAnAnmumumumumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzXzYzZAaBYAcAcAdCnzNzPtvtvxcxctvtvtvzvzvzvzvAQzQDCzHCNBcBbBcBdBcCNaMaMaMaMaMaMaMaMaMaMaMzRAiNiNjNkNlNmAlzUaMaMaMaMtxtxtxtxtxtxtxtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumumumumuAnAnAnArDEArDIAnDUDEArDIEpDWArArArArArAsAnAnAnAnAnmumumumumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzXzYAmAcAcAcAcAcAcEsErwoxQxQxQxQxQxOzvBezvBezFzQDCBtBfAJDCBFDCBGCNaMaMaMaMaMaMaMaMaMaMzRAiAMAvADAvADAvBOAlzUaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumuAnAnAnAnFYFZASASASASASASASASASASASASASASASASAKAnAnAnAnAnmumumumumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzXzYAxAyAzAzAzAzAzzNAAxPxQxQxQxQxQxczvBezvBezJzQDCBtBfBPDCBRBQBSCNaMaMaMaMaMaMaMaMaMaMACADADADBNNcOKADADADACaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumuAnAnASHkFYHkASASASASASASASASASASASASASASASASHmIJIIAnAnAnmumumumumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAEzNzNzNzNzNzNzNzNAAaMxkxQxQxQxQxQtvzvBezvBeAGCeCdCfCNBcCgCiChBcCNaMaMaMaMaMaMaMaMaMaMAtNTBuNhNeNgNeNfCrNQAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumuAnAnFYHkFYAnAnAnDUArArAsEpDUArILDIEpISASASASEpIUITAnAnAnmumumumumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHCNCNCNCNCNCNCNCNCNCjDCDCCkAPCNCNCNaMaMaMaMaMaMaMaMAtIVACATARAUARATACIVAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumuAnFYFYAnAnAnAnAnAnAnAnAKASASBMAKIWASAKASASASEpIUIXAnAnISmumumumumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWAWAWAWAWAWAWAWAWAWAWAWAWAXAYIYJaClCmCmCmCmCmCNDyCoCpDCDCCuAPCoDyCNaMaMaMaMaMaMaMaMAtADCrAtNYCvOfAtBuADAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumuAnFYAnAnAnmumuAnDUArDIJcJbASAZAKJbAZAKASASASISIUIUIUJlAKmumumumumumuaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWAWBlBmBnBlBmBmBoBpBqBmBrBsAYAWAWCwCmCmCmCmCmCNDyCxCpDCDCDCAPCxDyCNCNCNCNCNCNaMaMaMACADCrCCMQMRMPCCBuADACaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumuAnJoJoAnmumumuAnJpJqJqDWArArArDEArArJrASASASAKIUIUIUJyAKmumumumumumuaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWBlByJzBABBBCBCBCBCBCBCBDBEAYAWAWClCmCmCmCmCmCNDyCxCpDCDCDCCyCxDyDyDyDyDyDyCNaMaMzRAiNTCrDfMQBwMPDfBuNQAlzUaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumuAnFYFYFYFYAnAnmumuAnJAJBJAEpASASASASASASASASASASAKJDJCJEDUJrmumumumumumuaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWBIBJBKBJBLBJBJBJBJBJBJBJJFAWAWAWCNCNCNCNCzCACNDyCxCpDCDCDCCFCECGCGCGCGCGCGCGCGCHAtBgADCrAlACJHACAiBuADBgAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumuJIFYFYFYFYJJAnmumuISJKJAJAEpASASASASASASASASASASAKAnAnAnAnAnmumumumumumuaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWBWBXJLBZBBCaCaCaCaCaCaCbCcAYAWAWCNCJCICKCPCPCNCQCLCRDCDCDCDCDDDCDCCSDCDCCTCVCmCVJNADADADOJCWADADOJADADCrACaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumuJOJVJUFYJWFYFYmumuHmJXJYAoArArArArArArILArDIEpDUDEILArArArArArArAsmumuaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWAWBWBmCsBWBmBmBoBpBqBmCtBsAYAWAWCNCYCXDbCPCPDcDCDDDCDCDCDCDCDDDCDCDCDCDCCTDdCGCHAtOpADCrCCBuADCrCCBuADOuAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumuJZFYKaFYJUFYFYmumuAnAnAnAKASASASASASASAKKbKcKcKcKdAKASASASASASASAKmuaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWAWAWAWAWAWAWAWAWAWAWAWAWAXAYAWAWCNDrDpDFCPCPDcDCDDDCDCDCDCDMDLCGEcDCDCECEdCNaMaMCCBuADCrCMBuADCrCMBuADCrCCaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumuAnFYKjFYOQFYFYmumuaMaMmuAKASAZASASASASHmKcKcKuKcKcHmASASASASAZASAKmuaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNIqImImCPCPCNEKEEEXDCEYDCCyFlDyFxDCCTGOFGCNaMaMCMBuADCrCMBuNcCrCMBuADCrCMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumuAnKxKwFYFYKyFYmumuaMaMmuAKASASASASASASEpKcKcKzKcKcEpASASASASASASAKmuaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNGTGRGRGRHfCZDaCPCPCPHQCPCPCPCPCPCPCPCPCPCPNyCPCNDyCxIKDCDCDCCFCECGJMDCDCKvKiCNaMaMDfBuADCrCMBuADCrCMBuADCrDfaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumuAnAnFYFYFYFYAnmumumAaMaMAKASASISKAKCKBISKcKLKDKcKcISKAKCKBISASASAKaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNMSMSMSMSMSDhDiDjDkDlCPDmDnDoDlCPCPCPCPCPCPCPCPCNDyCxMTDCDCDCDCDDDCDCDCDCDCCTDdCGCHAtPxADCrDfBuADCrDfBuADPwAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumuAnAnAnAnKMKNAnmumBmAaMaMHmASASHmaMaMaMDWDIKAKCKBDUJraMaMaMHmASASHmaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNMSMVMSMSMSDsDiDtDuDlCPDmDvDwDlCPCPDxDxDxDxDxDxCNDyDzDADBDCDCDCDDDCDCDCDCDCCTCVCmCVKOADADPvADADADADADPvADCrACaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumuAnAnAnAnAnAnmuaMaMaMaMaMKPKQKQKRaMaMaMaMaMaMaMaMaMaMaMaMaMKPKQKQKRaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNMSMWMSMSMSDsDaCPCPCPNyCPCPCPCPCPDGDHDHDHDHDHDHCNCNCNCNMXKSKSCNCNCNCNDdCGCGCGCGCGCHEAACNNATzSzTKTzSzTATNNACBVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumumumumumumumuaMaMaMaMKPKVKUKRaMaMaMaMaMaMaMaMaMaMaMaMaMKPKVKUKRaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNMSMSMZMSNdDsDiDNDODlCPDmDPDQDlCPDGDRDSDSDSDSDSCNDTDTDTNDDVDVKWDXDXCNDyDyDyDyCNaMaMAtNENFAtNHNIEaNKNJAtNLNGAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumumumumumumuaMaMaMaMaMKPKVKUKRaMaMaMaMaMaMaMaMaMaMaMaMaMKPKVKUKRaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNNoMSMSNrMSDsDiEeEfDlCPDmEgEhDlCPDGDSDSDSDSDSDSCNEiEjEjElDVDVDVDXDXCNCNCNCNCNCNaMaMAtNuPBAtNwNVEaEaKXAtPANxAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumumumumumumuaMaMaMaMaMKYKQKQKZaMaMaMKYaMaMaMaMaMKZaMaMaMKYKQKQKZaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNNzMSMSMSMSEoDaCPCPCPCPCPCPCPCPCPDGDSDSLaEqLbLcCNEtDVDVDVEwExDVDVEyCNaMaMaMaMaMaMaMEAEBEBAtPzEaNREbPyAtEBEBBVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumumumuaMaMaMaMaMaMaMaMMHLfMLMHaMaMaMLgMOMIMIMIMJLkaMaMaMMHNnLmMHaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNMSNANOMVNWNSEFEGEGEGEHEHEHEIEJLnELEMEHEHEHCNCNCNNvDVDVEwEPEQExERESCNaMaMaMaMaMaMaMETEVEVBVDYDZEaNtNsEAEVEVEWaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumumumuaMaMaMaMaMaMaMaMLsMpMwLsaMaMKYLsLrMmMnMoLrLsKZaMaMLsMGMFLsaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNMSMSMSNWNXEZEZEZEZEZEHFaFbFcFdFeFfFgFbFaEHCNCNCNCNCNCNOmFiNqFkERESCNaMaMaMaMaMaMaMaMaMaMETATEUEUEUATEWaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumumumuaMaMaMaMaMaMaMaMLsOoPpLsaMaMLgMfPoOhOROhPnMeLkaMaMLsPmOgLsaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNPbMSNWNXEZEZEZEZEZEZEHFbFmFnFdFeFfFnFoFbEHFpFqFrFsFtCNDVFhFkDVDVEwFuaMaMaMaMaMaMaMaMaMaMaMETEVEVEVEWaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumumumuaMaMaMaMaMaMaMaMLyOeLpLoLpLpLXOdMaMaMaMaMaOcLyLpLpLoLpNBLXaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNMSNWNXEZEZEZEZEZEZEZEHFvFbFvFdFeFfFvFbFvEHFwDVDVDVDVMqDVDVDVDVDVFyFzaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumumumuaMaMaMaMaMaMaMaMLsMsEDMuCOMvLsOLMaMaMaMaMaOLLsMyMxGLMzMsLsaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNNWNXEZEZEZEZEZEZEZEZEHFAFbFbFdFeFfFbFbFBEHFCFDFEFFMCCNDVDVDVDVDVFHFIaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumuaMaMaMaMaMaMaMaMaMaMaMLsMsMDMDMDPqLsOwOGOHMbOwOGOHLsPrMDMDMKMsLsaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHCNCNCNCNCNCNCNCNCNCNCNEHFJFKFKFdFeFfFLFLFMEHFNFOFPFQFRCNFSFTFUFVFWFXCNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumuaMaMaMaMaMaMaMaMaMaMaMLwMsMDMDMDMDMbMaMaMaMaMaMaMaMbMDMDMMMDMsLwaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeFeFeFeFeFeFeFeFeFeFeEHEHMNEHEHFeEHEHMNEHEHEHEHEHEHEHCNCNCNCNCNCNCNCNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumuaMaMaMaMaMaMaMaMaMaMLWNbMDPtMDMDLsHjMaMaMaMaMaPuLsMDNMMDNUMsLWaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHEHEHEHNZEHEHEHFeFeFeFeFeFeEHFeEHFeFeFeFeFeFeFeFeEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumuaMaMaMaMaMaMaMaMaMaMLeNbMDMDLgLlLoLpLkLjLiLhLgLpLoLlLkOjOiOkLeaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHGaGbGbGbGbGcEHEHEHEHEHEHEHEHGdEHEHEHEHEHEHEHEHFeEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumuaMaMaMaMaMaMaMaMaMKYLsOPOlOlLsOnPhOnLwLjLtLhLwOqOOOrLsOtOsOMLsKZaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHGaGbGbGbGbGcEHGeGfGgGfGhGiGiGiGiGiGhGiGhGiGjEHFeEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumuaMaMaMaMmumuaMaMaMOvLdKsKsLYLXOnOnOnLWLjLiLhLWOrOrOxLyLZKsKsLdOyaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHGkGbGbGbGbGlEHGiGmGmGmGmGmGiGiGiGmGmGmGmGnGoEHFeEHEHEHEHEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumuaMaMaMaMmumuaMaMaMaMOvOzOzOyLsOBOAOnLePiMaPiLeOrOrOCLsOvOzOzOyaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHGkGpGqGqGbGbGrGiGiGsGtGsGiGiGiGiGiGsGtGsGuGiEHFeFeFeFeFeFeFeEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumuaMaMaMaMmumuaMaMaMaMaMaMaMaMLsOnOnOnLyLpMbLpLXODOrOELsaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHFeEHEHEHEHEHEHEHEHGiGmGmGmGmGmGiGiGiGmGmGmGmGvGiEHEHEHEHEHEHEHFeEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMLsOnOnOFLsMcMaMdLsOrOrOILsaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAFeEHEHzazazazazaEHGxGxGxGxGxGxGxGxGxGxGxGxGxGyGxEHzbzbzbzbzbEHFeFeFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMMeLkPjOnLsMhMaPlLsONPkLgMfaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHEHEHHgHgHgHgHgEHGBGCGCGCGCGCGCGCGCGCGCGCGCGDGBEHHgHgHgHgHgEHEHEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMOvMeLpMiMfMkMjMlMeMiLpMfOyaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGGGGGGGGGFGIGCGCGCGCGCGCGCGCGCGCGCGCGDGJGFGKGKGKGKGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumumumuaMaMaMaMmumuaMaMaMaMaMaMaMaMOvLdKsKsKsKsKsLdOyaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGMGGGMGGGFGIGCGCGCGCGCGCGCGCGCGCGCGCGDGJGFGKGNGKGNGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumumumuaMaMaMaMmumumuaMaMaMaMaMaMaMaMOvOzOzOzOzOzOyaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGGPcGGGGGFGIGCGCGCGCGCGPGQGPGCGCGCGCGDGJGFGKGKPdGKGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-mumumumumumuaMaMaMaMmumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGGGGGGGGGFGIGCGCGCGCGCGSPeGSGCGCGCGCGDGJGFGKGKGKGKGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGU
-mumumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGMGGGMGGGFGIGCGCGCGCGCGVGWGXGCGCGCGCGDGJGFGKGNGKGNGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGZGYGYGYHaHaHaGYGYHaHaHaGYGYGYGYGYGU
-mumumumuaMaMaMaMaMaMaMaMaMaMmumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHFbGHGGGGGGGGGGGFGIGCGCGCGCGCGCHcGCGCGCGCGCGDGJGFGKGKGKGKGKGHFbEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUHdGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYHeGU
-mumumumuaMaMaMaMaMaMaMaMmumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHOSEHHbHbHbHbHbEHGBGCGCGCGCGCGCHcGCGCGCGCGCGDGBEHHbHbHbHbHbEHOSEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYGYGYGYGYGYGYGYGYHhGYGYGYGYGYGU
-mumumumuaMaMaMaMaMaMaMmumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFJHiFbEHGzGzGzGzGzEHGxGxGxGxGxGxOTHlOTGxGxGxGxGyGxEHGEGEGEGEGEEHFbHnFMEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYGYGYGYGYGYGYGYGYHdGYGYGYGYGYGU
+mtmtmtmtmtmtmtmtmtmtAomtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvzkzkzlznzmzCzxwDtvzOzDvMtvAbAbtvvMzDzOycAexQxQyYyXtvzvzwzwzvzFzGDCzHCNtxxvAhxYtxtxaMaMaMaMaMaMaMaMaMaMtxtxtxtxtxtxtxtxyuaMaMaMaMaMzyuryNuPuPyOuryPaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzzmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtwgmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmt
+dCdCdCdCdCdCdCdCdCdCdCAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsAsdCdCdCdCdCdCdCmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMtvtvtvtvtvtvtvtvtvtvtvtvtvzAzBzBzAtvtvtvtvABxQxQyYyXtvzvzIzIzvzJzQDCzHCNApAfDCAqAFCNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzKururzLzLururzKaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumumumumumumumudCAnAnAnAnAnAsAZASBaAsAnAnAnAnAnAnAnAnAnAnAnmumudCmumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzMzNzNzNzNBvBvzNzNzPaMtvBzxQxQyYyXtvzvzwzwzvAGzQDCzHCNAJDCDCDCAPCNaMaMaMaMaMaMaMaMaMaMaMaMzRzSNaNaNazTzUaMaMaMaMaMtxzVururururzWtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumumumumumumumudCAnAnAnAnAnAsBMASASAsAnAnAnAnAnAnAnAnAnAnAnmumudCmumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzXzYzZAaBYAcAcAdCnzNzPtvtvxcxctvtvtvzvzvzvzvAQzQDCzHCNBcBbBcBdBcCNaMaMaMaMaMaMaMaMaMaMaMzRAiNiNjNkNlNmAlzUaMaMaMaMtxtxtxtxtxtxtxtxaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumumumumuAnAnAnAsAsAsAsAnAsAsAsAsEpAsAsAsAsAsAsAsAnAnAnAnAnmumudCmumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzXzYAmAcAcAcAcAcAcEsErwoxQxQxQxQxQxOzvBezvBezFzQDCBtBfAJDCBFDCBGCNaMaMaMaMaMaMaMaMaMaMzRAiAMAvADAvADAvBOAlzUaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumuAnAnAnAnFYFZASASASASASASASASASASASASASASASASAsAnAnAnAnAnmumudCmumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMzXzYAxAyAzAzAzAzAzzNAAxPxQxQxQxQxQxczvBezvBezJzQDCBtBfBPDCBRBQBSCNaMaMaMaMaMaMaMaMaMaMACADADADBNNcOKADADADACaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumuAnAnASHkFYHkASASASASASASASASASASASASASASASASAsIJIIAnAnAnmumudCmumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAEzNzNzNzNzNzNzNzNAAaMxkxQxQxQxQxQtvzvBezvBeAGCeCdCfCNBcCgCiChBcCNaMaMaMaMaMaMaMaMaMaMAtNTBuNhNeNgNeNfCrNQAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumuAnAnFYHkFYAnAnAnAsAsAsAsEpAsAsAsAsEpAsASASASEpIUITAnAnAnmumudCmumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHCNCNCNCNCNCNCNCNCNCjDCDCCkAPCNCNCNaMaMaMaMaMaMaMaMAtIVACATARAUARATACIVAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumuAnFYFYAnAnAnAnAnAnAnAnAsASASBMAsIWASAsASASASEpIUIXAnAnAsmumudCmumumumumtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWAWAWAWAWAWAWAWAWAWAWAWAWAXAYIYJaClCmCmCmCmCmCNDyCoCpDCDCCuAPCoDyCNaMaMaMaMaMaMaMaMAtADCrAtNYCvOfAtBuADAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumuAnFYAnAnAnmumuAnDUArDIAsJbASAZAsJbAZAsASASASAsIUIUIUJlAsmumudCmumumuaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWAWBlBmBnBlBmBmBoBpBqBmBrBsAYAWAWCwCmCmCmCmCmCNDyCxCpDCDCDCAPCxDyCNCNCNCNCNCNaMaMaMACADCrCCMQMRMPCCBuADACaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumuAnJoJoAnmumumuAnJpJqJqAsAsAsAsAsAsAsAsASASASAsIUIUIUJyAsmumudCmumumuaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWBlByJzBABBBCBCBCBCBCBCBDBEAYAWAWClCmCmCmCmCmCNDyCxCpDCDCDCCyCxDyDyDyDyDyDyCNaMaMzRAiNTCrDfMQBwMPDfBuNQAlzUaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmuAnFYFYFYFYAnAnmumuAnJAJBJAEpASASASASASASASASASASAsJDJCJEAsAsmumudCmumumuaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWBIBJBKBJBLBJBJBJBJBJBJBJJFAWAWAWCNCNCNCNCzCACNDyCxCpDCDCDCCFCECGCGCGCGCGCGCGCGCHAtBgADCrAlACJHACAiBuADBgAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmuJIFYFYFYFYJJAnmumuISJKJAJAEpASASASASASASASASASASAsAnAnAnAnAnmumudCmumumuaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWBWBXJLBZBBCaCaCaCaCaCaCbCcAYAWAWCNCJCICKCPCPCNCQCLCRDCDCDCDCDDDCDCCSDCDCCTCVCmCVJNADADADOJCWADADOJADADCrACaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmuJOJVJUFYJWFYFYmumuHmJXJYAsAsAsAsAsAsAsAsAsAsEpAsAsAsAsAsAsAsAsAsAsmumuaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWAWBWBmCsBWBmBmBoBpBqBmCtBsAYAWAWCNCYCXDbCPCPDcDCDDDCDCDCDCDCDDDCDCDCDCDCCTDdCGCHAtOpADCrCCBuADCrCCBuADOuAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmuJZFYKaFYJUFYFYmumuAnAnAnAsASASASASASASAsKbKcKcKcKdAsASASASASASASAsmuaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAVAWAWAWAWAWAWAWAWAWAWAWAWAWAXAYAWAWCNDrDpDFCPCPDcDCDDDCDCDCDCDMDLCGEcDCDCECEdCNaMaMCCBuADCrCMBuADCrCMBuADCrCCaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmuAnFYKjFYOQFYFYmumuaMaMmuAsASAZASASASASAsKcKcKuKcKcAsASASASASAZASAsmuaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNIqImImCPCPCNEKEEEXDCEYDCCyFlDyFxDCCTGOFGCNaMaMCMBuADCrCMBuNcCrCMBuADCrCMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmuAnKxKwFYFYKyFYmumuaMaMmuAsASASASASASASEpKcKcKzKcKcEpASASASASASASAsmuaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNGTGRGRGRHfCZDaCPCPCPHQCPCPCPCPCPCPCPCPCPCPNyCPCNDyCxIKDCDCDCCFCECGJMDCDCKvKiCNaMaMDfBuADCrCMBuADCrCMBuADCrDfaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmuAnAnFYFYFYFYAnmumumAaMaMAsASASAsKAKCKBAsKcKLKDKcKcAsKAKCKBAsASASAsaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNMSMSMSMSMSDhDiDjDkDlCPDmDnDoDlCPCPCPCPCPCPCPCPCNDyCxMTDCDCDCDCDDDCDCDCDCDCCTDdCGCHAtPxADCrDfBuADCrDfBuADPwAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmuAnAnAnAnKMKNAnmumBmAaMaMAsASASAsaMaMaMAsAsKAKCKBAsAsaMaMaMAsASASAsaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNMSMVMSMSMSDsDiDtDuDlCPDmDvDwDlCPCPDxDxDxDxDxDxCNDyDzDADBDCDCDCDDDCDCDCDCDCCTCVCmCVKOADADPvADADADADADPvADCrACaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmuAnAnAnAnAnAnmuaMaMaMaMaMKPKQKQKRaMaMaMaMaMaMaMaMaMaMaMaMaMKPKQKQKRaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNMSMWMSMSMSDsDaCPCPCPNyCPCPCPCPCPDGDHDHDHDHDHDHCNCNCNCNMXKSKSCNCNCNCNDdCGCGCGCGCGCHEAACNNATzSzTKTzSzTATNNACBVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumumumumumumumuaMaMaMaMKPKVKUKRaMaMaMaMaMaMaMaMaMaMaMaMaMKPKVKUKRaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNMSMSMZMSNdDsDiDNDODlCPDmDPDQDlCPDGDRDSDSDSDSDSCNDTDTDTNDDVDVKWDXDXCNDyDyDyDyCNaMaMAtNENFAtNHNIEaNKNJAtNLNGAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumumumumumumuaMaMaMaMaMKPKVKUKRaMaMaMaMaMaMaMaMaMaMaMaMaMKPKVKUKRaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNNoMSMSNrMSDsDiEeEfDlCPDmEgEhDlCPDGDSDSDSDSDSDSCNEiEjEjElDVDVDVDXDXCNCNCNCNCNCNaMaMAtNuPBAtNwNVEaEaKXAtPANxAtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumumumumumumuaMaMaMaMaMKYKQKQKZaMaMaMKYaMaMaMaMaMKZaMaMaMKYKQKQKZaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNNzMSMSMSMSEoDaCPCPCPCPCPCPCPCPCPDGDSDSLaEqLbLcCNEtDVDVDVEwExDVDVEyCNaMaMaMaMaMaMaMEAEBEBAtPzEaNREbPyAtEBEBBVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumumumuaMaMaMaMaMaMaMaMAKLfMLAKaMaMaMAKMOMIMIMIMJAKaMaMaMAKNnLmAKaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNMSNANOMVNWNSEFEGEGEGEHEHEHEIEJLnELEMEHEHEHCNCNCNNvDVDVEwEPEQExERESCNaMaMaMaMaMaMaMETEVEVBVDYDZEaNtNsEAEVEVEWaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumumumuaMaMaMaMaMaMaMaMAKMpMwAKaMaMKYAKLrMmMnMoLrAKKZaMaMAKMGMFAKaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNMSMSMSNWNXEZEZEZEZEZEHFaFbFcFdFeFfFgFbFaEHCNCNCNCNCNCNOmFiNqFkERESCNaMaMaMaMaMaMaMaMaMaMETATEUEUEUATEWaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumumumuaMaMaMaMaMaMaMaMAKOoPpAKaMaMAKAKPoOhOROhPnAKAKaMaMAKPmOgAKaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNPbMSNWNXEZEZEZEZEZEZEHFbFmFnFdFeFfFnFoFbEHFpFqFrFsFtCNDVFhFkDVDVEwFuaMaMaMaMaMaMaMaMaMaMaMETEVEVEVEWaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumumumuaMaMaMaMaMaMaMaMAKOeAKAKAKAKAKOdMaMaMaMaMaOcAKAKAKAKAKNBAKaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNMSNWNXEZEZEZEZEZEZEZEHFvFbFvFdFeFfFvFbFvEHFwDVDVDVDVMqDVDVDVDVDVFyFzaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumumumuaMaMaMaMaMaMaMaMAKMsEDMuCOMvAKOLMaMaMaMaMaOLAKMyMxGLMzMsAKaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMCNNWNXEZEZEZEZEZEZEZEZEHFAFbFbFdFeFfFbFbFBEHFCFDFEFFMCCNDVDVDVDVDVFHFIaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumuaMaMaMaMaMaMaMaMaMaMaMAKMsMDMDMDPqAKOwOGOHMbOwOGOHAKPrMDMDMKMsAKaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMAHCNCNCNCNCNCNCNCNCNCNCNEHFJFKFKFdFeFfFLFLFMEHFNFOFPFQFRCNFSFTFUFVFWFXCNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumuaMaMaMaMaMaMaMaMaMaMaMLwMsMDMDMDMDMbMaMaMaMaMaMaMaMbMDMDMMMDMsLwaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeFeFeFeFeFeFeFeFeFeFeEHEHMNEHEHFeEHEHMNEHEHEHEHEHEHEHCNCNCNCNCNCNCNCNaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumuaMaMaMaMaMaMaMaMaMaMLWNbMDPtMDMDAKHjMaMaMaMaMaPuAKMDNMMDNUMsLWaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHEHEHEHNZEHEHEHFeFeFeFeFeFeEHFeEHFeFeFeFeFeFeFeFeEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumuaMaMaMaMaMaMaMaMaMaMLeNbMDMDAKLlAKAKAKLjLiLhAKAKAKLlAKOjOiOkLeaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHGaGbGbGbGbGcEHEHEHEHEHEHEHEHGdEHEHEHEHEHEHEHEHFeEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumuaMaMaMaMaMaMaMaMaMKYAKOPOlOlAKOnPhOnLwLjLtLhLwOqOOOrAKOtOsOMAKKZaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHGaGbGbGbGbGcEHGeGfGgGfGhGiGiGiGiGiGhGiGhGiGjEHFeEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumuaMaMaMaMmumuaMaMaMOvAKKsKsAKAKOnOnOnLWLjLiLhLWOrOrOxAKAKKsKsAKOyaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHGkGbGbGbGbGlEHGiGmGmGmGmGmGiGiGiGmGmGmGmGnGoEHFeEHEHEHEHEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumuaMaMaMaMmumuaMaMaMaMOvOzOzOyAKOBOAOnLePiMaPiLeOrOrOCAKOvOzOzOyaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFeEHGkGpGqGqGbGbGrGiGiGsGtGsGiGiGiGiGiGsGtGsGuGiEHFeFeFeFeFeFeFeEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumuaMaMaMaMmumuaMaMaMaMaMaMaMaMAKOnOnOnAKAKMbAKAKODOrOEAKaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHFeEHEHEHEHEHEHEHEHGiGmGmGmGmGmGiGiGiGmGmGmGmGvGiEHEHEHEHEHEHEHFeEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMAKOnOnOFAKMcMaMdAKOrOrOIAKaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAFeEHEHzazazazazaEHGxGxGxGxGxGxGxGxGxGxGxGxGxGyGxEHzbzbzbzbzbEHFeFeFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMAKAKPjOnAKMhMaPlAKONPkAKAKaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHEHEHHgHgHgHgHgEHGBGCGCGCGCGCGCGCGCGCGCGCGCGDGBEHHgHgHgHgHgEHEHEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumumumuaMaMaMaMaMaMaMaMaMaMaMaMOvAKAKAKAKMkMjMlAKAKAKAKOyaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGGGGGGGGGFGIGCGCGCGCGCGCGCGCGCGCGCGCGDGJGFGKGKGKGKGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumumumuaMaMaMaMmumuaMaMaMaMaMaMaMaMOvAKKsKsKsKsKsAKOyaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGMGGGMGGGFGIGCGCGCGCGCGCGCGCGCGCGCGCGDGJGFGKGNGKGNGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumumumuaMaMaMaMmumumuaMaMaMaMaMaMaMaMOvOzOzOzOzOzOyaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGGPcGGGGGFGIGCGCGCGCGCGPGQGPGCGCGCGCGDGJGFGKGKPdGKGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+dCmumumumumuaMaMaMaMmumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGGGGGGGGGFGIGCGCGCGCGCGSPeGSGCGCGCGCGDGJGFGKGKGKGKGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGUGU
+dCmumumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHzjGAGGGMGGGMGGGFGIGCGCGCGCGCGVGWGXGCGCGCGCGDGJGFGKGNGKGNGKGAGwEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGZGYGYGYHaHaHaGYGYHaHaHaGYGYGYGYGYGU
+dCmumumuaMaMaMaMaMaMaMaMaMaMmumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHFbGHGGGGGGGGGGGFGIGCGCGCGCGCGCHcGCGCGCGCGCGDGJGFGKGKGKGKGKGHFbEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUHdGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYGYHeGU
+dCmumumuaMaMaMaMaMaMaMaMmumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFAEHOSEHHbHbHbHbHbEHGBGCGCGCGCGCGCHcGCGCGCGCGCGDGBEHHbHbHbHbHbEHOSEHFBEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYGYGYGYGYGYGYGYGYHhGYGYGYGYGYGU
+dCmumumuaMaMaMaMaMaMaMmumumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFJHiFbEHGzGzGzGzGzEHGxGxGxGxGxGxOTHlOTGxGxGxGxGyGxEHGEGEGEGEGEEHFbHnFMEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYGYGYGYGYGYGYGYGYHdGYGYGYGYGYGU
mumuaMaMaMaMaMaMaMaMaMaMmumumuaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHEHFbEHEHEHEHEHEHEHHoHpHpHpHpHpHqHrHoHpHpHpHpHsHoEHEHEHEHEHEHEHFbEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYHtHhGYGYGYGYGYGYGYGYGYGYGYGYGYGU
aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHFbFbFeFeFeFeFeEHHoHoHuHoHuHoHoHvHwHoHuHoHuHxHoEHFeFeFeFeFeFbFbEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYGYPfPfGYGYGYGYGYGYGYGYGYGYGYGYGU
mtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtmtaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMEHEHEHEHEHEHEHFeMNHoHoHoHyHyHyHoHoHoHyHyHyHyHyHoMNFeEHEHEHEHEHEHEHaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMGUGYGYGYGYPfHzHAPfGYGYGYGYGYGYGYGYGYGYGYGU
@@ -2395,25 +2375,25 @@ aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcIcIcIcIcIcMBInIoIpMtIkIkIrHYHYaMaMaMaM
aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIsIsIcIcIcItHYIuIvIwHYHYHYHYHYHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcIcIcIcIcIxHYIyIyIzHYIAIBICIDHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIEIEIcIcIcIFHYIyIyIyPsIyIyIyIHHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcIcIcIcIcOUHYIMINIOHYIPIQIRIDHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVaMaMaMOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcIcIcIcIcItHYHYHYHYHYHYHYHYHYHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcJdJeJfJgIcJhJiJjJhJkKKJmJnMrHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVaMaMOVaMaMOVOVOVOVOVOVOVaMaMOVaMaMOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcJdJsJtJgIcJuJuJuJuJvJwJxJwJxHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVaMOVOVOVOVOVOVOVOVOVaMOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcJdJGOWJgIcJuJuJuJuJuJuJuJuJuHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVaMOVOVOVOVOVOVOVOVOVaMOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcJdJPJQJgIcJuJuJuJuJuJuJRJSJTHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVaMOVOVOVOVOVOVOVOVOVaMOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcIcIcIcIcIcJuJuJuJuJuJuJuJuJuHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYKeKfKfKgKfKfKfKgKfKfKfKgKfKfKhHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYKkKlKlJkKmKoKnJkKpKpKqJkKrOXKtHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYKlKEKkJvKGLvLuJvKHKIKpJvKJKtIGHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYHYHYHYHYHYHYHYHYHYHYHYHYHYHYHYHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVaMaMOVOVOVOVOVOVOVaMaMOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
-aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMOVOVOVOVOVaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcIcIcIcIcOUHYIMINIOHYIPIQIRIDHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcIcIcIcIcItHYHYHYHYHYHYHYHYHYHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcJdJeJfJgIcJhJiJjJhJkKKJmJnMrHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcJdJsJtJgIcJuJuJuJuJvJwJxJwJxHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcJdJGOWJgIcJuJuJuJuJuJuJuJuJuHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcJdJPJQJgIcJuJuJuJuJuJuJRJSJTHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYIcIcIcIcIcIcJuJuJuJuJuJuJuJuJuHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYKeKfKfKgKfKfKfKgKfKfKfKgKfKfKhHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYKkKlKlJkKmKoKnJkKpKpKqJkKrOXKtHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYKlKEKkJvKGLvLuJvKHKIKpJvKJKtIGHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMHYHYHYHYHYHYHYHYHYHYHYHYHYHYHYHYHYaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
+aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM
"}
diff --git a/nano/templates/aicard.tmpl b/nano/templates/aicard.tmpl
index dbc268e628..be860a52ac 100644
--- a/nano/templates/aicard.tmpl
+++ b/nano/templates/aicard.tmpl
@@ -48,11 +48,17 @@ Used In File(s): \code\game\objects\items\devices\aicard.dm
{{if data.has_ai}}
-
- Integrity:
+
+ Hardware Integrity:
-
- {{:data.integrity}}%
+
+ {{:data.hardware_integrity}}%
+
+
+ Backup Capacitor:
+
+
+ {{:data.backup_capacitor}}%
diff --git a/nano/templates/law_manager.tmpl b/nano/templates/law_manager.tmpl
index d4860c2b90..fa91140881 100644
--- a/nano/templates/law_manager.tmpl
+++ b/nano/templates/law_manager.tmpl
@@ -41,18 +41,16 @@
}
-{{if data.isSlaved && data.isAdmin}}
-
This unit is law synced to {{:data.isSlaved}}.
+{{if data.isSlaved}}
+
Law synced to {{:data.isSlaved}}.
{{/if}}
-{{if data.isMalf || data.isAIMalf}}
-
-
- {{:helper.link('Law Management', null, {'set_view' : 0}, data.view == 0 ? 'selected' : null)}}
- {{:helper.link('Law Sets', null, {'set_view' : 1}, data.view == 1 ? 'selected' : null)}}
-
+
+
+ {{:helper.link('Law Management', null, {'set_view' : 0}, data.view == 0 ? 'selected' : null)}}
+ {{:helper.link('Law Sets', null, {'set_view' : 1}, data.view == 1 ? 'selected' : null)}}
-{{/if}}
+
{{if data.view == 0}}
{{if data.has_ion_laws}}
@@ -196,6 +194,8 @@
{{/if}}
{{else data.view == 1}}
+
Remember: Stating laws other than those currently loaded may be grounds for decommissioning - NanoTrasen
+
{{for data.law_sets}}
@@ -246,7 +246,7 @@
- {{:helper.link('Load Laws', null, {'transfer_laws' : value.ref}, data.isSlaved ? 'disabled' : null)}}{{:helper.link('State Laws', null, {'state_law_set' : value.ref})}}
+ {{:helper.link('Load Laws', null, {'transfer_laws' : value.ref}, data.isMalf ? null : 'disabled')}}{{:helper.link('State Laws', null, {'state_law_set' : value.ref})}}
{{/for}}
diff --git a/tools/GenerateChangelog/ss13_genchangelog.py b/tools/GenerateChangelog/ss13_genchangelog.py
index 472fbc69aa..6f434a8d25 100644
--- a/tools/GenerateChangelog/ss13_genchangelog.py
+++ b/tools/GenerateChangelog/ss13_genchangelog.py
@@ -53,9 +53,9 @@ validPrefixes = [
'rscadd',
'imageadd',
'imagedel',
+ 'maptweak',
'spellcheck',
- 'experiment',
- 'tgs'
+ 'experiment'
]
def dictToTuples(inp):