From c14fd6741cb8e80cf7ff11b9c29252611d661cf2 Mon Sep 17 00:00:00 2001 From: Ashe Higgs Date: Thu, 28 Sep 2017 11:23:05 -0400 Subject: [PATCH 01/60] Adds Nars-Ian and clock hawks --- .../mob/living/simple_animal/friendly/dog.dm | 35 ++++++++++ .../mob/living/simple_animal/parrot.dm | 64 +++++++++++++----- icons/mob/animal.dmi | Bin 180273 -> 192019 bytes icons/mob/pets.dmi | Bin 57414 -> 59813 bytes 4 files changed, 82 insertions(+), 17 deletions(-) diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index b9b526514b..6467990776 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -424,6 +424,41 @@ setDir(i) sleep(1) +/mob/living/simple_animal/pet/dog/corgi/Ian/narsie_act() + playsound(src, 'sound/magic/demon_dies.ogg', 75, TRUE) + var/mob/living/simple_animal/pet/dog/corgi/narsie/N = new(loc) + N.setDir(dir) + gib() + +/mob/living/simple_animal/pet/dog/corgi/narsie + name = "Nars-Ian" + desc = "Ia! Ia!" + icon_state = "narsian" + icon_living = "narsian" + icon_dead = "narsian_dead" + faction = list("dog", "cult") + gold_core_spawnable = FALSE + nofur = TRUE + +/mob/living/simple_animal/pet/dog/corgi/narsie/Life() + ..() + for(var/mob/living/simple_animal/pet/P in range(1, src)) + if(P != src && prob(5)) + visible_message("[src] devours [P]!", \ + "DELICIOUS SOULS") + playsound(src, 'sound/magic/demon_attack1.ogg', 75, TRUE) + narsie_act() + P.gib() + +/mob/living/simple_animal/pet/dog/corgi/narsie/update_corgi_fluff() + ..() + speak = list("Tari'karat-pasnar!", "IA! IA!", "BRRUUURGHGHRHR") + speak_emote = list("growls", "barks ominously") + emote_hear = list("barks echoingly!", "woofs hauntingly!", "yaps in an eldritch manner.", "mutters something unspeakable.") + emote_see = list("communes with the unnameable.", "ponders devouring some souls.", "shakes.") + +/mob/living/simple_animal/pet/dog/corgi/narsie/narsie_act() + adjustBruteLoss(-maxHealth) /mob/living/simple_animal/pet/dog/corgi/regenerate_icons() diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 6357f83286..3c1a5771c3 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -33,6 +33,7 @@ icon_state = "parrot_fly" icon_living = "parrot_fly" icon_dead = "parrot_dead" + var/icon_sit = "parrot_sit" density = FALSE health = 80 maxHealth = 80 @@ -284,7 +285,7 @@ return if(!stat && M.a_intent == INTENT_HARM) - icon_state = "parrot_fly" //It is going to be flying regardless of whether it flees or attacks + icon_state = icon_living //It is going to be flying regardless of whether it flees or attacks if(parrot_state == PARROT_PERCH) parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched @@ -320,7 +321,7 @@ if(M.melee_damage_upper > 0 && !stat) parrot_interest = M parrot_state = PARROT_SWOOP | PARROT_ATTACK //Attack other animals regardless - icon_state = "parrot_fly" + icon_state = icon_living //Mobs with objects /mob/living/simple_animal/parrot/attackby(obj/item/O, mob/living/user, params) @@ -335,7 +336,7 @@ parrot_state |= PARROT_ATTACK else parrot_state |= PARROT_FLEE - icon_state = "parrot_fly" + icon_state = icon_living drop_held_item(0) else if(istype(O, /obj/item/reagent_containers/food/snacks/cracker)) //Poly wants a cracker. qdel(O) @@ -358,7 +359,7 @@ parrot_interest = null parrot_state = PARROT_WANDER | PARROT_FLEE //Been shot and survived! RUN LIKE HELL! //parrot_been_shot += 5 - icon_state = "parrot_fly" + icon_state = icon_living drop_held_item(0) return @@ -371,7 +372,7 @@ //Sprite update for when a parrot gets pulled if(pulledby && stat == CONSCIOUS) - icon_state = "parrot_fly" + icon_state = icon_living if(!client) parrot_state = PARROT_WANDER return @@ -400,11 +401,11 @@ if(parrot_perch && parrot_perch.loc != src.loc) //Make sure someone hasnt moved our perch on us if(parrot_perch in view(src)) parrot_state = PARROT_SWOOP | PARROT_RETURN - icon_state = "parrot_fly" + icon_state = icon_living return else parrot_state = PARROT_WANDER - icon_state = "parrot_fly" + icon_state = icon_living return if(--parrot_sleep_dur) //Zzz @@ -445,7 +446,7 @@ if(parrot_interest) emote("me", 1, "looks in [parrot_interest]'s direction and takes flight.") parrot_state = PARROT_SWOOP | PARROT_STEAL - icon_state = "parrot_fly" + icon_state = icon_living return //-----WANDERING - This is basically a 'I dont know what to do yet' state @@ -530,7 +531,7 @@ src.loc = parrot_perch.loc drop_held_item() parrot_state = PARROT_PERCH - icon_state = "parrot_sit" + icon_state = icon_sit return walk_to(src, parrot_perch, 1, parrot_speed) @@ -603,8 +604,8 @@ */ /mob/living/simple_animal/parrot/movement_delay() - if(client && stat == CONSCIOUS && parrot_state != "parrot_fly") - icon_state = "parrot_fly" + if(client && stat == CONSCIOUS && parrot_state != icon_living) + icon_state = icon_living //Because the most appropriate place to set icon_state is movement_delay(), clearly return ..() @@ -797,12 +798,12 @@ if(stat || !client) return - if(icon_state == "parrot_fly") + if(icon_state == icon_living) for(var/atom/movable/AM in view(src,1)) for(var/perch_path in desired_perches) if(istype(AM, perch_path)) src.loc = AM.loc - icon_state = "parrot_sit" + icon_state = icon_sit return to_chat(src, "There is no perch nearby to sit on!") return @@ -816,7 +817,7 @@ if(stat || !client) return - if(icon_state == "parrot_fly") + if(icon_state == icon_living) for(var/mob/living/carbon/human/H in view(src,1)) if(H.has_buckled_mobs() && H.buckled_mobs.len >= H.max_buckled_mobs) //Already has a parrot, or is being eaten by a slime continue @@ -824,7 +825,7 @@ return to_chat(src, "There is nobody nearby that you can sit on!") else - icon_state = "parrot_fly" + icon_state = icon_living parrot_state = PARROT_WANDER if(buckled) to_chat(src, "You are no longer sitting on [buckled]'s shoulder.") @@ -842,7 +843,7 @@ H.buckle_mob(src, force=1) pixel_y = 9 pixel_x = pick(-8,8) //pick left or right shoulder - icon_state = "parrot_sit" + icon_state = icon_sit parrot_state = PARROT_PERCH to_chat(src, "You sit on [H]'s shoulder.") @@ -961,6 +962,12 @@ fdel(json_file) WRITE_FILE(json_file, json_encode(file_data)) +/mob/living/simple_animal/parrot/Poly/ratvar_act() + playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', 75, TRUE) + var/mob/living/simple_animal/parrot/clock_hawk/H = new(loc) + H.setDir(dir) + dust() + /mob/living/simple_animal/parrot/Poly/ghost name = "The Ghost of Poly" desc = "Doomed to squawk the earth." @@ -996,4 +1003,27 @@ loc = H H.ContractDisease(P) parrot_interest = null - H.visible_message("[src] dive bombs into [H]'s chest and vanishes!", "[src] dive bombs into your chest, vanishing! This can't be good!") \ No newline at end of file +<<<<<<< HEAD + H.visible_message("[src] dive bombs into [H]'s chest and vanishes!", "[src] dive bombs into your chest, vanishing! This can't be good!") +======= + H.visible_message("[src] dive bombs into [H]'s chest and vanishes!", "[src] dive bombs into your chest, vanishing! This can't be good!") + + +/mob/living/simple_animal/parrot/clock_hawk + name = "clock hawk" + desc = "Cbyl jnaan penpxre! Fdhnnnjx!" + icon_state = "clock_hawk_fly" + icon_living = "clock_hawk_fly" + icon_sit = "clock_hawk_sit" + speak = list("Penpxre!", "Ratvar vf n qhzo anzr naljnl!") + speak_emote = list("squawks rustily", "says crassly", "yells brassly") + emote_hear = list("squawks rustily.", "bawks metallically!") + emote_see = list("flutters its metal wings.") + faction = list("ratvar") + gold_core_spawnable = FALSE + del_on_death = TRUE + death_sound = 'sound/magic/clockwork/anima_fragment_death.ogg' + +/mob/living/simple_animal/parrot/clock_hawk/ratvar_act() + return +>>>>>>> 60d3ce5... Adds Nars-Ian and clock hawks (#30856) diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index 038514d22ae6742a5d82c6078ec97a009f997dba..b860bd8426060bef34188c2b7a4d1118ce21ee7a 100644 GIT binary patch literal 192019 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

fv>m)R#hM7k#UGu%~~E?FDkJ4`0+; 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 z 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 KJztQ3*L*1WAa{+0_J;Ev!7G6$ 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

oBIX+xDx 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

N&_^f?#UC$7U2Lk!qOHoHBQ8u&G)`h>FJ&iZX)q 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⋙i>o0#e^ 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 diff --git a/icons/mob/pets.dmi b/icons/mob/pets.dmi index e852426e62d81144f285f21664624d664855bf85..647781e2b15504b477095e06ffc0cbcd27ccfeb0 100644 GIT binary patch delta 20389 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 i{C7wJmPjO$jmcksO5jD;g$T6(0000 Date: Thu, 28 Sep 2017 22:36:51 -0400 Subject: [PATCH 02/60] Configuration datum refactor --- code/__DEFINES/configuration.dm | 10 + code/__HELPERS/_logging.dm | 38 +- code/__HELPERS/game.dm | 5 +- code/__HELPERS/global_lists.dm | 91 ++ code/__HELPERS/mobs.dm | 1 - code/__HELPERS/names.dm | 251 ++++ code/__HELPERS/text.dm | 4 +- code/__HELPERS/type2type.dm | 21 + code/__HELPERS/unsorted.dm | 2 +- code/_globalvars/configuration.dm | 10 +- code/_globalvars/sensitive.dm | 16 - .../controllers/configuration/config_entry.dm | 178 +++ .../configuration/configuration.dm | 281 ++++ .../configuration/entries/comms.dm | 22 + .../configuration/entries/config.dm | 387 +++++ .../configuration/entries/dbconfig.dm | 28 + .../configuration/entries/game_options.dm | 266 ++++ code/controllers/master.dm | 4 +- code/controllers/subsystem/blackbox.dm | 2 +- code/controllers/subsystem/dbcore.dm | 23 +- code/controllers/subsystem/events.dm | 4 +- code/controllers/subsystem/job.dm | 32 +- code/controllers/subsystem/lighting.dm | 2 +- code/controllers/subsystem/mapping.dm | 9 +- code/controllers/subsystem/minimap.dm | 2 +- code/controllers/subsystem/server_maint.dm | 21 +- code/controllers/subsystem/shuttle.dm | 6 +- code/controllers/subsystem/squeak.dm | 2 +- code/controllers/subsystem/ticker.dm | 19 +- code/controllers/subsystem/vote.dm | 31 +- code/datums/ai_laws.dm | 20 +- code/datums/antagonists/datum_traitor.dm | 13 +- code/datums/datacore.dm | 2 +- code/datums/dna.dm | 399 +++++- code/datums/explosion.dm | 2 +- code/datums/helper_datums/getrev.dm | 49 +- code/game/area/areas.dm | 2 +- code/game/gamemodes/blob/blob_finish.dm | 2 +- code/game/gamemodes/brother/traitor_bro.dm | 11 +- code/game/gamemodes/changeling/changeling.dm | 14 +- .../game/gamemodes/changeling/traitor_chan.dm | 14 +- code/game/gamemodes/clock_cult/clock_cult.dm | 4 +- code/game/gamemodes/cult/cult.dm | 4 +- code/game/gamemodes/devil/devil_game_mode.dm | 9 +- code/game/gamemodes/game_mode.dm | 32 +- .../miniantags/abduction/abduction.dm | 2 +- .../abduction/machinery/experiment.dm | 2 +- .../gamemodes/nuclear/nuclear_challenge.dm | 2 +- code/game/gamemodes/revolution/revolution.dm | 6 +- code/game/gamemodes/sandbox/h_sandbox.dm | 274 ++++ code/game/gamemodes/traitor/traitor.dm | 14 +- code/game/gamemodes/wizard/spellbook.dm | 6 +- code/game/machinery/cloning.dm | 6 +- code/game/machinery/computer/card.dm | 2 +- code/game/machinery/computer/cloning.dm | 188 +++ .../game/machinery/computer/communications.dm | 2 +- code/game/machinery/computer/medical.dm | 4 +- code/game/machinery/computer/security.dm | 10 +- code/game/objects/items/AI_modules.dm | 2 +- code/game/objects/items/crayons.dm | 11 +- code/game/objects/items/manuals.dm | 962 +++++++++++++ code/game/objects/structures/ai_core.dm | 2 +- .../objects/structures/beds_chairs/chair.dm | 2 +- .../crates_lockers/closets/cardboardbox.dm | 2 +- code/game/objects/structures/mirror.dm | 229 +++ code/game/turfs/space/space.dm | 2 +- code/game/world.dm | 60 +- code/modules/admin/IsBanned.dm | 13 +- code/modules/admin/NewBan.dm | 5 +- code/modules/admin/admin.dm | 35 +- code/modules/admin/admin_ranks.dm | 8 +- code/modules/admin/admin_verbs.dm | 4 +- code/modules/admin/ipintel.dm | 21 +- .../admin/permissionverbs/permissionedit.dm | 4 +- code/modules/admin/player_panel.dm | 12 +- code/modules/admin/secrets.dm | 9 +- code/modules/admin/sql_message_system.dm | 16 +- code/modules/admin/topic.dm | 47 +- code/modules/admin/verbs/adminhelp.dm | 11 +- code/modules/admin/verbs/adminpm.dm | 4 +- code/modules/admin/verbs/debug.dm | 6 +- code/modules/admin/verbs/fps.dm | 8 +- code/modules/admin/verbs/one_click_antag.dm | 26 +- code/modules/admin/verbs/panicbunker.dm | 13 +- code/modules/admin/verbs/playsound.dm | 5 +- code/modules/admin/verbs/possess.dm | 2 +- code/modules/admin/verbs/randomverbs.dm | 1262 +++++++++++++++++ .../admin/verbs/reestablish_db_connection.dm | 2 +- code/modules/awaymissions/gateway.dm | 2 +- code/modules/client/client_procs.dm | 79 +- code/modules/client/preferences.dm | 184 ++- code/modules/client/preferences_savefile.dm | 18 +- code/modules/client/verbs/ooc.dm | 4 +- code/modules/emoji/emoji_parse.dm | 2 +- code/modules/error_handler/error_handler.dm | 20 +- code/modules/error_handler/error_viewer.dm | 5 +- code/modules/events/_event.dm | 4 +- code/modules/events/wizard/summons.dm | 4 +- code/modules/hydroponics/grown/replicapod.dm | 2 +- code/modules/jobs/job_exp.dm | 23 +- code/modules/jobs/job_types/assistant.dm | 46 + code/modules/jobs/job_types/job.dm | 8 +- code/modules/jobs/job_types/security.dm | 4 +- code/modules/jobs/job_types/silicon.dm | 41 + code/modules/mob/dead/dead.dm | 13 +- code/modules/mob/dead/new_player/login.dm | 7 +- .../modules/mob/dead/new_player/new_player.dm | 20 +- .../mob/dead/new_player/preferences_setup.dm | 2 +- code/modules/mob/living/brain/brain.dm | 2 +- .../living/carbon/alien/humanoid/humanoid.dm | 131 +- .../mob/living/carbon/human/human_movement.dm | 7 +- .../mob/living/carbon/monkey/monkey.dm | 6 +- code/modules/mob/living/damage_procs.dm | 12 +- code/modules/mob/living/living.dm | 13 +- code/modules/mob/living/silicon/ai/say.dm | 2 +- .../modules/mob/living/silicon/robot/robot.dm | 7 +- .../living/silicon/robot/robot_movement.dm | 29 + code/modules/mob/living/silicon/robot/say.dm | 5 + .../mob/living/simple_animal/damage_procs.dm | 20 +- .../friendly/drone/drones_as_items.dm | 2 +- .../hostile/megafauna/megafauna.dm | 38 +- .../hostile/mining_mobs/necropolis_tendril.dm | 2 +- .../mob/living/simple_animal/simple_animal.dm | 5 +- .../mob/living/simple_animal/slime/life.dm | 2 +- .../mob/living/simple_animal/slime/slime.dm | 5 +- code/modules/mob/mob.dm | 2 +- code/modules/mob/transform_procs.dm | 2 +- .../file_system/programs/card.dm | 2 +- code/modules/projectiles/projectile.dm | 2 +- code/modules/projectiles/projectile/magic.dm | 4 +- .../security_levels/security_levels.dm | 12 +- code/modules/server_tools/server_tools.dm | 3 +- code/modules/shuttle/arrivals.dm | 2 +- code/modules/surgery/bodyparts/bodyparts.dm | 5 +- config/config.txt | 5 +- config/game_options.txt | 5 +- interface/interface.dm | 27 +- tgstation.dme | 12 +- 138 files changed, 5936 insertions(+), 571 deletions(-) create mode 100644 code/__DEFINES/configuration.dm delete mode 100644 code/_globalvars/sensitive.dm create mode 100644 code/controllers/configuration/config_entry.dm create mode 100644 code/controllers/configuration/configuration.dm create mode 100644 code/controllers/configuration/entries/comms.dm create mode 100644 code/controllers/configuration/entries/config.dm create mode 100644 code/controllers/configuration/entries/dbconfig.dm create mode 100644 code/controllers/configuration/entries/game_options.dm diff --git a/code/__DEFINES/configuration.dm b/code/__DEFINES/configuration.dm new file mode 100644 index 0000000000..c78dfb28ab --- /dev/null +++ b/code/__DEFINES/configuration.dm @@ -0,0 +1,10 @@ +//config files +#define CONFIG_DEF(X) /datum/config_entry/##X { resident_file = CURRENT_RESIDENT_FILE }; /datum/config_entry/##X +#define CONFIG_GET(X) global.config.Get(/datum/config_entry/##X) +#define CONFIG_SET(X, Y) global.config.Set(/datum/config_entry/##X, ##Y) + +#define CONFIG_MAPS_FILE "maps.txt" + +//flags +#define CONFIG_ENTRY_LOCKED 1 //can't edit +#define CONFIG_ENTRY_HIDDEN 2 //can't see value diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index 8f3a0163b9..91508ded32 100644 --- a/code/__HELPERS/_logging.dm +++ b/code/__HELPERS/_logging.dm @@ -26,74 +26,74 @@ /proc/log_admin(text) GLOB.admin_log.Add(text) - if (config.log_admin) + if (CONFIG_GET(flag/log_admin)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]ADMIN: [text]") //Items using this proc are stripped from public logs - use with caution /proc/log_admin_private(text) GLOB.admin_log.Add(text) - if (config.log_admin) + if (CONFIG_GET(flag/log_admin)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]ADMINPRIVATE: [text]") /proc/log_adminsay(text) - if (config.log_adminchat) + if (CONFIG_GET(flag/log_adminchat)) log_admin_private("ASAY: [text]") /proc/log_dsay(text) - if (config.log_adminchat) + if (CONFIG_GET(flag/log_adminchat)) log_admin("DSAY: [text]") /proc/log_game(text) - if (config.log_game) + if (CONFIG_GET(flag/log_game)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]GAME: [text]") /proc/log_vote(text) - if (config.log_vote) + if (CONFIG_GET(flag/log_vote)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]VOTE: [text]") /proc/log_access(text) - if (config.log_access) + if (CONFIG_GET(flag/log_access)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]ACCESS: [text]") /proc/log_say(text) - if (config.log_say) + if (CONFIG_GET(flag/log_say)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]SAY: [text]") /proc/log_prayer(text) - if (config.log_prayer) + if (CONFIG_GET(flag/log_prayer)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]PRAY: [text]") /proc/log_law(text) - if (config.log_law) + if (CONFIG_GET(flag/log_law)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]LAW: [text]") /proc/log_ooc(text) - if (config.log_ooc) + if (CONFIG_GET(flag/log_ooc)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]OOC: [text]") /proc/log_whisper(text) - if (config.log_whisper) + if (CONFIG_GET(flag/log_whisper)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]WHISPER: [text]") /proc/log_emote(text) - if (config.log_emote) + if (CONFIG_GET(flag/log_emote)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]EMOTE: [text]") /proc/log_attack(text) - if (config.log_attack) + if (CONFIG_GET(flag/log_attack)) WRITE_FILE(GLOB.world_attack_log, "\[[time_stamp()]]ATTACK: [text]") /proc/log_pda(text) - if (config.log_pda) + if (CONFIG_GET(flag/log_pda)) WRITE_FILE(GLOB.world_pda_log, "\[[time_stamp()]]PDA: [text]") /proc/log_comment(text) - if (config.log_pda) + if (CONFIG_GET(flag/log_pda)) //reusing the PDA option because I really don't think news comments are worth a config option WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]COMMENT: [text]") /proc/log_chat(text) - if (config.log_pda) + if (CONFIG_GET(flag/log_pda)) WRITE_FILE(GLOB.world_game_log, "\[[time_stamp()]]CHAT: [text]") /proc/log_qdel(text) @@ -102,6 +102,10 @@ /proc/log_sql(text) WRITE_FILE(GLOB.sql_error_log, "\[[time_stamp()]]SQL: [text]") +/proc/log_config(text) + WRITE_FILE(GLOB.config_error_log, text) + SEND_TEXT(world.log, text) + //This replaces world.log so it displays both in DD and the file /proc/log_world(text) WRITE_FILE(GLOB.world_runtime_log, text) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index c040e264e6..e38a6826f9 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -314,10 +314,11 @@ // Will return a list of active candidates. It increases the buffer 5 times until it finds a candidate which is active within the buffer. -/proc/get_candidates(be_special_type, afk_bracket = config.inactivity_period, jobbanType) +/proc/get_candidates(be_special_type, afk_bracket = CONFIG_GET(number/inactivity_period), jobbanType) var/list/candidates = list() // Keep looping until we find a non-afk candidate within the time bracket (we limit the bracket to 10 minutes (6000)) - while(!candidates.len && afk_bracket < config.afk_period) + var/afk_period = CONFIG_GET(number/afk_period) + while(!candidates.len && afk_bracket < afk_period) for(var/mob/dead/observer/G in GLOB.player_list) if(G.client != null) if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD)) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 1af231f893..c1afe0e345 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD ////////////////////////// /////Initial Building///// ////////////////////////// @@ -114,3 +115,93 @@ for(var/path in subtypesof(prototype)) L+= path return L +======= +////////////////////////// +/////Initial Building///// +////////////////////////// + +/proc/make_datum_references_lists() + //hair + init_sprite_accessory_subtypes(/datum/sprite_accessory/hair, GLOB.hair_styles_list, GLOB.hair_styles_male_list, GLOB.hair_styles_female_list) + //facial hair + init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, GLOB.facial_hair_styles_list, GLOB.facial_hair_styles_male_list, GLOB.facial_hair_styles_female_list) + //underwear + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f) + //undershirt + init_sprite_accessory_subtypes(/datum/sprite_accessory/undershirt, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f) + //socks + init_sprite_accessory_subtypes(/datum/sprite_accessory/socks, GLOB.socks_list) + //lizard bodyparts (blizzard intensifies) + init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, GLOB.body_markings_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard, GLOB.tails_list_lizard) + init_sprite_accessory_subtypes(/datum/sprite_accessory/tails_animated/lizard, GLOB.animated_tails_list_lizard) + init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, GLOB.tails_list_human) + init_sprite_accessory_subtypes(/datum/sprite_accessory/tails_animated/human, GLOB.animated_tails_list_human) + init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts, GLOB.snouts_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/horns,GLOB.horns_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, GLOB.ears_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.wings_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/wings_open, GLOB.wings_open_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, GLOB.frills_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/spines, GLOB.spines_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/spines_animated, GLOB.animated_spines_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/legs, GLOB.legs_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.r_wings_list,roundstart = TRUE) + + + //Species + for(var/spath in subtypesof(/datum/species)) + var/datum/species/S = new spath() + GLOB.species_list[S.id] = spath + + //Surgeries + for(var/path in subtypesof(/datum/surgery)) + GLOB.surgeries_list += new path() + + //Materials + for(var/path in subtypesof(/datum/material)) + var/datum/material/D = new path() + GLOB.materials_list[D.id] = D + + //Techs + for(var/path in subtypesof(/datum/tech)) + var/datum/tech/D = new path() + GLOB.tech_list[D.id] = D + + //Emotes + for(var/path in subtypesof(/datum/emote)) + var/datum/emote/E = new path() + E.emote_list[E.key] = E + + init_subtypes(/datum/crafting_recipe, GLOB.crafting_recipes) + +/* // Uncomment to debug chemical reaction list. +/client/verb/debug_chemical_list() + + for (var/reaction in chemical_reactions_list) + . += "chemical_reactions_list\[\"[reaction]\"\] = \"[chemical_reactions_list[reaction]]\"\n" + if(islist(chemical_reactions_list[reaction])) + var/list/L = chemical_reactions_list[reaction] + for(var/t in L) + . += " has: [t]\n" + to_chat(world, .) +*/ + +//creates every subtype of prototype (excluding prototype) and adds it to list L. +//if no list/L is provided, one is created. +/proc/init_subtypes(prototype, list/L) + if(!istype(L)) + L = list() + for(var/path in subtypesof(prototype)) + L += new path() + return L + +//returns a list of paths to every subtype of prototype (excluding prototype) +//if no list/L is provided, one is created. +/proc/init_paths(prototype, list/L) + if(!istype(L)) + L = list() + for(var/path in subtypesof(prototype)) + L+= path + return L +>>>>>>> 4178c20... Configuration datum refactor (#30763) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index ed855c33b9..de606b137e 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -220,7 +220,6 @@ GLOBAL_LIST_INIT(skin_tones, list( )) GLOBAL_LIST_EMPTY(species_list) -GLOBAL_LIST_EMPTY(roundstart_species) /proc/age2agedescription(age) switch(age) diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm index 67179e8c8f..f2c24dd557 100644 --- a/code/__HELPERS/names.dm +++ b/code/__HELPERS/names.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD #define ION_FILE "ion_laws.json" /proc/lizard_name(gender) @@ -244,3 +245,253 @@ GLOBAL_VAR(syndicate_code_response) //Code response for traitors. . += "." else . += ", " +======= +#define ION_FILE "ion_laws.json" + +/proc/lizard_name(gender) + if(gender == MALE) + return "[pick(GLOB.lizard_names_male)]-[pick(GLOB.lizard_names_male)]" + else + return "[pick(GLOB.lizard_names_female)]-[pick(GLOB.lizard_names_female)]" + +/proc/plasmaman_name() + return "[pick(GLOB.plasmaman_names)] \Roman[rand(1,99)]" + +/proc/church_name() + var/static/church_name + if (church_name) + return church_name + + var/name = "" + + name += pick("Holy", "United", "First", "Second", "Last") + + if (prob(20)) + name += " Space" + + name += " " + pick("Church", "Cathedral", "Body", "Worshippers", "Movement", "Witnesses") + name += " of [religion_name()]" + + return name + +GLOBAL_VAR(command_name) +/proc/command_name() + if (GLOB.command_name) + return GLOB.command_name + + var/name = "Central Command" + + GLOB.command_name = name + return name + +/proc/change_command_name(name) + + GLOB.command_name = name + + return name + +/proc/religion_name() + var/static/religion_name + if (religion_name) + return religion_name + + var/name = "" + + name += pick("bee", "science", "edu", "captain", "assistant", "monkey", "alien", "space", "unit", "sprocket", "gadget", "bomb", "revolution", "beyond", "station", "goon", "robot", "ivor", "hobnob") + name += pick("ism", "ia", "ology", "istism", "ites", "ick", "ian", "ity") + + return capitalize(name) + +/proc/station_name() + if(!GLOB.station_name) + var/newname + var/config_station_name = CONFIG_GET(string/stationname) + if(config_station_name) + newname = config_station_name + else + newname = new_station_name() + + set_station_name(newname) + + return GLOB.station_name + +/proc/set_station_name(newname) + GLOB.station_name = newname + + var/config_server_name = CONFIG_GET(string/servername) + if(config_server_name) + world.name = "[config_server_name][config_server_name == GLOB.station_name ? "" : ": [GLOB.station_name]"]" + else + world.name = GLOB.station_name + + +/proc/new_station_name() + var/random = rand(1,5) + var/name = "" + var/new_station_name = "" + + //Rare: Pre-Prefix + if (prob(10)) + name = pick(GLOB.station_prefixes) + new_station_name = name + " " + name = "" + + // Prefix + for(var/holiday_name in SSevents.holidays) + if(holiday_name == "Friday the 13th") + random = 13 + var/datum/holiday/holiday = SSevents.holidays[holiday_name] + name = holiday.getStationPrefix() + //get normal name + if(!name) + name = pick(GLOB.station_names) + if(name) + new_station_name += name + " " + + // Suffix + name = pick(GLOB.station_suffixes) + new_station_name += name + " " + + // ID Number + switch(random) + if(1) + new_station_name += "[rand(1, 99)]" + if(2) + new_station_name += pick(GLOB.greek_letters) + if(3) + new_station_name += "\Roman[rand(1,99)]" + if(4) + new_station_name += pick(GLOB.phonetic_alphabet) + if(5) + new_station_name += pick(GLOB.numbers_as_words) + if(13) + new_station_name += pick("13","XIII","Thirteen") + return new_station_name + +/proc/syndicate_name() + var/static/syndicate_name + if (syndicate_name) + return syndicate_name + + var/name = "" + + // Prefix + name += pick("Clandestine", "Prima", "Blue", "Zero-G", "Max", "Blasto", "Waffle", "North", "Omni", "Newton", "Cyber", "Bonk", "Gene", "Gib") + + // Suffix + if (prob(80)) + name += " " + + // Full + if (prob(60)) + name += pick("Syndicate", "Consortium", "Collective", "Corporation", "Group", "Holdings", "Biotech", "Industries", "Systems", "Products", "Chemicals", "Enterprises", "Family", "Creations", "International", "Intergalactic", "Interplanetary", "Foundation", "Positronics", "Hive") + // Broken + else + name += pick("Syndi", "Corp", "Bio", "System", "Prod", "Chem", "Inter", "Hive") + name += pick("", "-") + name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Code") + // Small + else + name += pick("-", "*", "") + name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Gen", "Star", "Dyne", "Code", "Hive") + + syndicate_name = name + return name + + +//Traitors and traitor silicons will get these. Revs will not. +GLOBAL_VAR(syndicate_code_phrase) //Code phrase for traitors. +GLOBAL_VAR(syndicate_code_response) //Code response for traitors. + + /* + Should be expanded. + How this works: + Instead of "I'm looking for James Smith," the traitor would say "James Smith" as part of a conversation. + Another traitor may then respond with: "They enjoy running through the void-filled vacuum of the derelict." + The phrase should then have the words: James Smith. + The response should then have the words: run, void, and derelict. + This way assures that the code is suited to the conversation and is unpredicatable. + Obviously, some people will be better at this than others but in theory, everyone should be able to do it and it only enhances roleplay. + Can probably be done through "{ }" but I don't really see the practical benefit. + One example of an earlier system is commented below. + /N + */ + +/proc/generate_code_phrase(return_list=FALSE)//Proc is used for phrase and response in master_controller.dm + + if(!return_list) + . = "" + else + . = list() + + var/words = pick(//How many words there will be. Minimum of two. 2, 4 and 5 have a lesser chance of being selected. 3 is the most likely. + 50; 2, + 200; 3, + 50; 4, + 25; 5 + ) + + var/list/safety = list(1,2,3)//Tells the proc which options to remove later on. + var/nouns = strings(ION_FILE, "ionabstract") + var/objects = strings(ION_FILE, "ionobjects") + var/adjectives = strings(ION_FILE, "ionadjectives") + var/threats = strings(ION_FILE, "ionthreats") + var/foods = strings(ION_FILE, "ionfood") + var/drinks = strings(ION_FILE, "iondrinks") + var/list/locations = GLOB.teleportlocs.len ? GLOB.teleportlocs : drinks //if null, defaults to drinks instead. + + var/list/names = list() + for(var/datum/data/record/t in GLOB.data_core.general)//Picks from crew manifest. + names += t.fields["name"] + + var/maxwords = words//Extra var to check for duplicates. + + for(words,words>0,words--)//Randomly picks from one of the choices below. + + if(words==1&&(1 in safety)&&(2 in safety))//If there is only one word remaining and choice 1 or 2 have not been selected. + safety = list(pick(1,2))//Select choice 1 or 2. + else if(words==1&&maxwords==2)//Else if there is only one word remaining (and there were two originally), and 1 or 2 were chosen, + safety = list(3)//Default to list 3 + + switch(pick(safety))//Chance based on the safety list. + if(1)//1 and 2 can only be selected once each to prevent more than two specific names/places/etc. + switch(rand(1,2))//Mainly to add more options later. + if(1) + if(names.len&&prob(70)) + . += pick(names) + else + if(prob(10)) + . += pick(lizard_name(MALE),lizard_name(FEMALE)) + else + var/new_name = pick(pick(GLOB.first_names_male,GLOB.first_names_female)) + new_name += " " + new_name += pick(GLOB.last_names) + . += new_name + if(2) + . += pick(get_all_jobs())//Returns a job. + safety -= 1 + if(2) + switch(rand(1,3))//Food, drinks, or things. Only selectable once. + if(1) + . += lowertext(pick(drinks)) + if(2) + . += lowertext(pick(foods)) + if(3) + . += lowertext(pick(locations)) + safety -= 2 + if(3) + switch(rand(1,4))//Abstract nouns, objects, adjectives, threats. Can be selected more than once. + if(1) + . += lowertext(pick(nouns)) + if(2) + . += lowertext(pick(objects)) + if(3) + . += lowertext(pick(adjectives)) + if(4) + . += lowertext(pick(threats)) + if(!return_list) + if(words==1) + . += "." + else + . += ", " +>>>>>>> 4178c20... Configuration datum refactor (#30763) diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 53691d122e..b4f5b2500a 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -19,7 +19,7 @@ return copytext(sqltext, 2, lentext(sqltext));//Quote() adds quotes around input, we already do that /proc/format_table_name(table as text) - return global.sqlfdbktableprefix + table + return CONFIG_GET(string/feedback_tableprefix) + table /* * Text sanitization @@ -469,7 +469,7 @@ GLOBAL_LIST_INIT(binary, list("0","1")) //in the json file and have it be reflected in the in game item/mob it came from. //(That's what things like savefiles are for) Note that this list is not shuffled. /proc/twitterize(list/proposed, filename, cullshort = 1, storemax = 1000) - if(!islist(proposed) || !filename || !config.log_twitter) + if(!islist(proposed) || !filename || !CONFIG_GET(flag/log_twitter)) return //Regular expressions are, as usual, absolute magic diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 60b5d82940..46d6c2ce5c 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -554,3 +554,24 @@ else return /datum return text2path(copytext(string_type, 1, last_slash)) + +//returns a string the last bit of a type, without the preceeding '/' +/proc/type2top(the_type) + //handle the builtins manually + if(!ispath(the_type)) + return + switch(the_type) + if(/datum) + return "datum" + if(/atom) + return "atom" + if(/obj) + return "obj" + if(/mob) + return "mob" + if(/area) + return "area" + if(/turf) + return "turf" + else //regex everything else (works for /proc too) + return lowertext(replacetext("[the_type]", "[type2parent(the_type)]/", "")) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index a20cad1cf2..8ffca0ea61 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1282,7 +1282,7 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types()) #define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); } #define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/______qdel_list_wrapper, L), time, TIMER_STOPPABLE) #define QDEL_LIST_ASSOC(L) if(L) { for(var/I in L) { qdel(L[I]); qdel(I); } L.Cut(); } -#define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qel(L[I]); L.Cut(); } +#define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); } /proc/______qdel_list_wrapper(list/L) //the underscores are to encourage people not to use this directly. QDEL_LIST(L) diff --git a/code/_globalvars/configuration.dm b/code/_globalvars/configuration.dm index 83bf3cfb5a..391744e34c 100644 --- a/code/_globalvars/configuration.dm +++ b/code/_globalvars/configuration.dm @@ -1,4 +1,4 @@ -GLOBAL_REAL(config, /datum/configuration) +GLOBAL_REAL(config, /datum/controller/configuration) GLOBAL_DATUM_INIT(revdata, /datum/getrev, new) @@ -11,9 +11,7 @@ GLOBAL_VAR_INIT(hub_visibility, FALSE) GLOBAL_VAR_INIT(ooc_allowed, TRUE) // used with admin verbs to disable ooc - not a config option apparently GLOBAL_VAR_INIT(dooc_allowed, TRUE) -GLOBAL_VAR_INIT(abandon_allowed, TRUE) GLOBAL_VAR_INIT(enter_allowed, TRUE) -GLOBAL_VAR_INIT(guests_allowed, TRUE) GLOBAL_VAR_INIT(shuttle_frozen, FALSE) GLOBAL_VAR_INIT(shuttle_left, FALSE) GLOBAL_VAR_INIT(tinted_weldhelh, TRUE) @@ -25,10 +23,16 @@ GLOBAL_VAR_INIT(Debug, FALSE) // global debug switch GLOBAL_VAR_INIT(Debug2, FALSE) //This was a define, but I changed it to a variable so it can be changed in-game.(kept the all-caps definition because... code...) -Errorage +//Protecting these because the proper way to edit them is with the config/secrets GLOBAL_VAR_INIT(MAX_EX_DEVESTATION_RANGE, 3) +GLOBAL_PROTECT(MAX_EX_DEVESTATION_RANGE) GLOBAL_VAR_INIT(MAX_EX_HEAVY_RANGE, 7) +GLOBAL_PROTECT(MAX_EX_HEAVY_RANGE) GLOBAL_VAR_INIT(MAX_EX_LIGHT_RANGE, 14) +GLOBAL_PROTECT(MAX_EX_LIGHT_RANGE) GLOBAL_VAR_INIT(MAX_EX_FLASH_RANGE, 14) +GLOBAL_PROTECT(MAX_EX_FLASH_RANGE) GLOBAL_VAR_INIT(MAX_EX_FLAME_RANGE, 14) +GLOBAL_PROTECT(MAX_EX_FLAME_RANGE) GLOBAL_VAR_INIT(DYN_EX_SCALE, 0.5) diff --git a/code/_globalvars/sensitive.dm b/code/_globalvars/sensitive.dm deleted file mode 100644 index e1a02621ac..0000000000 --- a/code/_globalvars/sensitive.dm +++ /dev/null @@ -1,16 +0,0 @@ -//Server API key -GLOBAL_REAL_VAR(comms_key) = "default_pwd" -GLOBAL_REAL_VAR(comms_allowed) = FALSE //By default, the server does not allow messages to be sent to it, unless the key is strong enough (this is to prevent misconfigured servers from becoming vulnerable) - -GLOBAL_REAL_VAR(medal_hub) -GLOBAL_REAL_VAR(medal_pass) = " " -GLOBAL_REAL_VAR(medals_enabled) = TRUE //will be auto set to false if the game fails contacting the medal hub to prevent unneeded calls. - -// MySQL configuration - -GLOBAL_REAL_VAR(sqladdress) = "localhost" -GLOBAL_REAL_VAR(sqlport) = "3306" -GLOBAL_REAL_VAR(sqlfdbkdb) = "test" -GLOBAL_REAL_VAR(sqlfdbklogin) = "root" -GLOBAL_REAL_VAR(sqlfdbkpass) = "" -GLOBAL_REAL_VAR(sqlfdbktableprefix) = "" diff --git a/code/controllers/configuration/config_entry.dm b/code/controllers/configuration/config_entry.dm new file mode 100644 index 0000000000..5358073dbe --- /dev/null +++ b/code/controllers/configuration/config_entry.dm @@ -0,0 +1,178 @@ +#undef CURRENT_RESIDENT_FILE + +#define LIST_MODE_NUM 0 +#define LIST_MODE_TEXT 1 +#define LIST_MODE_FLAG 2 + +/datum/config_entry + var/name //read-only, this is determined by the last portion of the derived entry type + var/value + var/default //read-only, just set value directly + + var/resident_file //the file which this belongs to, must be set + var/modified = FALSE //set to TRUE if the default has been overridden by a config entry + + var/protection = NONE + var/abstract_type = /datum/config_entry //do not instantiate if type matches this + + var/dupes_allowed = FALSE + +/datum/config_entry/New() + if(!resident_file) + CRASH("Config entry [type] has no resident_file set") + if(type == abstract_type) + CRASH("Abstract config entry [type] instatiated!") + name = lowertext(type2top(type)) + if(islist(value)) + var/list/L = value + default = L.Copy() + else + default = value + +/datum/config_entry/Destroy() + config.RemoveEntry(src) + return ..() + +/datum/config_entry/can_vv_get(var_name) + . = ..() + if(var_name == "value" || var_name == "default") + . &= !(protection & CONFIG_ENTRY_HIDDEN) + +/datum/config_entry/vv_edit_var(var_name, var_value) + var/static/list/banned_edits = list("name", "default", "resident_file", "protection", "abstract_type", "modified", "dupes_allowed") + if(var_name == "value") + if(protection & CONFIG_ENTRY_LOCKED) + return FALSE + . = ValidateAndSet("[var_value]") + if(.) + var_edited = TRUE + return + if(var_name in banned_edits) + return FALSE + return ..() + +/datum/config_entry/proc/ValidateAndSet(str_val) + CRASH("Invalid config entry type!") + +/datum/config_entry/proc/ValidateKeyedList(str_val, list_mode, splitter) + str_val = trim(str_val) + var/key_pos = findtext(str_val, splitter) + var/key_name = null + var/key_value = null + + if(key_pos || list_mode == LIST_MODE_FLAG) + key_name = lowertext(copytext(str_val, 1, key_pos)) + key_value = copytext(str_val, key_pos + 1) + var/temp + var/continue_check + switch(list_mode) + if(LIST_MODE_FLAG) + temp = TRUE + continue_check = TRUE + if(LIST_MODE_NUM) + temp = text2num(key_value) + continue_check = !isnull(temp) + if(LIST_MODE_TEXT) + temp = key_value + continue_check = temp + if(continue_check && ValidateKeyName(key_name)) + value[key_name] = temp + return TRUE + return FALSE + +/datum/config_entry/proc/ValidateKeyName(key_name) + return TRUE + +/datum/config_entry/string + value = "" + abstract_type = /datum/config_entry/string + var/auto_trim = TRUE + +/datum/config_entry/string/vv_edit_var(var_name, var_value) + return var_name != "auto_trim" && ..() + +/datum/config_entry/string/ValidateAndSet(str_val) + value = auto_trim ? trim(str_val) : str_val + return TRUE + +/datum/config_entry/number + value = 0 + abstract_type = /datum/config_entry/number + var/integer = TRUE + var/max_val = INFINITY + var/min_val = -INFINITY + +/datum/config_entry/number/ValidateAndSet(str_val) + var/temp = text2num(trim(str_val)) + if(!isnull(temp)) + value = Clamp(integer ? round(temp) : temp, min_val, max_val) + if(value != temp && !var_edited) + log_config("Changing [name] from [temp] to [value]!") + return TRUE + return FALSE + +/datum/config_entry/number/vv_edit_var(var_name, var_value) + var/static/list/banned_edits = list("max_val", "min_val", "integer") + return !(var_name in banned_edits) && ..() + +/datum/config_entry/flag + value = FALSE + abstract_type = /datum/config_entry/flag + +/datum/config_entry/flag/ValidateAndSet(str_val) + value = text2num(trim(str_val)) != 0 + return TRUE + +/datum/config_entry/number_list + abstract_type = /datum/config_entry/number_list + value = list() + +/datum/config_entry/number_list/ValidateAndSet(str_val) + str_val = trim(str_val) + var/list/new_list = list() + var/list/values = splittext(str_val," ") + for(var/I in values) + var/temp = text2num(I) + if(isnull(temp)) + return FALSE + new_list += temp + if(!new_list.len) + return FALSE + value = new_list + return TRUE + +/datum/config_entry/keyed_flag_list + abstract_type = /datum/config_entry/keyed_flag_list + value = list() + dupes_allowed = TRUE + +/datum/config_entry/keyed_flag_list/ValidateAndSet(str_val) + return ValidateKeyedList(str_val, LIST_MODE_FLAG, " ") + +/datum/config_entry/keyed_number_list + abstract_type = /datum/config_entry/keyed_number_list + value = list() + dupes_allowed = TRUE + var/splitter = " " + +/datum/config_entry/keyed_number_list/vv_edit_var(var_name, var_value) + return var_name != "splitter" && ..() + +/datum/config_entry/keyed_number_list/ValidateAndSet(str_val) + return ValidateKeyedList(str_val, LIST_MODE_NUM, splitter) + +/datum/config_entry/keyed_string_list + abstract_type = /datum/config_entry/keyed_string_list + value = list() + dupes_allowed = TRUE + var/splitter = " " + +/datum/config_entry/keyed_string_list/vv_edit_var(var_name, var_value) + return var_name != "splitter" && ..() + +/datum/config_entry/keyed_string_list/ValidateAndSet(str_val) + return ValidateKeyedList(str_val, LIST_MODE_TEXT, splitter) + +#undef LIST_MODE_NUM +#undef LIST_MODE_TEXT +#undef LIST_MODE_FLAG diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm new file mode 100644 index 0000000000..7624d2473d --- /dev/null +++ b/code/controllers/configuration/configuration.dm @@ -0,0 +1,281 @@ +GLOBAL_VAR_INIT(config_dir, "config/") +GLOBAL_PROTECT(config_dir) + +/datum/controller/configuration + name = "Configuration" + + var/hiding_entries_by_type = TRUE //Set for readability, admins can set this to FALSE if they want to debug it + var/list/entries + var/list/entries_by_type + + var/list/maplist + var/datum/map_config/defaultmap + + var/list/modes // allowed modes + var/list/gamemode_cache + var/list/votable_modes // votable modes + var/list/mode_names + var/list/mode_reports + var/list/mode_false_report_weight + +/datum/controller/configuration/New() + config = src + var/list/config_files = InitEntries() + LoadModes() + for(var/I in config_files) + LoadEntries(I) + if(Get(/datum/config_entry/flag/maprotation)) + loadmaplist(CONFIG_MAPS_FILE) + +/datum/controller/configuration/Destroy() + entries_by_type.Cut() + QDEL_LIST_ASSOC_VAL(entries) + QDEL_LIST_ASSOC_VAL(maplist) + QDEL_NULL(defaultmap) + + config = null + + return ..() + +/datum/controller/configuration/proc/InitEntries() + var/list/_entries = list() + entries = _entries + var/list/_entries_by_type = list() + entries_by_type = _entries_by_type + + . = list() + + for(var/I in typesof(/datum/config_entry)) //typesof is faster in this case + var/datum/config_entry/E = I + if(initial(E.abstract_type) == I) + continue + E = new I + _entries_by_type[I] = E + var/esname = E.name + var/datum/config_entry/test = _entries[esname] + if(test) + log_config("Error: [test.type] has the same name as [E.type]: [esname]! Not initializing [E.type]!") + qdel(E) + continue + _entries[esname] = E + .[E.resident_file] = TRUE + +/datum/controller/configuration/proc/RemoveEntry(datum/config_entry/CE) + entries -= CE.name + entries_by_type -= CE.type + +/datum/controller/configuration/proc/LoadEntries(filename) + log_config("Loading config file [filename]...") + var/list/lines = world.file2list("[GLOB.config_dir][filename]") + var/list/_entries = entries + for(var/L in lines) + if(!L) + continue + + if(copytext(L, 1, 2) == "#") + continue + + var/pos = findtext(L, " ") + var/entry = null + var/value = null + + if(pos) + entry = lowertext(copytext(L, 1, pos)) + value = copytext(L, pos + 1) + else + entry = lowertext(L) + + if(!entry) + continue + + var/datum/config_entry/E = _entries[entry] + if(!E) + log_config("Unknown setting in configuration: '[entry]'") + continue + + if(filename != E.resident_file) + log_config("Found [entry] in [filename] when it should have been in [E.resident_file]! Ignoring.") + continue + + var/validated = E.ValidateAndSet(value) + if(!validated) + log_config("Failed to validate setting \"[value]\" for [entry]") + else if(E.modified && !E.dupes_allowed) + log_config("Duplicate setting for [entry] ([value]) detected! Using latest.") + + if(validated) + E.modified = TRUE + +/datum/controller/configuration/can_vv_get(var_name) + return (var_name != "entries_by_type" || !hiding_entries_by_type) && ..() + +/datum/controller/configuration/vv_edit_var(var_name, var_value) + return !(var_name in list("entries_by_type", "entries")) && ..() + +/datum/controller/configuration/stat_entry() + if(!statclick) + statclick = new/obj/effect/statclick/debug(null, "Edit", src) + stat("[name]:", statclick) + +/datum/controller/configuration/proc/Get(entry_type) + var/datum/config_entry/E = entry_type + var/entry_is_abstract = initial(E.abstract_type) == entry_type + if(entry_is_abstract) + CRASH("Tried to retrieve an abstract config_entry: [entry_type]") + E = entries_by_type[entry_type] + if(!E) + CRASH("Missing config entry for [entry_type]!") + return E.value + +/datum/controller/configuration/proc/Set(entry_type, new_val) + var/datum/config_entry/E = entry_type + var/entry_is_abstract = initial(E.abstract_type) == entry_type + if(entry_is_abstract) + CRASH("Tried to retrieve an abstract config_entry: [entry_type]") + E = entries_by_type[entry_type] + if(!E) + CRASH("Missing config entry for [entry_type]!") + return E.ValidateAndSet(new_val) + +/datum/controller/configuration/proc/LoadModes() + gamemode_cache = typecacheof(/datum/game_mode, TRUE) + modes = list() + mode_names = list() + mode_reports = list() + mode_false_report_weight = list() + votable_modes = list() + var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability) + for(var/T in gamemode_cache) + // I wish I didn't have to instance the game modes in order to look up + // their information, but it is the only way (at least that I know of). + var/datum/game_mode/M = new T() + + if(M.config_tag) + if(!(M.config_tag in modes)) // ensure each mode is added only once + modes += M.config_tag + mode_names[M.config_tag] = M.name + probabilities[M.config_tag] = M.probability + mode_reports[M.config_tag] = M.generate_report() + mode_false_report_weight[M.config_tag] = M.false_report_weight + if(M.votable) + votable_modes += M.config_tag + qdel(M) + votable_modes += "secret" + +/datum/controller/configuration/proc/loadmaplist(filename) + filename = "[GLOB.config_dir][filename]" + var/list/Lines = world.file2list(filename) + + var/datum/map_config/currentmap = null + for(var/t in Lines) + if(!t) + continue + + t = trim(t) + if(length(t) == 0) + continue + else if(copytext(t, 1, 2) == "#") + continue + + var/pos = findtext(t, " ") + var/command = null + var/data = null + + if(pos) + command = lowertext(copytext(t, 1, pos)) + data = copytext(t, pos + 1) + else + command = lowertext(t) + + if(!command) + continue + + if (!currentmap && command != "map") + continue + + switch (command) + if ("map") + currentmap = new ("_maps/[data].json") + if(currentmap.defaulted) + log_config("Failed to load map config for [data]!") + if ("minplayers","minplayer") + currentmap.config_min_users = text2num(data) + if ("maxplayers","maxplayer") + currentmap.config_max_users = text2num(data) + if ("weight","voteweight") + currentmap.voteweight = text2num(data) + if ("default","defaultmap") + defaultmap = currentmap + if ("endmap") + LAZYINITLIST(maplist) + maplist[currentmap.map_name] = currentmap + currentmap = null + if ("disabled") + currentmap = null + else + WRITE_FILE(GLOB.config_error_log, "Unknown command in map vote config: '[command]'") + + +/datum/controller/configuration/proc/pick_mode(mode_name) + // I wish I didn't have to instance the game modes in order to look up + // their information, but it is the only way (at least that I know of). + // ^ This guy didn't try hard enough + for(var/T in gamemode_cache) + var/datum/game_mode/M = T + var/ct = initial(M.config_tag) + if(ct && ct == mode_name) + return new T + return new /datum/game_mode/extended() + +/datum/controller/configuration/proc/get_runnable_modes() + var/list/datum/game_mode/runnable_modes = new + var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability) + var/list/min_pop = Get(/datum/config_entry/keyed_number_list/min_pop) + var/list/max_pop = Get(/datum/config_entry/keyed_number_list/max_pop) + var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust) + for(var/T in gamemode_cache) + var/datum/game_mode/M = new T() + if(!(M.config_tag in modes)) + qdel(M) + continue + if(probabilities[M.config_tag]<=0) + qdel(M) + continue + if(min_pop[M.config_tag]) + M.required_players = min_pop[M.config_tag] + if(max_pop[M.config_tag]) + M.maximum_players = max_pop[M.config_tag] + if(M.can_start()) + var/final_weight = probabilities[M.config_tag] + if(SSpersistence.saved_modes.len == 3 && repeated_mode_adjust.len == 3) + var/recent_round = min(SSpersistence.saved_modes.Find(M.config_tag),3) + var/adjustment = 0 + while(recent_round) + adjustment += repeated_mode_adjust[recent_round] + recent_round = SSpersistence.saved_modes.Find(M.config_tag,recent_round+1,0) + final_weight *= ((100-adjustment)/100) + runnable_modes[M] = final_weight + return runnable_modes + +/datum/controller/configuration/proc/get_runnable_midround_modes(crew) + var/list/datum/game_mode/runnable_modes = new + var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability) + var/list/min_pop = Get(/datum/config_entry/keyed_number_list/min_pop) + var/list/max_pop = Get(/datum/config_entry/keyed_number_list/max_pop) + for(var/T in (gamemode_cache - SSticker.mode.type)) + var/datum/game_mode/M = new T() + if(!(M.config_tag in modes)) + qdel(M) + continue + if(probabilities[M.config_tag]<=0) + qdel(M) + continue + if(min_pop[M.config_tag]) + M.required_players = min_pop[M.config_tag] + if(max_pop[M.config_tag]) + M.maximum_players = max_pop[M.config_tag] + if(M.required_players <= crew) + if(M.maximum_players >= 0 && M.maximum_players < crew) + continue + runnable_modes[M] = probabilities[M.config_tag] + return runnable_modes diff --git a/code/controllers/configuration/entries/comms.dm b/code/controllers/configuration/entries/comms.dm new file mode 100644 index 0000000000..bf099f6cb6 --- /dev/null +++ b/code/controllers/configuration/entries/comms.dm @@ -0,0 +1,22 @@ +#define CURRENT_RESIDENT_FILE "comms.txt" + +CONFIG_DEF(string/comms_key) + protection = CONFIG_ENTRY_HIDDEN + +/datum/config_entry/string/comms_key/ValidateAndSet(str_val) + return str_val != "default_pwd" && length(str_val) > 6 && ..() + +CONFIG_DEF(string/cross_server_address) + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/cross_server_address/ValidateAndSet(str_val) + return str_val != "byond:\\address:port" && ..() + +CONFIG_DEF(string/cross_comms_name) + +GLOBAL_VAR_INIT(medals_enabled, TRUE) //will be auto set to false if the game fails contacting the medal hub to prevent unneeded calls. + +CONFIG_DEF(string/medal_hub_address) + +CONFIG_DEF(string/medal_hub_password) + protection = CONFIG_ENTRY_HIDDEN \ No newline at end of file diff --git a/code/controllers/configuration/entries/config.dm b/code/controllers/configuration/entries/config.dm new file mode 100644 index 0000000000..cabb6dca27 --- /dev/null +++ b/code/controllers/configuration/entries/config.dm @@ -0,0 +1,387 @@ +#define CURRENT_RESIDENT_FILE "config.txt" + +CONFIG_DEF(flag/autoadmin) // if autoadmin is enabled + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/autoadmin_rank) // the rank for autoadmins + value = "Game Master" + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/servername) // server name (the name of the game window) + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/serversqlname) // short form server name used for the DB + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/stationname) // station name (the name of the station in-game) + +CONFIG_DEF(number/lobby_countdown) // In between round countdown. + value = 120 + min_val = 0 + +CONFIG_DEF(number/round_end_countdown) // Post round murder death kill countdown + value = 25 + min_val = 0 + +CONFIG_DEF(flag/hub) // if the game appears on the hub or not + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_ooc) // log OOC channel + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_access) // log login/logout + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_say) // log client say + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_admin) // log admin actions + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_prayer) // log prayers + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_law) // log lawchanges + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_game) // log game events + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_vote) // log voting + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_whisper) // log client whisper + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_attack) // log attack messages + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_emote) // log emotes + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_adminchat) // log admin chat messages + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_pda) // log pda messages + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_twitter) // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases. + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_world_topic) // log all world.Topic() calls + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/allow_admin_ooccolor) // Allows admins with relevant permissions to have their own ooc colour + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/allow_vote_restart) // allow votes to restart + +CONFIG_DEF(flag/allow_vote_mode) // allow votes to change mode + +CONFIG_DEF(number/vote_delay) // minimum time between voting sessions (deciseconds, 10 minute default) + value = 6000 + min_val = 0 + +CONFIG_DEF(number/vote_period) // length of voting period (deciseconds, default 1 minute) + value = 600 + min_val = 0 + +CONFIG_DEF(flag/default_no_vote) // vote does not default to nochange/norestart + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/no_dead_vote) // dead people can't vote + +CONFIG_DEF(flag/allow_metadata) // Metadata is supported. + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/popup_admin_pm) // adminPMs to non-admins show in a pop-up 'reply' window when set + +CONFIG_DEF(number/fps) + value = 20 + min_val = 1 + max_val = 100 //byond will start crapping out at 50, so this is just ridic + var/sync_validate = FALSE + +/datum/config_entry/number/fps/ValidateAndSet(str_val) + . = ..() + if(.) + sync_validate = TRUE + var/datum/config_entry/number/ticklag/TL = config.entries_by_type[/datum/config_entry/number/ticklag] + if(!TL.sync_validate) + TL.ValidateAndSet(10 / value) + sync_validate = FALSE + +CONFIG_DEF(number/ticklag) + integer = FALSE + var/sync_validate = FALSE + +/datum/config_entry/number/ticklag/New() //ticklag weirdly just mirrors fps + var/datum/config_entry/CE = /datum/config_entry/number/fps + value = 10 / initial(CE.value) + ..() + +/datum/config_entry/number/ticklag/ValidateAndSet(str_val) + . = text2num(str_val) > 0 && ..() + if(.) + sync_validate = TRUE + var/datum/config_entry/number/fps/FPS = config.entries_by_type[/datum/config_entry/number/fps] + if(!FPS.sync_validate) + FPS.ValidateAndSet(10 / value) + sync_validate = FALSE + +CONFIG_DEF(flag/allow_holidays) + +CONFIG_DEF(number/tick_limit_mc_init) //SSinitialization throttling + value = TICK_LIMIT_MC_INIT_DEFAULT + min_val = 0 //oranges warned us + integer = FALSE + +CONFIG_DEF(flag/admin_legacy_system) //Defines whether the server uses the legacy admin system with admins.txt or the SQL system + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/hostedby) + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/norespawn) + +CONFIG_DEF(flag/guest_jobban) + +CONFIG_DEF(flag/usewhitelist) + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/ban_legacy_system) //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/use_age_restriction_for_jobs) //Do jobs use account age restrictions? --requires database + +CONFIG_DEF(flag/use_account_age_for_jobs) //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected. + +CONFIG_DEF(flag/use_exp_tracking) + +CONFIG_DEF(flag/use_exp_restrictions_heads) + +CONFIG_DEF(number/use_exp_restrictions_heads_hours) + value = 0 + min_val = 0 + +CONFIG_DEF(flag/use_exp_restrictions_heads_department) + +CONFIG_DEF(flag/use_exp_restrictions_other) + +CONFIG_DEF(flag/use_exp_restrictions_admin_bypass) + +CONFIG_DEF(string/server) + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/banappeals) + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/wikiurl) + protection = CONFIG_ENTRY_LOCKED + value = "http://www.tgstation13.org/wiki" + +CONFIG_DEF(string/forumurl) + protection = CONFIG_ENTRY_LOCKED + value = "http://tgstation13.org/phpBB/index.php" + +CONFIG_DEF(string/rulesurl) + protection = CONFIG_ENTRY_LOCKED + value = "http://www.tgstation13.org/wiki/Rules" + +CONFIG_DEF(string/githuburl) + protection = CONFIG_ENTRY_LOCKED + value = "https://www.github.com/tgstation/-tg-station" + +CONFIG_DEF(number/githubrepoid) + protection = CONFIG_ENTRY_LOCKED + value = null + min_val = 0 + +CONFIG_DEF(flag/guest_ban) + +CONFIG_DEF(number/id_console_jobslot_delay) + value = 30 + min_val = 0 + +CONFIG_DEF(number/inactivity_period) //time in ds until a player is considered inactive) + value = 3000 + min_val = 0 + +/datum/config_entry/number/inactivity_period/ValidateAndSet(str_val) + . = ..() + if(.) + value *= 10 //documented as seconds in config.txt + +CONFIG_DEF(number/afk_period) //time in ds until a player is considered inactive) + value = 3000 + min_val = 0 + +/datum/config_entry/number/afk_period/ValidateAndSet(str_val) + . = ..() + if(.) + value *= 10 //documented as seconds in config.txt + +CONFIG_DEF(flag/kick_inactive) //force disconnect for inactive players + +CONFIG_DEF(flag/load_jobs_from_txt) + +CONFIG_DEF(flag/forbid_singulo_possession) + +CONFIG_DEF(flag/useircbot) //tgs2 support + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/automute_on) //enables automuting/spam prevention + +CONFIG_DEF(string/panic_server_name) + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/panic_server_name/ValidateAndSet(str_val) + return str_val != "\[Put the name here\]" && ..() + +CONFIG_DEF(string/panic_address) //Reconnect a player this linked server if this server isn't accepting new players + +/datum/config_entry/string/panic_address/ValidateAndSet(str_val) + return str_val != "byond://address:port" && ..() + +CONFIG_DEF(string/invoke_youtubedl) + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +CONFIG_DEF(flag/show_irc_name) + +CONFIG_DEF(flag/see_own_notes) //Can players see their own admin notes (read-only)? + +CONFIG_DEF(number/note_fresh_days) + value = null + min_val = 0 + integer = FALSE + +CONFIG_DEF(number/note_stale_days) + value = null + min_val = 0 + integer = FALSE + +CONFIG_DEF(flag/maprotation) + +CONFIG_DEF(number/maprotatechancedelta) + value = 0.75 + min_val = 0 + max_val = 1 + integer = FALSE + +CONFIG_DEF(number/soft_popcap) + value = null + min_val = 0 + +CONFIG_DEF(number/hard_popcap) + value = null + min_val = 0 + +CONFIG_DEF(number/extreme_popcap) + value = null + min_val = 0 + +CONFIG_DEF(string/soft_popcap_message) + value = "Be warned that the server is currently serving a high number of users, consider using alternative game servers." + +CONFIG_DEF(string/hard_popcap_message) + value = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers." + +CONFIG_DEF(string/extreme_popcap_message) + value = "The server is currently serving a high number of users, find alternative servers." + +CONFIG_DEF(flag/panic_bunker) // prevents people the server hasn't seen before from connecting + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(number/notify_new_player_age) // how long do we notify admins of a new player + min_val = -1 + +CONFIG_DEF(number/notify_new_player_account_age) // how long do we notify admins of a new byond account + min_val = 0 + +CONFIG_DEF(flag/irc_first_connection_alert) // do we notify the irc channel when somebody is connecting for the first time? + +CONFIG_DEF(flag/check_randomizer) + +CONFIG_DEF(string/ipintel_email) + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +/datum/config_entry/string/ipintel_email/ValidateAndSet(str_val) + return str_val != "ch@nge.me" && ..() + +CONFIG_DEF(number/ipintel_rating_bad) + value = 1 + integer = FALSE + min_val = 0 + max_val = 1 + +CONFIG_DEF(number/ipintel_save_good) + protection = CONFIG_ENTRY_LOCKED + value = 12 + min_val = 0 + +CONFIG_DEF(number/ipintel_save_bad) + protection = CONFIG_ENTRY_LOCKED + value = 1 + min_val = 0 + +CONFIG_DEF(string/ipintel_domain) + protection = CONFIG_ENTRY_LOCKED + value = "check.getipintel.net" + +CONFIG_DEF(flag/aggressive_changelog) + +CONFIG_DEF(flag/autoconvert_notes) //if all connecting player's notes should attempt to be converted to the database + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/allow_webclient) + +CONFIG_DEF(flag/webclient_only_byond_members) + +CONFIG_DEF(flag/announce_admin_logout) + +CONFIG_DEF(flag/announce_admin_login) + +CONFIG_DEF(flag/allow_map_voting) + +CONFIG_DEF(flag/generate_minimaps) + +CONFIG_DEF(number/client_warn_version) + value = null + min_val = 500 + max_val = DM_VERSION - 1 + +CONFIG_DEF(string/client_warn_message) + value = "Your version of byond may have issues or be blocked from accessing this server in the future." + +CONFIG_DEF(number/client_error_version) + value = null + min_val = 500 + max_val = DM_VERSION - 1 + +CONFIG_DEF(string/client_error_message) + value = "Your version of byond is too old, may have issues, and is blocked from accessing this server." + +CONFIG_DEF(number/minute_topic_limit) + value = null + min_val = 0 + +CONFIG_DEF(number/second_topic_limit) + value = null + min_val = 0 + +CONFIG_DEF(number/error_cooldown) // The "cooldown" time for each occurrence of a unique error) + value = 600 + min_val = 0 + +CONFIG_DEF(number/error_limit) // How many occurrences before the next will silence them + value = 50 + +CONFIG_DEF(number/error_silence_time) // How long a unique error will be silenced for + value = 6000 + +CONFIG_DEF(number/error_msg_delay) // How long to wait between messaging admins about occurrences of a unique error + value = 50 + +CONFIG_DEF(flag/irc_announce_new_game) + +CONFIG_DEF(flag/debug_admin_hrefs) \ No newline at end of file diff --git a/code/controllers/configuration/entries/dbconfig.dm b/code/controllers/configuration/entries/dbconfig.dm new file mode 100644 index 0000000000..c46880686a --- /dev/null +++ b/code/controllers/configuration/entries/dbconfig.dm @@ -0,0 +1,28 @@ +#define CURRENT_RESIDENT_FILE "dbconfig.txt" + +CONFIG_DEF(flag/sql_enabled) // for sql switching + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/address) + value = "localhost" + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +CONFIG_DEF(number/port) + value = 3306 + min_val = 0 + max_val = 65535 + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +CONFIG_DEF(string/feedback_database) + value = "test" + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +CONFIG_DEF(string/feedback_login) + value = "root" + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +CONFIG_DEF(string/feedback_password) + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +CONFIG_DEF(string/feedback_tableprefix) + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm new file mode 100644 index 0000000000..106804a576 --- /dev/null +++ b/code/controllers/configuration/entries/game_options.dm @@ -0,0 +1,266 @@ +#define CURRENT_RESIDENT_FILE "game_options.txt" + +CONFIG_DEF(number_list/repeated_mode_adjust) + +CONFIG_DEF(keyed_number_list/probability) + +/datum/config_entry/keyed_number_list/probability/ValidateKeyName(key_name) + return key_name in config.modes + +CONFIG_DEF(keyed_number_list/max_pop) + +/datum/config_entry/keyed_number_list/max_pop/ValidateKeyName(key_name) + return key_name in config.modes + +CONFIG_DEF(keyed_number_list/min_pop) + +/datum/config_entry/keyed_number_list/min_pop/ValidateKeyName(key_name) + return key_name in config.modes + +CONFIG_DEF(keyed_flag_list/continuous) // which roundtypes continue if all antagonists die + +/datum/config_entry/keyed_flag_list/continuous/ValidateKeyName(key_name) + return key_name in config.modes + +CONFIG_DEF(keyed_flag_list/midround_antag) // which roundtypes use the midround antagonist system + +/datum/config_entry/keyed_flag_list/midround_antag/ValidateKeyName(key_name) + return key_name in config.modes + +CONFIG_DEF(keyed_string_list/policy) + +CONFIG_DEF(number/damage_multiplier) + value = 1 + integer = FALSE + +CONFIG_DEF(number/minimal_access_threshold) //If the number of players is larger than this threshold, minimal access will be turned on. + min_val = 0 + +CONFIG_DEF(flag/jobs_have_minimal_access) //determines whether jobs use minimal access or expanded access. + +CONFIG_DEF(flag/assistants_have_maint_access) + +CONFIG_DEF(flag/security_has_maint_access) + +CONFIG_DEF(flag/everyone_has_maint_access) + +CONFIG_DEF(flag/sec_start_brig) //makes sec start in brig instead of dept sec posts + +CONFIG_DEF(flag/force_random_names) + +CONFIG_DEF(flag/humans_need_surnames) + +CONFIG_DEF(flag/allow_ai) // allow ai job + +CONFIG_DEF(flag/disable_secborg) // disallow secborg module to be chosen. + +CONFIG_DEF(flag/disable_peaceborg) + +CONFIG_DEF(number/traitor_scaling_coeff) //how much does the amount of players get divided by to determine traitors + value = 6 + min_val = 1 + +CONFIG_DEF(number/brother_scaling_coeff) //how many players per brother team + value = 25 + min_val = 1 + +CONFIG_DEF(number/changeling_scaling_coeff) //how much does the amount of players get divided by to determine changelings + value = 6 + min_val = 1 + +CONFIG_DEF(number/security_scaling_coeff) //how much does the amount of players get divided by to determine open security officer positions + value = 8 + min_val = 1 + +CONFIG_DEF(number/abductor_scaling_coeff) //how many players per abductor team + value = 15 + min_val = 1 + +CONFIG_DEF(number/traitor_objectives_amount) + value = 2 + min_val = 0 + +CONFIG_DEF(number/brother_objectives_amount) + value = 2 + min_val = 0 + +CONFIG_DEF(flag/reactionary_explosions) //If we use reactionary explosions, explosions that react to walls and doors + +CONFIG_DEF(flag/protect_roles_from_antagonist) //If security and such can be traitor/cult/other + +CONFIG_DEF(flag/protect_assistant_from_antagonist) //If assistants can be traitor/cult/other + +CONFIG_DEF(flag/enforce_human_authority) //If non-human species are barred from joining as a head of staff + +CONFIG_DEF(flag/allow_latejoin_antagonists) // If late-joining players can be traitor/changeling + +CONFIG_DEF(number/midround_antag_time_check) // How late (in minutes) you want the midround antag system to stay on, setting this to 0 will disable the system + value = 60 + min_val = 0 + +CONFIG_DEF(number/midround_antag_life_check) // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist + value = 0.7 + integer = FALSE + min_val = 0 + max_val = 1 + +CONFIG_DEF(number/shuttle_refuel_delay) + value = 12000 + min_val = 0 + +CONFIG_DEF(flag/show_game_type_odds) //if set this allows players to see the odds of each roundtype on the get revision screen + +CONFIG_DEF(flag/join_with_mutant_race) //players can choose their mutant race before joining the game + +CONFIG_DEF(keyed_flag_list/roundstart_races) //races you can play as from the get go. If left undefined the game's roundstart var for species is used + var/first_edit = TRUE + +/datum/config_entry/keyed_flag_list/roundstart_races/New() + for(var/I in subtypesof(/datum/species)) + var/datum/species/S = I + if(initial(S.roundstart)) + value[initial(S.id)] = TRUE + ..() + +/datum/config_entry/keyed_flag_list/roundstart_races/ValidateAndSet(str_val) + var/list/old_val + if(first_edit) + old_val = value + old_val = old_val.Copy() + . = ..() + if(first_edit) + if(!.) + value = old_val + else + first_edit = FALSE + +CONFIG_DEF(flag/join_with_mutant_humans) //players can pick mutant bodyparts for humans before joining the game + +CONFIG_DEF(flag/no_summon_guns) //No + +CONFIG_DEF(flag/no_summon_magic) //Fun + +CONFIG_DEF(flag/no_summon_events) //Allowed + +CONFIG_DEF(flag/no_intercept_report) //Whether or not to send a communications intercept report roundstart. This may be overriden by gamemodes. + +CONFIG_DEF(number/arrivals_shuttle_dock_window) //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station + value = 55 + min_val = 30 + +CONFIG_DEF(flag/arrivals_shuttle_require_undocked) //Require the arrivals shuttle to be undocked before latejoiners can join + +CONFIG_DEF(flag/arrivals_shuttle_require_safe_latejoin) //Require the arrivals shuttle to be operational in order for latejoiners to join + +CONFIG_DEF(string/alert_green) + value = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced." + +CONFIG_DEF(string/alert_blue_upto) + value = "The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible, random searches are permitted." + +CONFIG_DEF(string/alert_blue_downto) + value = "The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed." + +CONFIG_DEF(string/alert_red_upto) + value = "There is an immediate serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised." + +CONFIG_DEF(string/alert_red_downto) + value = "The station's destruction has been averted. There is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised." + +CONFIG_DEF(string/alert_delta) + value = "Destruction of the station is imminent. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill." + +CONFIG_DEF(flag/revival_pod_plants) + +CONFIG_DEF(flag/revival_cloning) + +CONFIG_DEF(number/revival_brain_life) + value = -1 + min_val = -1 + +CONFIG_DEF(flag/rename_cyborg) + +CONFIG_DEF(flag/ooc_during_round) + +CONFIG_DEF(flag/emojis) + +CONFIG_DEF(number/run_delay) //Used for modifying movement speed for mobs. + +CONFIG_DEF(number/walk_delay) + + +CONFIG_DEF(number/human_delay) //Mob specific modifiers. NOTE: These will affect different mob types in different ways +CONFIG_DEF(number/robot_delay) +CONFIG_DEF(number/monkey_delay) +CONFIG_DEF(number/alien_delay) +CONFIG_DEF(number/slime_delay) +CONFIG_DEF(number/animal_delay) + +CONFIG_DEF(number/gateway_delay) //How long the gateway takes before it activates. Default is half an hour. + value = 18000 + min_val = 0 + +CONFIG_DEF(flag/ghost_interaction) + +CONFIG_DEF(flag/silent_ai) +CONFIG_DEF(flag/silent_borg) + +CONFIG_DEF(flag/sandbox_autoclose) // close the sandbox panel after spawning an item, potentially reducing griff + +CONFIG_DEF(number/default_laws) //Controls what laws the AI spawns with. + value = 0 + min_val = 0 + max_val = 3 + +CONFIG_DEF(number/silicon_max_law_amount) + value = 12 + min_val = 0 + +CONFIG_DEF(keyed_flag_list/random_laws) + +CONFIG_DEF(keyed_number_list/law_weight) + splitter = "," + +CONFIG_DEF(number/assistant_cap) + value = -1 + min_val = -1 + +CONFIG_DEF(flag/starlight) +CONFIG_DEF(flag/grey_assistants) + +CONFIG_DEF(number/lavaland_budget) + value = 60 + min_val = 0 + +CONFIG_DEF(number/space_budget) + value = 16 + min_val = 0 + +CONFIG_DEF(flag/allow_random_events) // Enables random events mid-round when set + +CONFIG_DEF(number/events_min_time_mul) // Multipliers for random events minimal starting time and minimal players amounts + value = 1 + min_val = 0 + integer = FALSE + +CONFIG_DEF(number/events_min_players_mul) + value = 1 + min_val = 0 + integer = FALSE + +CONFIG_DEF(number/mice_roundstart) + value = 10 + min_val = 0 + +CONFIG_DEF(number/bombcap) + value = 14 + min_val = 4 + +/datum/config_entry/number/bombcap/ValidateAndSet(str_val) + . = ..() + if(.) + GLOB.MAX_EX_DEVESTATION_RANGE = round(value / 4) + GLOB.MAX_EX_HEAVY_RANGE = round(value / 2) + GLOB.MAX_EX_LIGHT_RANGE = value + GLOB.MAX_EX_FLASH_RANGE = value + GLOB.MAX_EX_FLAME_RANGE = value diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 11c460e326..6ed3121179 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -169,7 +169,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/start_timeofday = REALTIMEOFDAY // Initialize subsystems. - current_ticklimit = config.tick_limit_mc_init + current_ticklimit = CONFIG_GET(number/tick_limit_mc_init) for (var/datum/controller/subsystem/SS in subsystems) if (SS.flags & SS_NO_INIT) continue @@ -189,7 +189,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new sortTim(subsystems, /proc/cmp_subsystem_display) // Set world options. world.sleep_offline = 1 - world.fps = config.fps + world.fps = CONFIG_GET(number/fps) var/initialized_tod = REALTIMEOFDAY sleep(1) initializations_finished_with_no_players_logged_in = initialized_tod < REALTIMEOFDAY - 10 diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm index 2870305c3e..56238d5b85 100644 --- a/code/controllers/subsystem/blackbox.dm +++ b/code/controllers/subsystem/blackbox.dm @@ -38,7 +38,7 @@ SUBSYSTEM_DEF(blackbox) var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port, round_id) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]')") query_record_playercount.Execute() - if(config.use_exp_tracking) + if(CONFIG_GET(flag/use_exp_tracking)) if((triggertime < 0) || (world.time > (triggertime +3000))) //subsystem fires once at roundstart then once every 10 minutes. a 5 min check skips the first fire. The <0 is midnight rollover check update_exp(10,FALSE) diff --git a/code/controllers/subsystem/dbcore.dm b/code/controllers/subsystem/dbcore.dm index 864274b8fb..12a5342e33 100644 --- a/code/controllers/subsystem/dbcore.dm +++ b/code/controllers/subsystem/dbcore.dm @@ -54,32 +54,27 @@ SUBSYSTEM_DEF(dbcore) if(failed_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to connect anymore. return FALSE - if(!config.sql_enabled) + if(!CONFIG_GET(flag/sql_enabled)) return FALSE - var/user = global.sqlfdbklogin - var/pass = global.sqlfdbkpass - var/db = global.sqlfdbkdb - var/address = global.sqladdress - var/port = global.sqlport + var/user = CONFIG_GET(string/feedback_login) + var/pass = CONFIG_GET(string/feedback_password) + var/db = CONFIG_GET(string/feedback_database) + var/address = CONFIG_GET(string/address) + var/port = CONFIG_GET(number/port) - doConnect("dbi:mysql:[db]:[address]:[port]", user, pass) + _dm_db_connect(_db_con, "dbi:mysql:[db]:[address]:[port]", user, pass, Default_Cursor, null) . = IsConnected() if (!.) log_sql("Connect() failed | [ErrorMsg()]") ++failed_connections -/datum/controller/subsystem/dbcore/proc/doConnect(dbi_handler, user_handler, password_handler) - if(!config.sql_enabled) - return FALSE - return _dm_db_connect(_db_con, dbi_handler, user_handler, password_handler, Default_Cursor, null) - /datum/controller/subsystem/dbcore/proc/Disconnect() failed_connections = 0 return _dm_db_close(_db_con) /datum/controller/subsystem/dbcore/proc/IsConnected() - if(!config.sql_enabled) + if(!CONFIG_GET(flag/sql_enabled)) return FALSE return _dm_db_is_connected(_db_con) @@ -87,7 +82,7 @@ SUBSYSTEM_DEF(dbcore) return _dm_db_quote(_db_con, str) /datum/controller/subsystem/dbcore/proc/ErrorMsg() - if(!config.sql_enabled) + if(!CONFIG_GET(flag/sql_enabled)) return "Database disabled by configuration" return _dm_db_error_msg(_db_con) diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 7816a6bdf8..f435d7e819 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -56,7 +56,7 @@ SUBSYSTEM_DEF(events) //selects a random event based on whether it can occur and it's 'weight'(probability) /datum/controller/subsystem/events/proc/spawnEvent() set waitfor = FALSE //for the admin prompt - if(!config.allow_random_events) + if(!CONFIG_GET(flag/allow_random_events)) // var/datum/round_event_control/E = locate(/datum/round_event_control/dust) in control // if(E) E.runEvent() return @@ -171,7 +171,7 @@ SUBSYSTEM_DEF(events) //sets up the holidays and holidays list /datum/controller/subsystem/events/proc/getHoliday() - if(!config.allow_holidays) + if(!CONFIG_GET(flag/allow_holidays)) return // Holiday stuff was not enabled in the config! var/YY = text2num(time2text(world.timeofday, "YY")) // get the current year diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index d64739698a..1eb6c75cc5 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -16,7 +16,7 @@ SUBSYSTEM_DEF(job) /datum/controller/subsystem/job/Initialize(timeofday) if(!occupations.len) SetupOccupations() - if(config.load_jobs_from_txt) + if(CONFIG_GET(flag/load_jobs_from_txt)) LoadJobs() ..() @@ -106,7 +106,7 @@ SUBSYSTEM_DEF(job) if(player.mind && job.title in player.mind.restricted_roles) Debug("FOC incompatible with antagonist role, Player: [player]") continue - if(config.enforce_human_authority && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features)) + if(CONFIG_GET(flag/enforce_human_authority) && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features)) Debug("FOC non-human failed, Player: [player]") continue if(player.client.prefs.GetJobDepartment(job, level) & job.flag) @@ -143,7 +143,7 @@ SUBSYSTEM_DEF(job) Debug("GRJ incompatible with antagonist role, Player: [player], Job: [job.title]") continue - if(config.enforce_human_authority && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features)) + if(CONFIG_GET(flag/enforce_human_authority) && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features)) Debug("GRJ non-human failed, Player: [player]") continue @@ -245,11 +245,12 @@ SUBSYSTEM_DEF(job) setup_officer_positions() //Jobs will have fewer access permissions if the number of players exceeds the threshold defined in game_options.txt - if(config.minimal_access_threshold) - if(config.minimal_access_threshold > unassigned.len) - config.jobs_have_minimal_access = 0 + var/mat = CONFIG_GET(number/minimal_access_threshold) + if(mat) + if(mat > unassigned.len) + CONFIG_SET(flag/jobs_have_minimal_access, FALSE) else - config.jobs_have_minimal_access = 1 + CONFIG_SET(flag/jobs_have_minimal_access, TRUE) //Shuffle players and jobs unassigned = shuffle(unassigned) @@ -317,7 +318,7 @@ SUBSYSTEM_DEF(job) Debug("DO incompatible with antagonist role, Player: [player], Job:[job.title]") continue - if(config.enforce_human_authority && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features)) + if(CONFIG_GET(flag/enforce_human_authority) && !player.client.prefs.pref_species.qualifies_for_rank(job.title, player.client.prefs.features)) Debug("DO non-human failed, Player: [player], Job:[job.title]") continue @@ -415,8 +416,8 @@ SUBSYSTEM_DEF(job) to_chat(M, "To speak on your departments radio, use the :h button. To see others, look closely at your headset.") if(job.req_admin_notify) to_chat(M, "You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp.") - if(config.minimal_access_threshold) - to_chat(M, "As this station was initially staffed with a [config.jobs_have_minimal_access ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card.") + if(CONFIG_GET(number/minimal_access_threshold)) + to_chat(M, "As this station was initially staffed with a [CONFIG_GET(flag/jobs_have_minimal_access) ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card.") if(job && H) job.after_spawn(H, M) @@ -429,9 +430,10 @@ SUBSYSTEM_DEF(job) if(!J) throw EXCEPTION("setup_officer_positions(): Security officer job is missing") - if(config.security_scaling_coeff > 0) + var/ssc = CONFIG_GET(number/security_scaling_coeff) + if(ssc > 0) if(J.spawn_positions > 0) - var/officer_positions = min(12, max(J.spawn_positions, round(unassigned.len/config.security_scaling_coeff))) //Scale between configured minimum and 12 officers + var/officer_positions = min(12, max(J.spawn_positions, round(unassigned.len / ssc))) //Scale between configured minimum and 12 officers Debug("Setting open security officer positions to [officer_positions]") J.total_positions = officer_positions J.spawn_positions = officer_positions @@ -491,8 +493,10 @@ SUBSYSTEM_DEF(job) SSblackbox.add_details("job_preferences",tmp_str) /datum/controller/subsystem/job/proc/PopcapReached() - if(config.hard_popcap || config.extreme_popcap) - var/relevent_cap = max(config.hard_popcap, config.extreme_popcap) + var/hpc = CONFIG_GET(number/hard_popcap) + var/epc = CONFIG_GET(number/extreme_popcap) + if(hpc || epc) + var/relevent_cap = max(hpc, epc) if((initial_players_to_assign - unassigned.len) >= relevent_cap) return 1 return 0 diff --git a/code/controllers/subsystem/lighting.dm b/code/controllers/subsystem/lighting.dm index 78e8b150c3..989c5b43c4 100644 --- a/code/controllers/subsystem/lighting.dm +++ b/code/controllers/subsystem/lighting.dm @@ -16,7 +16,7 @@ SUBSYSTEM_DEF(lighting) /datum/controller/subsystem/lighting/Initialize(timeofday) if(!initialized) - if (config.starlight) + if (CONFIG_GET(flag/starlight)) for(var/I in GLOB.sortedAreas) var/area/A = I if (A.dynamic_lighting == DYNAMIC_LIGHTING_IFSTARLIGHT) diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index f2bb300471..dd825c1700 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -43,7 +43,7 @@ SUBSYSTEM_DEF(mapping) loading_ruins = TRUE var/mining_type = config.minetype if (mining_type == "lavaland") - seedRuins(list(ZLEVEL_LAVALAND), global.config.lavaland_budget, /area/lavaland/surface/outdoors/unexplored, lava_ruins_templates) + seedRuins(list(ZLEVEL_LAVALAND), CONFIG_GET(number/lavaland_budget), /area/lavaland/surface/outdoors/unexplored, lava_ruins_templates) spawn_rivers() // deep space ruins @@ -55,7 +55,7 @@ SUBSYSTEM_DEF(mapping) else space_zlevels += i - seedRuins(space_zlevels, global.config.space_budget, /area/space, space_ruins_templates) + seedRuins(space_zlevels, CONFIG_GET(number/space_budget), /area/space, space_ruins_templates) loading_ruins = FALSE repopulate_sorted_areas() // Set up Z-level transistions. @@ -141,7 +141,8 @@ SUBSYSTEM_DEF(mapping) var/players = GLOB.clients.len var/list/mapvotes = list() //count votes - if(global.config.allow_map_voting) + var/amv = CONFIG_GET(flag/allow_map_voting) + if(amv) for (var/client/c in GLOB.clients) var/vote = c.prefs.preferred_map if (!vote) @@ -174,7 +175,7 @@ SUBSYSTEM_DEF(mapping) mapvotes.Remove(map) continue - if(global.config.allow_map_voting) + if(amv) mapvotes[map] = mapvotes[map]*VM.voteweight var/pickedmap = pickweight(mapvotes) diff --git a/code/controllers/subsystem/minimap.dm b/code/controllers/subsystem/minimap.dm index 4e58212b44..463b82b13e 100644 --- a/code/controllers/subsystem/minimap.dm +++ b/code/controllers/subsystem/minimap.dm @@ -9,7 +9,7 @@ SUBSYSTEM_DEF(minimap) /datum/controller/subsystem/minimap/Initialize(timeofday) var/hash = md5(SSmapping.config.GetFullMapPath()) - if(config.generate_minimaps) + if(CONFIG_GET(flag/generate_minimaps)) if(hash == trim(file2text(hash_path()))) for(var/z in z_levels) //We have these files cached, let's register them register_asset("minimap_[z].png", fcopy_rsc(map_path(z))) diff --git a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm index 87b06cd587..0b8fa750b6 100644 --- a/code/controllers/subsystem/server_maint.dm +++ b/code/controllers/subsystem/server_maint.dm @@ -10,7 +10,7 @@ SUBSYSTEM_DEF(server_maint) var/list/currentrun /datum/controller/subsystem/server_maint/Initialize(timeofday) - if (config.hub) + if (CONFIG_GET(flag/hub)) world.update_hub_visibility(TRUE) ..() @@ -21,16 +21,19 @@ SUBSYSTEM_DEF(server_maint) var/list/currentrun = src.currentrun var/round_started = SSticker.HasRoundStarted() + var/kick_inactive = CONFIG_GET(flag/kick_inactive) + var/afk_period + if(kick_inactive) + afk_period = CONFIG_GET(number/afk_period) for(var/I in currentrun) var/client/C = I //handle kicking inactive players - if(round_started && config.kick_inactive) - if(C.is_afk(config.afk_period)) - var/cmob = C.mob - if(!(isobserver(cmob) || (isdead(cmob) && C.holder))) - log_access("AFK: [key_name(C)]") - to_chat(C, "You have been inactive for more than [DisplayTimeText(config.afk_period)] and have been disconnected.") - qdel(C) + if(round_started && kick_inactive && C.is_afk(afk_period)) + var/cmob = C.mob + if(!(isobserver(cmob) || (isdead(cmob) && C.holder))) + log_access("AFK: [key_name(C)]") + to_chat(C, "You have been inactive for more than [DisplayTimeText(afk_period)] and have been disconnected.") + qdel(C) if (!(!C || world.time - C.connection_time < PING_BUFFER_TIME || C.inactivity >= (wait-1))) winset(C, null, "command=.update_ping+[world.time+world.tick_lag*TICK_USAGE_REAL/100]") @@ -40,7 +43,7 @@ SUBSYSTEM_DEF(server_maint) /datum/controller/subsystem/server_maint/Shutdown() kick_clients_in_lobby("The round came to an end with you in the lobby.", TRUE) //second parameter ensures only afk clients are kicked - var/server = config.server + var/server = CONFIG_GET(string/server) for(var/thing in GLOB.clients) if(!thing) continue diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index 2b1080049e..3ebc414a02 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -176,9 +176,9 @@ SUBSYSTEM_DEF(shuttle) Good luck.") return emergency = backup_shuttle - - if(world.time - SSticker.round_start_time < config.shuttle_refuel_delay) - to_chat(user, "The emergency shuttle is refueling. Please wait [DisplayTimeText((world.time - SSticker.round_start_time) - config.shuttle_refuel_delay)] before trying again.") + var/srd = CONFIG_GET(number/shuttle_refuel_delay) + if(world.time - SSticker.round_start_time < srd) + to_chat(user, "The emergency shuttle is refueling. Please wait [DisplayTimeText((world.time - SSticker.round_start_time) - srd)] before trying again.") return switch(emergency.mode) diff --git a/code/controllers/subsystem/squeak.dm b/code/controllers/subsystem/squeak.dm index 964d970e2b..0148011e8b 100644 --- a/code/controllers/subsystem/squeak.dm +++ b/code/controllers/subsystem/squeak.dm @@ -10,7 +10,7 @@ SUBSYSTEM_DEF(squeak) var/list/exposed_wires = list() /datum/controller/subsystem/squeak/Initialize(timeofday) - trigger_migration(config.mice_roundstart) + trigger_migration(CONFIG_GET(number/mice_roundstart)) return ..() /datum/controller/subsystem/squeak/proc/trigger_migration(num_mice=10) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 3932eada60..2a43d7a844 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -79,13 +79,13 @@ SUBSYSTEM_DEF(ticker) if(!GLOB.syndicate_code_response) GLOB.syndicate_code_response = generate_code_phrase() ..() - start_at = world.time + (config.lobby_countdown * 10) + start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10) /datum/controller/subsystem/ticker/fire() switch(current_state) if(GAME_STATE_STARTUP) if(Master.initializations_finished_with_no_players_logged_in) - start_at = world.time + (config.lobby_countdown * 10) + start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10) for(var/client/C in GLOB.clients) window_flash(C, ignorepref = TRUE) //let them know lobby has opened up. to_chat(world, "Welcome to [station_name()]!") @@ -207,7 +207,7 @@ SUBSYSTEM_DEF(ticker) else mode.announce() - if(!config.ooc_during_round) + if(!CONFIG_GET(flag/ooc_during_round)) toggle_ooc(FALSE) // Turn it off CHECK_TICK @@ -429,7 +429,7 @@ SUBSYSTEM_DEF(ticker) CHECK_TICK - if(config.cross_allowed) + if(CONFIG_GET(string/cross_server_address)) send_news_report() CHECK_TICK @@ -495,7 +495,8 @@ SUBSYSTEM_DEF(ticker) to_chat(world, "Tip of the round: [html_encode(m)]") /datum/controller/subsystem/ticker/proc/check_queue() - if(!queued_players.len || !config.hard_popcap) + var/hpc = CONFIG_GET(number/hard_popcap) + if(!queued_players.len || !hpc) return queue_delay++ @@ -503,7 +504,7 @@ SUBSYSTEM_DEF(ticker) switch(queue_delay) if(5) //every 5 ticks check if there is a slot available - if(living_player_count() < config.hard_popcap) + if(living_player_count() < hpc) if(next_in_line && next_in_line.client) to_chat(next_in_line, "A slot has opened! You have approximately 20 seconds to join. \>\>Join Game\<\<") SEND_SOUND(next_in_line, sound('sound/misc/notice1.ogg')) @@ -517,7 +518,7 @@ SUBSYSTEM_DEF(ticker) queue_delay = 0 /datum/controller/subsystem/ticker/proc/check_maprotate() - if (!config.maprotation) + if (!CONFIG_GET(flag/maprotation)) return if (SSshuttle.emergency && SSshuttle.emergency.mode != SHUTTLE_ESCAPE || SSshuttle.canRecall()) return @@ -527,7 +528,7 @@ SUBSYSTEM_DEF(ticker) maprotatechecked = 1 //map rotate chance defaults to 75% of the length of the round (in minutes) - if (!prob((world.time/600)*config.maprotatechancedelta)) + if (!prob((world.time/600)*CONFIG_GET(number/maprotatechancedelta))) return INVOKE_ASYNC(SSmapping, /datum/controller/subsystem/mapping/.proc/maprotate) @@ -687,7 +688,7 @@ SUBSYSTEM_DEF(ticker) return if(!delay) - delay = config.round_end_countdown * 10 + delay = CONFIG_GET(number/round_end_countdown) * 10 var/skip_delay = check_rights() if(delay_end && !skip_delay) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 0ea16b32d8..d377329312 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -18,7 +18,7 @@ SUBSYSTEM_DEF(vote) /datum/controller/subsystem/vote/fire() //called by master_controller if(mode) - time_remaining = round((started_time + config.vote_period - world.time)/10) + time_remaining = round((started_time + CONFIG_GET(number/vote_period) - world.time)/10) if(time_remaining < 0) result() @@ -54,7 +54,7 @@ SUBSYSTEM_DEF(vote) if(votes > greatest_votes) greatest_votes = votes //default-vote for everyone who didn't vote - if(!config.vote_no_default && choices.len) + if(!CONFIG_GET(flag/default_no_vote) && choices.len) var/list/non_voters = GLOB.directory.Copy() non_voters -= voted for (var/non_voter_ckey in non_voters) @@ -146,7 +146,7 @@ SUBSYSTEM_DEF(vote) /datum/controller/subsystem/vote/proc/submit_vote(vote) if(mode) - if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder) + if(CONFIG_GET(flag/no_dead_vote) && usr.stat == DEAD && !usr.client.holder) return 0 if(!(usr.ckey in voted)) if(vote && 1<=vote && vote<=choices.len) @@ -158,7 +158,7 @@ SUBSYSTEM_DEF(vote) /datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key) if(!mode) if(started_time) - var/next_allowed_time = (started_time + config.vote_delay) + var/next_allowed_time = (started_time + CONFIG_GET(number/vote_delay)) if(mode) to_chat(usr, "There is already a vote in progress! please wait for it to finish.") return 0 @@ -198,8 +198,9 @@ SUBSYSTEM_DEF(vote) if(mode == "custom") text += "\n[question]" log_vote(text) - to_chat(world, "\n[text]\nType vote or click here to place your votes.\nYou have [DisplayTimeText(config.vote_period)] to vote.") - time_remaining = round(config.vote_period/10) + var/vp = CONFIG_GET(number/vote_period) + to_chat(world, "\n[text]\nType vote or click here to place your votes.\nYou have [DisplayTimeText(vp)] to vote.") + time_remaining = round(vp/10) for(var/c in GLOB.clients) var/client/C = c var/datum/action/vote/V = new @@ -238,20 +239,22 @@ SUBSYSTEM_DEF(vote) else . += "

Start a vote:


  • " //restart - if(trialmin || config.allow_vote_restart) + var/avr = CONFIG_GET(flag/allow_vote_restart) + if(trialmin || avr) . += "Restart" else . += "Restart (Disallowed)" if(trialmin) - . += "\t([config.allow_vote_restart?"Allowed":"Disallowed"])" + . += "\t([avr ? "Allowed" : "Disallowed"])" . += "
  • " //gamemode - if(trialmin || config.allow_vote_mode) + var/avm = CONFIG_GET(flag/allow_vote_mode) + if(trialmin || avm) . += "GameMode" else . += "GameMode (Disallowed)" if(trialmin) - . += "\t([config.allow_vote_mode?"Allowed":"Disallowed"])" + . += "\t([avm ? "Allowed" : "Disallowed"])" . += "
  • " //custom @@ -275,15 +278,15 @@ SUBSYSTEM_DEF(vote) reset() if("toggle_restart") if(usr.client.holder) - config.allow_vote_restart = !config.allow_vote_restart + CONFIG_SET(flag/allow_vote_restart, !CONFIG_GET(flag/allow_vote_restart)) if("toggle_gamemode") if(usr.client.holder) - config.allow_vote_mode = !config.allow_vote_mode + CONFIG_SET(flag/allow_vote_mode, !CONFIG_GET(flag/allow_vote_mode)) if("restart") - if(config.allow_vote_restart || usr.client.holder) + if(CONFIG_GET(flag/allow_vote_restart) || usr.client.holder) initiate_vote("restart",usr.key) if("gamemode") - if(config.allow_vote_mode || usr.client.holder) + if(CONFIG_GET(flag/allow_vote_mode) || usr.client.holder) initiate_vote("gamemode",usr.key) if("custom") if(usr.client.holder) diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index 2222a959bc..a96d2cbbc0 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -208,7 +208,8 @@ /* General ai_law functions */ /datum/ai_laws/proc/set_laws_config() - switch(config.default_laws) + var/list/law_ids = CONFIG_GET(keyed_flag_list/random_laws) + switch(CONFIG_GET(number/default_laws)) if(0) add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.") add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.") @@ -220,7 +221,7 @@ var/list/randlaws = list() for(var/lpath in subtypesof(/datum/ai_laws)) var/datum/ai_laws/L = lpath - if(initial(L.id) in config.lawids) + if(initial(L.id) in law_ids) randlaws += lpath var/datum/ai_laws/lawtype if(randlaws.len) @@ -234,21 +235,14 @@ if(3) pick_weighted_lawset() - else: - log_law("Invalid law config. Please check silicon_laws.txt") - add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.") - add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.") - add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") - WARNING("Invalid custom AI laws, check silicon_laws.txt") - /datum/ai_laws/proc/pick_weighted_lawset() var/datum/ai_laws/lawtype - - while(!lawtype && config.law_weights.len) - var/possible_id = pickweight(config.law_weights) + var/list/law_weights = CONFIG_GET(keyed_number_list/law_weight) + while(!lawtype && law_weights) + var/possible_id = pickweight(law_weights) lawtype = lawid_to_type(possible_id) if(!lawtype) - config.law_weights -= possible_id + law_weights -= possible_id WARNING("Bad lawid in game_options.txt: [possible_id]") if(!lawtype) diff --git a/code/datums/antagonists/datum_traitor.dm b/code/datums/antagonists/datum_traitor.dm index eeb803ca1e..fe965efe45 100644 --- a/code/datums/antagonists/datum_traitor.dm +++ b/code/datums/antagonists/datum_traitor.dm @@ -138,10 +138,11 @@ assign_exchange_role(SSticker.mode.exchange_red) assign_exchange_role(SSticker.mode.exchange_blue) objective_count += 1 //Exchange counts towards number of objectives - for(var/i = objective_count, i < config.traitor_objectives_amount, i++) + var/toa = CONFIG_GET(number/traitor_objectives_amount) + for(var/i = objective_count, i < toa, i++) forge_single_objective() - if(is_hijacker && objective_count <= config.traitor_objectives_amount) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount + if(is_hijacker && objective_count <= toa) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount if (!(locate(/datum/objective/hijack) in owner.objectives)) var/datum/objective/hijack/hijack_objective = new hijack_objective.owner = owner @@ -174,6 +175,7 @@ if(prob(30)) objective_count += forge_single_objective() +<<<<<<< HEAD for(var/i = objective_count, i < config.traitor_objectives_amount, i++) if(prob(20)) //AI's are less likely to look for a late-joiner than normal traitors var/datum/objective/assassinate/late/late_objective = new @@ -185,6 +187,13 @@ kill_objective.owner = owner kill_objective.find_target() add_objective(kill_objective) +======= + for(var/i = objective_count, i < CONFIG_GET(number/traitor_objectives_amount), i++) + var/datum/objective/assassinate/kill_objective = new + kill_objective.owner = owner + kill_objective.find_target() + add_objective(kill_objective) +>>>>>>> 4178c20... Configuration datum refactor (#30763) var/datum/objective/survive/exist/exist_objective = new exist_objective.owner = owner diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index b20381ca85..299f6dbac9 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -222,7 +222,7 @@ G.fields["name"] = H.real_name G.fields["rank"] = assignment G.fields["age"] = H.age - if(config.mutant_races) + if(CONFIG_GET(flag/join_with_mutant_race)) G.fields["species"] = H.dna.species.name G.fields["fingerprint"] = md5(H.dna.uni_identity) G.fields["p_stat"] = "Active" diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 27a9338191..b090a12714 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /////////////////////////// DNA DATUM /datum/dna @@ -398,4 +399,400 @@ value = values return value -/////////////////////////// DNA HELPER-PROCS \ No newline at end of file +/////////////////////////// DNA HELPER-PROCS +======= + +/////////////////////////// DNA DATUM +/datum/dna + var/unique_enzymes + var/struc_enzymes + var/uni_identity + var/blood_type + var/datum/species/species = new /datum/species/human() //The type of mutant race the player is if applicable (i.e. potato-man) + var/list/features = list("FFF") //first value is mutant color + var/real_name //Stores the real name of the person who originally got this dna datum. Used primarely for changelings, + var/list/mutations = list() //All mutations are from now on here + var/list/temporary_mutations = list() //Timers for temporary mutations + var/list/previous = list() //For temporary name/ui/ue/blood_type modifications + var/mob/living/holder + +/datum/dna/New(mob/living/new_holder) + if(new_holder) + holder = new_holder + +/datum/dna/proc/transfer_identity(mob/living/carbon/destination, transfer_SE = 0) + if(!istype(destination)) + return + destination.dna.unique_enzymes = unique_enzymes + destination.dna.uni_identity = uni_identity + destination.dna.blood_type = blood_type + destination.set_species(species.type, icon_update=0) + destination.dna.features = features.Copy() + destination.dna.real_name = real_name + destination.dna.temporary_mutations = temporary_mutations.Copy() + if(transfer_SE) + destination.dna.struc_enzymes = struc_enzymes + +/datum/dna/proc/copy_dna(datum/dna/new_dna) + new_dna.unique_enzymes = unique_enzymes + new_dna.struc_enzymes = struc_enzymes + new_dna.uni_identity = uni_identity + new_dna.blood_type = blood_type + new_dna.features = features.Copy() + new_dna.species = new species.type + new_dna.real_name = real_name + new_dna.mutations = mutations.Copy() + +/datum/dna/proc/add_mutation(mutation_name) + var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name] + HM.on_acquiring(holder) + +/datum/dna/proc/remove_mutation(mutation_name) + var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name] + HM.on_losing(holder) + +/datum/dna/proc/check_mutation(mutation_name) + var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name] + return mutations.Find(HM) + +/datum/dna/proc/remove_all_mutations() + remove_mutation_group(mutations) + +/datum/dna/proc/remove_mutation_group(list/group) + if(!group) + return + for(var/datum/mutation/human/HM in group) + HM.force_lose(holder) + +/datum/dna/proc/generate_uni_identity() + . = "" + var/list/L = new /list(DNA_UNI_IDENTITY_BLOCKS) + + L[DNA_GENDER_BLOCK] = construct_block((holder.gender!=MALE)+1, 2) + if(ishuman(holder)) + var/mob/living/carbon/human/H = holder + if(!GLOB.hair_styles_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/hair,GLOB.hair_styles_list, GLOB.hair_styles_male_list, GLOB.hair_styles_female_list) + L[DNA_HAIR_STYLE_BLOCK] = construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len) + L[DNA_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.hair_color) + if(!GLOB.facial_hair_styles_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, GLOB.facial_hair_styles_list, GLOB.facial_hair_styles_male_list, GLOB.facial_hair_styles_female_list) + L[DNA_FACIAL_HAIR_STYLE_BLOCK] = construct_block(GLOB.facial_hair_styles_list.Find(H.facial_hair_style), GLOB.facial_hair_styles_list.len) + L[DNA_FACIAL_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.facial_hair_color) + L[DNA_SKIN_TONE_BLOCK] = construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len) + L[DNA_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.eye_color) + + for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++) + if(L[i]) + . += L[i] + else + . += random_string(DNA_BLOCK_SIZE,GLOB.hex_characters) + return . + +/datum/dna/proc/generate_struc_enzymes() + var/list/sorting = new /list(DNA_STRUC_ENZYMES_BLOCKS) + var/result = "" + for(var/datum/mutation/human/A in GLOB.good_mutations + GLOB.bad_mutations + GLOB.not_good_mutations) + if(A.name == RACEMUT && ismonkey(holder)) + sorting[A.dna_block] = num2hex(A.lowest_value + rand(0, 256 * 6), DNA_BLOCK_SIZE) + mutations |= A + else + sorting[A.dna_block] = random_string(DNA_BLOCK_SIZE, list("0","1","2","3","4","5","6")) + + for(var/B in sorting) + result += B + return result + +/datum/dna/proc/generate_unique_enzymes() + . = "" + if(istype(holder)) + real_name = holder.real_name + . += md5(holder.real_name) + else + . += random_string(DNA_UNIQUE_ENZYMES_LEN, GLOB.hex_characters) + return . + +/datum/dna/proc/update_ui_block(blocknumber) + if(!blocknumber || !ishuman(holder)) + return + var/mob/living/carbon/human/H = holder + switch(blocknumber) + if(DNA_HAIR_COLOR_BLOCK) + setblock(uni_identity, blocknumber, sanitize_hexcolor(H.hair_color)) + if(DNA_FACIAL_HAIR_COLOR_BLOCK) + setblock(uni_identity, blocknumber, sanitize_hexcolor(H.facial_hair_color)) + if(DNA_SKIN_TONE_BLOCK) + setblock(uni_identity, blocknumber, construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len)) + if(DNA_EYE_COLOR_BLOCK) + setblock(uni_identity, blocknumber, sanitize_hexcolor(H.eye_color)) + if(DNA_GENDER_BLOCK) + setblock(uni_identity, blocknumber, construct_block((H.gender!=MALE)+1, 2)) + if(DNA_FACIAL_HAIR_STYLE_BLOCK) + setblock(uni_identity, blocknumber, construct_block(GLOB.facial_hair_styles_list.Find(H.facial_hair_style), GLOB.facial_hair_styles_list.len)) + if(DNA_HAIR_STYLE_BLOCK) + setblock(uni_identity, blocknumber, construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len)) + +/datum/dna/proc/mutations_say_mods(message) + if(message) + for(var/datum/mutation/human/M in mutations) + message = M.say_mod(message) + return message + +/datum/dna/proc/mutations_get_spans() + var/list/spans = list() + for(var/datum/mutation/human/M in mutations) + spans |= M.get_spans() + return spans + +/datum/dna/proc/species_get_spans() + var/list/spans = list() + if(species) + spans |= species.get_spans() + return spans + + +/datum/dna/proc/is_same_as(datum/dna/D) + if(uni_identity == D.uni_identity && struc_enzymes == D.struc_enzymes && real_name == D.real_name) + if(species.type == D.species.type && features == D.features && blood_type == D.blood_type) + return 1 + return 0 + +//used to update dna UI, UE, and dna.real_name. +/datum/dna/proc/update_dna_identity() + uni_identity = generate_uni_identity() + unique_enzymes = generate_unique_enzymes() + +/datum/dna/proc/initialize_dna(newblood_type) + if(newblood_type) + blood_type = newblood_type + unique_enzymes = generate_unique_enzymes() + uni_identity = generate_uni_identity() + struc_enzymes = generate_struc_enzymes() + features = random_features() + + +/datum/dna/stored //subtype used by brain mob's stored_dna + +/datum/dna/stored/add_mutation(mutation_name) //no mutation changes on stored dna. + return + +/datum/dna/stored/remove_mutation(mutation_name) + return + +/datum/dna/stored/check_mutation(mutation_name) + return + +/datum/dna/stored/remove_all_mutations() + return + +/datum/dna/stored/remove_mutation_group(list/group) + return + +/////////////////////////// DNA MOB-PROCS ////////////////////// + +/mob/proc/set_species(datum/species/mrace, icon_update = 1) + return + +/mob/living/brain/set_species(datum/species/mrace, icon_update = 1) + if(mrace) + if(ispath(mrace)) + stored_dna.species = new mrace() + else + stored_dna.species = mrace //not calling any species update procs since we're a brain, not a monkey/human + + +/mob/living/carbon/set_species(datum/species/mrace, icon_update = 1) + if(mrace && has_dna()) + dna.species.on_species_loss(src) + var/old_species = dna.species + if(ispath(mrace)) + dna.species = new mrace() + else + dna.species = mrace + dna.species.on_species_gain(src, old_species) + +/mob/living/carbon/human/set_species(datum/species/mrace, icon_update = 1) + ..() + if(icon_update) + update_body() + update_hair() + update_body_parts() + update_mutations_overlay()// no lizard with human hulk overlay please. + + +/mob/proc/has_dna() + return + +/mob/living/carbon/has_dna() + return dna + + +/mob/living/carbon/human/proc/hardset_dna(ui, se, newreal_name, newblood_type, datum/species/mrace, newfeatures) + + if(newfeatures) + dna.features = newfeatures + + if(mrace) + var/datum/species/newrace = new mrace.type + newrace.copy_properties_from(mrace) + set_species(newrace, icon_update=0) + + if(newreal_name) + real_name = newreal_name + dna.generate_unique_enzymes() + + if(newblood_type) + dna.blood_type = newblood_type + + if(ui) + dna.uni_identity = ui + updateappearance(icon_update=0) + + if(se) + dna.struc_enzymes = se + domutcheck() + + if(mrace || newfeatures || ui) + update_body() + update_hair() + update_body_parts() + update_mutations_overlay() + + +/mob/living/carbon/proc/create_dna() + dna = new /datum/dna(src) + if(!dna.species) + var/rando_race = pick(CONFIG_GET(keyed_flag_list/roundstart_races)) + dna.species = new rando_race() + +//proc used to update the mob's appearance after its dna UI has been changed +/mob/living/carbon/proc/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0) + if(!has_dna()) + return + gender = (deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 2)-1) ? FEMALE : MALE + +/mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0) + ..() + var/structure = dna.uni_identity + hair_color = sanitize_hexcolor(getblock(structure, DNA_HAIR_COLOR_BLOCK)) + facial_hair_color = sanitize_hexcolor(getblock(structure, DNA_FACIAL_HAIR_COLOR_BLOCK)) + skin_tone = GLOB.skin_tones[deconstruct_block(getblock(structure, DNA_SKIN_TONE_BLOCK), GLOB.skin_tones.len)] + eye_color = sanitize_hexcolor(getblock(structure, DNA_EYE_COLOR_BLOCK)) + facial_hair_style = GLOB.facial_hair_styles_list[deconstruct_block(getblock(structure, DNA_FACIAL_HAIR_STYLE_BLOCK), GLOB.facial_hair_styles_list.len)] + hair_style = GLOB.hair_styles_list[deconstruct_block(getblock(structure, DNA_HAIR_STYLE_BLOCK), GLOB.hair_styles_list.len)] + if(icon_update) + update_body() + update_hair() + if(mutcolor_update) + update_body_parts() + if(mutations_overlay_update) + update_mutations_overlay() + + +/mob/proc/domutcheck() + return + +/mob/living/carbon/domutcheck(force_powers=0) //Set force_powers to 1 to bypass the power chance + if(!has_dna()) + return + + for(var/datum/mutation/human/A in GLOB.good_mutations | GLOB.bad_mutations | GLOB.not_good_mutations) + if(ismob(A.check_block(src, force_powers))) + return //we got monkeyized/humanized, this mob will be deleted, no need to continue. + + update_mutations_overlay() + + + +/////////////////////////// DNA HELPER-PROCS ////////////////////////////// +/proc/getleftblocks(input,blocknumber,blocksize) + if(blocknumber > 1) + return copytext(input,1,((blocksize*blocknumber)-(blocksize-1))) + +/proc/getrightblocks(input,blocknumber,blocksize) + if(blocknumber < (length(input)/blocksize)) + return copytext(input,blocksize*blocknumber+1,length(input)+1) + +/proc/getblock(input, blocknumber, blocksize=DNA_BLOCK_SIZE) + return copytext(input, blocksize*(blocknumber-1)+1, (blocksize*blocknumber)+1) + +/proc/setblock(istring, blocknumber, replacement, blocksize=DNA_BLOCK_SIZE) + if(!istring || !blocknumber || !replacement || !blocksize) + return 0 + return getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize) + +/mob/living/carbon/proc/randmut(list/candidates, difficulty = 2) + if(!has_dna()) + return + var/datum/mutation/human/num = pick(candidates) + . = num.force_give(src) + +/mob/living/carbon/proc/randmutb() + if(!has_dna()) + return + var/datum/mutation/human/HM = pick((GLOB.bad_mutations | GLOB.not_good_mutations) - GLOB.mutations_list[RACEMUT]) + . = HM.force_give(src) + +/mob/living/carbon/proc/randmutg() + if(!has_dna()) + return + var/datum/mutation/human/HM = pick(GLOB.good_mutations) + . = HM.force_give(src) + +/mob/living/carbon/proc/randmutvg() + if(!has_dna()) + return + var/datum/mutation/human/HM = pick((GLOB.good_mutations) - GLOB.mutations_list[HULK] - GLOB.mutations_list[DWARFISM]) + . = HM.force_give(src) + +/mob/living/carbon/proc/randmuti() + if(!has_dna()) + return + var/num = rand(1, DNA_UNI_IDENTITY_BLOCKS) + var/newdna = setblock(dna.uni_identity, num, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters)) + dna.uni_identity = newdna + updateappearance(mutations_overlay_update=1) + +/mob/living/carbon/proc/clean_dna() + if(!has_dna()) + return + dna.remove_all_mutations() + +/mob/living/carbon/proc/clean_randmut(list/candidates, difficulty = 2) + clean_dna() + randmut(candidates, difficulty) + +/proc/scramble_dna(mob/living/carbon/M, ui=FALSE, se=FALSE, probability) + if(!M.has_dna()) + return 0 + if(se) + for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++) + if(prob(probability)) + M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters)) + M.domutcheck() + if(ui) + for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++) + if(prob(probability)) + M.dna.uni_identity = setblock(M.dna.uni_identity, i, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters)) + M.updateappearance(mutations_overlay_update=1) + return 1 + +//value in range 1 to values. values must be greater than 0 +//all arguments assumed to be positive integers +/proc/construct_block(value, values, blocksize=DNA_BLOCK_SIZE) + var/width = round((16**blocksize)/values) + if(value < 1) + value = 1 + value = (value * width) - rand(1,width) + return num2hex(value, blocksize) + +//value is hex +/proc/deconstruct_block(value, values, blocksize=DNA_BLOCK_SIZE) + var/width = round((16**blocksize)/values) + value = round(hex2num(value) / width) + 1 + if(value > values) + value = values + return value + +/////////////////////////// DNA HELPER-PROCS +>>>>>>> 4178c20... Configuration datum refactor (#30763) diff --git a/code/datums/explosion.dm b/code/datums/explosion.dm index 5e381c0322..9869b43d8f 100644 --- a/code/datums/explosion.dm +++ b/code/datums/explosion.dm @@ -140,7 +140,7 @@ GLOBAL_LIST_EMPTY(explosions) var/list/exploded_this_tick = list() //open turfs that need to be blocked off while we sleep var/list/affected_turfs = GatherSpiralTurfs(max_range, epicenter) - var/reactionary = config.reactionary_explosions + var/reactionary = CONFIG_GET(flag/reactionary_explosions) var/list/cached_exp_block if(reactionary) diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm index c6958fa997..b3dc454ecc 100644 --- a/code/datums/helper_datums/getrev.dm +++ b/code/datums/helper_datums/getrev.dm @@ -47,19 +47,17 @@ else log_world(originmastercommit) /datum/getrev/proc/DownloadPRDetails() - if(!config.githubrepoid) + var/repo_id = CONFIG_GET(number/githubrepoid) + if(!repo_id) if(testmerge.len) log_world("PR details download failed: No github repo config set") return - if(!isnum(text2num(config.githubrepoid))) - log_world("PR details download failed: Invalid github repo id: [config.githubrepoid]") - return for(var/line in testmerge) if(!isnum(text2num(line))) log_world("PR details download failed: Invalid PR number: [line]") return - var/url = "https://api.github.com/repositories/[config.githubrepoid]/pulls/[line].json" + var/url = "https://api.github.com/repositories/[repo_id]/pulls/[line].json" GLOB.valid_HTTPSGet = TRUE var/json = HTTPSGet(url) if(!json) @@ -87,7 +85,7 @@ details = ": '" + html_encode(testmerge[line]["title"]) + "' by " + html_encode(testmerge[line]["user"]["login"]) if(details && findtext(details, "\[s\]") && (!usr || !usr.client.holder)) continue - . += "#[line][details]
    " + . += "#[line][details]
    " /client/verb/showrevinfo() set category = "OOC" @@ -101,44 +99,47 @@ to_chat(src, GLOB.revdata.GetTestMergeInfo()) prefix = "Based off origin/master commit: " var/pc = GLOB.revdata.originmastercommit - to_chat(src, "[prefix][copytext(pc, 1, min(length(pc), 7))]") + to_chat(src, "[prefix][copytext(pc, 1, min(length(pc), 7))]") else to_chat(src, "Revision unknown") to_chat(src, "Current Informational Settings:") - to_chat(src, "Protect Authority Roles From Traitor: [config.protect_roles_from_antagonist]") - to_chat(src, "Protect Assistant Role From Traitor: [config.protect_assistant_from_antagonist]") - to_chat(src, "Enforce Human Authority: [config.enforce_human_authority]") - to_chat(src, "Allow Latejoin Antagonists: [config.allow_latejoin_antagonists]") - to_chat(src, "Enforce Continuous Rounds: [config.continuous.len] of [config.modes.len] roundtypes") - to_chat(src, "Allow Midround Antagonists: [config.midround_antag.len] of [config.modes.len] roundtypes") - if(config.show_game_type_odds) + to_chat(src, "Protect Authority Roles From Traitor: [CONFIG_GET(flag/protect_roles_from_antagonist)]") + to_chat(src, "Protect Assistant Role From Traitor: [CONFIG_GET(flag/protect_assistant_from_antagonist)]") + to_chat(src, "Enforce Human Authority: [CONFIG_GET(flag/enforce_human_authority)]") + to_chat(src, "Allow Latejoin Antagonists: [CONFIG_GET(flag/allow_latejoin_antagonists)]") + to_chat(src, "Enforce Continuous Rounds: [length(CONFIG_GET(keyed_flag_list/continuous))] of [config.modes.len] roundtypes") + to_chat(src, "Allow Midround Antagonists: [length(CONFIG_GET(keyed_flag_list/midround_antag))] of [config.modes.len] roundtypes") + if(CONFIG_GET(flag/show_game_type_odds)) + var/list/probabilities = CONFIG_GET(keyed_number_list/probability) if(SSticker.IsRoundInProgress()) var/prob_sum = 0 var/current_odds_differ = FALSE var/list/probs = list() var/list/modes = config.gamemode_cache + var/list/min_pop = CONFIG_GET(keyed_number_list/min_pop) + var/list/max_pop = CONFIG_GET(keyed_number_list/max_pop) for(var/mode in modes) var/datum/game_mode/M = mode var/ctag = initial(M.config_tag) - if(!(ctag in config.probabilities)) + if(!(ctag in probabilities)) continue - if((config.min_pop[ctag] && (config.min_pop[ctag] > SSticker.totalPlayersReady)) || (config.max_pop[ctag] && (config.max_pop[ctag] < SSticker.totalPlayersReady)) || (initial(M.required_players) > SSticker.totalPlayersReady)) + if((min_pop[ctag] && (min_pop[ctag] > SSticker.totalPlayersReady)) || (max_pop[ctag] && (max_pop[ctag] < SSticker.totalPlayersReady)) || (initial(M.required_players) > SSticker.totalPlayersReady)) current_odds_differ = TRUE continue probs[ctag] = 1 - prob_sum += config.probabilities[ctag] + prob_sum += probabilities[ctag] if(current_odds_differ) to_chat(src, "Game Mode Odds for current round:") for(var/ctag in probs) - if(config.probabilities[ctag] > 0) - var/percentage = round(config.probabilities[ctag] / prob_sum * 100, 0.1) + if(probabilities[ctag] > 0) + var/percentage = round(probabilities[ctag] / prob_sum * 100, 0.1) to_chat(src, "[ctag] [percentage]%") to_chat(src, "All Game Mode Odds:") var/sum = 0 - for(var/ctag in config.probabilities) - sum += config.probabilities[ctag] - for(var/ctag in config.probabilities) - if(config.probabilities[ctag] > 0) - var/percentage = round(config.probabilities[ctag] / sum * 100, 0.1) + for(var/ctag in probabilities) + sum += probabilities[ctag] + for(var/ctag in probabilities) + if(probabilities[ctag] > 0) + var/percentage = round(probabilities[ctag] / sum * 100, 0.1) to_chat(src, "[ctag] [percentage]%") diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index fafd057fea..b062b8f054 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -118,7 +118,7 @@ GLOBAL_LIST_EMPTY(teleportlocs) else if(dynamic_lighting != DYNAMIC_LIGHTING_IFSTARLIGHT) dynamic_lighting = DYNAMIC_LIGHTING_DISABLED if(dynamic_lighting == DYNAMIC_LIGHTING_IFSTARLIGHT) - dynamic_lighting = config.starlight ? DYNAMIC_LIGHTING_ENABLED : DYNAMIC_LIGHTING_DISABLED + dynamic_lighting = CONFIG_GET(flag/starlight) ? DYNAMIC_LIGHTING_ENABLED : DYNAMIC_LIGHTING_DISABLED . = ..() diff --git a/code/game/gamemodes/blob/blob_finish.dm b/code/game/gamemodes/blob/blob_finish.dm index b1cea567a1..6d97fb52f9 100644 --- a/code/game/gamemodes/blob/blob_finish.dm +++ b/code/game/gamemodes/blob/blob_finish.dm @@ -7,7 +7,7 @@ if(B.blob_core || !B.placed) return 0 if(!GLOB.blob_cores.len) //blob is dead - if(config.continuous["blob"]) + if(CONFIG_GET(keyed_flag_list/continuous)["blob"]) message_sent = FALSE //disable the win count at this point continuous_sanity_checked = 1 //Nonstandard definition of "alive" gets past the check otherwise SSshuttle.clearHostileEnvironment(src) diff --git a/code/game/gamemodes/brother/traitor_bro.dm b/code/game/gamemodes/brother/traitor_bro.dm index 4e8a0dc6b6..0dd3d6be0f 100644 --- a/code/game/gamemodes/brother/traitor_bro.dm +++ b/code/game/gamemodes/brother/traitor_bro.dm @@ -17,7 +17,7 @@ /datum/objective_team/brother_team/proc/forge_brother_objectives() objectives = list() var/is_hijacker = prob(10) - for(var/i = 1 to max(1, config.brother_objectives_amount + (members.len > 2) - is_hijacker)) + for(var/i = 1 to max(1, CONFIG_GET(number/brother_objectives_amount) + (members.len > 2) - is_hijacker)) forge_single_objective() if(is_hijacker) if(!locate(/datum/objective/hijack) in objectives) @@ -58,16 +58,17 @@ var/meeting_areas = list("The Bar", "Dorms", "Escape Dock", "Arrivals", "Holodeck", "Primary Tool Storage", "Recreation Area", "Chapel", "Library") /datum/game_mode/traitor/bros/pre_setup() - if(config.protect_roles_from_antagonist) + if(CONFIG_GET(flag/protect_roles_from_antagonist)) restricted_jobs += protected_jobs - if(config.protect_assistant_from_antagonist) + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) restricted_jobs += "Assistant" var/list/datum/mind/possible_brothers = get_players_for_role(ROLE_BROTHER) var/num_teams = team_amount - if(config.brother_scaling_coeff) - num_teams = max(1, round(num_players()/config.brother_scaling_coeff)) + var/bsc = CONFIG_GET(number/brother_scaling_coeff) + if(bsc) + num_teams = max(1, round(num_players() / bsc)) for(var/j = 1 to num_teams) if(possible_brothers.len < min_team_size || antag_candidates.len <= required_enemies) diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index e67ac26d3a..8d2d7501f4 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -52,16 +52,17 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w /datum/game_mode/changeling/pre_setup() - if(config.protect_roles_from_antagonist) + if(CONFIG_GET(flag/protect_roles_from_antagonist)) restricted_jobs += protected_jobs - if(config.protect_assistant_from_antagonist) + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) restricted_jobs += "Assistant" var/num_changelings = 1 - if(config.changeling_scaling_coeff) - num_changelings = max(1, min( round(num_players()/(config.changeling_scaling_coeff*2))+2, round(num_players()/config.changeling_scaling_coeff) )) + var/csc = CONFIG_GET(number/changeling_scaling_coeff) + if(csc) + num_changelings = max(1, min(round(num_players() / (csc * 2)) + 2, round(num_players() / csc))) else num_changelings = max(1, min(num_players(), changeling_amount)) @@ -102,10 +103,11 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w ..() /datum/game_mode/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners - var/changelingcap = min( round(GLOB.joined_player_list.len/(config.changeling_scaling_coeff*2))+2, round(GLOB.joined_player_list.len/config.changeling_scaling_coeff) ) + var/csc = CONFIG_GET(number/changeling_scaling_coeff) + var/changelingcap = min(round(GLOB.joined_player_list.len / (csc * 2)) + 2, round(GLOB.joined_player_list.len / csc)) if(SSticker.mode.changelings.len >= changelingcap) //Caps number of latejoin antagonists return - if(SSticker.mode.changelings.len <= (changelingcap - 2) || prob(100 - (config.changeling_scaling_coeff*2))) + if(SSticker.mode.changelings.len <= (changelingcap - 2) || prob(100 - (csc * 2))) if(ROLE_CHANGELING in character.client.prefs.be_special) if(!jobban_isbanned(character, ROLE_CHANGELING) && !jobban_isbanned(character, "Syndicate")) if(age_check(character.client)) diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm index af33b649ed..f951e31c08 100644 --- a/code/game/gamemodes/changeling/traitor_chan.dm +++ b/code/game/gamemodes/changeling/traitor_chan.dm @@ -25,18 +25,19 @@ return 1 /datum/game_mode/traitor/changeling/pre_setup() - if(config.protect_roles_from_antagonist) + if(CONFIG_GET(flag/protect_roles_from_antagonist)) restricted_jobs += protected_jobs - if(config.protect_assistant_from_antagonist) + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) restricted_jobs += "Assistant" var/list/datum/mind/possible_changelings = get_players_for_role(ROLE_CHANGELING) var/num_changelings = 1 - if(config.changeling_scaling_coeff) - num_changelings = max(1, min( round(num_players()/(config.changeling_scaling_coeff*4))+2, round(num_players()/(config.changeling_scaling_coeff*2)) )) + var/csc = CONFIG_GET(number/changeling_scaling_coeff) + if(csc) + num_changelings = max(1, min(round(num_players() / (csc * 4)) + 2, round(num_players() / (csc * 2)))) else num_changelings = max(1, min(num_players(), changeling_amount/2)) @@ -64,11 +65,12 @@ return /datum/game_mode/traitor/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners - var/changelingcap = min( round(GLOB.joined_player_list.len/(config.changeling_scaling_coeff*4))+2, round(GLOB.joined_player_list.len/(config.changeling_scaling_coeff*2)) ) + var/csc = CONFIG_GET(number/changeling_scaling_coeff) + var/changelingcap = min( round(GLOB.joined_player_list.len / (csc * 4)) + 2, round(GLOB.joined_player_list.len / (csc * 2))) if(SSticker.mode.changelings.len >= changelingcap) //Caps number of latejoin antagonists ..() return - if(SSticker.mode.changelings.len <= (changelingcap - 2) || prob(100 / (config.changeling_scaling_coeff * 4))) + if(SSticker.mode.changelings.len <= (changelingcap - 2) || prob(100 / (csc * 4))) if(ROLE_CHANGELING in character.client.prefs.be_special) if(!jobban_isbanned(character, ROLE_CHANGELING) && !jobban_isbanned(character, "Syndicate")) if(age_check(character.client)) diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm index 0fb720f9d6..8e4bd680c4 100644 --- a/code/game/gamemodes/clock_cult/clock_cult.dm +++ b/code/game/gamemodes/clock_cult/clock_cult.dm @@ -109,9 +109,9 @@ Credit where due: var/roundstart_player_count /datum/game_mode/clockwork_cult/pre_setup() - if(config.protect_roles_from_antagonist) + if(CONFIG_GET(flag/protect_roles_from_antagonist)) restricted_jobs += protected_jobs - if(config.protect_assistant_from_antagonist) + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) restricted_jobs += "Assistant" var/starter_servants = 3 //Guaranteed three servants var/number_players = num_players() diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 6406232596..868e02589b 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -55,10 +55,10 @@ /datum/game_mode/cult/pre_setup() cult_objectives += "sacrifice" - if(config.protect_roles_from_antagonist) + if(CONFIG_GET(flag/protect_roles_from_antagonist)) restricted_jobs += protected_jobs - if(config.protect_assistant_from_antagonist) + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) restricted_jobs += "Assistant" //cult scaling goes here diff --git a/code/game/gamemodes/devil/devil_game_mode.dm b/code/game/gamemodes/devil/devil_game_mode.dm index 755fdef87f..844b027e93 100644 --- a/code/game/gamemodes/devil/devil_game_mode.dm +++ b/code/game/gamemodes/devil/devil_game_mode.dm @@ -20,15 +20,16 @@ + Crew: Resist the lure of sin and remain pure!" /datum/game_mode/devil/pre_setup() - if(config.protect_roles_from_antagonist) + if(CONFIG_GET(flag/protect_roles_from_antagonist)) restricted_jobs += protected_jobs - if(config.protect_assistant_from_antagonist) + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) restricted_jobs += "Assistant" var/num_devils = 1 - if(config.traitor_scaling_coeff) - num_devils = max(minimum_devils, min( round(num_players()/(config.traitor_scaling_coeff*3))+ 2 + num_modifier, round(num_players()/(config.traitor_scaling_coeff*1.5)) + num_modifier )) + var/tsc = CONFIG_GET(number/traitor_scaling_coeff) + if(tsc) + num_devils = max(minimum_devils, min( round(num_players() / (tsc * 3))+ 2 + num_modifier, round(num_players() / (tsc * 1.5)) + num_modifier)) else num_devils = max(minimum_devils, min(num_players(), traitors_possible)) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 18a19fb153..9f67693613 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -78,7 +78,7 @@ ///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things /datum/game_mode/proc/post_setup(report) //Gamemodes can override the intercept report. Passing TRUE as the argument will force a report. if(!report) - report = config.intercept + report = !CONFIG_GET(flag/no_intercept_report) addtimer(CALLBACK(GLOBAL_PROC, .proc/display_roundstart_logout_report), ROUNDSTART_LOGOUT_REPORT_TIME) if(SSdbcore.Connect()) @@ -113,8 +113,9 @@ for(var/mob/Player in GLOB.mob_list) if(Player.mind && Player.stat != DEAD && !isnewplayer(Player) && !isbrain(Player) && Player.client) living_crew += Player - if(living_crew.len / GLOB.joined_player_list.len <= config.midround_antag_life_check) //If a lot of the player base died, we start fresh - message_admins("Convert_roundtype failed due to too many dead people. Limit is [config.midround_antag_life_check * 100]% living crew") + var/malc = CONFIG_GET(number/midround_antag_life_check) + if(living_crew.len / GLOB.joined_player_list.len <= malc) //If a lot of the player base died, we start fresh + message_admins("Convert_roundtype failed due to too many dead people. Limit is [malc * 100]% living crew") return null var/list/datum/game_mode/runnable_modes = config.get_runnable_midround_modes(living_crew.len) @@ -138,8 +139,9 @@ if(SSshuttle.emergency.timeLeft(1) < initial(SSshuttle.emergencyCallTime)*0.5) return 1 - if(world.time >= (config.midround_antag_time_check * 600)) - message_admins("Convert_roundtype failed due to round length. Limit is [config.midround_antag_time_check] minutes.") + var/matc = CONFIG_GET(number/midround_antag_time_check) + if(world.time >= (matc * 600)) + message_admins("Convert_roundtype failed due to round length. Limit is [matc] minutes.") return null var/list/antag_candidates = list() @@ -154,9 +156,9 @@ antag_candidates = shuffle(antag_candidates) - if(config.protect_roles_from_antagonist) + if(CONFIG_GET(flag/protect_roles_from_antagonist)) replacementmode.restricted_jobs += replacementmode.protected_jobs - if(config.protect_assistant_from_antagonist) + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) replacementmode.restricted_jobs += "Assistant" message_admins("The roundtype will be converted. If you have other plans for the station or feel the station is too messed up to inhabit stop the creation of antags or end the round now.") @@ -168,7 +170,7 @@ round_converted = 0 return //somewhere between 1 and 3 minutes from now - if(!config.midround_antag[SSticker.mode.config_tag]) + if(!CONFIG_GET(keyed_flag_list/midround_antag)[SSticker.mode.config_tag]) round_converted = 0 return 1 for(var/mob/living/carbon/human/H in antag_candidates) @@ -189,7 +191,9 @@ return TRUE if(station_was_nuked) return TRUE - if(!round_converted && (!config.continuous[config_tag] || (config.continuous[config_tag] && config.midround_antag[config_tag]))) //Non-continuous or continous with replacement antags + var/list/continuous = CONFIG_GET(keyed_flag_list/continuous) + var/list/midround_antag = CONFIG_GET(keyed_flag_list/midround_antag) + if(!round_converted && (!continuous[config_tag] || (continuous[config_tag] && midround_antag[config_tag]))) //Non-continuous or continous with replacement antags if(!continuous_sanity_checked) //make sure we have antags to be checking in the first place for(var/mob/Player in GLOB.mob_list) if(Player.mind) @@ -198,8 +202,8 @@ return 0 if(!continuous_sanity_checked) message_admins("The roundtype ([config_tag]) has no antagonists, continuous round has been defaulted to on and midround_antag has been defaulted to off.") - config.continuous[config_tag] = 1 - config.midround_antag[config_tag] = 0 + continuous[config_tag] = TRUE + midround_antag[config_tag] = FALSE SSshuttle.clearHostileEnvironment(src) return 0 @@ -213,7 +217,7 @@ living_antag_player = Player return 0 - if(!config.continuous[config_tag] || force_ending) + if(!continuous[config_tag] || force_ending) return 1 else @@ -222,7 +226,7 @@ if(round_ends_with_antag_death) return 1 else - config.midround_antag[config_tag] = 0 + midround_antag[config_tag] = 0 return 0 return 0 @@ -517,7 +521,7 @@ /datum/game_mode/proc/get_remaining_days(client/C) if(!C) return 0 - if(!config.use_age_restriction_for_jobs) + if(!CONFIG_GET(flag/use_age_restriction_for_jobs)) return 0 if(!isnum(C.player_age)) return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced diff --git a/code/game/gamemodes/miniantags/abduction/abduction.dm b/code/game/gamemodes/miniantags/abduction/abduction.dm index ed5c2e9d76..d6f1b775e9 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction.dm @@ -34,7 +34,7 @@ to_chat(world, "Crew - don't get abducted and stop the abductors.") /datum/game_mode/abduction/pre_setup() - var/num_teams = max(1, min(max_teams, round(num_players() / config.abductor_scaling_coeff))) + var/num_teams = max(1, min(max_teams, round(num_players() / CONFIG_GET(number/abductor_scaling_coeff)))) var/possible_teams = max(1, round(antag_candidates.len / 2)) num_teams = min(num_teams, possible_teams) diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm index 0a7427b610..99059e7a25 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm @@ -62,7 +62,7 @@ /obj/machinery/abductor/experiment/proc/dissection_icon(mob/living/carbon/human/H) var/icon/photo = null var/g = (H.gender == FEMALE) ? "f" : "m" - if(!config.mutant_races || H.dna.species.use_skintones) + if(!CONFIG_GET(flag/join_with_mutant_race) || H.dna.species.use_skintones) photo = icon("icon" = 'icons/mob/human.dmi', "icon_state" = "[H.skin_tone]_[g]") else photo = icon("icon" = 'icons/mob/human.dmi', "icon_state" = "[H.dna.species.id]_[g]") diff --git a/code/game/gamemodes/nuclear/nuclear_challenge.dm b/code/game/gamemodes/nuclear/nuclear_challenge.dm index f51b9ac914..6e7a567324 100644 --- a/code/game/gamemodes/nuclear/nuclear_challenge.dm +++ b/code/game/gamemodes/nuclear/nuclear_challenge.dm @@ -58,7 +58,7 @@ U.hidden_uplink.owner = "[user.key]" U.hidden_uplink.telecrystals = CHALLENGE_TELECRYSTALS U.hidden_uplink.set_gamemode(/datum/game_mode/nuclear) - config.shuttle_refuel_delay = max(config.shuttle_refuel_delay, CHALLENGE_SHUTTLE_DELAY) + CONFIG_SET(number/shuttle_refuel_delay, max(CONFIG_GET(number/shuttle_refuel_delay), CHALLENGE_SHUTTLE_DELAY)) SSblackbox.set_val("nuclear_challenge_mode",1) qdel(src) diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm index 4ada75bb05..0b0ca07bb6 100644 --- a/code/game/gamemodes/revolution/revolution.dm +++ b/code/game/gamemodes/revolution/revolution.dm @@ -44,10 +44,10 @@ /////////////////////////////////////////////////////////////////////////////// /datum/game_mode/revolution/pre_setup() - if(config.protect_roles_from_antagonist) + if(CONFIG_GET(flag/protect_roles_from_antagonist)) restricted_jobs += protected_jobs - if(config.protect_assistant_from_antagonist) + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) restricted_jobs += "Assistant" for (var/i=1 to max_headrevs) @@ -230,7 +230,7 @@ //Checks if the round is over// /////////////////////////////// /datum/game_mode/revolution/check_finished() - if(config.continuous["revolution"]) + if(CONFIG_GET(keyed_flag_list/continuous)["revolution"]) if(finished) SSshuttle.clearHostileEnvironment(src) return ..() diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm index 7a17d54b4c..8d9396da71 100644 --- a/code/game/gamemodes/sandbox/h_sandbox.dm +++ b/code/game/gamemodes/sandbox/h_sandbox.dm @@ -30,6 +30,7 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE) /obj/item/assembly, /obj/item/device/onetankbomb, /obj/item/radio, /obj/item/device/pda/ai, /obj/item/device/uplink, /obj/item/smallDelivery, /obj/item/projectile, /obj/item/borg/sight, /obj/item/borg/stun, /obj/item/robot_module) +<<<<<<< HEAD /datum/hSB/proc/update() var/global/list/hrefs = list( @@ -301,3 +302,276 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE) if(config.sandbox_autoclose) usr << browse(null,"window=sandbox") +======= + +/datum/hSB/proc/update() + var/global/list/hrefs = list( + "Space Gear", + "Suit Up (Space Travel Gear)" = "hsbsuit", + "Spawn Gas Mask" = "hsbspawn&path=[/obj/item/clothing/mask/gas]", + "Spawn Emergency Air Tank" = "hsbspawn&path=[/obj/item/tank/internals/emergency_oxygen/double]", + + "Standard Tools", + "Spawn Flashlight" = "hsbspawn&path=[/obj/item/device/flashlight]", + "Spawn Toolbox" = "hsbspawn&path=[/obj/item/storage/toolbox/mechanical]", + "Spawn Light Replacer" = "hsbspawn&path=[/obj/item/device/lightreplacer]", + "Spawn Medical Kit" = "hsbspawn&path=[/obj/item/storage/firstaid/regular]", + "Spawn All-Access ID" = "hsbaaid", + + "Building Supplies", + "Spawn 50 Wood" = "hsbwood", + "Spawn 50 Metal" = "hsbmetal", + "Spawn 50 Plasteel" = "hsbplasteel", + "Spawn 50 Reinforced Glass" = "hsbrglass", + "Spawn 50 Glass" = "hsbglass", + "Spawn Full Cable Coil" = "hsbspawn&path=[/obj/item/stack/cable_coil]", + "Spawn Hyper Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/hyper]", + "Spawn Inf. Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/infinite]", + "Spawn Rapid Construction Device" = "hsbrcd", + "Spawn RCD Ammo" = "hsb_safespawn&path=[/obj/item/rcd_ammo]", + "Spawn Airlock" = "hsbairlock", + + "Miscellaneous", + "Spawn Air Scrubber" = "hsbscrubber", + "Spawn Welding Fuel Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/fueltank]", + "Spawn Water Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/watertank]", + + "Bots", + "Spawn Cleanbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/cleanbot]", + "Spawn Floorbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/floorbot]", + "Spawn Medbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/medbot]", + + "Canisters", + "Spawn O2 Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/oxygen]", + "Spawn Air Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/air]") + + + if(!hsbinfo) + hsbinfo = "
    Sandbox Panel

    " + if(admin) + hsbinfo += "Administration
    " + hsbinfo += "- Toggle Object Spawning
    " + hsbinfo += "- Toggle Item Spawn Panel Auto-close
    " + hsbinfo += "Canister Spawning
    " + hsbinfo += "- Spawn Plasma Canister
    " + hsbinfo += "- Spawn CO2 Canister
    " + hsbinfo += "- Spawn Nitrogen Canister
    " + hsbinfo += "- Spawn N2O Canister
    " + else + hsbinfo += "Some item spawning may be disabled by the administrators.
    " + hsbinfo += "Only administrators may spawn dangerous canisters.
    " + for(var/T in hrefs) + var/href = hrefs[T] + if(href) + hsbinfo += "- [T]
    " + else + hsbinfo += "
    [T]
    " + hsbinfo += "
    " + hsbinfo += "- Spawn Clothing...
    " + hsbinfo += "- Spawn Reagent Container...
    " + hsbinfo += "- Spawn Other Item...

    " + + usr << browse(hsbinfo, "window=hsbpanel") + +/datum/hSB/Topic(href, href_list) + if(!usr || !src || !(src.owner == usr.ckey)) + if(usr) + usr << browse(null,"window=sandbox") + return + + if(href_list["hsb"]) + switch(href_list["hsb"]) + // + // Admin: toggle spawning + // + if("hsbtobj") + if(!admin) return + if(GLOB.hsboxspawn) + to_chat(world, "Sandbox: \black[usr.key] has disabled object spawning!") + GLOB.hsboxspawn = FALSE + return + else + to_chat(world, "Sandbox: \black[usr.key] has enabled object spawning!") + GLOB.hsboxspawn = TRUE + return + // + // Admin: Toggle auto-close + // + if("hsbtac") + if(!admin) return + var/sbac = CONFIG_GET(flag/sandbox_autoclose) + if(sbac) + to_chat(world, "Sandbox: \black [usr.key] has removed the object spawn limiter.") + else + to_chat(world, "Sandbox: \black [usr.key] has added a limiter to object spawning. The window will now auto-close after use.") + CONFIG_SET(flag/sandbox_autoclose, !sbac) + return + // + // Spacesuit with full air jetpack set as internals + // + if("hsbsuit") + var/mob/living/carbon/human/P = usr + if(!istype(P)) return + if(P.wear_suit) + P.wear_suit.loc = P.loc + P.wear_suit.layer = initial(P.wear_suit.layer) + P.wear_suit.plane = initial(P.wear_suit.plane) + P.wear_suit = null + P.wear_suit = new/obj/item/clothing/suit/space(P) + P.wear_suit.layer = ABOVE_HUD_LAYER + P.wear_suit.plane = ABOVE_HUD_PLANE + P.update_inv_wear_suit() + if(P.head) + P.head.loc = P.loc + P.head.layer = initial(P.head.layer) + P.head.plane = initial(P.head.plane) + P.head = null + P.head = new/obj/item/clothing/head/helmet/space(P) + P.head.layer = ABOVE_HUD_LAYER + P.head.plane = ABOVE_HUD_PLANE + P.update_inv_head() + if(P.wear_mask) + P.wear_mask.loc = P.loc + P.wear_mask.layer = initial(P.wear_mask.layer) + P.wear_mask.plane = initial(P.wear_mask.plane) + P.wear_mask = null + P.wear_mask = new/obj/item/clothing/mask/gas(P) + P.wear_mask.layer = ABOVE_HUD_LAYER + P.wear_mask.plane = ABOVE_HUD_PLANE + P.update_inv_wear_mask() + if(P.back) + P.back.loc = P.loc + P.back.layer = initial(P.back.layer) + P.back.plane = initial(P.back.plane) + P.back = null + P.back = new/obj/item/tank/jetpack/oxygen(P) + P.back.layer = ABOVE_HUD_LAYER + P.back.plane = ABOVE_HUD_PLANE + P.update_inv_back() + P.internal = P.back + P.update_internals_hud_icon(1) + + if("hsbscrubber") // This is beyond its normal capability but this is sandbox and you spawned one, I assume you need it + var/obj/hsb = new/obj/machinery/portable_atmospherics/scrubber{volume_rate=50*ONE_ATMOSPHERE;on=1}(usr.loc) + hsb.update_icon() // hackish but it wasn't meant to be spawned I guess? + + // + // Stacked Materials + // + + if("hsbrglass") + new/obj/item/stack/sheet/rglass{amount=50}(usr.loc) + + if("hsbmetal") + new/obj/item/stack/sheet/metal{amount=50}(usr.loc) + + if("hsbplasteel") + new/obj/item/stack/sheet/plasteel{amount=50}(usr.loc) + + if("hsbglass") + new/obj/item/stack/sheet/glass{amount=50}(usr.loc) + + if("hsbwood") + new/obj/item/stack/sheet/mineral/wood{amount=50}(usr.loc) + + // + // All access ID + // + if("hsbaaid") + var/obj/item/card/id/gold/ID = new(usr.loc) + ID.registered_name = usr.real_name + ID.assignment = "Sandbox" + ID.access = get_all_accesses() + ID.update_label() + + // + // RCD - starts with full clip + // Spawn check due to grief potential (destroying floors, walls, etc) + // + if("hsbrcd") + if(!GLOB.hsboxspawn) return + + new/obj/item/construction/rcd/combat(usr.loc) + + // + // New sandbox airlock maker + // + if("hsbairlock") + new /datum/airlock_maker(usr.loc) + + // + // Object spawn window + // + + // Clothing + if("hsbcloth") + if(!GLOB.hsboxspawn) return + + if(!clothinfo) + clothinfo = "Clothing (Reagent Containers) (Other Items)

    " + var/list/all_items = subtypesof(/obj/item/clothing) + for(var/typekey in spawn_forbidden) + all_items -= typesof(typekey) + for(var/O in reverseRange(all_items)) + clothinfo += "[O]
    " + + usr << browse(clothinfo,"window=sandbox") + + // Reagent containers + if("hsbreag") + if(!GLOB.hsboxspawn) return + + if(!reaginfo) + reaginfo = "Reagent Containers (Clothing) (Other Items)

    " + var/list/all_items = subtypesof(/obj/item/reagent_containers) + for(var/typekey in spawn_forbidden) + all_items -= typesof(typekey) + for(var/O in reverseRange(all_items)) + reaginfo += "[O]
    " + + usr << browse(reaginfo,"window=sandbox") + + // Other items + if("hsbobj") + if(!GLOB.hsboxspawn) return + + if(!objinfo) + objinfo = "Other Items (Clothing) (Reagent Containers)

    " + var/list/all_items = subtypesof(/obj/item/) - typesof(/obj/item/clothing) - typesof(/obj/item/reagent_containers) + for(var/typekey in spawn_forbidden) + all_items -= typesof(typekey) + + for(var/O in reverseRange(all_items)) + objinfo += "[O]
    " + + usr << browse(objinfo,"window=sandbox") + + // + // Safespawn checks to see if spawning is disabled. + // + if("hsb_safespawn") + if(!GLOB.hsboxspawn) + usr << browse(null,"window=sandbox") + return + + var/typepath = text2path(href_list["path"]) + if(!typepath) + to_chat(usr, "Bad path: \"[href_list["path"]]\"") + return + new typepath(usr.loc) + + if(CONFIG_GET(flag/sandbox_autoclose)) + usr << browse(null,"window=sandbox") + // + // For everything else in the href list + // + if("hsbspawn") + var/typepath = text2path(href_list["path"]) + if(!typepath) + to_chat(usr, "Bad path: \"[href_list["path"]]\"") + return + new typepath(usr.loc) + + if(CONFIG_GET(flag/sandbox_autoclose)) + usr << browse(null,"window=sandbox") +>>>>>>> 4178c20... Configuration datum refactor (#30763) diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm index 77b91a8571..64d4f84eec 100644 --- a/code/game/gamemodes/traitor/traitor.dm +++ b/code/game/gamemodes/traitor/traitor.dm @@ -31,16 +31,17 @@ /datum/game_mode/traitor/pre_setup() - if(config.protect_roles_from_antagonist) + if(CONFIG_GET(flag/protect_roles_from_antagonist)) restricted_jobs += protected_jobs - if(config.protect_assistant_from_antagonist) + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) restricted_jobs += "Assistant" var/num_traitors = 1 - if(config.traitor_scaling_coeff) - num_traitors = max(1, min( round(num_players()/(config.traitor_scaling_coeff*2))+ 2 + num_modifier, round(num_players()/(config.traitor_scaling_coeff)) + num_modifier )) + var/tsc = CONFIG_GET(number/traitor_scaling_coeff) + if(tsc) + num_traitors = max(1, min(round(num_players() / (tsc * 2)) + 2 + num_modifier, round(num_players() / tsc) + num_modifier)) else num_traitors = max(1, min(num_players(), traitors_possible)) @@ -68,10 +69,11 @@ return 1 /datum/game_mode/traitor/make_antag_chance(mob/living/carbon/human/character) //Assigns traitor to latejoiners - var/traitorcap = min(round(GLOB.joined_player_list.len / (config.traitor_scaling_coeff * 2)) + 2 + num_modifier, round(GLOB.joined_player_list.len/config.traitor_scaling_coeff) + num_modifier ) + var/tsc = CONFIG_GET(number/traitor_scaling_coeff) + var/traitorcap = min(round(GLOB.joined_player_list.len / (tsc * 2)) + 2 + num_modifier, round(GLOB.joined_player_list.len / tsc) + num_modifier) if((SSticker.mode.traitors.len + pre_traitors.len) >= traitorcap) //Upper cap for number of latejoin antagonists return - if((SSticker.mode.traitors.len + pre_traitors.len) <= (traitorcap - 2) || prob(100 / (config.traitor_scaling_coeff * 2))) + if((SSticker.mode.traitors.len + pre_traitors.len) <= (traitorcap - 2) || prob(100 / (tsc * 2))) if(ROLE_TRAITOR in character.client.prefs.be_special) if(!jobban_isbanned(character, ROLE_TRAITOR) && !jobban_isbanned(character, "Syndicate")) if(age_check(character.client)) diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index 31060fffc3..5e22aaac42 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -478,7 +478,7 @@ /datum/spellbook_entry/summon/guns/IsAvailible() if(!SSticker.mode) // In case spellbook is placed on map return 0 - return (!config.no_summon_guns) + return !CONFIG_GET(flag/no_summon_guns) /datum/spellbook_entry/summon/guns/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) SSblackbox.add_details("wizard_spell_learned", name) @@ -495,7 +495,7 @@ /datum/spellbook_entry/summon/magic/IsAvailible() if(!SSticker.mode) // In case spellbook is placed on map return 0 - return (!config.no_summon_magic) + return !CONFIG_GET(flag/no_summon_magic) /datum/spellbook_entry/summon/magic/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) SSblackbox.add_details("wizard_spell_learned", name) @@ -513,7 +513,7 @@ /datum/spellbook_entry/summon/events/IsAvailible() if(!SSticker.mode) // In case spellbook is placed on map return 0 - return (!config.no_summon_events) + return !CONFIG_GET(flag/no_summon_events) /datum/spellbook_entry/summon/events/Buy(mob/living/carbon/human/user,obj/item/spellbook/book) SSblackbox.add_details("wizard_spell_learned", name) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 88941c2344..86e69b8973 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -231,9 +231,9 @@ else if(mob_occupant.cloneloss > (100 - heal_level)) mob_occupant.Unconscious(80) - + var/dmg_mult = CONFIG_GET(number/damage_multiplier) //Slowly get that clone healed and finished. - mob_occupant.adjustCloneLoss(-((speed_coeff/2) * config.damage_multiplier)) + mob_occupant.adjustCloneLoss(-((speed_coeff / 2) * dmg_mult)) var/progress = CLONE_INITIAL_DAMAGE - mob_occupant.getCloneLoss() // To avoid the default cloner making incomplete clones progress += (100 - MINIMUM_HEAL_LEVEL) @@ -251,7 +251,7 @@ BP.attach_limb(mob_occupant) //Premature clones may have brain damage. - mob_occupant.adjustBrainLoss(-((speed_coeff/2) * config.damage_multiplier)) + mob_occupant.adjustBrainLoss(-((speed_coeff / 2) * dmg_mult)) check_brine() diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index 0548d94f3d..f64199a248 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -47,7 +47,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) /obj/machinery/computer/card/Initialize() . = ..() - change_position_cooldown = config.id_console_jobslot_delay + change_position_cooldown = CONFIG_GET(number/id_console_jobslot_delay) /obj/machinery/computer/card/attackby(obj/O, mob/user, params)//TODO:SANITY if(istype(O, /obj/item/card/id)) diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index ab7a639818..2c3757fb61 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -315,6 +315,7 @@ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) else scanner.locked = FALSE +<<<<<<< HEAD playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) else if(href_list["view_rec"]) @@ -500,3 +501,190 @@ src.records += R scantemp = "Subject successfully scanned." playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) +======= + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + + else if(href_list["view_rec"]) + playsound(src, "terminal_type", 25, 0) + src.active_record = find_record("id", href_list["view_rec"], records) + if(active_record) + if(!active_record.fields["ckey"]) + records -= active_record + active_record = null + src.temp = "Record Corrupt" + else + src.menu = 3 + else + src.temp = "Record missing." + + else if (href_list["del_rec"]) + if ((!src.active_record) || (src.menu < 3)) + return + if (src.menu == 3) //If we are viewing a record, confirm deletion + src.temp = "Delete record?" + src.menu = 4 + playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) + + else if (src.menu == 4) + var/obj/item/card/id/C = usr.get_active_held_item() + if (istype(C)||istype(C, /obj/item/device/pda)) + if(src.check_access(C)) + src.temp = "[src.active_record.fields["name"]] => Record deleted." + src.records.Remove(active_record) + active_record = null + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + src.menu = 2 + else + src.temp = "Access Denied." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + + else if (href_list["disk"]) //Load or eject. + switch(href_list["disk"]) + if("load") + if (!diskette || !istype(diskette.fields) || !diskette.fields["name"] || !diskette.fields) + src.temp = "Load error." + src.updateUsrDialog() + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + if (!src.active_record) + src.temp = "Record error." + src.menu = 1 + src.updateUsrDialog() + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + + for(var/key in diskette.fields) + src.active_record.fields[key] = diskette.fields[key] + src.temp = "Load successful." + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + + if("eject") + if(src.diskette) + src.diskette.loc = src.loc + src.diskette = null + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) + if("save") + if(!diskette || diskette.read_only || !active_record || !active_record.fields) + src.temp = "Save error." + src.updateUsrDialog() + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + + diskette.fields = active_record.fields.Copy() + diskette.name = "data disk - '[src.diskette.fields["name"]]'" + src.temp = "Save successful." + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + + else if (href_list["refresh"]) + src.updateUsrDialog() + playsound(src, "terminal_type", 25, 0) + + else if (href_list["clone"]) + var/datum/data/record/C = find_record("id", href_list["clone"], records) + //Look for that player! They better be dead! + if(C) + var/obj/machinery/clonepod/pod = GetAvailablePod() + //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs. + if(!LAZYLEN(pods)) + temp = "No Clonepods detected." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else if(!pod) + temp = "No Clonepods available." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else if(!CONFIG_GET(flag/revival_cloning)) + temp = "Unable to initiate cloning cycle." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else if(pod.occupant) + temp = "Cloning cycle already in progress." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["mrace"], C.fields["features"], C.fields["factions"])) + temp = "[C.fields["name"]] => Cloning cycle in progress..." + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + records.Remove(C) + if(active_record == C) + active_record = null + menu = 1 + else + temp = "[C.fields["name"]] => Initialisation failure." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + + else + temp = "Data corruption." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + + else if (href_list["menu"]) + src.menu = text2num(href_list["menu"]) + playsound(src, "terminal_type", 25, 0) + + src.add_fingerprint(usr) + src.updateUsrDialog() + return + +/obj/machinery/computer/cloning/proc/scan_occupant(occupant) + var/mob/living/mob_occupant = get_mob_or_brainmob(occupant) + var/datum/dna/dna + if(iscarbon(mob_occupant)) + var/mob/living/carbon/C = mob_occupant + dna = C.has_dna() + if(isbrain(mob_occupant)) + var/mob/living/brain/B = mob_occupant + dna = B.stored_dna + + if(!istype(dna)) + scantemp = "Unable to locate valid genetic data." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + if(mob_occupant.suiciding || mob_occupant.hellbound) + scantemp = "Subject's brain is not responding to scanning stimuli." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + if((mob_occupant.disabilities & NOCLONE) && (src.scanner.scan_level < 2)) + scantemp = "Subject no longer contains the fundamental materials required to create a living clone." + playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0) + return + if ((!mob_occupant.ckey) || (!mob_occupant.client)) + scantemp = "Mental interface failure." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + if (find_record("ckey", mob_occupant.ckey, records)) + scantemp = "Subject already in database." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + + var/datum/data/record/R = new() + if(dna.species) + // We store the instance rather than the path, because some + // species (abductors, slimepeople) store state in their + // species datums + R.fields["mrace"] = dna.species + else + var/datum/species/rando_race = pick(CONFIG_GET(keyed_flag_list/roundstart_races)) + R.fields["mrace"] = rando_race.type + + R.fields["ckey"] = mob_occupant.ckey + R.fields["name"] = mob_occupant.real_name + R.fields["id"] = copytext(md5(mob_occupant.real_name), 2, 6) + R.fields["UE"] = dna.unique_enzymes + R.fields["UI"] = dna.uni_identity + R.fields["SE"] = dna.struc_enzymes + R.fields["blood_type"] = dna.blood_type + R.fields["features"] = dna.features + R.fields["factions"] = mob_occupant.faction + + if (!isnull(mob_occupant.mind)) //Save that mind so traitors can continue traitoring after cloning. + R.fields["mind"] = "\ref[mob_occupant.mind]" + + //Add an implant if needed + var/obj/item/implant/health/imp + for(var/obj/item/implant/health/HI in mob_occupant.implants) + imp = HI + break + if(!imp) + imp = new /obj/item/implant/health(mob_occupant) + imp.implant(mob_occupant) + R.fields["imp"] = "\ref[imp]" + + src.records += R + scantemp = "Subject successfully scanned." + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) +>>>>>>> 4178c20... Configuration datum refactor (#30763) diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index bd203772cb..89b2bc4620 100755 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -454,7 +454,7 @@ if (src.authenticated==2) dat += "

    Captain Functions" dat += "
    \[ Make a Captain's Announcement \]" - if(config.cross_allowed) + if(CONFIG_GET(string/cross_server_address)) dat += "
    \[ Send a message to an allied station \]" if(SSmapping.config.allow_custom_shuttles == "yes") dat += "
    \[ Purchase Shuttle \]" diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index f2ea3238ef..6ec144d257 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -124,7 +124,7 @@ dat += "ID:[active1.fields["id"]]" dat += "Sex: [active1.fields["sex"]] " dat += "Age: [active1.fields["age"]] " - if(config.mutant_races) + if(CONFIG_GET(flag/join_with_mutant_race)) dat += "Species: [active1.fields["species"]] " dat += "Fingerprint: [active1.fields["fingerprint"]] " dat += "Physical Status: [active1.fields["p_stat"]] " @@ -543,7 +543,7 @@ P.info = "
    Medical Record - (MR-[GLOB.data_core.medicalPrintCount])

    " if(active1 in GLOB.data_core.general) P.info += text("Name: [] ID: []
    \nSex: []
    \nAge: []
    ", src.active1.fields["name"], src.active1.fields["id"], src.active1.fields["sex"], src.active1.fields["age"]) - if(config.mutant_races) + if(CONFIG_GET(flag/join_with_mutant_race)) P.info += "\nSpecies: [active1.fields["species"]]
    " P.info += text("\nFingerprint: []
    \nPhysical Status: []
    \nMental Status: []
    ", src.active1.fields["fingerprint"], src.active1.fields["p_stat"], src.active1.fields["m_stat"]) else diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 00787f10e2..1a74c44c30 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -186,7 +186,7 @@ ID: [active1.fields["id"]]  Sex: [active1.fields["sex"]]  Age: [active1.fields["age"]] "} - if(config.mutant_races) + if(CONFIG_GET(flag/join_with_mutant_race)) dat += "Species: [active1.fields["species"]] " dat += {"Rank: [active1.fields["rank"]]  Fingerprint: [active1.fields["fingerprint"]]  @@ -373,7 +373,7 @@ What a mess.*/ P.info = "
    Security Record - (SR-[GLOB.data_core.securityPrintCount])

    " if((istype(active1, /datum/data/record) && GLOB.data_core.general.Find(active1))) P.info += text("Name: [] ID: []
    \nSex: []
    \nAge: []
    ", active1.fields["name"], active1.fields["id"], active1.fields["sex"], active1.fields["age"]) - if(config.mutant_races) + if(CONFIG_GET(flag/join_with_mutant_race)) P.info += "\nSpecies: [active1.fields["species"]]
    " P.info += text("\nFingerprint: []
    \nPhysical Status: []
    \nMental Status: []
    ", active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"]) else @@ -519,7 +519,7 @@ What a mess.*/ G.fields["rank"] = "Unassigned" G.fields["sex"] = "Male" G.fields["age"] = "Unknown" - if(config.mutant_races) + if(CONFIG_GET(flag/join_with_mutant_race)) G.fields["species"] = "Human" G.fields["photo_front"] = new /icon() G.fields["photo_side"] = new /icon() @@ -604,7 +604,7 @@ What a mess.*/ active1.fields["age"] = t1 if("species") if(istype(active1, /datum/data/record)) - var/t1 = input("Select a species", "Species Selection") as null|anything in GLOB.roundstart_species + var/t1 = input("Select a species", "Species Selection") as null|anything in CONFIG_GET(keyed_flag_list/roundstart_races) if(!canUseSecurityRecordsConsole(usr, t1, a1)) return active1.fields["species"] = t1 @@ -772,7 +772,7 @@ What a mess.*/ if(6) R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable") if(7) - R.fields["species"] = pick(GLOB.roundstart_species) + R.fields["species"] = pick(CONFIG_GET(keyed_flag_list/roundstart_races)) if(8) var/datum/data/record/G = pick(GLOB.data_core.general) R.fields["photo_front"] = G.fields["photo_front"] diff --git a/code/game/objects/items/AI_modules.dm b/code/game/objects/items/AI_modules.dm index fd7a87ac8c..45788b77b9 100644 --- a/code/game/objects/items/AI_modules.dm +++ b/code/game/objects/items/AI_modules.dm @@ -54,7 +54,7 @@ AI MODULES for(var/mylaw in lawlist) if(mylaw != "") tot_laws++ - if(tot_laws > config.silicon_max_law_amount && !bypass_law_amt_check)//allows certain boards to avoid this check, eg: reset + if(tot_laws > CONFIG_GET(number/silicon_max_law_amount) && !bypass_law_amt_check)//allows certain boards to avoid this check, eg: reset to_chat(user, "Not enough memory allocated to [law_datum.owner ? law_datum.owner : "the AI core"]'s law processor to handle this amount of laws.") message_admins("[key_name_admin(user)] tried to upload laws to [law_datum.owner ? key_name_admin(law_datum.owner) : "an AI core"] that would exceed the law cap.") overflow = TRUE diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index ca5fa2c28b..23905200e9 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -72,16 +72,15 @@ user.visible_message("[user] is jamming [src] up [user.p_their()] nose and into [user.p_their()] brain. It looks like [user.p_theyre()] trying to commit suicide!") return (BRUTELOSS|OXYLOSS) -/obj/item/toy/crayon/New() - ..() +/obj/item/toy/crayon/Initialize() + . = ..() // Makes crayons identifiable in things like grinders if(name == "crayon") name = "[item_color] crayon" - if(config) - if(config.mutant_races == 1) - graffiti |= "antilizard" - graffiti |= "prolizard" + if(CONFIG_GET(flag/join_with_mutant_race)) + graffiti |= "antilizard" + graffiti |= "prolizard" all_drawables = graffiti + letters + numerals + oriented + runes + graffiti_large_h drawtype = pick(all_drawables) diff --git a/code/game/objects/items/manuals.dm b/code/game/objects/items/manuals.dm index 7ee1f49a48..a8bdce5fe9 100644 --- a/code/game/objects/items/manuals.dm +++ b/code/game/objects/items/manuals.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /*********************MANUALS (BOOKS)***********************/ //Oh god what the fuck I am not good at computer @@ -956,3 +957,964 @@ author = "Engineering Encyclopedia" title = "Hacking" page_link = "Hacking" +======= +/*********************MANUALS (BOOKS)***********************/ + +//Oh god what the fuck I am not good at computer +/obj/item/book/manual + icon = 'icons/obj/library.dmi' + due_date = 0 // Game time in 1/10th seconds + unique = 1 // 0 - Normal book, 1 - Should not be treated as normal book, unable to be copied, unable to be modified + +/obj/item/book/manual/engineering_particle_accelerator + name = "Particle Accelerator User's Guide" + icon_state ="bookParticleAccelerator" + author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned + title = "Particle Accelerator User's Guide" + dat = {" + + + + + +

    Experienced user's guide

    + +

    Setting up

    + +
      +
    1. Wrench all pieces to the floor
    2. +
    3. Add wires to all the pieces
    4. +
    5. Close all the panels with your screwdriver
    6. +
    + +

    Use

    + +
      +
    1. Open the control panel
    2. +
    3. Set the speed to 2
    4. +
    5. Start firing at the singularity generator
    6. +
    7. When the singularity reaches a large enough size so it starts moving on its own set the speed down to 0, but don't shut it off
    8. +
    9. Remember to wear a radiation suit when working with this machine... we did tell you that at the start, right?
    10. +
    + + + "} + + +/obj/item/book/manual/engineering_singularity_safety + name = "Singularity Safety in Special Circumstances" + icon_state ="bookEngineeringSingularitySafety" + author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned + title = "Singularity Safety in Special Circumstances" +//big pile of shit below. + + dat = {" + + + + +

    Singularity Safety in Special Circumstances

    + +

    Power outage

    + + A power problem has made the entire station lose power? Could be station-wide wiring problems or syndicate power sinks. In any case follow these steps: +

    + Step one: PANIC!
    + Step two: Get your ass over to engineering! QUICKLY!!!
    + Step three: Make sure the SMES is still powering the emitters, if not, setup the generator in secure storage and disconnect the emitters from the SMES.
    + Step four: Next, head over to the APC and swipe it with your ID card - if it doesn't unlock, continue with step 15.
    + Step five: Open the console and disengage the cover lock.
    + Step six: Pry open the APC with a Crowbar.
    + Step seven: Take out the empty power cell.
    + Step eight: Put in the new, full power cell - if you don't have one, continue with step 15.
    + Step nine: Quickly put on a Radiation suit.
    + Step ten: Check if the singularity field generators withstood the down-time - if they didn't, continue with step 15.
    + Step eleven: Since disaster was averted you now have to ensure it doesn't repeat. If it was a powersink which caused it and if the engineering apc is wired to the same powernet, which the powersink is on, you have to remove the piece of wire which links the apc to the powernet. If it wasn't a powersink which caused it, then skip to step 14.
    + Step twelve: Grab your crowbar and pry away the tile closest to the APC.
    + Step thirteen: Use the wirecutters to cut the wire which is conecting the grid to the terminal.
    + Step fourteen: Go to the bar and tell the guys how you saved them all. Stop reading this guide here.
    + Step fifteen: GET THE FUCK OUT OF THERE!!!
    +

    + +

    Shields get damaged

    + + Step one: GET THE FUCK OUT OF THERE!!! FORGET THE WOMEN AND CHILDREN, SAVE YOURSELF!!!
    + + + "} + +/obj/item/book/manual/hydroponics_pod_people + name = "The Human Harvest - From seed to market" + icon_state ="bookHydroponicsPodPeople" + author = "Farmer John" + title = "The Human Harvest - From seed to market" + dat = {" + + + + +

    Growing Humans

    + + Why would you want to grow humans? Well I'm expecting most readers to be in the slave trade, but a few might actually + want to revive fallen comrades. Growing pod people is easy, but prone to disaster. +

    +

      +
    1. Find a dead person who is in need of cloning.
    2. +
    3. Take a blood sample with a syringe.
    4. +
    5. Inject a seed pack with the blood sample.
    6. +
    7. Plant the seeds.
    8. +
    9. Tend to the plants water and nutrition levels until it is time to harvest the cloned human.
    10. +
    +

    + It really is that easy! Good luck! + + + + "} + +/obj/item/book/manual/medical_cloning + name = "Cloning techniques of the 26th century" + icon_state ="bookCloning" + author = "Medical Journal, volume 3" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned + title = "Cloning techniques of the 26th century" +//big pile of shit below. + + dat = {" + + + + + +

    How to Clone People

    + So there’s 50 dead people lying on the floor, chairs are spinning like no tomorrow and you haven’t the foggiest idea of what to do? Not to worry! This guide is intended to teach you how to clone people and how to do it right, in a simple step-by-step process! If at any point of the guide you have a mental meltdown, genetics probably isn’t for you and you should get a job-change as soon as possible before you’re sued for malpractice. + +
      +
    1. Acquire body
    2. +
    3. Strip body
    4. +
    5. Put body in cloning machine
    6. +
    7. Scan body
    8. +
    9. Clone body
    10. +
    11. Get clean Structurel Enzymes for the body
    12. +
    13. Put body in morgue
    14. +
    15. Await cloned body
    16. +
    17. Use the clean SW injector
    18. +
    19. Give person clothes back
    20. +
    21. Send person on their way
    22. +
    + +

    Step 1: Acquire body

    + This is pretty much vital for the process because without a body, you cannot clone it. Usually, bodies will be brought to you, so you do not need to worry so much about this step. If you already have a body, great! Move on to the next step. + +

    Step 2: Strip body

    + The cloning machine does not like abiotic items. What this means is you can’t clone anyone if they’re wearing clothes, so take all of it off. If it’s just one person, it’s courteous to put their possessions in the closet. If you have about seven people awaiting cloning, just leave the piles where they are, but don’t mix them around and for God’s sake don’t let the Clown in to steal them. + +

    Step 3: Put body in cloning machine

    + Grab the body and then put it inside the DNA modifier. If you cannot do this, then you messed up at Step 2. Go back and check you took EVERYTHING off - a commonly missed item is their headset. + +

    Step 4: Scan body

    + Go onto the computer and scan the body by pressing ‘Scan - ’. If you’re successful, they will be added to the records (note that this can be done at any time, even with living people, so that they can be cloned without a body in the event that they are lying dead on port solars and didn‘t turn on their suit sensors)! If not, and it says “Error: Mental interface failure.”, then they have left their bodily confines and are one with the spirits. If this happens, just shout at them to get back in their body, click ‘Refresh‘ and try scanning them again. If there’s no success, threaten them with gibbing. Still no success? Skip over to Step 7 and don‘t continue after it, as you have an unresponsive body and it cannot be cloned. If you got “Error: Unable to locate valid genetic data.“, you are trying to clone a monkey - start over. + +

    Step 5: Clone body

    + Now that the body has a record, click ’View Records’, click the subject’s name, and then click ‘Clone’ to start the cloning process. Congratulations! You’re halfway there. Remember not to ‘Eject’ the cloning pod as this will kill the developing clone and you’ll have to start the process again. + +

    Step 6: Get clean SEs for body

    + Cloning is a finicky and unreliable process. Whilst it will most certainly bring someone back from the dead, they can have any number of nasty disabilities given to them during the cloning process! For this reason, you need to prepare a clean, defect-free Structural Enzyme (SE) injection for when they’re done. If you’re a competent Geneticist, you will already have one ready on your working computer. If, for any reason, you do not, then eject the body from the DNA modifier (NOT THE CLONING POD) and take it next door to the Genetics research room. Put the body in one of those DNA modifiers and then go onto the console. Go into View/Edit/Transfer Buffer, find an open slot and click “SE“ to save it. Then click ‘Injector’ to get the SEs in syringe form. Put this in your pocket or something for when the body is done. + +

    Step 7: Put body in morgue

    + Now that the cloning process has been initiated and you have some clean Structural Enzymes, you no longer need the body! Drag it to the morgue and tell the Chef over the radio that they have some fresh meat waiting for them in there. To put a body in a morgue bed, simply open the tray, grab the body, put it on the open tray, then close the tray again. Use one of the nearby pens to label the bed “CHEF MEAT” in order to avoid confusion. + +

    Step 8: Await cloned body

    + Now go back to the lab and wait for your patient to be cloned. It won’t be long now, I promise. + +

    Step 9: Use the clean SE injector on person

    + Has your body been cloned yet? Great! As soon as the guy pops out, grab your injector and jab it in them. Once you’ve injected them, they now have clean Structural Enzymes and their defects, if any, will disappear in a short while. + +

    Step 10: Give person clothes back

    + Obviously the person will be naked after they have been cloned. Provided you weren’t an irresponsible little shit, you should have protected their possessions from thieves and should be able to give them back to the patient. No matter how cruel you are, it’s simply against protocol to force your patients to walk outside naked. + +

    Step 11: Send person on their way

    + Give the patient one last check-over - make sure they don’t still have any defects and that they have all their possessions. Ask them how they died, if they know, so that you can report any foul play over the radio. Once you’re done, your patient is ready to go back to work! Chances are they do not have Medbay access, so you should let them out of Genetics and the Medbay main entrance. + +

    If you’ve gotten this far, congratulations! You have mastered the art of cloning. Now, the real problem is how to resurrect yourself after that traitor had his way with you for cloning his target. + + + + + + "} + + +/obj/item/book/manual/ripley_build_and_repair + name = "APLU \"Ripley\" Construction and Operation Manual" + icon_state ="book" + author = "Weyland-Yutani Corp" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned + title = "APLU \"Ripley\" Construction and Operation Manual" +//big pile of shit below. + + dat = {" + + + + +

    + Weyland-Yutani - Building Better Worlds +

    Autonomous Power Loader Unit \"Ripley\"

    +
    +

    Specifications:

    +
      +
    • Class: Autonomous Power Loader
    • +
    • Scope: Logistics and Construction
    • +
    • Weight: 820kg (without operator and with empty cargo compartment)
    • +
    • Height: 2.5m
    • +
    • Width: 1.8m
    • +
    • Top speed: 5km/hour
    • +
    • Operation in vacuum/hostile environment: Possible +
    • Airtank Volume: 500liters
    • +
    • Devices: +
        +
      • Hydraulic Clamp
      • +
      • High-speed Drill
      • +
      +
    • +
    • Propulsion Device: Powercell-powered electro-hydraulic system.
    • +
    • Powercell capacity: Varies.
    • +
    + +

    Construction:

    +
      +
    1. Connect all exosuit parts to the chassis frame
    2. +
    3. Connect all hydraulic fittings and tighten them up with a wrench
    4. +
    5. Adjust the servohydraulics with a screwdriver
    6. +
    7. Wire the chassis. (Cable is not included.)
    8. +
    9. Use the wirecutters to remove the excess cable if needed.
    10. +
    11. Install the central control module (Not included. Use supplied datadisk to create one).
    12. +
    13. Secure the mainboard with a screwdriver.
    14. +
    15. Install the peripherals control module (Not included. Use supplied datadisk to create one).
    16. +
    17. Secure the peripherals control module with a screwdriver
    18. +
    19. Install the internal armor plating (Not included due to Nanotrasen regulations. Can be made using 5 metal sheets.)
    20. +
    21. Secure the internal armor plating with a wrench
    22. +
    23. Weld the internal armor plating to the chassis
    24. +
    25. Install the external reinforced armor plating (Not included due to Nanotrasen regulations. Can be made using 5 reinforced metal sheets.)
    26. +
    27. Secure the external reinforced armor plating with a wrench
    28. +
    29. Weld the external reinforced armor plating to the chassis
    30. +
    31. +
    32. Additional Information:
    33. +
    34. The firefighting variation is made in a similar fashion.
    35. +
    36. A firesuit must be connected to the Firefighter chassis for heat shielding.
    37. +
    38. Internal armor is plasteel for additional strength.
    39. +
    40. External armor must be installed in 2 parts, totaling 10 sheets.
    41. +
    42. Completed mech is more resiliant against fire, and is a bit more durable overall
    43. +
    44. Nanotrasen is determined to the safety of its investments employees.
    45. +
    + + + +

    Operation

    + Coming soon... + "} + +/obj/item/book/manual/experimentor + name = "Mentoring your Experiments" + icon_state = "rdbook" + author = "Dr. H.P. Kritz" + title = "Mentoring your Experiments" + dat = {" + + + + +

    THE E.X.P.E.R.I-MENTOR

    + The Enhanced Xenobiological Period Extraction (and) Restoration Instructor is a machine designed to discover the secrets behind every item in existence. + With advanced technology, it can process 99.95% of items, and discover their uses and secrets. + The E.X.P.E.R.I-MENTOR is a Research apparatus that takes items, and through a process of elimination, it allows you to deduce new technological designs from them. + Due to the volatile nature of the E.X.P.E.R.I-MENTOR, there is a slight chance for malfunction, potentially causing irreparable damage to you or your environment. + However, upgrading the apparatus has proven to decrease the chances of undesirable, potentially life-threatening outcomes. + Please note that the E.X.P.E.R.I-MENTOR uses a state-of-the-art random generator, which has a larger entropy than the observable universe, + therefore it can generate wildly different results each day, therefore it is highly suggested to re-scan objects of interests frequently (e.g. each shift). + +

    BASIC PROCESS

    + The usage of the E.X.P.E.R.I-MENTOR is quite simple: +
      +
    1. Find an item with a technological background
    2. +
    3. Insert the item into the E.X.P.E.R.I-MENTOR
    4. +
    5. Cycle through each processing method of the device.
    6. +
    7. Stand back, even in case of a successful experiment, as the machine might produce undesired behaviour.
    8. +
    + +

    ADVANCED USAGE

    + The E.X.P.E.R.I-MENTOR has a variety of uses, beyond menial research work. The different results can be used to combat localised events, or even to get special items. + + The E.X.P.E.R.I-MENTOR's OBLITERATE function has the added use of transferring the destroyed item's material into a linked lathe. + + The IRRADIATE function can be used to transform items into other items, resulting in potential upgrades (or downgrades). + + Users should remember to always wear appropriate protection when using the machine, because malfunction can occur at any moment! + +

    EVENTS

    +

    GLOBAL (happens at any time):

    +
      +
    1. DETECTION MALFUNCTION - The machine's onboard sensors have malfunctioned, causing it to redefine the item's experiment type. + Produces the message: The E.X.P.E.R.I-MENTOR's onboard detection system has malfunctioned!
    2. + +
    3. IANIZATION - The machine's onboard corgi-filter has malfunctioned, causing it to produce a corgi from.. somewhere. + Produces the message: The E.X.P.E.R.I-MENTOR melts the banana, ian-izing the air around it!
    4. + +
    5. RUNTIME ERROR - The machine's onboard C4T-P processor has encountered a critical error, causing it to produce a cat from.. somewhere. + Produces the message: The E.X.P.E.R.I-MENTOR encounters a run-time error!
    6. + +
    7. B100DG0D.EXE - The machine has encountered an unknown subroutine, which has been injected into its runtime. It upgrades the held item! + Produces the message: The E.X.P.E.R.I-MENTOR improves the banana, drawing the life essence of those nearby!
    8. + +
    9. POWERSINK - The machine's PSU has tripped the charging mechanism! It consumes massive amounts of power! + Produces the message: The E.X.P.E.R.I-MENTOR begins to smoke and hiss, shaking violently!
    10. +
    +

    FAIL:

    + This event is produced when the item mismatches the selected experiment. + Produces a random message similar to: "the Banana rumbles, and shakes, the experiment was a failure!" + +

    POKE:

    +
      +
    1. WILD ARMS - The machine's gryoscopic processors malfunction, causing it to lash out at nearby people with its arms. + Produces the message: The E.X.P.E.R.I-MENTOR malfunctions and destroys the banana, lashing its arms out at nearby people!
    2. + +
    3. MISTYPE - The machine's interface has been garbled, and it switches to OBLITERATE. + Produces the message: The E.X.P.E.R.I-MENTOR malfunctions!
    4. + +
    5. THROW - The machine's spatial recognition device has shifted several meters across the room, causing it to try and repostion the item there. + Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, throwing the banana!
    6. +
    +

    IRRADIATE:

    +
      +
    1. RADIATION LEAK - The machine's shield has failed, resulting in a toxic radiation leak. + Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, melting the banana and leaking radiation!
    2. + +
    3. RADIATION DUMP - The machine's recycling and containment functions have failed, resulting in a dump of toxic waste around it + Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, spewing toxic waste!
    4. + +
    5. MUTATION - The machine's radio-isotope level meter has malfunctioned, causing it over-irradiate the item, making it transform. + Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, transforming the banana!
    6. +
    +

    GAS:

    +
      +
    1. TOXIN LEAK - The machine's filtering and vent systems have failed, resulting in a cloud of toxic gas being expelled. + Produces the message: The E.X.P.E.R.I-MENTOR destroys the banana, leaking dangerous gas!
    2. + +
    3. GAS LEAK - The machine's vent systems have failed, resulting in a cloud of harmless, but obscuring gas. + Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, spewing harmless gas!
    4. + +
    5. ELECTROMAGNETIC IONS - The machine's electrolytic scanners have failed, causing a dangerous Electromagnetic reaction. + Produces the message: The E.X.P.E.R.I-MENTOR melts the banana, ionizing the air around it!
    6. +
    +

    HEAT:

    +
      +
    1. TOASTER - The machine's heating coils have come into contact with the machine's gas storage, causing a large, sudden blast of flame. + Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, melting the banana and releasing a burst of flame!
    2. + +
    3. SAUNA - The machine's vent loop has sprung a leak, resulting in a large amount of superheated air being dumped around it. + Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, melting the banana and leaking hot air!
    4. + +
    5. EMERGENCY VENT - The machine's temperature gauge has malfunctioned, resulting in it attempting to cool the area around it, but instead, dumping a cloud of steam. + Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, activating its emergency coolant systems!
    6. +
    +

    COLD:

    +
      +
    1. FREEZER - The machine's cooling loop has sprung a leak, resulting in a cloud of super-cooled liquid being blasted into the air. + Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, shattering the banana and releasing a dangerous cloud of coolant!
    2. + +
    3. FRIDGE - The machine's cooling loop has been exposed to the outside air, resulting in a large decrease in temperature. + Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, shattering the banana and leaking cold air!
    4. + +
    5. SNOWSTORM - The machine's cooling loop has come into contact with the heating coils, resulting in a sudden blast of cool air. + Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, releasing a flurry of chilly air as the banana pops out!
    6. +
    +

    OBLITERATE:

    +
      +
    1. IMPLOSION - The machine's pressure leveller has malfunctioned, causing it to pierce the space-time momentarily, making everything in the area fly towards it. + Produces the message: The E.X.P.E.R.I-MENTOR's crusher goes way too many levels too high, crushing right through space-time!
    2. + +
    3. DISTORTION - The machine's pressure leveller has completely disabled, resulting in a momentary space-time distortion, causing everything to fly around. + Produces the message: The E.X.P.E.R.I-MENTOR's crusher goes one level too high, crushing right into space-time!
    4. +
    + + + "} + +/obj/item/book/manual/research_and_development + name = "Research and Development 101" + icon_state = "rdbook" + author = "Dr. L. Ight" + title = "Research and Development 101" + dat = {" + + + + + +

    Science For Dummies

    + So you want to further SCIENCE? Good man/woman/thing! However, SCIENCE is a complicated process even though it's quite easy. For the most part, it's a three step process: +
      +
    1. 1) Deconstruct items in the Destructive Analyzer to advance technology or improve the design.
    2. +
    3. 2) Build unlocked designs in the Protolathe and Circuit Imprinter
    4. +
    5. 3) Repeat!
    6. +
    + + Those are the basic steps to furthing science. What do you do science with, however? Well, you have four major tools: R&D Console, the Destructive Analyzer, the Protolathe, and the Circuit Imprinter. + +

    The R&D Console

    + The R&D console is the cornerstone of any research lab. It is the central system from which the Destructive Analyzer, Protolathe, and Circuit Imprinter (your R&D systems) are controled. More on those systems in their own sections. On its own, the R&D console acts as a database for all your technological gains and new devices you discover. So long as the R&D console remains intact, you'll retain all that SCIENCE you've discovered. Protect it though, because if it gets damaged, you'll lose your data! In addition to this important purpose, the R&D console has a disk menu that lets you transfer data from the database onto disk or from the disk into the database. It also has a settings menu that lets you re-sync with nearby R&D devices (if they've become disconnected), lock the console from the unworthy, upload the data to all other R&D consoles in the network (all R&D consoles are networked by default), connect/disconnect from the network, and purge all data from the database. + NOTE: The technology list screen, circuit imprinter, and protolathe menus are accessible by non-scientists. This is intended to allow 'public' systems for the plebians to utilize some new devices. + +

    Destructive Analyzer

    + This is the source of all technology. Whenever you put a handheld object in it, it analyzes it and determines what sort of technological advancements you can discover from it. If the technology of the object is equal or higher then your current knowledge, you can destroy the object to further those sciences. Some devices (notably, some devices made from the protolathe and circuit imprinter) aren't 100% reliable when you first discover them. If these devices break down, you can put them into the Destructive Analyzer and improve their reliability rather then futher science. If their reliability is high enough ,it'll also advance their related technologies. + +

    Circuit Imprinter

    + This machine, along with the Protolathe, is used to actually produce new devices. The Circuit Imprinter takes glass and various chemicals (depends on the design) to produce new circuit boards to build new machines or computers. It can even be used to print AI modules. + +

    Protolathe

    + This machine is an advanced form of the Autolathe that produce non-circuit designs. Unlike the Autolathe, it can use processed metal, glass, solid plasma, silver, gold, and diamonds along with a variety of chemicals to produce devices. The downside is that, again, not all devices you make are 100% reliable when you first discover them. + +

    Reliability and You

    + As it has been stated, many devices when they're first discovered do not have a 100% reliablity when you first discover them. Instead, the reliablity of the device is dependent upon a base reliability value, whatever improvements to the design you've discovered through the Destructive Analyzer, and any advancements you've made with the device's source technologies. To be able to improve the reliability of a device, you have to use the device until it breaks beyond repair. Once that happens, you can analyze it in a Destructive Analyzer. Once the device reachs a certain minimum reliability, you'll gain tech advancements from it. + +

    Building a Better Machine

    + Many machines produces from circuit boards and inserted into a machine frame require a variety of parts to construct. These are parts like capacitors, batteries, matter bins, and so forth. As your knowledge of science improves, more advanced versions are unlocked. If you use these parts when constructing something, its attributes may be improved. For example, if you use an advanced matter bin when constructing an autolathe (rather then a regular one), it'll hold more materials. Experiment around with stock parts of various qualities to see how they affect the end results! Be warned, however: Tier 3 and higher stock parts don't have 100% reliability and their low reliability may affect the reliability of the end machine. + + + "} + + +/obj/item/book/manual/robotics_cyborgs + name = "Cyborgs for Dummies" + icon_state = "borgbook" + author = "XISC" + title = "Cyborgs for Dummies" + dat = {" + + + + + +

    Cyborgs for Dummies

    + +

    Chapters

    + +
      +
    1. Cyborg Related Equipment
    2. +
    3. Cyborg Modules
    4. +
    5. Cyborg Construction
    6. +
    7. Cyborg Deconstruction
    8. +
    9. Cyborg Maintenance
    10. +
    11. Cyborg Repairs
    12. +
    13. In Case of Emergency
    14. +
    + + +

    Cyborg Related Equipment

    + +

    Exosuit Fabricator

    + The Exosuit Fabricator is the most important piece of equipment related to cyborgs. It allows the construction of the core cyborg parts. Without these machines, cyborgs can not be built. It seems that they may also benefit from advanced research techniques. + +

    Cyborg Recharging Station

    + This useful piece of equipment will suck power out of the power systems to charge a cyborg's power cell back up to full charge. + +

    Robotics Control Console

    + This useful piece of equipment can be used to immobolize or destroy a cyborg. A word of warning: Cyborgs are expensive pieces of equipment, do not destroy them without good reason, or Nanotrasen may see to it that it never happens again. + + +

    Cyborg Modules

    + When a cyborg is created it picks out of an array of modules to designate its purpose. There are 6 different cyborg modules. + +

    Standard Cyborg

    + The standard cyborg module is a multi-purpose cyborg. It is equipped with various modules, allowing it to do basic tasks.
    + +

    Engineering Cyborg

    + The Engineering cyborg module comes equipped with various engineering-related tools to help with engineering-related tasks.
    + +

    Mining Cyborg

    + The Mining Cyborg module comes equipped with the latest in mining equipment. They are efficient at mining due to no need for oxygen, but their power cells limit their time in the mines. + +

    Security Cyborg

    + The Security Cyborg module is equipped with effective security measures used to apprehend and arrest criminals without harming them a bit. + +

    Janitor Cyborg

    + The Janitor Cyborg module is equipped with various cleaning-facilitating devices. + +

    Service Cyborg

    + The service cyborg module comes ready to serve your human needs. It includes various entertainment and refreshment devices. Occasionally some service cyborgs may have been referred to as "Bros" + +

    Cyborg Construction

    + Cyborg construction is a rather easy process, requiring a decent amount of metal and a few other supplies.
    The required materials to make a cyborg are: +
      +
    • Metal
    • +
    • Two Flashes
    • +
    • One Power Cell (Preferrably rated to 15000w)
    • +
    • Some electrical wires
    • +
    • One Human Brain
    • +
    • One Man-Machine Interface
    • +
    + Once you have acquired the materials, you can start on construction of your cyborg.
    To construct a cyborg, follow the steps below: +
      +
    1. Start the Exosuit Fabricators constructing all of the cyborg parts
    2. +
    3. While the parts are being constructed, take your human brain, and place it inside the Man-Machine Interface
    4. +
    5. Once you have a Robot Head, place your two flashes inside the eye sockets
    6. +
    7. Once you have your Robot Chest, wire the Robot chest, then insert the power cell
    8. +
    9. Attach all of the Robot parts to the Robot frame
    10. +
    11. Insert the Man-Machine Interface (With the Brain inside) Into the Robot Body
    12. +
    13. Congratulations! You have a new cyborg!
    14. +
    + +

    Cyborg Deconstruction

    + If you want to deconstruct a cyborg, say to remove its MMI without blowing the Cyborg to pieces, they come apart very quickly, and very safely, in a few simple steps. +
      +
    • Crowbar
    • +
    • Wrench
    • + Optional: +
    • Screwdriver
    • +
    • Wirecutters
    • +
    +
      +
    1. Begin by unlocking the Cyborg's access panel using your ID
    2. +
    3. Use your crowbar to open the Cyborg's access panel
    4. +
    5. Using your bare hands, remove the power cell from the Cyborg
    6. +
    7. Lockdown the Cyborg to disengage safety protocols
    8. +
        + Option 1: Robotics console +
      1. Use the Robotics console in the RD's office
      2. +
      3. Find the entry for your Cyborg
      4. +
      5. Press the Lockdown button on the Robotics console
      6. +
      +
        + Option 2: Lockdown wire +
      1. Use your screwdriver to expose the Cyborg's wiring
      2. +
      3. Use your wirecutters to start cutting all of the wires until the lockdown light turns off, cutting all of the wires irregardless of the lockdown light works as well
      4. +
      +
    9. Use your wrench to unfasten the Cyborg's bolts, the Cyborg will then fall apart onto the floor, the MMI will be there as well
    10. +
    + +

    Cyborg Maintenance

    + Occasionally Cyborgs may require maintenance of a couple types, this could include replacing a power cell with a charged one, or possibly maintaining the cyborg's internal wiring. + +

    Replacing a Power Cell

    + Replacing a Power cell is a common type of maintenance for cyborgs. It usually involves replacing the cell with a fully charged one, or upgrading the cell with a larger capacity cell.
    The steps to replace a cell are follows: +
      +
    1. Unlock the Cyborg's Interface by swiping your ID on it
    2. +
    3. Open the Cyborg's outer panel using a crowbar
    4. +
    5. Remove the old power cell
    6. +
    7. Insert the new power cell
    8. +
    9. Close the Cyborg's outer panel using a crowbar
    10. +
    11. Lock the Cyborg's Interface by swiping your ID on it, this will prevent non-qualified personnel from attempting to remove the power cell
    12. +
    + +

    Exposing the Internal Wiring

    + Exposing the internal wiring of a cyborg is fairly easy to do, and is mainly used for cyborg repairs.
    You can easily expose the internal wiring by following the steps below: +
      +
    1. Follow Steps 1 - 3 of "Replacing a Cyborg's Power Cell"
    2. +
    3. Open the cyborg's internal wiring panel by using a screwdriver to unsecure the panel
    4. +
    + To re-seal the cyborg's internal wiring: +
      +
    1. Use a screwdriver to secure the cyborg's internal panel
    2. +
    3. Follow steps 4 - 6 of "Replacing a Cyborg's Power Cell" to close up the cyborg
    4. +
    + +

    Cyborg Repairs

    + Occasionally a Cyborg may become damaged. This could be in the form of impact damage from a heavy or fast-travelling object, or it could be heat damage from high temperatures, or even lasers or Electromagnetic Pulses (EMPs). + +

    Dents

    + If a cyborg becomes damaged due to impact from heavy or fast-moving objects, it will become dented. Sure, a dent may not seem like much, but it can compromise the structural integrity of the cyborg, possibly causing a critical failure. + Dents in a cyborg's frame are rather easy to repair, all you need is to apply a welding tool to the dented area, and the high-tech cyborg frame will repair the dent under the heat of the welder. + +

    Excessive Heat Damage

    + If a cyborg becomes damaged due to excessive heat, it is likely that the internal wires will have been damaged. You must replace those wires to ensure that the cyborg remains functioning properly.
    To replace the internal wiring follow the steps below: +
      +
    1. Unlock the Cyborg's Interface by swiping your ID
    2. +
    3. Open the Cyborg's External Panel using a crowbar
    4. +
    5. Remove the Cyborg's Power Cell
    6. +
    7. Using a screwdriver, expose the internal wiring or the Cyborg
    8. +
    9. Replace the damaged wires inside the cyborg
    10. +
    11. Secure the internal wiring cover using a screwdriver
    12. +
    13. Insert the Cyborg's Power Cell
    14. +
    15. Close the Cyborg's External Panel using a crowbar
    16. +
    17. Lock the Cyborg's Interface by swiping your ID
    18. +
    + These repair tasks may seem difficult, but are essential to keep your cyborgs running at peak efficiency. + +

    In Case of Emergency

    + In case of emergency, there are a few steps you can take. + +

    "Rogue" Cyborgs

    + If the cyborgs seem to become "rogue", they may have non-standard laws. In this case, use extreme caution. + To repair the situation, follow these steps: +
      +
    1. Locate the nearest robotics console
    2. +
    3. Determine which cyborgs are "Rogue"
    4. +
    5. Press the lockdown button to immobolize the cyborg
    6. +
    7. Locate the cyborg
    8. +
    9. Expose the cyborg's internal wiring
    10. +
    11. Check to make sure the LawSync and AI Sync lights are lit
    12. +
    13. If they are not lit, pulse the LawSync wire using a multitool to enable the cyborg's Law Sync
    14. +
    15. Proceed to a cyborg upload console. Nanotrasen usually places these in the same location as AI uplaod consoles.
    16. +
    17. Use a "Reset" upload moduleto reset the cyborg's laws
    18. +
    19. Proceed to a Robotics Control console
    20. +
    21. Remove the lockdown on the cyborg
    22. +
    + +

    As a last resort

    + If all else fails in a case of cyborg-related emergency. There may be only one option. Using a Robotics Control console, you may have to remotely detonate the cyborg. +

    WARNING:

    Do not detonate a borg without an explicit reason for doing so. Cyborgs are expensive pieces of Nanotrasen equipment, and you may be punished for detonating them without reason. + + + + "} + + + +/obj/item/book/manual/chef_recipes + name = "Chef Recipes" + icon_state = "cooked_book" + author = "Lord Frenrir Cageth" + title = "Chef Recipes" + dat = {" + + + + + +

    Food for Dummies

    + Here is a guide on basic food recipes and also how to not poison your customers accidentally. + + +

    Basic ingredients preparation:

    + + Dough: 10u water + 15u flour for simple dough.
    + 15u egg yolk + 15u flour + 5u sugar for cake batter.
    + Doughs can be transformed by using a knife and rolling pin.
    + All doughs can be microwaved.
    + Bowl: Add water to it for soup preparation.
    + Meat: Microwave it, process it, slice it into microwavable cutlets with your knife, or use it raw.
    + Cheese: Add 5u universal enzyme (catalyst) to milk and soy milk to prepare cheese (sliceable) and tofu.
    + Rice: Mix 10u rice with 10u water in a bowl then microwave it. + +

    Custom food:

    + Add ingredients to a base item to prepare a custom meal.
    + The bases are:
    + - bun (burger)
    + - breadslices(sandwich)
    + - plain bread
    + - plain pie
    + - vanilla cake
    + - empty bowl (salad)
    + - bowl with 10u water (soup)
    + - boiled spaghetti
    + - pizza bread
    + - metal rod (kebab) + +

    Table Craft:

    + Put ingredients on table, then click and drag the table onto yourself to see what recipes you can prepare. + +

    Microwave:

    + Use it to cook or boil food ingredients (meats, doughs, egg, spaghetti, donkpocket, etc...). + It can cook multiple items at once. + +

    Processor:

    + Use it to process certain ingredients (meat into faggot, doughslice into spaghetti, potato into fries,etc...) + +

    Gibber:

    + Stuff an animal in it to grind it into meat. + +

    Meat spike:

    + Stick an animal on it then begin collecting its meat. + + +

    Example recipes:

    + Vanilla Cake: Microwave cake batter.
    + Burger: 1 bun + 1 meat steak
    + Bread: Microwave dough.
    + Waffles: 2 pastry base
    + Popcorn: Microwave corn.
    + Meat Steak: Microwave meat.
    + Meat Pie: 1 plain pie + 1u black pepper + 1u salt + 2 meat cutlets
    + Boiled Spagetti: Microwave spaghetti.
    + Donuts: 1u sugar + 1 pastry base
    + Fries: Process potato. + +

    Sharing your food:

    + You can put your meals on your kitchen counter or load them in the snack vending machines. + + + "} + + +/obj/item/book/manual/barman_recipes + name = "Barman Recipes" + icon_state = "barbook" + author = "Sir John Rose" + title = "Barman Recipes" + dat = {" + + + + + +

    Drinks for dummies

    + Heres a guide for some basic drinks. + +

    Manly Dorf:

    + Mix ale and beer into a glass. + +

    Grog:

    + Mix rum and water into a glass. + +

    Black Russian:

    + Mix vodka and kahlua into a glass. + +

    Irish Cream:

    + Mix cream and whiskey into a glass. + +

    Screwdriver:

    + Mix vodka and orange juice into a glass. + +

    Cafe Latte:

    + Mix milk and coffee into a glass. + +

    Mead:

    + Mix Enzyme, water and sugar into a glass. + +

    Gin Tonic:

    + Mix gin and tonic into a glass. + +

    Classic Martini:

    + Mix vermouth and gin into a glass. + + + + + "} + + +/obj/item/book/manual/detective + name = "The Film Noir: Proper Procedures for Investigations" + icon_state ="bookDetective" + author = "Nanotrasen" + title = "The Film Noir: Proper Procedures for Investigations" + dat = {" + + + + +

    Detective Work

    + + Between your bouts of self-narration, and drinking whiskey on the rocks, you might get a case or two to solve.
    + To have the best chance to solve your case, follow these directions: +

    +

      +
    1. Go to the crime scene.
    2. +
    3. Take your scanner and scan EVERYTHING (Yes, the doors, the tables, even the dog.)
    4. +
    5. Once you are reasonably certain you have every scrap of evidence you can use, find all possible entry points and scan them, too.
    6. +
    7. Return to your office.
    8. +
    9. Using your forensic scanning computer, scan your Scanner to upload all of your evidence into the database.
    10. +
    11. Browse through the resulting dossiers, looking for the one that either has the most complete set of prints, or the most suspicious items handled.
    12. +
    13. If you have 80% or more of the print (The print is displayed) go to step 10, otherwise continue to step 8.
    14. +
    15. Look for clues from the suit fibres you found on your perp, and go about looking for more evidence with this new information, scanning as you go.
    16. +
    17. Try to get a fingerprint card of your perp, as if used in the computer, the prints will be completed on their dossier.
    18. +
    19. Assuming you have enough of a print to see it, grab the biggest complete piece of the print and search the security records for it.
    20. +
    21. Since you now have both your dossier and the name of the person, print both out as evidence, and get security to nab your baddie.
    22. +
    23. Give yourself a pat on the back and a bottle of the ships finest vodka, you did it!
    24. +
    +

    + It really is that easy! Good luck! + + + "} + +/obj/item/book/manual/nuclear + name = "Fission Mailed: Nuclear Sabotage 101" + icon_state ="bookNuclear" + author = "Syndicate" + title = "Fission Mailed: Nuclear Sabotage 101" + dat = {" + Nuclear Explosives 101:
    + Hello and thank you for choosing the Syndicate for your nuclear information needs.
    + Today's crash course will deal with the operation of a Fusion Class Nanotrasen made Nuclear Device.
    + First and foremost, DO NOT TOUCH ANYTHING UNTIL THE BOMB IS IN PLACE.
    + Pressing any button on the compacted bomb will cause it to extend and bolt itself into place.
    + If this is done to unbolt it one must completely log in which at this time may not be possible.
    + To make the nuclear device functional:
    +

  • Place the nuclear device in the designated detonation zone.
  • +
  • Extend and anchor the nuclear device from its interface.
  • +
  • Insert the nuclear authorisation disk into slot.
  • +
  • Type numeric authorisation code into the keypad. This should have been provided. Note: If you make a mistake press R to reset the device. +
  • Press the E button to log onto the device.
  • + You now have activated the device. To deactivate the buttons at anytime for example when you've already prepped the bomb for detonation remove the auth disk OR press the R on the keypad.
    + Now the bomb CAN ONLY be detonated using the timer. Manual detonation is not an option.
    + Note: Nanotrasen is a pain in the neck.
    + Toggle off the SAFETY.
    + Note: You wouldn't believe how many Syndicate Operatives with doctorates have forgotten this step.
    + So use the - - and + + to set a det time between 5 seconds and 10 minutes.
    + Then press the timer toggle button to start the countdown.
    + Now remove the auth. disk so that the buttons deactivate.
    + Note: THE BOMB IS STILL SET AND WILL DETONATE
    + Now before you remove the disk if you need to move the bomb you can:
    + Toggle off the anchor, move it, and re-anchor.

    + Good luck. Remember the order:
    + Disk, Code, Safety, Timer, Disk, RUN!
    + Intelligence Analysts believe that normal Nanotrasen procedure is for the Captain to secure the nuclear authorisation disk.
    + Good luck! + "} + +// Wiki books that are linked to the configured wiki link. + +// A book that links to the wiki +/obj/item/book/manual/wiki + var/page_link = "" + window_size = "970x710" + +/obj/item/book/manual/wiki/attack_self() + if(!dat) + initialize_wikibook() + ..() + +/obj/item/book/manual/wiki/proc/initialize_wikibook() + var/wikiurl = CONFIG_GET(string/wikiurl) + if(wikiurl) + dat = {" + + + + + + +

    You start skimming through the manual...

    + + + + + + "} + +/obj/item/book/manual/wiki/chemistry + name = "Chemistry Textbook" + icon_state ="chemistrybook" + author = "Nanotrasen" + title = "Chemistry Textbook" + page_link = "Guide_to_chemistry" + +/obj/item/book/manual/wiki/engineering_construction + name = "Station Repairs and Construction" + icon_state ="bookEngineering" + author = "Engineering Encyclopedia" + title = "Station Repairs and Construction" + page_link = "Guide_to_construction" + +/obj/item/book/manual/wiki/engineering_guide + name = "Engineering Textbook" + icon_state ="bookEngineering2" + author = "Engineering Encyclopedia" + title = "Engineering Textbook" + page_link = "Guide_to_engineering" + +/obj/item/book/manual/wiki/security_space_law + name = "Space Law" + desc = "A set of Nanotrasen guidelines for keeping law and order on their space stations." + icon_state = "bookSpaceLaw" + author = "Nanotrasen" + title = "Space Law" + page_link = "Space_Law" + +/obj/item/book/manual/wiki/infections + name = "Infections - Making your own pandemic!" + icon_state = "bookInfections" + author = "Infections Encyclopedia" + title = "Infections - Making your own pandemic!" + page_link = "Infections" + +/obj/item/book/manual/wiki/telescience + name = "Teleportation Science - Bluespace for dummies!" + icon_state = "book7" + author = "University of Bluespace" + title = "Teleportation Science - Bluespace for dummies!" + page_link = "Guide_to_telescience" + +/obj/item/book/manual/wiki/engineering_hacking + name = "Hacking" + icon_state ="bookHacking" + author = "Engineering Encyclopedia" + title = "Hacking" + page_link = "Hacking" +>>>>>>> 4178c20... Configuration datum refactor (#30763) diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm index 0a7b9eb312..709d86d4d7 100644 --- a/code/game/objects/structures/ai_core.dm +++ b/code/game/objects/structures/ai_core.dm @@ -134,7 +134,7 @@ to_chat(user, "Sticking an inactive [M.name] into the frame would sort of defeat the purpose.") return - if((config) && (!config.allow_ai) || jobban_isbanned(M.brainmob, "AI")) + if(!CONFIG_GET(flag/allow_ai) || jobban_isbanned(M.brainmob, "AI")) to_chat(user, "This [M.name] does not seem to fit!") return diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm index 4754cc63e7..7a4f04a4e3 100644 --- a/code/game/objects/structures/beds_chairs/chair.dm +++ b/code/game/objects/structures/beds_chairs/chair.dm @@ -93,7 +93,7 @@ set category = "Object" set src in oview(1) - if(config.ghost_interaction) + if(CONFIG_GET(flag/ghost_interaction)) spin() else if(!usr || !isturf(usr.loc)) diff --git a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm index a920a53c7f..1bf7daf2e2 100644 --- a/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm +++ b/code/game/objects/structures/crates_lockers/closets/cardboardbox.dm @@ -23,7 +23,7 @@ return move_delay = 1 if(step(src, direction)) - spawn(config.walk_speed*move_speed_multiplier) + spawn(CONFIG_GET(number/walk_delay) * move_speed_multiplier) move_delay = 0 else move_delay = 0 diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index a32db59bc5..c2e082810f 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD //wip wip wup /obj/structure/mirror name = "mirror" @@ -223,3 +224,231 @@ /obj/structure/mirror/magic/proc/curse(mob/living/user) return +======= +//wip wip wup +/obj/structure/mirror + name = "mirror" + desc = "Mirror mirror on the wall, who's the most robust of them all?" + icon = 'icons/obj/watercloset.dmi' + icon_state = "mirror" + density = FALSE + anchored = TRUE + max_integrity = 200 + integrity_failure = 100 + + +/obj/structure/mirror/attack_hand(mob/user) + if(broken || !Adjacent(user)) + return + + if(ishuman(user)) + var/mob/living/carbon/human/H = user + + var/userloc = H.loc + + //see code/modules/mob/dead/new_player/preferences.dm at approx line 545 for comments! + //this is largely copypasted from there. + + //handle facial hair (if necessary) + if(H.gender == MALE) + var/new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in GLOB.facial_hair_styles_list + if(userloc != H.loc) + return //no tele-grooming + if(new_style) + H.facial_hair_style = new_style + else + H.facial_hair_style = "Shaved" + + //handle normal hair + var/new_style = input(user, "Select a hair style", "Grooming") as null|anything in GLOB.hair_styles_list + if(userloc != H.loc) + return //no tele-grooming + if(new_style) + H.hair_style = new_style + + H.update_hair() + +/obj/structure/mirror/examine_status(mob/user) + if(broken) + return // no message spam + ..() + +/obj/structure/mirror/obj_break(damage_flag) + if(!broken && !(flags_1 & NODECONSTRUCT_1)) + icon_state = "mirror_broke" + playsound(src, "shatter", 70, 1) + desc = "Oh no, seven years of bad luck!" + broken = 1 + +/obj/structure/mirror/deconstruct(disassembled = TRUE) + if(!(flags_1 & NODECONSTRUCT_1)) + if(!disassembled) + new /obj/item/shard( src.loc ) + qdel(src) + +/obj/structure/mirror/attackby(obj/item/I, mob/living/user, params) + if(istype(I, /obj/item/weldingtool) && user.a_intent != INTENT_HARM) + var/obj/item/weldingtool/WT = I + if(broken) + user.changeNext_move(CLICK_CD_MELEE) + if(WT.remove_fuel(0, user)) + to_chat(user, "You begin repairing [src]...") + playsound(src, 'sound/items/welder.ogg', 100, 1) + if(do_after(user, 10*I.toolspeed, target = src)) + if(!user || !WT || !WT.isOn()) + return + to_chat(user, "You repair [src].") + broken = 0 + icon_state = initial(icon_state) + desc = initial(desc) + else + return ..() + +/obj/structure/mirror/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) + switch(damage_type) + if(BRUTE) + playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) + if(BURN) + playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) + + +/obj/structure/mirror/magic + name = "magic mirror" + desc = "Turn and face the strange... face." + icon_state = "magic_mirror" + var/list/races_blacklist = list("skeleton", "agent", "angel", "military_synth", "memezombie") + var/list/choosable_races = list() + +/obj/structure/mirror/magic/New() + if(!choosable_races.len) + for(var/speciestype in subtypesof(/datum/species)) + var/datum/species/S = new speciestype() + if(!(S.id in races_blacklist)) + choosable_races += S.id + ..() + +/obj/structure/mirror/magic/lesser/New() + var/list/L = CONFIG_GET(keyed_flag_list/roundstart_races) + choosable_races = L.Copy() + ..() + +/obj/structure/mirror/magic/badmin/New() + for(var/speciestype in subtypesof(/datum/species)) + var/datum/species/S = new speciestype() + choosable_races += S.id + ..() + +/obj/structure/mirror/magic/attack_hand(mob/user) + if(!ishuman(user)) + return + + var/mob/living/carbon/human/H = user + + var/choice = input(user, "Something to change?", "Magical Grooming") as null|anything in list("name", "race", "gender", "hair", "eyes") + + if(!Adjacent(user)) + return + + switch(choice) + if("name") + var/newname = copytext(sanitize(input(H, "Who are we again?", "Name change", H.name) as null|text),1,MAX_NAME_LEN) + + if(!newname) + return + if(!Adjacent(user)) + return + H.real_name = newname + H.name = newname + if(H.dna) + H.dna.real_name = newname + if(H.mind) + H.mind.name = newname + + if("race") + var/newrace + var/racechoice = input(H, "What are we again?", "Race change") as null|anything in choosable_races + newrace = GLOB.species_list[racechoice] + + if(!newrace) + return + if(!Adjacent(user)) + return + H.set_species(newrace, icon_update=0) + + if(H.dna.species.use_skintones) + var/new_s_tone = input(user, "Choose your skin tone:", "Race change") as null|anything in GLOB.skin_tones + + if(new_s_tone) + H.skin_tone = new_s_tone + H.dna.update_ui_block(DNA_SKIN_TONE_BLOCK) + + if(MUTCOLORS in H.dna.species.species_traits) + var/new_mutantcolor = input(user, "Choose your skin color:", "Race change") as color|null + if(new_mutantcolor) + var/temp_hsv = RGBtoHSV(new_mutantcolor) + + if(ReadHSV(temp_hsv)[3] >= ReadHSV("#7F7F7F")[3]) // mutantcolors must be bright + H.dna.features["mcolor"] = sanitize_hexcolor(new_mutantcolor) + + else + to_chat(H, "Invalid color. Your color is not bright enough.") + + H.update_body() + H.update_hair() + H.update_body_parts() + H.update_mutations_overlay() // no hulk lizard + + if("gender") + if(!(H.gender in list("male", "female"))) //blame the patriarchy + return + if(!Adjacent(user)) + return + if(H.gender == "male") + if(alert(H, "Become a Witch?", "Confirmation", "Yes", "No") == "Yes") + H.gender = "female" + to_chat(H, "Man, you feel like a woman!") + else + return + + else + if(alert(H, "Become a Warlock?", "Confirmation", "Yes", "No") == "Yes") + H.gender = "male" + to_chat(H, "Whoa man, you feel like a man!") + else + return + H.dna.update_ui_block(DNA_GENDER_BLOCK) + H.update_body() + H.update_mutations_overlay() //(hulk male/female) + + if("hair") + var/hairchoice = alert(H, "Hair style or hair color?", "Change Hair", "Style", "Color") + if(!Adjacent(user)) + return + if(hairchoice == "Style") //So you just want to use a mirror then? + ..() + else + var/new_hair_color = input(H, "Choose your hair color", "Hair Color") as null|color + if(new_hair_color) + H.hair_color = sanitize_hexcolor(new_hair_color) + H.dna.update_ui_block(DNA_HAIR_COLOR_BLOCK) + if(H.gender == "male") + var/new_face_color = input(H, "Choose your facial hair color", "Hair Color") as null|color + if(new_face_color) + H.facial_hair_color = sanitize_hexcolor(new_face_color) + H.dna.update_ui_block(DNA_FACIAL_HAIR_COLOR_BLOCK) + H.update_hair() + + if("eyes") + var/new_eye_color = input(H, "Choose your eye color", "Eye Color") as null|color + if(!Adjacent(user)) + return + if(new_eye_color) + H.eye_color = sanitize_hexcolor(new_eye_color) + H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK) + H.update_body() + if(choice) + curse(user) + +/obj/structure/mirror/magic/proc/curse(mob/living/user) + return +>>>>>>> 4178c20... Configuration datum refactor (#30763) diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index b1b00b3e55..6eec793c0e 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -66,7 +66,7 @@ return /turf/open/space/proc/update_starlight() - if(config.starlight) + if(CONFIG_GET(flag/starlight)) for(var/t in RANGE_TURFS(1,src)) //RANGE_TURFS is in code\__HELPERS\game.dm if(isspaceturf(t)) //let's NOT update this that much pls diff --git a/code/game/world.dm b/code/game/world.dm index 3763a408ac..316ed70961 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -12,7 +12,7 @@ GLOBAL_PROTECT(security_mode) make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once) - config = new + new /datum/controller/configuration CheckSchemaVersion() SetRoundID() @@ -25,7 +25,7 @@ GLOBAL_PROTECT(security_mode) load_motd() load_admins() LoadVerbs(/datum/verbs/menu) - if(config.usewhitelist) + if(CONFIG_GET(flag/usewhitelist)) load_whitelist() LoadBans() @@ -33,7 +33,7 @@ GLOBAL_PROTECT(security_mode) Master.Initialize(10, FALSE) - if(config.irc_announce_new_game) + if(CONFIG_GET(flag/irc_announce_new_game)) IRCBroadcast("New round starting on [SSmapping.config.map_name]!") /world/proc/SetupExternalRSC() @@ -48,7 +48,7 @@ GLOBAL_PROTECT(security_mode) #endif /world/proc/CheckSchemaVersion() - if(config.sql_enabled) + if(CONFIG_GET(flag/sql_enabled)) if(SSdbcore.Connect()) log_world("Database connection established.") var/datum/DBQuery/query_db_version = SSdbcore.NewQuery("SELECT major, minor FROM [format_table_name("schema_revision")] ORDER BY date DESC LIMIT 1") @@ -68,7 +68,7 @@ GLOBAL_PROTECT(security_mode) log_world("Your server failed to establish a connection with the database.") /world/proc/SetRoundID() - if(config.sql_enabled) + if(CONFIG_GET(flag/sql_enabled)) if(SSdbcore.Connect()) var/datum/DBQuery/query_round_start = SSdbcore.NewQuery("INSERT INTO [format_table_name("round")] (start_datetime, server_ip, server_port) VALUES (Now(), INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]')") query_round_start.Execute() @@ -122,12 +122,13 @@ GLOBAL_PROTECT(security_mode) var/pinging = ("ping" in input) var/playing = ("players" in input) - if(!pinging && !playing && config && config.log_world_topic) + if(!pinging && !playing && config && CONFIG_GET(flag/log_world_topic)) WRITE_FILE(GLOB.world_game_log, "TOPIC: \"[T]\", from:[addr], master:[master], key:[key]") if(input[SERVICE_CMD_PARAM_KEY]) return ServiceCommand(input) - var/key_valid = (global.comms_allowed && input["key"] == global.comms_key) + var/comms_key = CONFIG_GET(string/comms_key) + var/key_valid = (comms_key && input["key"] == comms_key) if(pinging) var/x = 1 @@ -157,10 +158,10 @@ GLOBAL_PROTECT(security_mode) var/list/s = list() s["version"] = GLOB.game_version s["mode"] = GLOB.master_mode - s["respawn"] = config ? GLOB.abandon_allowed : 0 + s["respawn"] = config ? !CONFIG_GET(flag/norespawn) : FALSE s["enter"] = GLOB.enter_allowed - s["vote"] = config.allow_vote_mode - s["ai"] = config.allow_ai + s["vote"] = CONFIG_GET(flag/allow_vote_mode) + s["ai"] = CONFIG_GET(flag/allow_ai) s["host"] = host ? host : null s["active_players"] = get_active_player_count() s["players"] = GLOB.clients.len @@ -262,17 +263,6 @@ GLOBAL_PROTECT(security_mode) GLOB.join_motd = file2text("config/motd.txt") + "
    " + GLOB.revdata.GetTestMergeInfo() /world/proc/update_status() - var/s = "" - - if (config && config.server_name) - s += "[config.server_name] — " - - s += "[station_name()]"; - s += " (" - s += "
    " //Change this to wherever you want the hub to link to. - s += "Default" //Replace this with something else. Or ever better, delete it and uncomment the game version. - s += "" - s += ")" var/list/features = list() @@ -282,13 +272,25 @@ GLOBAL_PROTECT(security_mode) if (!GLOB.enter_allowed) features += "closed" - features += GLOB.abandon_allowed ? "respawn" : "no respawn" + var/s = "" + var/hostedby + if(config) + var/server_name = CONFIG_GET(string/servername) + if (server_name) + s += "[server_name] — " + features += "[CONFIG_GET(flag/norespawn) ? "no " : ""]respawn" + if(CONFIG_GET(flag/allow_vote_mode)) + features += "vote" + if(CONFIG_GET(flag/allow_ai)) + features += "AI allowed" + hostedby = CONFIG_GET(string/hostedby) - if (config && config.allow_vote_mode) - features += "vote" - - if (config && config.allow_ai) - features += "AI allowed" + s += "[station_name()]"; + s += " (" + s += "" //Change this to wherever you want the hub to link to. + s += "Default" //Replace this with something else. Or ever better, delete it and uncomment the game version. + s += "" + s += ")" var/n = 0 for (var/mob/M in GLOB.player_list) @@ -300,8 +302,8 @@ GLOBAL_PROTECT(security_mode) else if (n > 0) features += "~[n] player" - if (!host && config && config.hostedby) - features += "hosted by [config.hostedby]" + if (!host && hostedby) + features += "hosted by [hostedby]" if (features) s += ": [jointext(features, ", ")]" diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index 39a465d2b4..10a3774ae1 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -20,7 +20,7 @@ admin = 1 //Whitelist - if(config.usewhitelist) + if(CONFIG_GET(flag/usewhitelist)) if(!check_whitelist(ckey(key))) if (admin) log_admin("The admin [key] has been allowed to bypass the whitelist") @@ -32,19 +32,20 @@ //Guest Checking if(IsGuestKey(key)) - if (!GLOB.guests_allowed) + if (CONFIG_GET(flag/guest_ban)) log_access("Failed Login: [key] - Guests not allowed") return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a byond account.") - if (config.panic_bunker && SSdbcore && SSdbcore.IsConnected()) + if (CONFIG_GET(flag/panic_bunker) && SSdbcore.Connect()) log_access("Failed Login: [key] - Guests not allowed during panic bunker") return list("reason"="guest", "desc"="\nReason: Sorry but the server is currently not accepting connections from never before seen players or guests. If you have played on this server with a byond account before, please log in to the byond account you have played from.") //Population Cap Checking - if(config.extreme_popcap && living_player_count() >= config.extreme_popcap && !admin) + var/extreme_popcap = CONFIG_GET(number/extreme_popcap) + if(extreme_popcap && living_player_count() >= extreme_popcap && !admin) log_access("Failed Login: [key] - Population cap reached") - return list("reason"="popcap", "desc"= "\nReason: [config.extreme_popcap_message]") + return list("reason"="popcap", "desc"= "\nReason: [CONFIG_GET(string/extreme_popcap_message)]") - if(config.ban_legacy_system) + if(CONFIG_GET(flag/ban_legacy_system)) //Ban Checking . = CheckBan( ckey(key), computer_id, address ) diff --git a/code/modules/admin/NewBan.dm b/code/modules/admin/NewBan.dm index 5ea980a91d..27d5502edf 100644 --- a/code/modules/admin/NewBan.dm +++ b/code/modules/admin/NewBan.dm @@ -11,8 +11,9 @@ GLOBAL_PROTECT(Banlist) . = list() var/appeal - if(config && config.banappeals) - appeal = "\nFor more information on your ban, or to appeal, head to [config.banappeals]" + var/bran = CONFIG_GET(string/banappeals) + if(bran) + appeal = "\nFor more information on your ban, or to appeal, head to [bran]" GLOB.Banlist.cd = "/base" if( "[ckey][id]" in GLOB.Banlist.dir ) GLOB.Banlist.cd = "[ckey][id]" diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index b56caa4e9a..881e59204d 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -31,7 +31,7 @@ if(M.client) body += " played by [M.client] " body += "\[[M.client.holder ? M.client.holder.rank : "Player"]\]" - if(config.use_exp_tracking) + if(CONFIG_GET(flag/use_exp_tracking)) body += "\[" + M.client.get_exp_living() + "\]" if(isnewplayer(M)) @@ -555,28 +555,30 @@ set category = "Server" set desc="People can't be AI" set name="Toggle AI" - config.allow_ai = !( config.allow_ai ) - if (!( config.allow_ai )) + var/alai = CONFIG_GET(flag/allow_ai) + CONFIG_SET(flag/allow_ai, !alai) + if (alai) to_chat(world, "The AI job is no longer chooseable.") else to_chat(world, "The AI job is chooseable now.") log_admin("[key_name(usr)] toggled AI allowed.") world.update_status() - SSblackbox.add_details("admin_toggle","Toggle AI|[config.allow_ai]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.add_details("admin_toggle","Toggle AI|[!alai]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/toggleaban() set category = "Server" set desc="Respawn basically" set name="Toggle Respawn" - GLOB.abandon_allowed = !( GLOB.abandon_allowed ) - if (GLOB.abandon_allowed) + var/new_nores = !CONFIG_GET(flag/norespawn) + CONFIG_SET(flag/norespawn, new_nores) + if (!new_nores) to_chat(world, "You may now respawn.") else to_chat(world, "You may no longer respawn :(") - message_admins("[key_name_admin(usr)] toggled respawn to [GLOB.abandon_allowed ? "On" : "Off"].") - log_admin("[key_name(usr)] toggled respawn to [GLOB.abandon_allowed ? "On" : "Off"].") + message_admins("[key_name_admin(usr)] toggled respawn to [!new_nores ? "On" : "Off"].") + log_admin("[key_name(usr)] toggled respawn to [!new_nores ? "On" : "Off"].") world.update_status() - SSblackbox.add_details("admin_toggle","Toggle Respawn|[GLOB.abandon_allowed]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.add_details("admin_toggle","Toggle Respawn|[!new_nores]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/delay() set category = "Server" @@ -683,14 +685,15 @@ set category = "Server" set desc="Guests can't enter" set name="Toggle guests" - GLOB.guests_allowed = !( GLOB.guests_allowed ) - if (!( GLOB.guests_allowed )) + var/new_guest_ban = !CONFIG_GET(flag/guest_ban) + CONFIG_SET(flag/guest_ban, new_guest_ban) + if (new_guest_ban) to_chat(world, "Guests may no longer enter the game.") else to_chat(world, "Guests may now enter the game.") - log_admin("[key_name(usr)] toggled guests game entering [GLOB.guests_allowed?"":"dis"]allowed.") - message_admins("[key_name_admin(usr)] toggled guests game entering [GLOB.guests_allowed?"":"dis"]allowed.") - SSblackbox.add_details("admin_toggle","Toggle Guests|[GLOB.guests_allowed]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + log_admin("[key_name(usr)] toggled guests game entering [!new_guest_ban ? "" : "dis"]allowed.") + message_admins("[key_name_admin(usr)] toggled guests game entering [!new_guest_ban ? "" : "dis"]allowed.") + SSblackbox.add_details("admin_toggle","Toggle Guests|[!new_guest_ban]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/output_ai_laws() var/ai_number = 0 @@ -828,10 +831,10 @@ /client/proc/adminGreet(logout) if(SSticker.HasRoundStarted()) var/string - if(logout && config && config.announce_admin_logout) + if(logout && CONFIG_GET(flag/announce_admin_logout)) string = pick( "Admin logout: [key_name(src)]") - else if(!logout && config && config.announce_admin_login && (prefs.toggles & ANNOUNCE_LOGIN)) + else if(!logout && CONFIG_GET(flag/announce_admin_login) && (prefs.toggles & ANNOUNCE_LOGIN)) string = pick( "Admin login: [key_name(src)]") if(string) diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index 828fbb2e91..343c5686f2 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -117,7 +117,7 @@ GLOBAL_PROTECT(admin_ranks) return GLOB.admin_ranks.Cut() - if(config.admin_legacy_system) + if(CONFIG_GET(flag/admin_legacy_system)) var/previous_rights = 0 //load text from file and process each line separately for(var/line in world.file2list("config/admin_ranks.txt")) @@ -143,7 +143,7 @@ GLOBAL_PROTECT(admin_ranks) if(!SSdbcore.Connect()) log_world("Failed to connect to database in load_admin_ranks(). Reverting to legacy system.") WRITE_FILE(GLOB.world_game_log, "Failed to connect to database in load_admin_ranks(). Reverting to legacy system.") - config.admin_legacy_system = 1 + CONFIG_SET(flag/admin_legacy_system, TRUE) load_admin_ranks() return @@ -191,7 +191,7 @@ GLOBAL_PROTECT(admin_ranks) for(var/datum/admin_rank/R in GLOB.admin_ranks) rank_names[R.name] = R - if(config.admin_legacy_system) + if(CONFIG_GET(flag/admin_legacy_system)) //load text from file var/list/lines = world.file2list("config/admins.txt") @@ -221,7 +221,7 @@ GLOBAL_PROTECT(admin_ranks) if(!SSdbcore.Connect()) log_world("Failed to connect to database in load_admins(). Reverting to legacy system.") WRITE_FILE(GLOB.world_game_log, "Failed to connect to database in load_admins(). Reverting to legacy system.") - config.admin_legacy_system = 1 + CONFIG_SET(flag/admin_legacy_system, TRUE) load_admins() return diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 526d05b76b..0f2702f3b6 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -262,7 +262,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( verbs += GLOB.admin_verbs_poll if(rights & R_SOUNDS) verbs += GLOB.admin_verbs_sounds - if(config.invoke_youtubedl) + if(CONFIG_GET(string/invoke_youtubedl)) verbs += /client/proc/play_web_sound if(rights & R_SPAWN) verbs += GLOB.admin_verbs_spawn @@ -399,7 +399,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( set name = "Unban Panel" set category = "Admin" if(holder) - if(config.ban_legacy_system) + if(CONFIG_GET(flag/ban_legacy_system)) holder.unbanpanel() else holder.DB_ban_panel() diff --git a/code/modules/admin/ipintel.dm b/code/modules/admin/ipintel.dm index 50f81e01c3..d048b71170 100644 --- a/code/modules/admin/ipintel.dm +++ b/code/modules/admin/ipintel.dm @@ -14,18 +14,18 @@ . = FALSE if (intel < 0) return - if (intel <= config.ipintel_rating_bad) - if (world.realtime < cacherealtime+(config.ipintel_save_good*60*60*10)) + if (intel <= CONFIG_GET(number/ipintel_rating_bad)) + if (world.realtime < cacherealtime + (CONFIG_GET(number/ipintel_save_good) * 60 * 60 * 10)) return TRUE else - if (world.realtime < cacherealtime+(config.ipintel_save_bad*60*60*10)) + if (world.realtime < cacherealtime + (CONFIG_GET(number/ipintel_save_bad) * 60 * 60 * 10)) return TRUE /proc/get_ip_intel(ip, bypasscache = FALSE, updatecache = TRUE) var/datum/ipintel/res = new() res.ip = ip . = res - if (!ip || !config.ipintel_email || !SSipintel.enabled) + if (!ip || !CONFIG_GET(string/ipintel_email) || !SSipintel.enabled) return if (!bypasscache) var/datum/ipintel/cachedintel = SSipintel.cache[ip] @@ -34,19 +34,20 @@ return cachedintel if(SSdbcore.Connect()) + var/rating_bad = CONFIG_GET(number/ipintel_rating_bad) var/datum/DBQuery/query_get_ip_intel = SSdbcore.NewQuery({" SELECT date, intel, TIMESTAMPDIFF(MINUTE,date,NOW()) FROM [format_table_name("ipintel")] WHERE ip = INET_ATON('[ip]') AND (( - intel < [config.ipintel_rating_bad] + intel < [rating_bad] AND - date + INTERVAL [config.ipintel_save_good] HOUR > NOW() + date + INTERVAL [CONFIG_GET(number/ipintel_save_good)] HOUR > NOW() ) OR ( - intel >= [config.ipintel_rating_bad] + intel >= [rating_bad] AND - date + INTERVAL [config.ipintel_save_bad] HOUR > NOW() + date + INTERVAL [CONFIG_GET(number/ipintel_save_bad)] HOUR > NOW() )) "}) if(!query_get_ip_intel.Execute()) @@ -77,7 +78,11 @@ if (!SSipintel.enabled) return +<<<<<<< HEAD var/list/http[] = world.Export("http://[config.ipintel_domain]/check.php?ip=[ip]&contact=[config.ipintel_email]&format=json&flags_1=f") +======= + var/list/http[] = world.Export("http://[CONFIG_GET(string/ipintel_domain)]/check.php?ip=[ip]&contact=[CONFIG_GET(string/ipintel_email)]&format=json&flags=f") +>>>>>>> 4178c20... Configuration datum refactor (#30763) if (http) var/status = text2num(http["STATUS"]) diff --git a/code/modules/admin/permissionverbs/permissionedit.dm b/code/modules/admin/permissionverbs/permissionedit.dm index f0f263f815..24a53eff2b 100644 --- a/code/modules/admin/permissionverbs/permissionedit.dm +++ b/code/modules/admin/permissionverbs/permissionedit.dm @@ -51,7 +51,7 @@ usr << browse(output,"window=editrights;size=900x650") /datum/admins/proc/log_admin_rank_modification(adm_ckey, new_rank) - if(config.admin_legacy_system) + if(CONFIG_GET(flag/admin_legacy_system)) return if(!usr.client) @@ -105,7 +105,7 @@ /datum/admins/proc/log_admin_permission_modification(adm_ckey, new_permission) - if(config.admin_legacy_system) + if(CONFIG_GET(flag/admin_legacy_system)) return if(!usr.client) return diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 39e07e0a9f..9e43ef92f8 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -329,14 +329,14 @@ else dat += "ETA: [(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]
    " dat += "Continuous Round Status
    " - dat += "[config.continuous[SSticker.mode.config_tag] ? "Continue if antagonists die" : "End on antagonist death"]" - if(config.continuous[SSticker.mode.config_tag]) - dat += ", [config.midround_antag[SSticker.mode.config_tag] ? "creating replacement antagonists" : "not creating new antagonists"]
    " + dat += "[CONFIG_GET(keyed_flag_list/continuous)[SSticker.mode.config_tag] ? "Continue if antagonists die" : "End on antagonist death"]" + if(CONFIG_GET(keyed_flag_list/continuous)[SSticker.mode.config_tag]) + dat += ", [CONFIG_GET(keyed_flag_list/midround_antag)[SSticker.mode.config_tag] ? "creating replacement antagonists" : "not creating new antagonists"]
    " else dat += "
    " - if(config.midround_antag[SSticker.mode.config_tag]) - dat += "Time limit: [config.midround_antag_time_check] minutes into round
    " - dat += "Living crew limit: [config.midround_antag_life_check * 100]% of crew alive
    " + if(CONFIG_GET(keyed_flag_list/midround_antag)[SSticker.mode.config_tag]) + dat += "Time limit: [CONFIG_GET(number/midround_antag_time_check)] minutes into round
    " + dat += "Living crew limit: [CONFIG_GET(number/midround_antag_life_check) * 100]% of crew alive
    " dat += "If limits past: [SSticker.mode.round_ends_with_antag_death ? "End The Round" : "Continue As Extended"]
    " dat += "End Round Now
    " dat += "[SSticker.delay_end ? "End Round Normally" : "Delay Round End"]" diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index 99f95cd6f4..9fd49ed497 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -354,16 +354,9 @@ SSblackbox.add_details("admin_secrets_fun_used","Bomb Cap") var/newBombCap = input(usr,"What would you like the new bomb cap to be. (entered as the light damage range (the 3rd number in common (1,2,3) notation)) Must be above 4)", "New Bomb Cap", GLOB.MAX_EX_LIGHT_RANGE) as num|null - if (newBombCap < 4) + if (!CONFIG_SET(number/bombcap, newBombCap)) return - GLOB.MAX_EX_DEVESTATION_RANGE = round(newBombCap/4) - GLOB.MAX_EX_HEAVY_RANGE = round(newBombCap/2) - GLOB.MAX_EX_LIGHT_RANGE = newBombCap - //I don't know why these are their own variables, but fuck it, they are. - GLOB.MAX_EX_FLASH_RANGE = newBombCap - GLOB.MAX_EX_FLAME_RANGE = newBombCap - message_admins("[key_name_admin(usr)] changed the bomb cap to [GLOB.MAX_EX_DEVESTATION_RANGE], [GLOB.MAX_EX_HEAVY_RANGE], [GLOB.MAX_EX_LIGHT_RANGE]") log_admin("[key_name(usr)] changed the bomb cap to [GLOB.MAX_EX_DEVESTATION_RANGE], [GLOB.MAX_EX_HEAVY_RANGE], [GLOB.MAX_EX_LIGHT_RANGE]") diff --git a/code/modules/admin/sql_message_system.dm b/code/modules/admin/sql_message_system.dm index 50236c548d..587bd6b26c 100644 --- a/code/modules/admin/sql_message_system.dm +++ b/code/modules/admin/sql_message_system.dm @@ -33,8 +33,9 @@ if(!timestamp) timestamp = SQLtime() if(!server) - if (config && config.server_sql_name) - server = config.server_sql_name + var/ssqlname = CONFIG_GET(string/serversqlname) + if (ssqlname) + server = ssqlname server = sanitizeSQL(server) if(isnull(secret)) switch(alert("Hide note from being viewed by players?", "Secret note?","Yes","No","Cancel")) @@ -216,8 +217,10 @@ var/editor_ckey = query_get_messages.item[8] var/age = text2num(query_get_messages.item[9]) var/alphatext = "" - if (agegate && type == "note" && isnum(config.note_stale_days) && isnum(config.note_fresh_days) && config.note_stale_days > config.note_fresh_days) - var/alpha = Clamp(100 - (age - config.note_fresh_days) * (85 / (config.note_stale_days - config.note_fresh_days)), 15, 100) + var/nsd = CONFIG_GET(number/note_stale_days) + var/nfd = CONFIG_GET(number/note_fresh_days) + if (agegate && type == "note" && isnum(nsd) && isnum(nfd) && nsd > nfd) + var/alpha = Clamp(100 - (age - nfd) * (85 / (nsd - nfd)), 15, 100) if (alpha < 100) if (alpha <= 15) if (skipped) @@ -353,8 +356,9 @@ proc/get_message_output(type, target_ckey) var/notetext notesfile >> notetext var/server - if(config && config.server_sql_name) - server = config.server_sql_name + var/ssqlname = CONFIG_GET(string/serversqlname) + if (ssqlname) + server = ssqlname var/regex/note = new("^(\\d{2}-\\w{3}-\\d{4}) \\| (.+) ~(\\w+)$", "i") note.Find(notetext) var/timestamp = note.group[1] diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 7f9f5a7d27..c182107a6a 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -5,7 +5,7 @@ return var/msg = !auth ? "no" : "a bad" message_admins("[key_name_admin(usr)] clicked an href with [msg] authorization key!") - if(config.debug_admin_hrefs) + if(CONFIG_GET(flag/debug_admin_hrefs)) message_admins("Debug mode enabled, call not blocked. Please ask your coders to review this round's logs.") log_world("UAH: [href]") return TRUE @@ -318,35 +318,36 @@ else if(href_list["toggle_continuous"]) if(!check_rights(R_ADMIN)) return - - if(!config.continuous[SSticker.mode.config_tag]) - config.continuous[SSticker.mode.config_tag] = 1 + var/list/continuous = CONFIG_GET(keyed_flag_list/continuous) + if(!continuous[SSticker.mode.config_tag]) + continuous[SSticker.mode.config_tag] = TRUE else - config.continuous[SSticker.mode.config_tag] = 0 + continuous[SSticker.mode.config_tag] = FALSE - message_admins("[key_name_admin(usr)] toggled the round to [config.continuous[SSticker.mode.config_tag] ? "continue if all antagonists die" : "end with the antagonists"].") + message_admins("[key_name_admin(usr)] toggled the round to [continuous[SSticker.mode.config_tag] ? "continue if all antagonists die" : "end with the antagonists"].") check_antagonists() else if(href_list["toggle_midround_antag"]) if(!check_rights(R_ADMIN)) return - if(!config.midround_antag[SSticker.mode.config_tag]) - config.midround_antag[SSticker.mode.config_tag] = 1 + var/list/midround_antag = CONFIG_GET(keyed_flag_list/midround_antag) + if(!midround_antag[SSticker.mode.config_tag]) + midround_antag[SSticker.mode.config_tag] = TRUE else - config.midround_antag[SSticker.mode.config_tag] = 0 + midround_antag[SSticker.mode.config_tag] = FALSE - message_admins("[key_name_admin(usr)] toggled the round to [config.midround_antag[SSticker.mode.config_tag] ? "use" : "skip"] the midround antag system.") + message_admins("[key_name_admin(usr)] toggled the round to [midround_antag[SSticker.mode.config_tag] ? "use" : "skip"] the midround antag system.") check_antagonists() else if(href_list["alter_midround_time_limit"]) if(!check_rights(R_ADMIN)) return - var/timer = input("Enter new maximum time",, config.midround_antag_time_check ) as num|null + var/timer = input("Enter new maximum time",, CONFIG_GET(number/midround_antag_time_check)) as num|null if(!timer) return - config.midround_antag_time_check = timer + CONFIG_SET(number/midround_antag_time_check, timer) message_admins("[key_name_admin(usr)] edited the maximum midround antagonist time to [timer] minutes.") check_antagonists() @@ -354,9 +355,10 @@ if(!check_rights(R_ADMIN)) return - var/ratio = input("Enter new life ratio",, config.midround_antag_life_check*100) as num - if(ratio) - config.midround_antag_life_check = ratio/100 + var/ratio = input("Enter new life ratio",, CONFIG_GET(number/midround_antag_life_check) * 100) as num + if(!ratio) + return + CONFIG_SET(number/midround_antag_life_check, ratio / 100) message_admins("[key_name_admin(usr)] edited the midround antagonist living crew ratio to [ratio]% alive.") check_antagonists() @@ -586,8 +588,9 @@ to_chat(M, "You have been appearance banned by [usr.client.ckey].") to_chat(M, "The reason is: [reason]") to_chat(M, "Appearance ban can be lifted only upon request.") - if(config.banappeals) - to_chat(M, "To try to resolve this matter head to [config.banappeals]") + var/bran = CONFIG_GET(string/banappeals) + if(bran) + to_chat(M, "To try to resolve this matter head to [bran]") else to_chat(M, "No ban appeals URL has been set.") if("No") @@ -1156,8 +1159,9 @@ to_chat(M, "This is a temporary ban, it will be removed in [mins] minutes.") SSblackbox.inc("ban_tmp",1) SSblackbox.inc("ban_tmp_mins",mins) - if(config.banappeals) - to_chat(M, "To try to resolve this matter head to [config.banappeals]") + var/bran = CONFIG_GET(string/banappeals) + if(bran) + to_chat(M, "To try to resolve this matter head to [bran]") else to_chat(M, "No ban appeals URL has been set.") log_admin_private("[key_name(usr)] has banned [M.ckey].\nReason: [key_name(M)]\nThis will be removed in [mins] minutes.") @@ -1180,8 +1184,9 @@ AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0) to_chat(M, "You have been banned by [usr.client.ckey].\nReason: [reason]") to_chat(M, "This is a permanent ban.") - if(config.banappeals) - to_chat(M, "To try to resolve this matter head to [config.banappeals]") + var/bran = CONFIG_GET(string/banappeals) + if(bran) + to_chat(M, "To try to resolve this matter head to [bran]") else to_chat(M, "No ban appeals URL has been set.") if(!DB_ban_record(BANTYPE_PERMA, M, -1, reason)) diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 7922a89c80..a61de11c30 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -589,19 +589,20 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) /proc/send2irc(msg,msg2) if(world.RunningService()) world.ExportService("[SERVICE_REQUEST_IRC_ADMIN_CHANNEL_MESSAGE] [msg] | [msg2]") - else if(config.useircbot) + else if(CONFIG_GET(flag/useircbot)) shell("python nudge.py [msg] [msg2]") /proc/send2otherserver(source,msg,type = "Ahelp") - if(config.cross_allowed) + var/comms_key = CONFIG_GET(string/comms_key) + if(comms_key) var/list/message = list() message["message_sender"] = source message["message"] = msg - message["source"] = "([config.cross_name])" - message["key"] = global.comms_key + message["source"] = "([CONFIG_GET(string/cross_comms_name)])" + message["key"] = comms_key message["crossmessage"] = type - world.Export("[config.cross_address]?[list2params(message)]") + world.Export("[CONFIG_GET(string/cross_server_address)]?[list2params(message)]") /proc/ircadminwho() diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index db29021463..038e454a24 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -185,7 +185,7 @@ SEND_SOUND(recipient, sound('sound/effects/adminhelp.ogg')) //AdminPM popup for ApocStation and anybody else who wants to use it. Set it with POPUP_ADMIN_PM in config.txt ~Carn - if(config.popup_admin_pm) + if(CONFIG_GET(flag/popup_admin_pm)) spawn() //so we don't hold the caller proc up var/sender = src var/sendername = key @@ -277,7 +277,7 @@ return "Error: Ticket could not be found" var/static/stealthkey - var/adminname = config.showircname ? irc_tagged : "Administrator" + var/adminname = CONFIG_GET(flag/show_irc_name) ? irc_tagged : "Administrator" if(!C) return "Error: No client" diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index f8131ec5c7..ba42dbb9ba 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -836,11 +836,11 @@ GLOBAL_PROTECT(AdminProcCallCount) if(!holder) return - global.medals_enabled = !global.medals_enabled + GLOB.medals_enabled = !GLOB.medals_enabled - message_admins("[key_name_admin(src)] [global.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.") + message_admins("[key_name_admin(src)] [GLOB.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.") SSblackbox.add_details("admin_verb","Toggle Medal Disable") // If... - log_admin("[key_name(src)] [global.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.") + log_admin("[key_name(src)] [GLOB.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.") /client/proc/view_runtimes() set category = "Debug" diff --git a/code/modules/admin/verbs/fps.dm b/code/modules/admin/verbs/fps.dm index bedcd0a6e5..f893c43e08 100644 --- a/code/modules/admin/verbs/fps.dm +++ b/code/modules/admin/verbs/fps.dm @@ -7,13 +7,14 @@ if(!check_rights(R_DEBUG)) return - var/new_fps = round(input("Sets game frames-per-second. Can potentially break the game (default: [config.fps])","FPS", world.fps) as num|null) + var/cfg_fps = CONFIG_GET(number/fps) + var/new_fps = round(input("Sets game frames-per-second. Can potentially break the game (default: [cfg_fps])","FPS", world.fps) as num|null) if(new_fps <= 0) to_chat(src, "Error: set_server_fps(): Invalid world.fps value. No changes made.") return - if(new_fps > config.fps*1.5) - if(alert(src, "You are setting fps to a high value:\n\t[new_fps] frames-per-second\n\tconfig.fps = [config.fps]","Warning!","Confirm","ABORT-ABORT-ABORT") != "Confirm") + if(new_fps > cfg_fps * 1.5) + if(alert(src, "You are setting fps to a high value:\n\t[new_fps] frames-per-second\n\tconfig.fps = [cfg_fps]","Warning!","Confirm","ABORT-ABORT-ABORT") != "Confirm") return var/msg = "[key_name(src)] has modified world.fps to [new_fps]" @@ -21,4 +22,5 @@ message_admins(msg, 0) SSblackbox.add_details("admin_toggle","Set Server FPS|[new_fps]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + CONFIG_SET(number/fps, new_fps) world.fps = new_fps diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index e8ba7c8bab..d14fb1f167 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -31,10 +31,10 @@ /datum/admins/proc/makeTraitors() var/datum/game_mode/traitor/temp = new - if(config.protect_roles_from_antagonist) + if(CONFIG_GET(flag/protect_roles_from_antagonist)) temp.restricted_jobs += temp.protected_jobs - if(config.protect_assistant_from_antagonist) + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) temp.restricted_jobs += "Assistant" var/list/mob/living/carbon/human/candidates = list() @@ -67,10 +67,10 @@ /datum/admins/proc/makeChanglings() var/datum/game_mode/changeling/temp = new - if(config.protect_roles_from_antagonist) + if(CONFIG_GET(flag/protect_roles_from_antagonist)) temp.restricted_jobs += temp.protected_jobs - if(config.protect_assistant_from_antagonist) + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) temp.restricted_jobs += "Assistant" var/list/mob/living/carbon/human/candidates = list() @@ -100,10 +100,10 @@ /datum/admins/proc/makeRevs() var/datum/game_mode/revolution/temp = new - if(config.protect_roles_from_antagonist) + if(CONFIG_GET(flag/protect_roles_from_antagonist)) temp.restricted_jobs += temp.protected_jobs - if(config.protect_assistant_from_antagonist) + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) temp.restricted_jobs += "Assistant" var/list/mob/living/carbon/human/candidates = list() @@ -142,10 +142,10 @@ /datum/admins/proc/makeCult() var/datum/game_mode/cult/temp = new - if(config.protect_roles_from_antagonist) + if(CONFIG_GET(flag/protect_roles_from_antagonist)) temp.restricted_jobs += temp.protected_jobs - if(config.protect_assistant_from_antagonist) + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) temp.restricted_jobs += "Assistant" var/list/mob/living/carbon/human/candidates = list() @@ -175,10 +175,10 @@ /datum/admins/proc/makeClockCult() var/datum/game_mode/clockwork_cult/temp = new - if(config.protect_roles_from_antagonist) + if(CONFIG_GET(flag/protect_roles_from_antagonist)) temp.restricted_jobs += temp.protected_jobs - if(config.protect_assistant_from_antagonist) + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) temp.restricted_jobs += "Assistant" var/list/mob/living/carbon/human/candidates = list() @@ -340,7 +340,7 @@ missiondesc += "
    Your Mission: [mission]" to_chat(Commando, missiondesc) - if(config.enforce_human_authority) + if(CONFIG_GET(flag/enforce_human_authority)) Commando.set_species(/datum/species/human) //Logging and cleanup @@ -382,7 +382,7 @@ missionobj.completed = 1 newmob.mind.objectives += missionobj - if(config.enforce_human_authority) + if(CONFIG_GET(flag/enforce_human_authority)) newmob.set_species(/datum/species/human) //Greet the official @@ -497,7 +497,7 @@ missiondesc += "
    Your Mission: [mission]" to_chat(ERTOperative, missiondesc) - if(config.enforce_human_authority) + if(CONFIG_GET(flag/enforce_human_authority)) ERTOperative.set_species(/datum/species/human) //Logging and cleanup diff --git a/code/modules/admin/verbs/panicbunker.dm b/code/modules/admin/verbs/panicbunker.dm index 3da486be78..b159445963 100644 --- a/code/modules/admin/verbs/panicbunker.dm +++ b/code/modules/admin/verbs/panicbunker.dm @@ -1,15 +1,16 @@ /client/proc/panicbunker() set category = "Server" set name = "Toggle Panic Bunker" - if (!config.sql_enabled) + if (!CONFIG_GET(flag/sql_enabled)) to_chat(usr, "The Database is not enabled!") return - config.panic_bunker = (!config.panic_bunker) + var/new_pb = !CONFIG_GET(flag/panic_bunker) + CONFIG_SET(flag/panic_bunker, new_pb) - log_admin("[key_name(usr)] has toggled the Panic Bunker, it is now [(config.panic_bunker?"on":"off")]") - message_admins("[key_name_admin(usr)] has toggled the Panic Bunker, it is now [(config.panic_bunker?"enabled":"disabled")].") - if (config.panic_bunker && (!SSdbcore || !SSdbcore.IsConnected())) + log_admin("[key_name(usr)] has toggled the Panic Bunker, it is now [new_pb ? "on" : "off"]") + message_admins("[key_name_admin(usr)] has toggled the Panic Bunker, it is now [new_pb ? "enabled" : "disabled"].") + if (new_pb && !SSdbcore.Connect()) message_admins("The Database is not connected! Panic bunker will not work until the connection is reestablished.") - SSblackbox.add_details("admin_toggle","Toggle Panic Bunker|[config.panic_bunker]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.add_details("admin_toggle","Toggle Panic Bunker|[new_pb]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm index 61df0cb8d1..d63d0d712f 100644 --- a/code/modules/admin/verbs/playsound.dm +++ b/code/modules/admin/verbs/playsound.dm @@ -62,7 +62,8 @@ if(!check_rights(R_SOUNDS)) return - if(!config.invoke_youtubedl) + var/ytdl = CONFIG_GET(string/invoke_youtubedl) + if(!ytdl) to_chat(src, "Youtube-dl was not configured, action unavailable") //Check config.txt for the INVOKE_YOUTUBEDL value return @@ -79,7 +80,7 @@ to_chat(src, "For youtube-dl shortcuts like ytsearch: please use the appropriate full url from the website.") return var/shell_scrubbed_input = shell_url_scrub(web_sound_input) - var/list/output = world.shelleo("[config.invoke_youtubedl] --format \"bestaudio\[ext=mp3]/best\[ext=mp4]\[height<=360]/bestaudio\[ext=m4a]/bestaudio\[ext=aac]\" --get-url \"[shell_scrubbed_input]\"") + var/list/output = world.shelleo("[ytdl] --format \"bestaudio\[ext=mp3]/best\[ext=mp4]\[height<=360]/bestaudio\[ext=m4a]/bestaudio\[ext=aac]\" --get-url \"[shell_scrubbed_input]\"") var/errorlevel = output[SHELLEO_ERRORLEVEL] var/stdout = output[SHELLEO_STDOUT] var/stderr = output[SHELLEO_STDERR] diff --git a/code/modules/admin/verbs/possess.dm b/code/modules/admin/verbs/possess.dm index e271cdb3a7..483c9470a2 100644 --- a/code/modules/admin/verbs/possess.dm +++ b/code/modules/admin/verbs/possess.dm @@ -2,7 +2,7 @@ set name = "Possess Obj" set category = "Object" - if(O.dangerous_possession && config.forbid_singulo_possession) + if(O.dangerous_possession && CONFIG_GET(flag/forbid_singulo_possession)) to_chat(usr, "[O] is too powerful for you to possess.") return diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 975e8aa731..c30308223f 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /client/proc/cmd_admin_drop_everything(mob/M in GLOB.mob_list) set category = null set name = "Drop Everything" @@ -1256,4 +1257,1265 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits to_chat(usr, "ERROR: Unable to update player flags. Please check logs.") else message_admins("[key_name_admin(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name_admin(C)]") +======= +/client/proc/cmd_admin_drop_everything(mob/M in GLOB.mob_list) + set category = null + set name = "Drop Everything" + if(!holder) + to_chat(src, "Only administrators may use this command.") + return + + var/confirm = alert(src, "Make [M] drop everything?", "Message", "Yes", "No") + if(confirm != "Yes") + return + + for(var/obj/item/W in M) + if(!M.dropItemToGround(W)) + qdel(W) + M.regenerate_icons() + + log_admin("[key_name(usr)] made [key_name(M)] drop everything!") + var/msg = "[key_name_admin(usr)] made [key_name_admin(M)] drop everything!" + message_admins(msg) + admin_ticket_log(M, msg) + SSblackbox.add_details("admin_verb","Drop Everything") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/cmd_admin_subtle_message(mob/M in GLOB.mob_list) + set category = "Special Verbs" + set name = "Subtle Message" + + if(!ismob(M)) + return + if (!holder) + to_chat(src, "Only administrators may use this command.") + return + + message_admins("[key_name_admin(src)] has started answering [key_name(M.key, 0, 0)]'s prayer.") + var/msg = input("Message:", text("Subtle PM to [M.key]")) as text + + if (!msg) + message_admins("[key_name_admin(src)] decided not to answer [key_name(M.key, 0, 0)]'s prayer") + return + if(usr) + if (usr.client) + if(usr.client.holder) + to_chat(M, "You hear a voice in your head... [msg]") + + log_admin("SubtlePM: [key_name(usr)] -> [key_name(M)] : [msg]") + msg = " SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg]" + message_admins(msg) + admin_ticket_log(M, msg) + SSblackbox.add_details("admin_verb","Subtle Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/cmd_admin_world_narrate() + set category = "Special Verbs" + set name = "Global Narrate" + + if (!holder) + to_chat(src, "Only administrators may use this command.") + return + + var/msg = input("Message:", text("Enter the text you wish to appear to everyone:")) as text + + if (!msg) + return + to_chat(world, "[msg]") + log_admin("GlobalNarrate: [key_name(usr)] : [msg]") + message_admins("[key_name_admin(usr)] Sent a global narrate") + SSblackbox.add_details("admin_verb","Global Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/cmd_admin_direct_narrate(mob/M) + set category = "Special Verbs" + set name = "Direct Narrate" + + if(!holder) + to_chat(src, "Only administrators may use this command.") + return + + if(!M) + M = input("Direct narrate to whom?", "Active Players") as null|anything in GLOB.player_list + + if(!M) + return + + var/msg = input("Message:", text("Enter the text you wish to appear to your target:")) as text + + if( !msg ) + return + + to_chat(M, msg) + log_admin("DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg]") + msg = " DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg]
    " + message_admins(msg) + admin_ticket_log(M, msg) + SSblackbox.add_details("admin_verb","Direct Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/cmd_admin_local_narrate(atom/A) + set category = "Special Verbs" + set name = "Local Narrate" + + if (!holder) + to_chat(src, "Only administrators may use this command.") + return + if(!A) + return + var/range = input("Range:", "Narrate to mobs within how many tiles:", 7) as num + if(!range) + return + var/msg = input("Message:", text("Enter the text you wish to appear to everyone within view:")) as text + if (!msg) + return + for(var/mob/M in view(range,A)) + to_chat(M, msg) + + log_admin("LocalNarrate: [key_name(usr)] at [get_area(A)][COORD(A)]: [msg]") + message_admins(" LocalNarrate: [key_name_admin(usr)] at [get_area(A)][ADMIN_JMP(A)]: [msg]
    ") + SSblackbox.add_details("admin_verb","Local Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/cmd_admin_godmode(mob/M in GLOB.mob_list) + set category = "Special Verbs" + set name = "Godmode" + if(!holder) + to_chat(src, "Only administrators may use this command.") + return + M.status_flags ^= GODMODE + to_chat(usr, "Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"]") + + log_admin("[key_name(usr)] has toggled [key_name(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]") + var/msg = "[key_name_admin(usr)] has toggled [key_name_admin(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]" + message_admins(msg) + admin_ticket_log(M, msg) + SSblackbox.add_details("admin_toggle","Godmode|[M.status_flags & GODMODE]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + + +/proc/cmd_admin_mute(whom, mute_type, automute = 0) + if(!whom) + return + + var/muteunmute + var/mute_string + var/feedback_string + switch(mute_type) + if(MUTE_IC) + mute_string = "IC (say and emote)" + feedback_string = "IC" + if(MUTE_OOC) + mute_string = "OOC" + feedback_string = "OOC" + if(MUTE_PRAY) + mute_string = "pray" + feedback_string = "Pray" + if(MUTE_ADMINHELP) + mute_string = "adminhelp, admin PM and ASAY" + feedback_string = "Adminhelp" + if(MUTE_DEADCHAT) + mute_string = "deadchat and DSAY" + feedback_string = "Deadchat" + if(MUTE_ALL) + mute_string = "everything" + feedback_string = "Everything" + else + return + + var/client/C + if(istype(whom, /client)) + C = whom + else if(istext(whom)) + C = GLOB.directory[whom] + else + return + + var/datum/preferences/P + if(C) + P = C.prefs + else + P = GLOB.preferences_datums[whom] + if(!P) + return + + if(automute) + if(!CONFIG_GET(flag/automute_on)) + return + else + if(!check_rights()) + return + + if(automute) + muteunmute = "auto-muted" + P.muted |= mute_type + log_admin("SPAM AUTOMUTE: [muteunmute] [key_name(whom)] from [mute_string]") + message_admins("SPAM AUTOMUTE: [muteunmute] [key_name_admin(whom)] from [mute_string].") + if(C) + to_chat(C, "You have been [muteunmute] from [mute_string] by the SPAM AUTOMUTE system. Contact an admin.") + SSblackbox.add_details("admin_toggle","Auto Mute [feedback_string]|1") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + return + + if(P.muted & mute_type) + muteunmute = "unmuted" + P.muted &= ~mute_type + else + muteunmute = "muted" + P.muted |= mute_type + + log_admin("[key_name(usr)] has [muteunmute] [key_name(whom)] from [mute_string]") + message_admins("[key_name_admin(usr)] has [muteunmute] [key_name_admin(whom)] from [mute_string].") + if(C) + to_chat(C, "You have been [muteunmute] from [mute_string] by [key_name(usr, include_name = FALSE)].") + SSblackbox.add_details("admin_toggle","Mute [feedback_string]|[P.muted & mute_type]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + + +//I use this proc for respawn character too. /N +/proc/create_xeno(ckey) + if(!ckey) + var/list/candidates = list() + for(var/mob/M in GLOB.player_list) + if(M.stat != DEAD) + continue //we are not dead! + if(!(ROLE_ALIEN in M.client.prefs.be_special)) + continue //we don't want to be an alium + if(M.client.is_afk()) + continue //we are afk + if(M.mind && M.mind.current && M.mind.current.stat != DEAD) + continue //we have a live body we are tied to + candidates += M.ckey + if(candidates.len) + ckey = input("Pick the player you want to respawn as a xeno.", "Suitable Candidates") as null|anything in candidates + else + to_chat(usr, "Error: create_xeno(): no suitable candidates.") + if(!istext(ckey)) + return 0 + + var/alien_caste = input(usr, "Please choose which caste to spawn.","Pick a caste",null) as null|anything in list("Queen","Praetorian","Hunter","Sentinel","Drone","Larva") + var/obj/effect/landmark/spawn_here = GLOB.xeno_spawn.len ? pick(GLOB.xeno_spawn) : null + var/mob/living/carbon/alien/new_xeno + switch(alien_caste) + if("Queen") + new_xeno = new /mob/living/carbon/alien/humanoid/royal/queen(spawn_here) + if("Praetorian") + new_xeno = new /mob/living/carbon/alien/humanoid/royal/praetorian(spawn_here) + if("Hunter") + new_xeno = new /mob/living/carbon/alien/humanoid/hunter(spawn_here) + if("Sentinel") + new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(spawn_here) + if("Drone") + new_xeno = new /mob/living/carbon/alien/humanoid/drone(spawn_here) + if("Larva") + new_xeno = new /mob/living/carbon/alien/larva(spawn_here) + else + return 0 + if(!spawn_here) + SSjob.SendToLateJoin(new_xeno, FALSE) + + new_xeno.ckey = ckey + var/msg = "[key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste]." + message_admins(msg) + admin_ticket_log(new_xeno, msg) + return 1 + +/* +If a guy was gibbed and you want to revive him, this is a good way to do so. +Works kind of like entering the game with a new character. Character receives a new mind if they didn't have one. +Traitors and the like can also be revived with the previous role mostly intact. +/N */ +/client/proc/respawn_character() + set category = "Special Verbs" + set name = "Respawn Character" + set desc = "Respawn a person that has been gibbed/dusted/killed. They must be a ghost for this to work and preferably should not have a body to go back into." + if(!holder) + to_chat(src, "Only administrators may use this command.") + return + var/input = ckey(input(src, "Please specify which key will be respawned.", "Key", "")) + if(!input) + return + + var/mob/dead/observer/G_found + for(var/mob/dead/observer/G in GLOB.player_list) + if(G.ckey == input) + G_found = G + break + + if(!G_found)//If a ghost was not found. + to_chat(usr, "There is no active key like that in the game or the person is not currently a ghost.") + return + + if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something + //Check if they were an alien + if(G_found.mind.assigned_role=="Alien") + if(alert("This character appears to have been an alien. Would you like to respawn them as such?",,"Yes","No")=="Yes") + var/turf/T + if(GLOB.xeno_spawn.len) + T = pick(GLOB.xeno_spawn) + + var/mob/living/carbon/alien/new_xeno + switch(G_found.mind.special_role)//If they have a mind, we can determine which caste they were. + if("Hunter") + new_xeno = new /mob/living/carbon/alien/humanoid/hunter(T) + if("Sentinel") + new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(T) + if("Drone") + new_xeno = new /mob/living/carbon/alien/humanoid/drone(T) + if("Praetorian") + new_xeno = new /mob/living/carbon/alien/humanoid/royal/praetorian(T) + if("Queen") + new_xeno = new /mob/living/carbon/alien/humanoid/royal/queen(T) + else//If we don't know what special role they have, for whatever reason, or they're a larva. + create_xeno(G_found.ckey) + return + + if(!T) + SSjob.SendToLateJoin(new_xeno, FALSE) + + //Now to give them their mind back. + G_found.mind.transfer_to(new_xeno) //be careful when doing stuff like this! I've already checked the mind isn't in use + new_xeno.key = G_found.key + to_chat(new_xeno, "You have been fully respawned. Enjoy the game.") + var/msg = "[key_name_admin(usr)] has respawned [new_xeno.key] as a filthy xeno." + message_admins(msg) + admin_ticket_log(new_xeno, msg) + return //all done. The ghost is auto-deleted + + //check if they were a monkey + else if(findtext(G_found.real_name,"monkey")) + if(alert("This character appears to have been a monkey. Would you like to respawn them as such?",,"Yes","No")=="Yes") + var/mob/living/carbon/monkey/new_monkey = new + SSjob.SendToLateJoin(new_monkey) + G_found.mind.transfer_to(new_monkey) //be careful when doing stuff like this! I've already checked the mind isn't in use + new_monkey.key = G_found.key + to_chat(new_monkey, "You have been fully respawned. Enjoy the game.") + var/msg = "[key_name_admin(usr)] has respawned [new_monkey.key] as a filthy xeno." + message_admins(msg) + admin_ticket_log(new_monkey, msg) + return //all done. The ghost is auto-deleted + + + //Ok, it's not a xeno or a monkey. So, spawn a human. + var/mob/living/carbon/human/new_character = new//The mob being spawned. + SSjob.SendToLateJoin(new_character) + + var/datum/data/record/record_found //Referenced to later to either randomize or not randomize the character. + if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something + /*Try and locate a record for the person being respawned through GLOB.data_core. + This isn't an exact science but it does the trick more often than not.*/ + var/id = md5("[G_found.real_name][G_found.mind.assigned_role]") + + record_found = find_record("id", id, GLOB.data_core.locked) + + if(record_found)//If they have a record we can determine a few things. + new_character.real_name = record_found.fields["name"] + new_character.gender = record_found.fields["sex"] + new_character.age = record_found.fields["age"] + new_character.hardset_dna(record_found.fields["identity"], record_found.fields["enzymes"], record_found.fields["name"], record_found.fields["blood_type"], record_found.fields["species"], record_found.fields["features"]) + else + var/datum/preferences/A = new() + A.copy_to(new_character) + A.real_name = G_found.real_name + new_character.dna.update_dna_identity() + + new_character.name = new_character.real_name + + if(G_found.mind && !G_found.mind.active) + G_found.mind.transfer_to(new_character) //be careful when doing stuff like this! I've already checked the mind isn't in use + else + new_character.mind_initialize() + if(!new_character.mind.assigned_role) + new_character.mind.assigned_role = "Assistant"//If they somehow got a null assigned role. + + new_character.key = G_found.key + + /* + The code below functions with the assumption that the mob is already a traitor if they have a special role. + So all it does is re-equip the mob with powers and/or items. Or not, if they have no special role. + If they don't have a mind, they obviously don't have a special role. + */ + + //Two variables to properly announce later on. + var/admin = key_name_admin(src) + var/player_key = G_found.key + + //Now for special roles and equipment. + var/datum/antagonist/traitor/traitordatum = new_character.mind.has_antag_datum(ANTAG_DATUM_TRAITOR) + if(traitordatum) + SSjob.EquipRank(new_character, new_character.mind.assigned_role, 1) + traitordatum.equip() + + + switch(new_character.mind.special_role) + if("Wizard") + new_character.loc = pick(GLOB.wizardstart) + //SSticker.mode.learn_basic_spells(new_character) + SSticker.mode.equip_wizard(new_character) + if("Syndicate") + var/obj/effect/landmark/synd_spawn = locate("landmark*Syndicate-Spawn") + if(synd_spawn) + new_character.loc = get_turf(synd_spawn) + call(/datum/game_mode/proc/equip_syndicate)(new_character) + if("Space Ninja") + var/list/ninja_spawn = list() + for(var/obj/effect/landmark/L in GLOB.landmarks_list) + if(L.name=="carpspawn") + ninja_spawn += L + var/datum/antagonist/ninja/ninjadatum = new_character.mind.has_antag_datum(ANTAG_DATUM_NINJA) + ninjadatum.equip_space_ninja() + if(ninja_spawn.len) + var/obj/effect/landmark/ninja_spawn_here = pick(ninja_spawn) + new_character.loc = ninja_spawn_here.loc + + else//They may also be a cyborg or AI. + switch(new_character.mind.assigned_role) + if("Cyborg")//More rigging to make em' work and check if they're traitor. + new_character = new_character.Robotize() + if("AI") + new_character = new_character.AIize() + else + SSjob.EquipRank(new_character, new_character.mind.assigned_role, 1)//Or we simply equip them. + + //Announces the character on all the systems, based on the record. + if(!issilicon(new_character))//If they are not a cyborg/AI. + if(!record_found&&new_character.mind.assigned_role!=new_character.mind.special_role)//If there are no records for them. If they have a record, this info is already in there. MODE people are not announced anyway. + //Power to the user! + if(alert(new_character,"Warning: No data core entry detected. Would you like to announce the arrival of this character by adding them to various databases, such as medical records?",,"No","Yes")=="Yes") + GLOB.data_core.manifest_inject(new_character) + + if(alert(new_character,"Would you like an active AI to announce this character?",,"No","Yes")=="Yes") + AnnounceArrival(new_character, new_character.mind.assigned_role) + + var/msg = "[admin] has respawned [player_key] as [new_character.real_name]." + message_admins(msg) + admin_ticket_log(new_character, msg) + + to_chat(new_character, "You have been fully respawned. Enjoy the game.") + + SSblackbox.add_details("admin_verb","Respawn Character") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + return new_character + +/client/proc/cmd_admin_add_freeform_ai_law() + set category = "Fun" + set name = "Add Custom AI law" + if(!holder) + to_chat(src, "Only administrators may use this command.") + return + var/input = input(usr, "Please enter anything you want the AI to do. Anything. Serious.", "What?", "") as text|null + if(!input) + return + + log_admin("Admin [key_name(usr)] has added a new AI law - [input]") + message_admins("Admin [key_name_admin(usr)] has added a new AI law - [input]") + + var/show_log = alert(src, "Show ion message?", "Message", "Yes", "No") + var/announce_ion_laws = (show_log == "Yes" ? 1 : -1) + + var/datum/round_event/ion_storm/add_law_only/ion = new() + ion.announceEvent = announce_ion_laws + ion.ionMessage = input + + SSblackbox.add_details("admin_verb","Add Custom AI Law") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/cmd_admin_rejuvenate(mob/living/M in GLOB.mob_list) + set category = "Special Verbs" + set name = "Rejuvenate" + if(!holder) + to_chat(src, "Only administrators may use this command.") + return + if(!mob) + return + if(!istype(M)) + alert("Cannot revive a ghost") + return + M.revive(full_heal = 1, admin_revive = 1) + + log_admin("[key_name(usr)] healed / revived [key_name(M)]") + var/msg = "Admin [key_name_admin(usr)] healed / revived [key_name_admin(M)]!" + message_admins(msg) + admin_ticket_log(M, msg) + SSblackbox.add_details("admin_verb","Rejuvinate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/cmd_admin_create_centcom_report() + set category = "Special Verbs" + set name = "Create Command Report" + if(!holder) + to_chat(src, "Only administrators may use this command.") + return + var/input = input(usr, "Please enter anything you want. Anything. Serious.", "What?", "") as message|null + if(!input) + return + + var/confirm = alert(src, "Do you want to announce the contents of the report to the crew?", "Announce", "Yes", "No", "Cancel") + var/announce_command_report = TRUE + switch(confirm) + if("Yes") + priority_announce(input, null, 'sound/ai/commandreport.ogg') + announce_command_report = FALSE + if("Cancel") + return + + print_command_report(input, "[announce_command_report ? "Classified " : ""][command_name()] Update", announce_command_report) + + log_admin("[key_name(src)] has created a command report: [input]") + message_admins("[key_name_admin(src)] has created a command report") + SSblackbox.add_details("admin_verb","Create Command Report") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/cmd_change_command_name() + set category = "Special Verbs" + set name = "Change Command Name" + if(!holder) + to_chat(src, "Only administrators may use this command.") + return + var/input = input(usr, "Please input a new name for Central Command.", "What?", "") as text|null + if(!input) + return + change_command_name(input) + message_admins("[key_name_admin(src)] has changed Central Command's name to [input]") + log_admin("[key_name(src)] has changed the Central Command name to: [input]") + +/client/proc/cmd_admin_delete(atom/A as obj|mob|turf in world) + set category = "Admin" + set name = "Delete" + + if (!holder) + to_chat(src, "Only administrators may use this command.") + return + + admin_delete(A) + +/client/proc/admin_delete(datum/D) + var/atom/A = D + var/coords = istype(A) ? " at ([A.x], [A.y], [A.z])" : "" + if (alert(src, "Are you sure you want to delete:\n[D]\nat[coords]?", "Confirmation", "Yes", "No") == "Yes") + log_admin("[key_name(usr)] deleted [D][coords]") + message_admins("[key_name_admin(usr)] deleted [D][coords]") + SSblackbox.add_details("admin_verb","Delete") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + if(isturf(D)) + var/turf/T = D + T.ChangeTurf(T.baseturf) + else + qdel(D) + +/client/proc/cmd_admin_list_open_jobs() + set category = "Admin" + set name = "Manage Job Slots" + + if (!holder) + to_chat(src, "Only administrators may use this command.") + return + holder.manage_free_slots() + SSblackbox.add_details("admin_verb","Manage Job Slots") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in world) + set category = "Special Verbs" + set name = "Explosion" + + if (!holder) + to_chat(src, "Only administrators may use this command.") + return + + var/devastation = input("Range of total devastation. -1 to none", text("Input")) as num|null + if(devastation == null) return + var/heavy = input("Range of heavy impact. -1 to none", text("Input")) as num|null + if(heavy == null) return + var/light = input("Range of light impact. -1 to none", text("Input")) as num|null + if(light == null) return + var/flash = input("Range of flash. -1 to none", text("Input")) as num|null + if(flash == null) return + var/flames = input("Range of flames. -1 to none", text("Input")) as num|null + if(flames == null) return + + if ((devastation != -1) || (heavy != -1) || (light != -1) || (flash != -1) || (flames != -1)) + if ((devastation > 20) || (heavy > 20) || (light > 20) || (flames > 20)) + if (alert(src, "Are you sure you want to do this? It will laaag.", "Confirmation", "Yes", "No") == "No") + return + + explosion(O, devastation, heavy, light, flash, null, null,flames) + log_admin("[key_name(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])") + message_admins("[key_name_admin(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])") + SSblackbox.add_details("admin_verb","Explosion") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + return + else + return + +/client/proc/cmd_admin_emp(atom/O as obj|mob|turf in world) + set category = "Special Verbs" + set name = "EM Pulse" + + if (!holder) + to_chat(src, "Only administrators may use this command.") + return + + var/heavy = input("Range of heavy pulse.", text("Input")) as num|null + if(heavy == null) return + var/light = input("Range of light pulse.", text("Input")) as num|null + if(light == null) return + + if (heavy || light) + + empulse(O, heavy, light) + log_admin("[key_name(usr)] created an EM Pulse ([heavy],[light]) at ([O.x],[O.y],[O.z])") + message_admins("[key_name_admin(usr)] created an EM Pulse ([heavy],[light]) at ([O.x],[O.y],[O.z])") + SSblackbox.add_details("admin_verb","EM Pulse") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + + return + else + return + +/client/proc/cmd_admin_gib(mob/M in GLOB.mob_list) + set category = "Special Verbs" + set name = "Gib" + + if (!holder) + to_chat(src, "Only administrators may use this command.") + return + + var/confirm = alert(src, "Drop a brain?", "Confirm", "Yes", "No","Cancel") + if(confirm == "Cancel") + return + //Due to the delay here its easy for something to have happened to the mob + if(!M) + return + + log_admin("[key_name(usr)] has gibbed [key_name(M)]") + message_admins("[key_name_admin(usr)] has gibbed [key_name_admin(M)]") + + if(isobserver(M)) + new /obj/effect/gibspawner/generic(get_turf(M)) + return + if(confirm == "Yes") + M.gib() + else + M.gib(1) + SSblackbox.add_details("admin_verb","Gib") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/cmd_admin_gib_self() + set name = "Gibself" + set category = "Fun" + + var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No") + if(confirm == "Yes") + log_admin("[key_name(usr)] used gibself.") + message_admins("[key_name_admin(usr)] used gibself.") + SSblackbox.add_details("admin_verb","Gib Self") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + mob.gib(1, 1, 1) + +/client/proc/cmd_admin_check_contents(mob/living/M in GLOB.mob_list) + set category = "Special Verbs" + set name = "Check Contents" + + var/list/L = M.get_contents() + for(var/t in L) + to_chat(usr, "[t]") + SSblackbox.add_details("admin_verb","Check Contents") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/toggle_view_range() + set category = "Special Verbs" + set name = "Change View Range" + set desc = "switches between 1x and custom views" + + if(view == world.view) + change_view(input("Select view range:", "FUCK YE", 7) in list(1,2,3,4,5,6,7,8,9,10,11,12,13,14,128)) + else + change_view(world.view) + + log_admin("[key_name(usr)] changed their view range to [view].") + //message_admins("\blue [key_name_admin(usr)] changed their view range to [view].") //why? removed by order of XSI + + SSblackbox.add_details("admin_toggle","Change View Range|[view]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/admin_call_shuttle() + + set category = "Admin" + set name = "Call Shuttle" + + if(EMERGENCY_AT_LEAST_DOCKED) + return + + if (!holder) + to_chat(src, "Only administrators may use this command.") + return + + var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No") + if(confirm != "Yes") + return + + SSshuttle.emergency.request() + SSblackbox.add_details("admin_verb","Call Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + log_admin("[key_name(usr)] admin-called the emergency shuttle.") + message_admins("[key_name_admin(usr)] admin-called the emergency shuttle.") + return + +/client/proc/admin_cancel_shuttle() + set category = "Admin" + set name = "Cancel Shuttle" + if(!check_rights(0)) + return + if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") + return + + if(EMERGENCY_AT_LEAST_DOCKED) + return + + SSshuttle.emergency.cancel() + SSblackbox.add_details("admin_verb","Cancel Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + log_admin("[key_name(usr)] admin-recalled the emergency shuttle.") + message_admins("[key_name_admin(usr)] admin-recalled the emergency shuttle.") + + return + +/client/proc/everyone_random() + set category = "Fun" + set name = "Make Everyone Random" + set desc = "Make everyone have a random appearance. You can only use this before rounds!" + + if(SSticker.HasRoundStarted()) + to_chat(usr, "Nope you can't do this, the game's already started. This only works before rounds!") + return + + var/frn = CONFIG_GET(flag/force_random_names) + if(frn) + CONFIG_SET(flag/force_random_names, FALSE) + message_admins("Admin [key_name_admin(usr)] has disabled \"Everyone is Special\" mode.") + to_chat(usr, "Disabled.") + return + + + var/notifyplayers = alert(src, "Do you want to notify the players?", "Options", "Yes", "No", "Cancel") + if(notifyplayers == "Cancel") + return + + log_admin("Admin [key_name(src)] has forced the players to have random appearances.") + message_admins("Admin [key_name_admin(usr)] has forced the players to have random appearances.") + + if(notifyplayers == "Yes") + to_chat(world, "Admin [usr.key] has forced the players to have completely random identities!") + + to_chat(usr, "Remember: you can always disable the randomness by using the verb again, assuming the round hasn't started yet.") + + CONFIG_SET(flag/force_random_names, TRUE) + SSblackbox.add_details("admin_verb","Make Everyone Random") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + + +/client/proc/toggle_random_events() + set category = "Server" + set name = "Toggle random events on/off" + set desc = "Toggles random events such as meteors, black holes, blob (but not space dust) on/off" + var/new_are = !CONFIG_GET(flag/allow_random_events) + CONFIG_SET(flag/allow_random_events, new_are) + if(new_are) + to_chat(usr, "Random events enabled") + message_admins("Admin [key_name_admin(usr)] has enabled random events.") + else + to_chat(usr, "Random events disabled") + message_admins("Admin [key_name_admin(usr)] has disabled random events.") + SSblackbox.add_details("admin_toggle","Toggle Random Events|[new_are]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + + +/client/proc/admin_change_sec_level() + set category = "Special Verbs" + set name = "Set Security Level" + set desc = "Changes the security level. Announcement only, i.e. setting to Delta won't activate nuke" + + if (!holder) + to_chat(src, "Only administrators may use this command.") + return + + var/level = input("Select security level to change to","Set Security Level") as null|anything in list("green","blue","red","delta") + if(level) + set_security_level(level) + + log_admin("[key_name(usr)] changed the security level to [level]") + message_admins("[key_name_admin(usr)] changed the security level to [level]") + SSblackbox.add_details("admin_verb","Set Security Level [capitalize(level)]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/toggle_nuke(obj/machinery/nuclearbomb/N in GLOB.nuke_list) + set name = "Toggle Nuke" + set category = "Fun" + set popup_menu = 0 + if(!check_rights(R_DEBUG)) + return + + if(!N.timing) + var/newtime = input(usr, "Set activation timer.", "Activate Nuke", "[N.timer_set]") as num + if(!newtime) + return + N.timer_set = newtime + N.set_safety() + N.set_active() + + log_admin("[key_name(usr)] [N.timing ? "activated" : "deactivated"] a nuke at ([N.x],[N.y],[N.z]).") + message_admins("[ADMIN_LOOKUPFLW(usr)] [N.timing ? "activated" : "deactivated"] a nuke at [ADMIN_COORDJMP(N)].") + SSblackbox.add_details("admin_toggle","Toggle Nuke|[N.timing]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits + +/client/proc/create_outfits() + set category = "Debug" + set name = "Create Custom Outfit" + + if(!check_rights(R_DEBUG)) + return + + holder.create_outfit() + +/datum/admins/proc/create_outfit() + var/list/uniforms = typesof(/obj/item/clothing/under) + var/list/suits = typesof(/obj/item/clothing/suit) + var/list/gloves = typesof(/obj/item/clothing/gloves) + var/list/shoes = typesof(/obj/item/clothing/shoes) + var/list/headwear = typesof(/obj/item/clothing/head) + var/list/glasses = typesof(/obj/item/clothing/glasses) + var/list/masks = typesof(/obj/item/clothing/mask) + var/list/ids = typesof(/obj/item/card/id) + + var/uniform_select = "" + + var/suit_select = "" + + var/gloves_select = "" + + var/shoes_select = "" + + var/head_select = "" + + var/glasses_select = "" + + var/mask_select = "" + + var/id_select = "" + + var/dat = {" + Create Outfit +
    + + [HrefTokenFormField()] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Name: + +
    Uniform: + [uniform_select] +
    Suit: + [suit_select] +
    Back: + +
    Belt: + +
    Gloves: + [gloves_select] +
    Shoes: + [shoes_select] +
    Head: + [head_select] +
    Mask: + [mask_select] +
    Ears: + +
    Glasses: + [glasses_select] +
    ID: + [id_select] +
    Left Pocket: + +
    Right Pocket: + +
    Suit Store: + +
    Right Hand: + +
    Left Hand: + +
    +
    + +
    + "} + usr << browse(dat, "window=dressup;size=550x600") + +/client/proc/toggle_antag_hud() + set category = "Admin" + set name = "Toggle AntagHUD" + set desc = "Toggles the Admin AntagHUD" + + if(!holder) return + + var/adding_hud = !has_antag_hud() + + for(var/datum/atom_hud/H in GLOB.huds) + if(istype(H, /datum/atom_hud/antag)) + (adding_hud) ? H.add_hud_to(usr) : H.remove_hud_from(usr) + + to_chat(usr, "You toggled your admin antag HUD [adding_hud ? "ON" : "OFF"].") + message_admins("[key_name_admin(usr)] toggled their admin antag HUD [adding_hud ? "ON" : "OFF"].") + log_admin("[key_name(usr)] toggled their admin antag HUD [adding_hud ? "ON" : "OFF"].") + SSblackbox.add_details("admin_toggle","Toggle Antag HUD|[adding_hud]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/has_antag_hud() + var/datum/atom_hud/A = GLOB.huds[ANTAG_HUD_TRAITOR] + return A.hudusers[mob] + +/client/proc/open_shuttle_manipulator() + set category = "Admin" + set name = "Shuttle Manipulator" + set desc = "Opens the shuttle manipulator UI." + + for(var/obj/machinery/shuttle_manipulator/M in GLOB.machines) + M.ui_interact(usr) + +/client/proc/mass_zombie_infection() + set category = "Fun" + set name = "Mass Zombie Infection" + set desc = "Infects all humans with a latent organ that will zombify \ + them on death." + + if(!holder) + return + + var/confirm = alert(src, "Please confirm you want to add latent zombie organs in all humans?", "Confirm Zombies", "Yes", "No") + if(confirm != "Yes") + return + + for(var/mob/living/carbon/human/H in GLOB.mob_list) + new /obj/item/organ/zombie_infection(H) + + message_admins("[key_name_admin(usr)] added a latent zombie infection to all humans.") + log_admin("[key_name(usr)] added a latent zombie infection to all humans.") + SSblackbox.add_details("admin_verb","Mass Zombie Infection") + +/client/proc/mass_zombie_cure() + set category = "Fun" + set name = "Mass Zombie Cure" + set desc = "Removes the zombie infection from all humans, returning them to normal." + if(!holder) + return + + var/confirm = alert(src, "Please confirm you want to cure all zombies?", "Confirm Zombie Cure", "Yes", "No") + if(confirm != "Yes") + return + + for(var/obj/item/organ/zombie_infection/I in GLOB.zombie_infection_list) + qdel(I) + + message_admins("[key_name_admin(usr)] cured all zombies.") + log_admin("[key_name(usr)] cured all zombies.") + SSblackbox.add_details("admin_verb","Mass Zombie Cure") + +/client/proc/polymorph_all() + set category = "Fun" + set name = "Polymorph All" + set desc = "Applies the effects of the bolt of change to every single mob." + + if(!holder) + return + + var/confirm = alert(src, "Please confirm you want polymorph all mobs?", "Confirm Polymorph", "Yes", "No") + if(confirm != "Yes") + return + + var/list/mobs = shuffle(GLOB.living_mob_list.Copy()) // might change while iterating + var/who_did_it = key_name_admin(usr) + + message_admins("[key_name_admin(usr)] started polymorphed all living mobs.") + log_admin("[key_name(usr)] polymorphed all living mobs.") + SSblackbox.add_details("admin_verb","Polymorph All") + + for(var/mob/living/M in mobs) + CHECK_TICK + + if(!M) + continue + + M.audible_message("...wabbajack...wabbajack...") + playsound(M.loc, 'sound/magic/staff_change.ogg', 50, 1, -1) + + wabbajack(M) + + message_admins("Mass polymorph started by [who_did_it] is complete.") + + +/client/proc/show_tip() + set category = "Admin" + set name = "Show Tip" + set desc = "Sends a tip (that you specify) to all players. After all \ + you're the experienced player here." + + if(!holder) + return + + var/input = input(usr, "Please specify your tip that you want to send to the players.", "Tip", "") as message|null + if(!input) + return + + if(!SSticker) + return + + SSticker.selected_tip = input + + // If we've already tipped, then send it straight away. + if(SSticker.tipped) + SSticker.send_tip_of_the_round() + + + message_admins("[key_name_admin(usr)] sent a tip of the round.") + log_admin("[key_name(usr)] sent \"[input]\" as the Tip of the Round.") + SSblackbox.add_details("admin_verb","Show Tip") + +#define ON_PURRBATION(H) (!(H.dna.features["tail_human"] == "None" && H.dna.features["ears"] == "None")) + +/proc/mass_purrbation() + for(var/M in GLOB.mob_list) + if(ishumanbasic(M)) + purrbation_apply(M) + CHECK_TICK + +/proc/mass_remove_purrbation() + for(var/M in GLOB.mob_list) + if(ishumanbasic(M)) + purrbation_remove(M) + CHECK_TICK + +/proc/purrbation_toggle(mob/living/carbon/human/H) + if(!ishumanbasic(H)) + return + if(!ON_PURRBATION(H)) + purrbation_apply(H) + . = TRUE + else + purrbation_remove(H) + . = FALSE + +/proc/purrbation_apply(mob/living/carbon/human/H) + if(!ishuman(H)) + return + if(ON_PURRBATION(H)) + return + to_chat(H, "Something is nya~t right.") + H.dna.features["tail_human"] = "Cat" + H.dna.features["ears"] = "Cat" + H.regenerate_icons() + playsound(get_turf(H), 'sound/effects/meow1.ogg', 50, 1, -1) + +/proc/purrbation_remove(mob/living/carbon/human/H) + if(!ishuman(H)) + return + if(!ON_PURRBATION(H)) + return + to_chat(H, "You are no longer a cat.") + H.dna.features["tail_human"] = "None" + H.dna.features["ears"] = "None" + H.regenerate_icons() + +#undef ON_PURRBATION + +/client/proc/modify_goals() + set category = "Debug" + set name = "Modify goals" + + if(!check_rights(R_ADMIN)) + return + + holder.modify_goals() + +/datum/admins/proc/modify_goals() + var/dat = "" + for(var/datum/station_goal/S in SSticker.mode.station_goals) + dat += "[S.name] - Announce | Remove
    " + dat += "
    Add New Goal" + usr << browse(dat, "window=goals;size=400x400") + + +/client/proc/toggle_hub() + set category = "Server" + set name = "Toggle Hub" + + world.update_hub_visibility(!GLOB.hub_visibility) + + log_admin("[key_name(usr)] has toggled the server's hub status for the round, it is now [(GLOB.hub_visibility?"on":"off")] the hub.") + message_admins("[key_name_admin(usr)] has toggled the server's hub status for the round, it is now [(GLOB.hub_visibility?"on":"off")] the hub.") + if (GLOB.hub_visibility && !world.reachable) + message_admins("WARNING: The server will not show up on the hub because byond is detecting that a filewall is blocking incoming connections.") + + SSblackbox.add_details("admin_toggle","Toggled Hub Visibility|[GLOB.hub_visibility]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/client/proc/smite(mob/living/carbon/human/target as mob) + set name = "Smite" + set category = "Fun" + if(!holder) + return + + var/list/punishment_list = list(ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_BSA) + + var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list + + if(QDELETED(target) || !punishment) + return + + switch(punishment) + if(ADMIN_PUNISHMENT_LIGHTNING) + var/turf/T = get_step(get_step(target, NORTH), NORTH) + T.Beam(target, icon_state="lightning[rand(1,12)]", time = 5) + target.adjustFireLoss(75) + target.electrocution_animation(40) + to_chat(target, "The gods have punished you for your sins!") + if(ADMIN_PUNISHMENT_BRAINDAMAGE) + target.adjustBrainLoss(75) + if(ADMIN_PUNISHMENT_GIB) + target.gib(FALSE) + if(ADMIN_PUNISHMENT_BSA) + bluespace_artillery(target) + + var/msg = "[key_name_admin(usr)] punished [key_name_admin(target)] with [punishment]." + message_admins(msg) + admin_ticket_log(target, msg) + log_admin("[key_name(usr)] punished [key_name(target)] with [punishment].") + + +/client/proc/trigger_centcom_recall() + if(!holder) + return + var/message = pick(GLOB.admiral_messages) + message = input("Enter message from the on-call admiral to be put in the recall report.", "Admiral Message", message) as text|null + + if(!message) + return + + message_admins("[key_name_admin(usr)] triggered a CentCom recall, with the admiral message of: [message]") + log_game("[key_name(usr)] triggered a CentCom recall, with the message of: [message]") + SSshuttle.centcom_recall(SSshuttle.emergency.timer, message) + +/client/proc/cmd_admin_check_player_exp() //Allows admins to determine who the newer players are. + set category = "Admin" + set name = "Player Playtime" + if(!check_rights(R_ADMIN)) + return + + var/list/msg = list() + msg += "Playtime ReportPlaytime:
    " + src << browse(msg.Join(), "window=Player_playtime_check") + +/datum/admins/proc/cmd_show_exp_panel(client/C) + if(!check_rights(R_ADMIN)) + return + if(!C) + to_chat(usr, "ERROR: Client not found.") + return + + var/list/body = list() + body += "Playtime for [C.key]
    Playtime:" + body += C.get_exp_report() + body += "Toggle Exempt status" + body += "" + usr << browse(body.Join(), "window=playerplaytime[C.ckey];size=550x615") + +/datum/admins/proc/toggle_exempt_status(client/C) + if(!check_rights(R_ADMIN)) + return + if(!C) + to_chat(usr, "ERROR: Client not found.") + return + + if(!C.set_db_player_flags()) + to_chat(usr, "ERROR: Unable read player flags from database. Please check logs.") + var/dbflags = C.prefs.db_flags + var/newstate = FALSE + if(dbflags & DB_FLAG_EXEMPT) + newstate = FALSE + else + newstate = TRUE + + if(C.update_flag_db(DB_FLAG_EXEMPT, newstate)) + to_chat(usr, "ERROR: Unable to update player flags. Please check logs.") + else + message_admins("[key_name_admin(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name_admin(C)]") +>>>>>>> 4178c20... Configuration datum refactor (#30763) log_admin("[key_name(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name(C)]") \ No newline at end of file diff --git a/code/modules/admin/verbs/reestablish_db_connection.dm b/code/modules/admin/verbs/reestablish_db_connection.dm index 3578e98b1b..5c5edf6d17 100644 --- a/code/modules/admin/verbs/reestablish_db_connection.dm +++ b/code/modules/admin/verbs/reestablish_db_connection.dm @@ -1,7 +1,7 @@ /client/proc/reestablish_db_connection() set category = "Special Verbs" set name = "Reestablish DB Connection" - if (!config.sql_enabled) + if (!CONFIG_GET(flag/sql_enabled)) to_chat(usr, "The Database is not enabled!") return diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm index 9a721bee62..12f99f3c50 100644 --- a/code/modules/awaymissions/gateway.dm +++ b/code/modules/awaymissions/gateway.dm @@ -80,7 +80,7 @@ GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation) if(!GLOB.the_gateway) GLOB.the_gateway = src update_icon() - wait = world.time + config.gateway_delay //+ thirty minutes default + wait = world.time + CONFIG_GET(number/gateway_delay) //+ thirty minutes default awaygate = locate(/obj/machinery/gateway/centeraway) /obj/machinery/gateway/centerstation/Destroy() diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 6fbc7d552f..60936aa5fb 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -42,7 +42,8 @@ to_chat(src, "An error has been detected in how your client is receiving resources. Attempting to correct.... (If you keep seeing these messages you might want to close byond and reconnect)") src << browse("...", "window=asset_cache_browser") - if (!holder && config.minutetopiclimit) + var/mtl = CONFIG_GET(number/minute_topic_limit) + if (!holder && mtl) var/minute = round(world.time, 600) if (!topiclimiter) topiclimiter = new(LIMITER_SIZE) @@ -50,17 +51,18 @@ topiclimiter[CURRENT_MINUTE] = minute topiclimiter[MINUTE_COUNT] = 0 topiclimiter[MINUTE_COUNT] += 1 - if (topiclimiter[MINUTE_COUNT] > config.minutetopiclimit) + if (topiclimiter[MINUTE_COUNT] > mtl) var/msg = "Your previous action was ignored because you've done too many in a minute." if (minute != topiclimiter[ADMINSWARNED_AT]) //only one admin message per-minute. (if they spam the admins can just boot/ban them) topiclimiter[ADMINSWARNED_AT] = minute msg += " Administrators have been informed." - log_game("[key_name(src)] Has hit the per-minute topic limit of [config.minutetopiclimit] topic calls in a given game minute") - message_admins("[key_name_admin(src)] [ADMIN_FLW(usr)] [ADMIN_KICK(usr)] Has hit the per-minute topic limit of [config.minutetopiclimit] topic calls in a given game minute") + log_game("[key_name(src)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute") + message_admins("[key_name_admin(src)] [ADMIN_FLW(usr)] [ADMIN_KICK(usr)] Has hit the per-minute topic limit of [mtl] topic calls in a given game minute") to_chat(src, "[msg]") return - if (!holder && config.secondtopiclimit) + var/stl = CONFIG_GET(number/second_topic_limit) + if (!holder && stl) var/second = round(world.time, 10) if (!topiclimiter) topiclimiter = new(LIMITER_SIZE) @@ -68,7 +70,7 @@ topiclimiter[CURRENT_SECOND] = second topiclimiter[SECOND_COUNT] = 0 topiclimiter[SECOND_COUNT] += 1 - if (topiclimiter[SECOND_COUNT] > config.secondtopiclimit) + if (topiclimiter[SECOND_COUNT] > stl) to_chat(src, "Your previous action was ignored because you've done too many in a second") return @@ -110,7 +112,7 @@ return 1 /client/proc/handle_spam_prevention(message, mute_type) - if(config.automute_on && !holder && src.last_message == message) + if(CONFIG_GET(flag/automute_on) && !holder && last_message == message) src.last_message_count++ if(src.last_message_count >= SPAM_TRIGGER_AUTOMUTE) to_chat(src, "You have exceeded the spam filter limit for identical messages. An auto-mute was applied.") @@ -174,11 +176,11 @@ GLOBAL_LIST(external_rsc_urls) if(localhost_rank) var/datum/admins/localhost_holder = new(localhost_rank, ckey) localhost_holder.associate(src) - if(config.autoadmin) + if(CONFIG_GET(flag/autoadmin)) if(!GLOB.admin_datums[ckey]) var/datum/admin_rank/autorank for(var/datum/admin_rank/R in GLOB.admin_ranks) - if(R.name == config.autoadmin_rank) + if(R.name == CONFIG_GET(string/autoadmin_rank)) autorank = R break if(!autorank) @@ -206,7 +208,7 @@ GLOBAL_LIST(external_rsc_urls) log_access("Login: [key_name(src)] from [address ? address : "localhost"]-[computer_id] || BYOND v[byond_version]") var/alert_mob_dupe_login = FALSE - if(config.log_access) + if(CONFIG_GET(flag/log_access)) for(var/I in GLOB.clients) if(!I || I == src) continue @@ -240,30 +242,32 @@ GLOBAL_LIST(external_rsc_urls) connection_realtime = world.realtime connection_timeofday = world.timeofday winset(src, null, "command=\".configure graphics-hwmode on\"") - if (byond_version < config.client_error_version) //Out of date client. + var/cev = CONFIG_GET(number/client_error_version) + var/cwv = CONFIG_GET(number/client_warn_version) + if (byond_version < cev) //Out of date client. to_chat(src, "Your version of byond is too old:") - to_chat(src, config.client_error_message) + to_chat(src, CONFIG_GET(string/client_error_message)) to_chat(src, "Your version: [byond_version]") - to_chat(src, "Required version: [config.client_error_version] or later") + to_chat(src, "Required version: [cev] or later") to_chat(src, "Visit http://www.byond.com/download/ to get the latest version of byond.") if (holder) to_chat(src, "Because you are an admin, you are being allowed to walk past this limitation, But it is still STRONGLY suggested you upgrade") else qdel(src) return 0 - else if (byond_version < config.client_warn_version) //We have words for this client. + else if (byond_version < cwv) //We have words for this client. to_chat(src, "Your version of byond may be getting out of date:") - to_chat(src, config.client_warn_message) + to_chat(src, CONFIG_GET(string/client_warn_message)) to_chat(src, "Your version: [byond_version]") - to_chat(src, "Required version to remove this message: [config.client_warn_version] or later") + to_chat(src, "Required version to remove this message: [cwv] or later") to_chat(src, "Visit http://www.byond.com/download/ to get the latest version of byond.") if (connection == "web" && !holder) - if (!config.allowwebclient) + if (!CONFIG_GET(flag/allow_webclient)) to_chat(src, "Web client is disabled") qdel(src) return 0 - if (config.webclientmembersonly && !IsByondMember()) + if (CONFIG_GET(flag/webclient_only_byond_members) && !IsByondMember()) to_chat(src, "Sorry, but the web client is restricted to byond members only.") qdel(src) return 0 @@ -276,25 +280,24 @@ GLOBAL_LIST(external_rsc_urls) add_admin_verbs() to_chat(src, get_message_output("memo")) adminGreet() - if((global.comms_key == "default_pwd" || length(global.comms_key) <= 6) && global.comms_allowed) //It's the default value or less than 6 characters long, but it somehow didn't disable comms. - to_chat(src, "The server's API key is either too short or is the default value! Consider changing it immediately!") add_verbs_from_config() var/cached_player_age = set_client_age_from_db(tdata) //we have to cache this because other shit may change it and we need it's current value now down below. if (isnum(cached_player_age) && cached_player_age == -1) //first connection player_age = 0 + var/nnpa = CONFIG_GET(number/notify_new_player_age) if (isnum(cached_player_age) && cached_player_age == -1) //first connection - if (config.notify_new_player_age >= 0) + if (nnpa >= 0) message_admins("New user: [key_name_admin(src)] is connecting here for the first time.") - if (config.irc_first_connection_alert) + if (CONFIG_GET(flag/irc_first_connection_alert)) send2irc_adminless_only("New-user", "[key_name(src)] is connecting for the first time!") - else if (isnum(cached_player_age) && cached_player_age < config.notify_new_player_age) + else if (isnum(cached_player_age) && cached_player_age < nnpa) message_admins("New user: [key_name_admin(src)] just connected with an age of [cached_player_age] day[(player_age==1?"":"s")]") - if(config.use_account_age_for_jobs && account_age >= 0) + if(CONFIG_GET(flag/use_account_age_for_jobs) && account_age >= 0) player_age = account_age - if(account_age >= 0 && account_age < config.notify_new_player_account_age) + if(account_age >= 0 && account_age < nnpa) message_admins("[key_name_admin(src)] (IP: [address], ID: [computer_id]) is a new BYOND account [account_age] day[(account_age==1?"":"s")] old, created on [account_join_date].") - if (config.irc_first_connection_alert) + if (CONFIG_GET(flag/irc_first_connection_alert)) send2irc_adminless_only("new_byond_user", "[key_name(src)] (IP: [address], ID: [computer_id]) is a new BYOND account [account_age] day[(account_age==1?"":"s")] old, created on [account_join_date].") get_message_output("watchlist entry", ckey) check_ip_intel() @@ -306,7 +309,7 @@ GLOBAL_LIST(external_rsc_urls) if(prefs.lastchangelog != GLOB.changelog_hash) //bolds the changelog button on the interface so we know there are updates. to_chat(src, "You have unread updates in the changelog.") - if(config.aggressive_changelog) + if(CONFIG_GET(flag/aggressive_changelog)) changelog() else winset(src, "infowindow.changelog", "font-style=bold") @@ -316,7 +319,7 @@ GLOBAL_LIST(external_rsc_urls) to_chat(src, message) GLOB.clientmessages.Remove(ckey) - if(config && config.autoconvert_notes) + if(CONFIG_GET(flag/autoconvert_notes)) convert_notes_sql(ckey) to_chat(src, get_message_output("message", ckey)) if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them. @@ -432,15 +435,17 @@ GLOBAL_LIST(external_rsc_urls) if(!query_client_in_db.Execute()) return if(!query_client_in_db.NextRow()) - if (config.panic_bunker && !holder && !(ckey in GLOB.deadmins)) + if (CONFIG_GET(flag/panic_bunker) && !holder && !(ckey in GLOB.deadmins)) log_access("Failed Login: [key] - New account attempting to connect during panic bunker") message_admins("Failed Login: [key] - New account attempting to connect during panic bunker") to_chat(src, "Sorry but the server is currently not accepting connections from never before seen players.") var/list/connectiontopic_a = params2list(connectiontopic) - if(config.panic_address && !connectiontopic_a["redirect"]) - to_chat(src, "Sending you to [config.panic_server_name ? config.panic_server_name : config.panic_address].") + var/list/panic_addr = CONFIG_GET(string/panic_address) + if(panic_addr && !connectiontopic_a["redirect"]) + var/panic_name = CONFIG_GET(string/panic_server_name) + to_chat(src, "Sending you to [panic_name ? panic_name : panic_addr].") winset(src, null, "command=.options") - src << link("[config.panic_address]?redirect=1") + src << link("[panic_addr]?redirect=1") qdel(src) return @@ -501,7 +506,7 @@ GLOBAL_LIST(external_rsc_urls) if (connection != "seeker") return topic = params2list(topic) - if (!config.check_randomizer) + if (!CONFIG_GET(flag/check_randomizer)) return var/static/cidcheck = list() var/static/tokens = list() @@ -594,15 +599,15 @@ GLOBAL_LIST(external_rsc_urls) /client/proc/check_ip_intel() set waitfor = 0 //we sleep when getting the intel, no need to hold up the client connection while we sleep - if (config.ipintel_email) + if (CONFIG_GET(string/ipintel_email)) var/datum/ipintel/res = get_ip_intel(address) - if (res.intel >= config.ipintel_rating_bad) + if (res.intel >= CONFIG_GET(number/ipintel_rating_bad)) message_admins("Proxy Detection: [key_name_admin(src)] IP intel rated [res.intel*100]% likely to be a Proxy/VPN.") ip_intel = res.intel /client/proc/add_verbs_from_config() - if(config.see_own_notes) + if(CONFIG_GET(flag/see_own_notes)) verbs += /client/proc/self_notes @@ -612,7 +617,7 @@ GLOBAL_LIST(external_rsc_urls) //checks if a client is afk //3000 frames = 5 minutes -/client/proc/is_afk(duration = config.inactivity_period) +/client/proc/is_afk(duration = CONFIG_GET(number/inactivity_period)) if(inactivity > duration) return inactivity return FALSE diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 15b0bd95df..b576829240 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -274,8 +274,174 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "
    " dat += "" +<<<<<<< HEAD // dat += "Size: [character_size]
    " dat += "
    " +======= + + dat += "

    Body

    " + dat += "Random Body " + dat += "Always Random Body: [be_random_body ? "Yes" : "No"]
    " + + dat += "" + + if(pref_species.use_skintones) + + dat += "" + + if(HAIR in pref_species.species_traits) + + dat += "" + + if(EYECOLOR in pref_species.species_traits) + + dat += "" + + if(CONFIG_GET(flag/join_with_mutant_race)) //We don't allow mutant bodyparts for humans either unless this is true. + + if((MUTCOLORS in pref_species.species_traits) || (MUTCOLORS_PARTSONLY in pref_species.species_traits)) + + dat += "" + + if("tail_lizard" in pref_species.mutant_bodyparts) + dat += "" + + if("snout" in pref_species.mutant_bodyparts) + dat += "" + + if("horns" in pref_species.mutant_bodyparts) + dat += "" + + if("frills" in pref_species.mutant_bodyparts) + dat += "" + + if("spines" in pref_species.mutant_bodyparts) + dat += "" + + if("body_markings" in pref_species.mutant_bodyparts) + dat += "" + if("legs" in pref_species.mutant_bodyparts) + dat += "" + if(CONFIG_GET(flag/join_with_mutant_humans)) + + if("tail_human" in pref_species.mutant_bodyparts) + dat += "" + + if("ears" in pref_species.mutant_bodyparts) + dat += "" + + if("wings" in pref_species.mutant_bodyparts && GLOB.r_wings_list.len >1) + dat += "" + + dat += "
    " + + if(CONFIG_GET(flag/join_with_mutant_race)) + dat += "Species:
    [pref_species.name]
    " + else + dat += "Species: Human
    " + + dat += "Underwear:
    [underwear]
    " + dat += "Undershirt:
    [undershirt]
    " + dat += "Socks:
    [socks]
    " + dat += "Backpack:
    [backbag]
    " + dat += "Uplink Spawn Location:
    [uplink_spawn_loc]
    " + + dat += "

    Skin Tone

    " + + dat += "[skin_tone]
    " + + dat += "
    " + + dat += "

    Hair Style

    " + + dat += "[hair_style]
    " + dat += "< >
    " + dat += "    Change
    " + + + dat += "
    " + + dat += "

    Facial Hair Style

    " + + dat += "[facial_hair_style]
    " + dat += "< >
    " + dat += "    Change
    " + + dat += "
    " + + dat += "

    Eye Color

    " + + dat += "    Change
    " + + dat += "
    " + + dat += "

    Mutant Color

    " + + dat += "    Change
    " + + dat += "
    " + + dat += "

    Tail

    " + + dat += "[features["tail_lizard"]]
    " + + dat += "
    " + + dat += "

    Snout

    " + + dat += "[features["snout"]]
    " + + dat += "
    " + + dat += "

    Horns

    " + + dat += "[features["horns"]]
    " + + dat += "
    " + + dat += "

    Frills

    " + + dat += "[features["frills"]]
    " + + dat += "
    " + + dat += "

    Spines

    " + + dat += "[features["spines"]]
    " + + dat += "
    " + + dat += "

    Body Markings

    " + + dat += "[features["body_markings"]]
    " + + dat += "
    " + + dat += "

    Legs

    " + + dat += "[features["legs"]]
    " + + dat += "
    " + + dat += "

    Tail

    " + + dat += "[features["tail_human"]]
    " + + dat += "
    " + + dat += "

    Ears

    " + + dat += "[features["ears"]]
    " + + dat += "
    " + + dat += "

    Wings

    " + + dat += "[features["wings"]]
    " + + dat += "
    " + +>>>>>>> 4178c20... Configuration datum refactor (#30763) if (1) // Game Preferences dat += "" continue - if(config.enforce_human_authority && !user.client.prefs.pref_species.qualifies_for_rank(rank, user.client.prefs.features)) + if(CONFIG_GET(flag/enforce_human_authority) && !user.client.prefs.pref_species.qualifies_for_rank(rank, user.client.prefs.features)) if(user.client.prefs.pref_species.id == "human") HTML += "[rank]" else @@ -1023,10 +1189,10 @@ GLOBAL_LIST_EMPTY(preferences_datums) if("species") - var/result = input(user, "Select a species", "Species Selection") as null|anything in GLOB.roundstart_species + var/result = input(user, "Select a species", "Species Selection") as null|anything in CONFIG_GET(keyed_flag_list/roundstart_races) if(result) - var/newtype = GLOB.roundstart_species[result] + var/newtype = GLOB.species_list[result] pref_species = new newtype() //Now that we changed our species, we must verify that the mutant colour is still allowed. var/temp_hsv = RGBtoHSV(features["mcolor"]) @@ -1622,7 +1788,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(be_random_body) random_character(gender) - if(config.humans_need_surnames) + if(CONFIG_GET(flag/humans_need_surnames)) var/firstspace = findtext(real_name, " ") var/name_length = length(real_name) if(!firstspace) //we need a surname @@ -1657,7 +1823,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) character.dna.features = features.Copy() //Flavor text is now a DNA feature character.dna.real_name = character.real_name var/datum/species/chosen_species - if(pref_species != /datum/species/human && config.mutant_races) + if(pref_species != /datum/species/human && CONFIG_GET(flag/join_with_mutant_race)) chosen_species = pref_species.type else chosen_species = /datum/species/human diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 9daad5cae7..e2612ebf4b 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -290,11 +290,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car //Species var/species_id S["species"] >> species_id - if(config.mutant_races && species_id && (species_id in GLOB.roundstart_species)) - var/newtype = GLOB.roundstart_species[species_id] + var/list/roundstart_races = CONFIG_GET(keyed_flag_list/roundstart_races) + if(species_id && (species_id in roundstart_races) && CONFIG_GET(flag/join_with_mutant_race)) + var/newtype = GLOB.species_list[species_id] pref_species = new newtype() - else if (config.roundstart_races.len) - var/rando_race = pick(config.roundstart_races) + else if (roundstart_races.len) + var/rando_race = pick(roundstart_races) if (rando_race) pref_species = new rando_race() @@ -327,8 +328,17 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["feature_lizard_spines"] >> features["spines"] S["feature_lizard_body_markings"] >> features["body_markings"] S["feature_lizard_legs"] >> features["legs"] +<<<<<<< HEAD S["feature_human_tail"] >> features["tail_human"] S["feature_human_ears"] >> features["ears"] +======= + if(!CONFIG_GET(flag/join_with_mutant_humans)) + features["tail_human"] = "none" + features["ears"] = "none" + else + S["feature_human_tail"] >> features["tail_human"] + S["feature_human_ears"] >> features["ears"] +>>>>>>> 4178c20... Configuration datum refactor (#30763) S["clown_name"] >> custom_names["clown"] S["mime_name"] >> custom_names["mime"] S["ai_name"] >> custom_names["ai"] diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm index 7715362c06..e2022729be 100644 --- a/code/modules/client/verbs/ooc.dm +++ b/code/modules/client/verbs/ooc.dm @@ -62,7 +62,7 @@ if(holder) if(!holder.fakekey || C.holder) if(check_rights_for(src, R_ADMIN)) - to_chat(C, "[config.allow_admin_ooccolor && prefs.ooccolor ? "" :"" ]OOC: [keyname][holder.fakekey ? "/([holder.fakekey])" : ""]: [msg]") + to_chat(C, "[CONFIG_GET(flag/allow_admin_ooccolor) && prefs.ooccolor ? "" :"" ]OOC: [keyname][holder.fakekey ? "/([holder.fakekey])" : ""]: [msg]") else to_chat(C, "OOC: [keyname][holder.fakekey ? "/([holder.fakekey])" : ""]: [msg]") else @@ -239,7 +239,7 @@ GLOBAL_VAR_INIT(normal_ooc_colour, OOC_COLOR) set category = "OOC" set desc = "View the notes that admins have written about you" - if(!config.see_own_notes) + if(!CONFIG_GET(flag/see_own_notes)) to_chat(usr, "Sorry, that function is not enabled on this server.") return diff --git a/code/modules/emoji/emoji_parse.dm b/code/modules/emoji/emoji_parse.dm index 58f261f8cc..7d1953738f 100644 --- a/code/modules/emoji/emoji_parse.dm +++ b/code/modules/emoji/emoji_parse.dm @@ -1,6 +1,6 @@ /proc/emoji_parse(text) . = text - if(!config.emojis) + if(!CONFIG_GET(flag/emojis)) return var/static/list/emojis = icon_states(icon('icons/emoji.dmi')) var/parsed = "" diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm index c0c8cf5b74..17ac8b3628 100644 --- a/code/modules/error_handler/error_handler.dm +++ b/code/modules/error_handler/error_handler.dm @@ -33,14 +33,20 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0) // We can runtime before config is initialized because BYOND initialize objs/map before a bunch of other stuff happens. // This is a bunch of workaround code for that. Hooray! - - var/configured_error_cooldown = initial(config.error_cooldown) - var/configured_error_limit = initial(config.error_limit) - var/configured_error_silence_time = initial(config.error_silence_time) + var/configured_error_cooldown + var/configured_error_limit + var/configured_error_silence_time if(config) - configured_error_cooldown = config.error_cooldown - configured_error_limit = config.error_limit - configured_error_silence_time = config.error_silence_time + configured_error_cooldown = CONFIG_GET(number/error_cooldown) + configured_error_limit = CONFIG_GET(number/error_limit) + configured_error_silence_time = CONFIG_GET(number/error_silence_time) + else + var/datum/config_entry/CE = /datum/config_entry/number/error_cooldown + configured_error_cooldown = initial(CE.value) + CE = /datum/config_entry/number/error_limit + configured_error_limit = initial(CE.value) + CE = /datum/config_entry/number/error_silence_time + configured_error_silence_time = initial(CE.value) //Each occurence of a unique error adds to its cooldown time... diff --git a/code/modules/error_handler/error_viewer.dm b/code/modules/error_handler/error_viewer.dm index dddff75bb2..b19153956f 100644 --- a/code/modules/error_handler/error_viewer.dm +++ b/code/modules/error_handler/error_viewer.dm @@ -119,9 +119,10 @@ GLOBAL_DATUM(error_cache, /datum/error_viewer/error_cache) //log_debug("Runtime in [e.file], line [e.line]: [html_encode(e.name)] [error_entry.make_link(viewtext)]") var/err_msg_delay if(config) - err_msg_delay = config.error_msg_delay + err_msg_delay = CONFIG_GET(number/error_msg_delay) else - err_msg_delay = initial(config.error_msg_delay) + var/datum/config_entry/CE = /datum/config_entry/number/error_msg_delay + err_msg_delay = initial(CE.value) error_source.next_message_at = world.time + err_msg_delay /datum/error_viewer/error_source diff --git a/code/modules/events/_event.dm b/code/modules/events/_event.dm index 79e99a1931..be78544ac4 100644 --- a/code/modules/events/_event.dm +++ b/code/modules/events/_event.dm @@ -30,8 +30,8 @@ /datum/round_event_control/New() ..() if(config && !wizardevent) // Magic is unaffected by configs - earliest_start = Ceiling(earliest_start * config.events_min_time_mul) - min_players = Ceiling(min_players * config.events_min_players_mul) + earliest_start = Ceiling(earliest_start * CONFIG_GET(number/events_min_time_mul)) + min_players = Ceiling(min_players * CONFIG_GET(number/events_min_players_mul)) /datum/round_event_control/wizard wizardevent = 1 diff --git a/code/modules/events/wizard/summons.dm b/code/modules/events/wizard/summons.dm index dfdcd889ca..64778ae65d 100644 --- a/code/modules/events/wizard/summons.dm +++ b/code/modules/events/wizard/summons.dm @@ -6,7 +6,7 @@ earliest_start = 0 /datum/round_event_control/wizard/summonguns/New() - if(config.no_summon_guns) + if(CONFIG_GET(flag/no_summon_guns)) weight = 0 ..() @@ -21,7 +21,7 @@ earliest_start = 0 /datum/round_event_control/wizard/summonmagic/New() - if(config.no_summon_magic) + if(CONFIG_GET(flag/no_summon_magic)) weight = 0 ..() diff --git a/code/modules/hydroponics/grown/replicapod.dm b/code/modules/hydroponics/grown/replicapod.dm index 3c332b950c..26321c6dc8 100644 --- a/code/modules/hydroponics/grown/replicapod.dm +++ b/code/modules/hydroponics/grown/replicapod.dm @@ -55,7 +55,7 @@ var/obj/machinery/hydroponics/parent = loc var/make_podman = 0 var/ckey_holder = null - if(config.revival_pod_plants) + if(CONFIG_GET(flag/revival_pod_plants)) if(ckey) for(var/mob/M in GLOB.player_list) if(isobserver(M)) diff --git a/code/modules/jobs/job_exp.dm b/code/modules/jobs/job_exp.dm index f7679898d4..220fa2e9ac 100644 --- a/code/modules/jobs/job_exp.dm +++ b/code/modules/jobs/job_exp.dm @@ -6,13 +6,13 @@ GLOBAL_PROTECT(exp_to_update) /datum/job/proc/required_playtime_remaining(client/C) if(!C) return 0 - if(!config.use_exp_tracking) + if(!CONFIG_GET(flag/use_exp_tracking)) return 0 if(!exp_requirements || !exp_type) return 0 if(!job_is_xp_locked(src.title)) return 0 - if(config.use_exp_restrictions_admin_bypass && check_rights(R_ADMIN, FALSE, C.mob)) + if(CONFIG_GET(flag/use_exp_restrictions_admin_bypass) && check_rights(R_ADMIN, FALSE, C.mob)) return 0 var/isexempt = C.prefs.db_flags & DB_FLAG_EXEMPT if(isexempt) @@ -26,20 +26,21 @@ GLOBAL_PROTECT(exp_to_update) /datum/job/proc/get_exp_req_amount() if(title in GLOB.command_positions) - if(config.use_exp_restrictions_heads_hours) - return config.use_exp_restrictions_heads_hours * 60 + var/uerhh = CONFIG_GET(number/use_exp_restrictions_heads_hours) + if(uerhh) + return uerhh * 60 return exp_requirements /datum/job/proc/get_exp_req_type() if(title in GLOB.command_positions) - if(config.use_exp_restrictions_heads_department && exp_type_department) + if(CONFIG_GET(flag/use_exp_restrictions_heads_department) && exp_type_department) return exp_type_department return exp_type /proc/job_is_xp_locked(jobtitle) - if(!config.use_exp_restrictions_heads && jobtitle in GLOB.command_positions) + if(!CONFIG_GET(flag/use_exp_restrictions_heads) && jobtitle in GLOB.command_positions) return FALSE - if(!config.use_exp_restrictions_other && !(jobtitle in GLOB.command_positions)) + if(!CONFIG_GET(flag/use_exp_restrictions_other) && !(jobtitle in GLOB.command_positions)) return FALSE return TRUE @@ -55,7 +56,7 @@ GLOBAL_PROTECT(exp_to_update) return amount /client/proc/get_exp_report() - if(!config.use_exp_tracking) + if(!CONFIG_GET(flag/use_exp_tracking)) return "Tracking is disabled in the server configuration file." var/list/play_records = prefs.exp if(!play_records.len) @@ -86,7 +87,7 @@ GLOBAL_PROTECT(exp_to_update) return_text += "
  • [dep] [get_exp_format(exp_data[dep])] ([percentage]%)
  • " else return_text += "
  • [dep] [get_exp_format(exp_data[dep])]
  • " - if(config.use_exp_restrictions_admin_bypass && check_rights(R_ADMIN, 0, mob)) + if(CONFIG_GET(flag/use_exp_restrictions_admin_bypass) && check_rights(R_ADMIN, 0, mob)) return_text += "
  • Admin (all jobs auto-unlocked)
  • " return_text += "" var/list/jobs_locked = list() @@ -139,7 +140,7 @@ GLOBAL_PROTECT(exp_to_update) //resets a client's exp to what was in the db. /client/proc/set_exp_from_db() - if(!config.use_exp_tracking) + if(!CONFIG_GET(flag/use_exp_tracking)) return -1 if(!SSdbcore.Connect()) return -1 @@ -181,7 +182,7 @@ GLOBAL_PROTECT(exp_to_update) /client/proc/update_exp_list(minutes, announce_changes = FALSE) - if(!config.use_exp_tracking) + if(!CONFIG_GET(flag/use_exp_tracking)) return -1 if(!SSdbcore.Connect()) return -1 diff --git a/code/modules/jobs/job_types/assistant.dm b/code/modules/jobs/job_types/assistant.dm index 41c3cd0a94..6c8b050394 100644 --- a/code/modules/jobs/job_types/assistant.dm +++ b/code/modules/jobs/job_types/assistant.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /* Assistant */ @@ -40,3 +41,48 @@ Assistant uniform = /obj/item/clothing/under/color/grey else uniform = /obj/item/clothing/under/color/random +======= +/* +Assistant +*/ +/datum/job/assistant + title = "Assistant" + flag = ASSISTANT + department_flag = CIVILIAN + faction = "Station" + total_positions = -1 + spawn_positions = -1 + supervisors = "absolutely everyone" + selection_color = "#dddddd" + access = list() //See /datum/job/assistant/get_access() + minimal_access = list() //See /datum/job/assistant/get_access() + outfit = /datum/outfit/job/assistant + + +/datum/job/assistant/get_access() + if(CONFIG_GET(flag/assistants_have_maint_access) || !CONFIG_GET(flag/jobs_have_minimal_access)) //Config has assistant maint access set + . = ..() + . |= list(ACCESS_MAINT_TUNNELS) + else + return ..() + +/datum/job/assistant/config_check() + var/ac = CONFIG_GET(number/assistant_cap) + if(ac != 0) + total_positions = ac + spawn_positions = ac + return 1 + return 0 + + +/datum/outfit/job/assistant + name = "Assistant" + jobtype = /datum/job/assistant + +/datum/outfit/job/assistant/pre_equip(mob/living/carbon/human/H) + ..() + if (CONFIG_GET(flag/grey_assistants)) + uniform = /obj/item/clothing/under/color/grey + else + uniform = /obj/item/clothing/under/color/random +>>>>>>> 4178c20... Configuration datum refactor (#30763) diff --git a/code/modules/jobs/job_types/job.dm b/code/modules/jobs/job_types/job.dm index 6b736db7fe..2e18807541 100644 --- a/code/modules/jobs/job_types/job.dm +++ b/code/modules/jobs/job_types/job.dm @@ -75,7 +75,7 @@ if(!visualsOnly && announce) announce(H) - if(config.enforce_human_authority && (title in GLOB.command_positions)) + if(CONFIG_GET(flag/enforce_human_authority) && (title in GLOB.command_positions)) H.dna.features["tail_human"] = "None" H.dna.features["ears"] = "None" H.regenerate_icons() @@ -86,12 +86,12 @@ . = list() - if(config.jobs_have_minimal_access) + if(CONFIG_GET(flag/jobs_have_minimal_access)) . = src.minimal_access.Copy() else . = src.access.Copy() - if(config.jobs_have_maint_access & EVERYONE_HAS_MAINT_ACCESS) //Config has global maint access set + if(CONFIG_GET(flag/everyone_has_maint_access)) //Config has global maint access set . |= list(ACCESS_MAINT_TUNNELS) /datum/job/proc/announce_head(var/mob/living/carbon/human/H, var/channels) //tells the given channel that the given mob is the new department head. See communications.dm for valid channels. @@ -109,7 +109,7 @@ /datum/job/proc/available_in_days(client/C) if(!C) return 0 - if(!config.use_age_restriction_for_jobs) + if(!CONFIG_GET(flag/use_age_restriction_for_jobs)) return 0 if(!isnum(C.player_age)) return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced diff --git a/code/modules/jobs/job_types/security.dm b/code/modules/jobs/job_types/security.dm index 67a705455c..442b75c972 100644 --- a/code/modules/jobs/job_types/security.dm +++ b/code/modules/jobs/job_types/security.dm @@ -1,6 +1,6 @@ //Warden and regular officers add this result to their get_access() /datum/job/proc/check_config_for_sec_maint() - if(config.jobs_have_maint_access & SECURITY_HAS_MAINT_ACCESS) + if(CONFIG_GET(flag/security_has_maint_access)) return list(ACCESS_MAINT_TUNNELS) return list() @@ -246,7 +246,7 @@ GLOBAL_LIST_INIT(available_depts, list(SEC_DEPT_ENGINEERING, SEC_DEPT_MEDICAL, S W.access |= dep_access var/teleport = 0 - if(!config.sec_start_brig) + if(!CONFIG_GET(flag/sec_start_brig)) if(destination || spawn_point) teleport = 1 if(teleport) diff --git a/code/modules/jobs/job_types/silicon.dm b/code/modules/jobs/job_types/silicon.dm index 2e0a710d41..d6cd75ee7b 100644 --- a/code/modules/jobs/job_types/silicon.dm +++ b/code/modules/jobs/job_types/silicon.dm @@ -14,6 +14,7 @@ AI minimal_player_age = 30 exp_requirements = 180 exp_type = EXP_TYPE_CREW +<<<<<<< HEAD /datum/job/ai/equip(mob/living/carbon/human/H) return H.AIize(FALSE) @@ -54,4 +55,44 @@ Cyborg /datum/job/cyborg/after_spawn(mob/living/silicon/robot/R, mob/M) if(config.rename_cyborg) //name can't be set in robot/New without the client +======= + +/datum/job/ai/equip(mob/living/carbon/human/H) + return H.AIize(FALSE) + +/datum/job/ai/after_spawn(mob/living/silicon/ai/AI, mob/M) + AI.rename_self("ai", M.client) + + //we may have been created after our borg + if(SSticker.current_state == GAME_STATE_SETTING_UP) + for(var/mob/living/silicon/robot/R in GLOB.silicon_mobs) + if(!R.connected_ai) + R.TryConnectToAI() + + +/datum/job/ai/config_check() + return CONFIG_GET(flag/allow_ai) + +/* +Cyborg +*/ +/datum/job/cyborg + title = "Cyborg" + flag = CYBORG + department_flag = ENGSEC + faction = "Station" + total_positions = 0 + spawn_positions = 1 + supervisors = "your laws and the AI" //Nodrak + selection_color = "#ddffdd" + minimal_player_age = 21 + exp_requirements = 120 + exp_type = EXP_TYPE_CREW + +/datum/job/cyborg/equip(mob/living/carbon/human/H) + return H.Robotize(FALSE, FALSE) + +/datum/job/cyborg/after_spawn(mob/living/silicon/robot/R, mob/M) + if(CONFIG_GET(flag/rename_cyborg)) //name can't be set in robot/New without the client +>>>>>>> 4178c20... Configuration datum refactor (#30763) R.rename_self("cyborg", M.client) \ No newline at end of file diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index 8a6250403f..26b671dd96 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -11,7 +11,7 @@ INITIALIZE_IMMEDIATE(/mob/dead) prepare_huds() - if(config.cross_allowed) + if(CONFIG_GET(string/cross_server_address)) verbs += /mob/dead/proc/server_hop return INITIALIZE_HINT_NORMAL @@ -32,19 +32,20 @@ INITIALIZE_IMMEDIATE(/mob/dead) set desc= "Jump to the other server" if(notransform) return - if(!config.cross_allowed) + var/csa = CONFIG_GET(string/cross_server_address) + if(csa) verbs -= /mob/dead/proc/server_hop to_chat(src, "Server Hop has been disabled.") return - if (alert(src, "Jump to server running at [config.cross_address]?", "Server Hop", "Yes", "No") != "Yes") + if (alert(src, "Jump to server running at [csa]?", "Server Hop", "Yes", "No") != "Yes") return 0 - if (client && config.cross_allowed) - to_chat(src, "Sending you to [config.cross_address].") + if (client && csa) + to_chat(src, "Sending you to [csa].") new /obj/screen/splash(client) notransform = TRUE sleep(29) //let the animation play notransform = FALSE winset(src, null, "command=.options") //other wise the user never knows if byond is downloading resources - client << link(config.cross_address + "?server_hop=[key]") + client << link(csa + "?server_hop=[key]") else to_chat(src, "There is no other server configured!") diff --git a/code/modules/mob/dead/new_player/login.dm b/code/modules/mob/dead/new_player/login.dm index 4de3b1d4dd..ce3c2cd64a 100644 --- a/code/modules/mob/dead/new_player/login.dm +++ b/code/modules/mob/dead/new_player/login.dm @@ -1,5 +1,5 @@ /mob/dead/new_player/Login() - if(config.use_exp_tracking) + if(CONFIG_GET(flag/use_exp_tracking)) client.set_exp_from_db() client.set_db_player_flags() if(!mind) @@ -15,8 +15,9 @@ if(GLOB.admin_notice) to_chat(src, "Admin Notice:\n \t [GLOB.admin_notice]") - if(config.soft_popcap && living_player_count() >= config.soft_popcap) - to_chat(src, "Server Notice:\n \t [config.soft_popcap_message]") + var/spc = CONFIG_GET(number/soft_popcap) + if(spc && living_player_count() >= spc) + to_chat(src, "Server Notice:\n \t [CONFIG_GET(string/soft_popcap_message)]") sight |= SEE_TURFS diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 4ecf2845db..aca1d9b63f 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -97,10 +97,12 @@ //Determines Relevent Population Cap var/relevant_cap - if(config.hard_popcap && config.extreme_popcap) - relevant_cap = min(config.hard_popcap, config.extreme_popcap) + var/hpc = CONFIG_GET(number/hard_popcap) + var/epc = CONFIG_GET(number/extreme_popcap) + if(hpc && epc) + relevant_cap = min(hpc, epc) else - relevant_cap = max(config.hard_popcap, config.extreme_popcap) + relevant_cap = max(hpc, epc) if(href_list["show_preferences"]) client.prefs.ShowChoices(src) @@ -133,7 +135,7 @@ return if(SSticker.queued_players.len || (relevant_cap && living_player_count() >= relevant_cap && !(ckey(key) in GLOB.admin_datums))) - to_chat(usr, "[config.hard_popcap_message]") + to_chat(usr, "[CONFIG_GET(string/hard_popcap_message)]") var/queue_position = SSticker.queued_players.Find(usr) if(queue_position == 1) @@ -309,7 +311,7 @@ return 0 if(job.required_playtime_remaining(client)) return 0 - if(config.enforce_human_authority && !client.prefs.pref_species.qualifies_for_rank(rank, client.prefs.features)) + if(CONFIG_GET(flag/enforce_human_authority) && !client.prefs.pref_species.qualifies_for_rank(rank, client.prefs.features)) return 0 return 1 @@ -326,11 +328,11 @@ var/arrivals_docked = TRUE if(SSshuttle.arrivals) close_spawn_windows() //In case we get held up - if(SSshuttle.arrivals.damaged && config.arrivals_shuttle_require_safe_latejoin) + if(SSshuttle.arrivals.damaged && CONFIG_GET(flag/arrivals_shuttle_require_safe_latejoin)) src << alert("The arrivals shuttle is currently malfunctioning! You cannot join.") return FALSE - if(config.arrivals_shuttle_require_undocked) + if(CONFIG_GET(flag/arrivals_shuttle_require_undocked)) SSshuttle.arrivals.RequireUndocked(src) arrivals_docked = SSshuttle.arrivals.mode != SHUTTLE_CALL @@ -374,7 +376,7 @@ GLOB.joined_player_list += character.ckey GLOB.latejoiners += character - if(config.allow_latejoin_antagonists && humanc) //Borgs aren't allowed to be antags. Will need to be tweaked if we get true latejoin ais. + if(CONFIG_GET(flag/allow_latejoin_antagonists) && humanc) //Borgs aren't allowed to be antags. Will need to be tweaked if we get true latejoin ais. if(SSshuttle.emergency) switch(SSshuttle.emergency.mode) if(SHUTTLE_RECALL, SHUTTLE_IDLE) @@ -458,7 +460,7 @@ var/mob/living/carbon/human/H = new(loc) - if(config.force_random_names || jobban_isbanned(src, "appearance")) + if(CONFIG_GET(flag/force_random_names) || jobban_isbanned(src, "appearance")) client.prefs.random_character() client.prefs.real_name = client.prefs.pref_species.random_name(gender,1) client.prefs.copy_to(H) diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm index 0a8dc6c733..cc98fd827e 100644 --- a/code/modules/mob/dead/new_player/preferences_setup.dm +++ b/code/modules/mob/dead/new_player/preferences_setup.dm @@ -14,7 +14,7 @@ facial_hair_color = hair_color eye_color = random_eye_color() if(!pref_species) - var/rando_race = pick(config.roundstart_races) + var/rando_race = pick(CONFIG_GET(keyed_flag_list/roundstart_races)) pref_species = new rando_race() features = random_features() age = rand(AGE_MIN,AGE_MAX) diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm index c437daef48..94ed0129c7 100644 --- a/code/modules/mob/living/brain/brain.dm +++ b/code/modules/mob/living/brain/brain.dm @@ -19,7 +19,7 @@ /mob/living/brain/proc/create_dna() stored_dna = new /datum/dna/stored(src) if(!stored_dna.species) - var/rando_race = pick(config.roundstart_races) + var/rando_race = pick(CONFIG_GET(keyed_flag_list/roundstart_races)) stored_dna.species = new rando_race() /mob/living/brain/Destroy() diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index 0a325521b0..b9bfc277c0 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /mob/living/carbon/alien/humanoid name = "alien" icon_state = "alien" @@ -121,4 +122,132 @@ /mob/living/carbon/alien/humanoid/check_breath(datum/gas_mixture/breath) if(breath && breath.total_moles() > 0 && !sneaking) playsound(get_turf(src), pick('sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg'), 50, 0, -5) - ..() \ No newline at end of file + ..() +======= +/mob/living/carbon/alien/humanoid + name = "alien" + icon_state = "alien" + pass_flags = PASSTABLE + butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/xeno = 5, /obj/item/stack/sheet/animalhide/xeno = 1) + possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM) + limb_destroyer = 1 + var/obj/item/r_store = null + var/obj/item/l_store = null + var/caste = "" + var/alt_icon = 'icons/mob/alienleap.dmi' //used to switch between the two alien icon files. + var/leap_on_click = 0 + var/pounce_cooldown = 0 + var/pounce_cooldown_time = 30 + var/custom_pixel_x_offset = 0 //for admin fuckery. + var/custom_pixel_y_offset = 0 + var/sneaking = 0 //For sneaky-sneaky mode and appropriate slowdown + var/drooling = 0 //For Neruotoxic spit overlays + bodyparts = list(/obj/item/bodypart/chest/alien, /obj/item/bodypart/head/alien, /obj/item/bodypart/l_arm/alien, + /obj/item/bodypart/r_arm/alien, /obj/item/bodypart/r_leg/alien, /obj/item/bodypart/l_leg/alien) + + +//This is fine right now, if we're adding organ specific damage this needs to be updated +/mob/living/carbon/alien/humanoid/Initialize() + AddAbility(new/obj/effect/proc_holder/alien/regurgitate(null)) + . = ..() + +/mob/living/carbon/alien/humanoid/movement_delay() + . = ..() + var/static/config_alien_delay + if(isnull(config_alien_delay)) + config_alien_delay = CONFIG_GET(number/alien_delay) + . += move_delay_add + config_alien_delay + sneaking //move_delay_add is used to slow aliens with stun + +/mob/living/carbon/alien/humanoid/restrained(ignore_grab) + . = handcuffed + + +/mob/living/carbon/alien/humanoid/show_inv(mob/user) + user.set_machine(src) + var/list/dat = list() + dat += {" +
    + [name] +
    "} + for(var/i in 1 to held_items.len) + var/obj/item/I = get_item_for_held_index(i) + dat += "
    [get_held_index_name(i)]:[(I && !(I.flags_1 & ABSTRACT_1)) ? I : "Empty"]" + dat += "
    Empty Pouches" + + if(handcuffed) + dat += "
    Handcuffed" + if(legcuffed) + dat += "
    Legcuffed" + + dat += {" +
    +
    Close + "} + user << browse(dat.Join(), "window=mob\ref[src];size=325x500") + onclose(user, "mob\ref[src]") + + +/mob/living/carbon/alien/humanoid/Topic(href, href_list) + ..() + //strip panel + if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) + if(href_list["pouches"]) + visible_message("[usr] tries to empty [src]'s pouches.", \ + "[usr] tries to empty [src]'s pouches.") + if(do_mob(usr, src, POCKET_STRIP_DELAY * 0.5)) + dropItemToGround(r_store) + dropItemToGround(l_store) + +/mob/living/carbon/alien/humanoid/cuff_resist(obj/item/I) + playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free + ..(I, cuff_break = INSTANT_CUFFBREAK) + +/mob/living/carbon/alien/humanoid/resist_grab(moving_resist) + if(pulledby.grab_state) + visible_message("[src] has broken free of [pulledby]'s grip!") + pulledby.stop_pulling() + . = 0 + +/mob/living/carbon/alien/humanoid/get_standard_pixel_y_offset(lying = 0) + if(leaping) + return -32 + else if(custom_pixel_y_offset) + return custom_pixel_y_offset + else + return initial(pixel_y) + +/mob/living/carbon/alien/humanoid/get_standard_pixel_x_offset(lying = 0) + if(leaping) + return -32 + else if(custom_pixel_x_offset) + return custom_pixel_x_offset + else + return initial(pixel_x) + +/mob/living/carbon/alien/humanoid/get_permeability_protection() + return 0.8 + +/mob/living/carbon/alien/humanoid/alien_evolve(mob/living/carbon/alien/humanoid/new_xeno) + drop_all_held_items() + for(var/atom/movable/A in stomach_contents) + stomach_contents.Remove(A) + new_xeno.stomach_contents.Add(A) + A.loc = new_xeno + ..() + +//For alien evolution/promotion/queen finder procs. Checks for an active alien of that type +/proc/get_alien_type(var/alienpath) + for(var/mob/living/carbon/alien/humanoid/A in GLOB.living_mob_list) + if(!istype(A, alienpath)) + continue + if(!A.key || A.stat == DEAD) //Only living aliens with a ckey are valid. + continue + return A + return FALSE + + +/mob/living/carbon/alien/humanoid/check_breath(datum/gas_mixture/breath) + if(breath && breath.total_moles() > 0 && !sneaking) + playsound(get_turf(src), pick('sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg'), 50, 0, -5) + ..() +>>>>>>> 4178c20... Configuration datum refactor (#30763) diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 06f3007e6b..4fba96df58 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -1,8 +1,9 @@ /mob/living/carbon/human/movement_delay() . = 0 - . += ..() - . += config.human_delay - . += dna.species.movement_delay(src) + var/static/config_human_delay + if(isnull(config_human_delay)) + config_human_delay = CONFIG_GET(number/human_delay) + . += ..() + config_human_delay + dna.species.movement_delay(src) /mob/living/carbon/human/slip(knockdown_amount, obj/O, lube) if(isobj(shoes) && (shoes.flags_1&NOSLIP_1) && !(lube&GALOSHES_DONT_HELP)) diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 81e918e152..2fcfe97d65 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -62,7 +62,11 @@ if (bodytemperature < 283.222) . += (283.222 - bodytemperature) / 10 * 1.75 - return . + config.monkey_delay + + var/static/config_monkey_delay + if(isnull(config_monkey_delay)) + config_monkey_delay = CONFIG_GET(number/monkey_delay) + . += config_monkey_delay /mob/living/carbon/monkey/Stat() ..() diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index fccb3ab8dd..8401d92676 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -157,7 +157,7 @@ /mob/living/proc/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE) if(!forced && (status_flags & GODMODE)) return FALSE - bruteloss = Clamp((bruteloss + (amount * config.damage_multiplier)), 0, maxHealth*2) + bruteloss = Clamp((bruteloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) if(updating_health) updatehealth() return amount @@ -168,7 +168,7 @@ /mob/living/proc/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE) if(!forced && (status_flags & GODMODE)) return FALSE - oxyloss = Clamp((oxyloss + (amount * config.damage_multiplier)), 0, maxHealth*2) + oxyloss = Clamp((oxyloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) if(updating_health) updatehealth() return amount @@ -187,7 +187,7 @@ /mob/living/proc/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE) if(!forced && (status_flags & GODMODE)) return FALSE - toxloss = Clamp((toxloss + (amount * config.damage_multiplier)), 0, maxHealth*2) + toxloss = Clamp((toxloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) if(updating_health) updatehealth() return amount @@ -206,7 +206,7 @@ /mob/living/proc/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE) if(!forced && (status_flags & GODMODE)) return FALSE - fireloss = Clamp((fireloss + (amount * config.damage_multiplier)), 0, maxHealth*2) + fireloss = Clamp((fireloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) if(updating_health) updatehealth() return amount @@ -217,7 +217,7 @@ /mob/living/proc/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE) if(!forced && (status_flags & GODMODE)) return FALSE - cloneloss = Clamp((cloneloss + (amount * config.damage_multiplier)), 0, maxHealth*2) + cloneloss = Clamp((cloneloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) if(updating_health) updatehealth() return amount @@ -236,7 +236,7 @@ /mob/living/proc/adjustBrainLoss(amount) if(status_flags & GODMODE) return 0 - brainloss = Clamp((brainloss + (amount * config.damage_multiplier)), 0, maxHealth*2) + brainloss = Clamp((brainloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) /mob/living/proc/setBrainLoss(amount) if(status_flags & GODMODE) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 649e19ba29..8d992ea687 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -412,7 +412,7 @@ set category = "OOC" set src in view() - if(config.allow_Metadata) + if(CONFIG_GET(flag/allow_metadata)) if(client) to_chat(src, "[src]'s Metainfo:
    [client.prefs.metadata]") else @@ -464,16 +464,21 @@ if(isopenturf(loc) && !is_flying()) var/turf/open/T = loc . += T.slowdown + var/static/config_run_delay + var/static/config_walk_delay + if(isnull(config_run_delay)) + config_run_delay = CONFIG_GET(number/run_delay) + config_walk_delay = CONFIG_GET(number/walk_delay) if(ignorewalk) - . += config.run_speed + . += config_run_delay else switch(m_intent) if(MOVE_INTENT_RUN) if(drowsyness > 0) . += 6 - . += config.run_speed + . += config_run_delay if(MOVE_INTENT_WALK) - . += config.walk_speed + . += config_walk_delay /mob/living/proc/makeTrail(turf/target_turf, turf/start, direction) if(!has_gravity()) diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm index e148bd2763..8429889ebd 100644 --- a/code/modules/mob/living/silicon/ai/say.dm +++ b/code/modules/mob/living/silicon/ai/say.dm @@ -15,7 +15,7 @@ return "[radio_freq ? " (" + speaker.GetJob() + ")" : ""]" + "[speaker.GetSource() ? "" : ""]" /mob/living/silicon/ai/IsVocal() - return !config.silent_ai + return !CONFIG_GET(flag/silent_ai) /mob/living/silicon/ai/radio(message, message_mode, list/spans, language) if(incapacitated()) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index e264f00cf1..0c5489cf59 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -207,13 +207,18 @@ "Medical" = /obj/item/robot_module/medical, \ "Miner" = /obj/item/robot_module/miner, \ "Janitor" = /obj/item/robot_module/janitor, \ +<<<<<<< HEAD "Service" = /obj/item/robot_module/butler, \ "MediHound" = /obj/item/robot_module/medihound, \ "Security K9" = /obj/item/robot_module/k9, \ "Scrub Puppy" = /obj/item/robot_module/scrubpup) if(!config.forbid_peaceborg) +======= + "Service" = /obj/item/robot_module/butler) + if(!CONFIG_GET(flag/disable_peaceborg)) +>>>>>>> 4178c20... Configuration datum refactor (#30763) modulelist["Peacekeeper"] = /obj/item/robot_module/peacekeeper - if(!config.forbid_secborg) + if(!CONFIG_GET(flag/disable_secborg)) modulelist["Security"] = /obj/item/robot_module/security var/input_module = input("Please, select a module!", "Robot", null, null) as null|anything in modulelist diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm index 167137d9d1..d48cd9e301 100644 --- a/code/modules/mob/living/silicon/robot/robot_movement.dm +++ b/code/modules/mob/living/silicon/robot/robot_movement.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /mob/living/silicon/robot/Process_Spacemove(movement_dir = 0) if(ionpulse()) return 1 @@ -22,3 +23,31 @@ . = ..() if(riding_datum) riding_datum.on_vehicle_move() +======= +/mob/living/silicon/robot/Process_Spacemove(movement_dir = 0) + if(ionpulse()) + return 1 + return ..() + +/mob/living/silicon/robot/movement_delay() + . = ..() + var/static/config_robot_delay + if(isnull(config_robot_delay)) + config_robot_delay = CONFIG_GET(number/robot_delay) + . += speed + config_robot_delay + +/mob/living/silicon/robot/mob_negates_gravity() + return magpulse + +/mob/living/silicon/robot/mob_has_gravity() + return ..() || mob_negates_gravity() + +/mob/living/silicon/robot/experience_pressure_difference(pressure_difference, direction) + if(!magpulse) + return ..() + +/mob/living/silicon/robot/Moved() + . = ..() + if(riding_datum) + riding_datum.on_vehicle_move() +>>>>>>> 4178c20... Configuration datum refactor (#30763) diff --git a/code/modules/mob/living/silicon/robot/say.dm b/code/modules/mob/living/silicon/robot/say.dm index 866debc30e..ada91337eb 100644 --- a/code/modules/mob/living/silicon/robot/say.dm +++ b/code/modules/mob/living/silicon/robot/say.dm @@ -1,2 +1,7 @@ +<<<<<<< HEAD /mob/living/silicon/robot/IsVocal() return !config.silent_borg +======= +/mob/living/silicon/robot/IsVocal() + return !CONFIG_GET(flag/silent_borg) +>>>>>>> 4178c20... Configuration datum refactor (#30763) diff --git a/code/modules/mob/living/simple_animal/damage_procs.dm b/code/modules/mob/living/simple_animal/damage_procs.dm index 01a30e9b04..5405ee03c6 100644 --- a/code/modules/mob/living/simple_animal/damage_procs.dm +++ b/code/modules/mob/living/simple_animal/damage_procs.dm @@ -9,33 +9,33 @@ /mob/living/simple_animal/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE) if(forced) - . = adjustHealth(amount * config.damage_multiplier, updating_health, forced) + . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) else if(damage_coeff[BRUTE]) - . = adjustHealth(amount * damage_coeff[BRUTE] * config.damage_multiplier, updating_health, forced) + . = adjustHealth(amount * damage_coeff[BRUTE] * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/simple_animal/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE) if(forced) - . = adjustHealth(amount * config.damage_multiplier, updating_health, forced) + . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) else if(damage_coeff[BURN]) - . = adjustHealth(amount * damage_coeff[BURN] * config.damage_multiplier, updating_health, forced) + . = adjustHealth(amount * damage_coeff[BURN] * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/simple_animal/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE) if(forced) - . = adjustHealth(amount * config.damage_multiplier, updating_health, forced) + . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) else if(damage_coeff[OXY]) - . = adjustHealth(amount * damage_coeff[OXY] * config.damage_multiplier, updating_health, forced) + . = adjustHealth(amount * damage_coeff[OXY] * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/simple_animal/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE) if(forced) - . = adjustHealth(amount * config.damage_multiplier, updating_health, forced) + . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) else if(damage_coeff[TOX]) - . = adjustHealth(amount * damage_coeff[TOX] * config.damage_multiplier, updating_health, forced) + . = adjustHealth(amount * damage_coeff[TOX] * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/simple_animal/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE) if(forced) - . = adjustHealth(amount * config.damage_multiplier, updating_health, forced) + . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) else if(damage_coeff[CLONE]) - . = adjustHealth(amount * damage_coeff[CLONE] * config.damage_multiplier, updating_health, forced) + . = adjustHealth(amount * damage_coeff[CLONE] * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/simple_animal/adjustStaminaLoss(amount) return diff --git a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm index 8881eb5407..9900133723 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm @@ -30,7 +30,7 @@ /obj/item/drone_shell/attack_ghost(mob/user) if(jobban_isbanned(user,"drone")) return - if(config.use_age_restriction_for_jobs) + if(CONFIG_GET(flag/use_age_restriction_for_jobs)) if(!isnum(user.client.player_age)) //apparently what happens when there's no DB connected. just don't let anybody be a drone without admin intervention return if(user.client.player_age < DRONE_MINIMUM_AGE) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm index a80340c28a..3d2f7cf28e 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -130,7 +130,7 @@ if(admin_spawned) return FALSE - if(global.medal_hub && global.medal_pass && global.medals_enabled) + if(MedalsAvailable()) for(var/mob/living/L in view(7,src)) if(L.stat) continue @@ -147,10 +147,10 @@ set waitfor = FALSE if(!player || !medal) return - if(global.medal_hub && global.medal_pass && global.medals_enabled) - var/result = world.SetMedal(medal, player, global.medal_hub, global.medal_pass) + if(MedalsAvailable()) + var/result = world.SetMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password)) if(isnull(result)) - global.medals_enabled = FALSE + GLOB.medals_enabled = FALSE log_game("MEDAL ERROR: Could not contact hub to award medal:[medal] player:[player.ckey]") message_admins("Error! Failed to contact hub to award [medal] medal to [player.ckey]!") else if (result) @@ -161,9 +161,8 @@ set waitfor = FALSE if(!score || !player) return - if(global.medal_hub && global.medal_pass && global.medals_enabled) + if(MedalsAvailable()) var/list/oldscore = GetScore(score,player,1) - if(increment) if(!oldscore[score]) oldscore[score] = 1 @@ -174,10 +173,10 @@ var/newscoreparam = list2params(oldscore) - var/result = world.SetScores(player.ckey, newscoreparam, global.medal_hub, global.medal_pass) + var/result = world.SetScores(player.ckey, newscoreparam, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password)) if(isnull(result)) - global.medals_enabled = FALSE + GLOB.medals_enabled = FALSE log_game("SCORE ERROR: Could not contact hub to set score. Score:[score] player:[player.ckey]") message_admins("Error! Failed to contact hub to set [score] score for [player.ckey]!") @@ -186,11 +185,11 @@ if(!score || !player) return - if(global.medal_hub && global.medal_pass && global.medals_enabled) + if(MedalsAvailable()) - var/scoreget = world.GetScores(player.ckey, score, global.medal_hub, global.medal_pass) + var/scoreget = world.GetScores(player.ckey, score, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password)) if(isnull(scoreget)) - global.medals_enabled = FALSE + GLOB.medals_enabled = FALSE log_game("SCORE ERROR: Could not contact hub to get score. Score:[score] player:[player.ckey]") message_admins("Error! Failed to contact hub to get score: [score] for [player.ckey]!") return @@ -207,12 +206,12 @@ if(!player || !medal) return - if(global.medal_hub && global.medal_pass && global.medals_enabled) + if(MedalsAvailable()) - var/result = world.GetMedal(medal, player, global.medal_hub, global.medal_pass) + var/result = world.GetMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password)) if(isnull(result)) - global.medals_enabled = FALSE + GLOB.medals_enabled = FALSE log_game("MEDAL ERROR: Could not contact hub to get medal:[medal] player:[player.ckey]") message_admins("Error! Failed to contact hub to get [medal] medal for [player.ckey]!") else if (result) @@ -222,12 +221,12 @@ if(!player || !medal) return - if(global.medal_hub && global.medal_pass && global.medals_enabled) + if(MedalsAvailable()) - var/result = world.ClearMedal(medal, player, global.medal_hub, global.medal_pass) + var/result = world.ClearMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password)) if(isnull(result)) - global.medals_enabled = FALSE + GLOB.medals_enabled = FALSE log_game("MEDAL ERROR: Could not contact hub to clear medal:[medal] player:[player.ckey]") message_admins("Error! Failed to contact hub to clear [medal] medal for [player.ckey]!") else if (result) @@ -237,6 +236,9 @@ /proc/ClearScore(client/player) - world.SetScores(player.ckey, "", global.medal_hub, global.medal_pass) + world.SetScores(player.ckey, "", CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password)) + +/proc/MedalsAvailable() + return CONFIG_GET(string/medal_hub_address) && CONFIG_GET(string/medal_hub_password) && GLOB.medals_enabled #undef MEDAL_PREFIX diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm index 5a3672af6d..d5d116d678 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/necropolis_tendril.dm @@ -55,7 +55,7 @@ last_tendril = FALSE break if(last_tendril && !admin_spawned) - if(global.medal_hub && global.medal_pass && global.medals_enabled) + if(MedalsAvailable()) for(var/mob/living/L in view(7,src)) if(L.stat) continue diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 144fec4a4a..5467aad549 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -275,7 +275,10 @@ . = speed - . += config.animal_delay + var/static/config_animal_delay + if(isnull(config_animal_delay)) + config_animal_delay = CONFIG_GET(number/animal_delay) + . += config_animal_delay /mob/living/simple_animal/Stat() ..() diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm index 6026a86724..a3c37e9889 100644 --- a/code/modules/mob/living/simple_animal/slime/life.dm +++ b/code/modules/mob/living/simple_animal/slime/life.dm @@ -234,7 +234,7 @@ Feedstop(0, 0) return - add_nutrition((rand(7,15) * config.damage_multiplier)) + add_nutrition((rand(7, 15) * CONFIG_GET(number/damage_multiplier))) //Heal yourself. adjustBruteLoss(-3) diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index 0e7d7a157e..92d64702bb 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -146,7 +146,10 @@ if(health <= 0) // if damaged, the slime moves twice as slow . *= 2 - . += config.slime_delay + var/static/config_slime_delay + if(isnull(config_slime_delay)) + config_slime_delay = CONFIG_GET(number/slime_delay) + . += config_slime_delay /mob/living/simple_animal/slime/ObjCollide(obj/O) if(!client && powerlevel > 0) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index f768cbe2d2..df99f53e88 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -436,7 +436,7 @@ set name = "Respawn" set category = "OOC" - if (!( GLOB.abandon_allowed )) + if (CONFIG_GET(flag/norespawn)) return if ((stat != DEAD || !( SSticker ))) to_chat(usr, "You must be dead to use this!") diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index f9763cde7d..a543e0825b 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -383,7 +383,7 @@ else if(transfer_after) R.key = key - if (config.rename_cyborg) + if (CONFIG_GET(flag/rename_cyborg)) R.rename_self("cyborg") if(R.mmi) diff --git a/code/modules/modular_computers/file_system/programs/card.dm b/code/modules/modular_computers/file_system/programs/card.dm index 5dd6d16d54..ead6a35eea 100644 --- a/code/modules/modular_computers/file_system/programs/card.dm +++ b/code/modules/modular_computers/file_system/programs/card.dm @@ -44,7 +44,7 @@ addtimer(CALLBACK(src, .proc/SetConfigCooldown), 0) /datum/computer_file/program/card_mod/proc/SetConfigCooldown() - change_position_cooldown = config.id_console_jobslot_delay + change_position_cooldown = CONFIG_GET(number/id_console_jobslot_delay) /datum/computer_file/program/card_mod/event_idremoved(background, slot) if(!slot || slot == 2)// slot being false means both are removed diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index e18ac0ab5c..84db583282 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -280,7 +280,7 @@ if(can_hit_target(original, permutated)) Collide(original) Range() - sleep(config.run_speed * 0.9) + sleep(CONFIG_GET(number/run_delay) * 0.9) //Returns true if the target atom is on our current turf and above the right layer /obj/item/projectile/proc/can_hit_target(atom/target, var/list/passthrough) diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 8c4f80b772..6571ab79b5 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -276,7 +276,9 @@ to_chat(new_mob, "Your form morphs into that of a [randomize].") - to_chat(new_mob, config.policies["polymorph"]) + var/poly_msg = CONFIG_GET(keyed_string_list/policy)["polymorph"] + if(poly_msg) + to_chat(new_mob, poly_msg) qdel(M) return new_mob diff --git a/code/modules/security_levels/security_levels.dm b/code/modules/security_levels/security_levels.dm index 1fa3e89d3a..a145028ad3 100644 --- a/code/modules/security_levels/security_levels.dm +++ b/code/modules/security_levels/security_levels.dm @@ -21,7 +21,7 @@ GLOBAL_VAR_INIT(security_level, 0) if(level >= SEC_LEVEL_GREEN && level <= SEC_LEVEL_DELTA && level != GLOB.security_level) switch(level) if(SEC_LEVEL_GREEN) - minor_announce(config.alert_desc_green, "Attention! Security level lowered to green:") + minor_announce(CONFIG_GET(string/alert_green), "Attention! Security level lowered to green:") if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) if(GLOB.security_level >= SEC_LEVEL_RED) SSshuttle.emergency.modTimer(4) @@ -33,11 +33,11 @@ GLOBAL_VAR_INIT(security_level, 0) FA.update_icon() if(SEC_LEVEL_BLUE) if(GLOB.security_level < SEC_LEVEL_BLUE) - minor_announce(config.alert_desc_blue_upto, "Attention! Security level elevated to blue:",1) + minor_announce(CONFIG_GET(string/alert_blue_upto), "Attention! Security level elevated to blue:",1) if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) SSshuttle.emergency.modTimer(0.5) else - minor_announce(config.alert_desc_blue_downto, "Attention! Security level lowered to blue:") + minor_announce(CONFIG_GET(string/alert_blue_downto), "Attention! Security level lowered to blue:") if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) SSshuttle.emergency.modTimer(2) GLOB.security_level = SEC_LEVEL_BLUE @@ -47,14 +47,14 @@ GLOBAL_VAR_INIT(security_level, 0) FA.update_icon() if(SEC_LEVEL_RED) if(GLOB.security_level < SEC_LEVEL_RED) - minor_announce(config.alert_desc_red_upto, "Attention! Code red!",1) + minor_announce(CONFIG_GET(string/alert_red_upto), "Attention! Code red!",1) if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) if(GLOB.security_level == SEC_LEVEL_GREEN) SSshuttle.emergency.modTimer(0.25) else SSshuttle.emergency.modTimer(0.5) else - minor_announce(config.alert_desc_red_downto, "Attention! Code red!") + minor_announce(CONFIG_GET(string/alert_red_downto), "Attention! Code red!") GLOB.security_level = SEC_LEVEL_RED /* - At the time of commit, setting status displays didn't work properly @@ -68,7 +68,7 @@ GLOBAL_VAR_INIT(security_level, 0) for(var/obj/machinery/computer/shuttle/pod/pod in GLOB.machines) pod.admin_controlled = 0 if(SEC_LEVEL_DELTA) - minor_announce(config.alert_desc_delta, "Attention! Delta security level reached!",1) + minor_announce(CONFIG_GET(string/alert_delta), "Attention! Delta security level reached!",1) if(SSshuttle.emergency.mode == SHUTTLE_CALL || SSshuttle.emergency.mode == SHUTTLE_RECALL) if(GLOB.security_level == SEC_LEVEL_GREEN) SSshuttle.emergency.modTimer(0.25) diff --git a/code/modules/server_tools/server_tools.dm b/code/modules/server_tools/server_tools.dm index f16a56b2f9..9cacb4542f 100644 --- a/code/modules/server_tools/server_tools.dm +++ b/code/modules/server_tools/server_tools.dm @@ -77,7 +77,8 @@ GLOBAL_PROTECT(reboot_mode) if(rtod - last_irc_status < IRC_STATUS_THROTTLE) return last_irc_status = rtod - return "[GLOB.round_id ? "Round #[GLOB.round_id]: " : ""][GLOB.clients.len] players on [SSmapping.config.map_name], Mode: [GLOB.master_mode]; Round [SSticker.HasRoundStarted() ? (SSticker.IsRoundInProgress() ? "Active" : "Finishing") : "Starting"] -- [config.server ? config.server : "[world.internet_address]:[world.port]"]" + var/config_server = CONFIG_GET(string/server) + return "[GLOB.round_id ? "Round #[GLOB.round_id]: " : ""][GLOB.clients.len] players on [SSmapping.config.map_name], Mode: [GLOB.master_mode]; Round [SSticker.HasRoundStarted() ? (SSticker.IsRoundInProgress() ? "Active" : "Finishing") : "Starting"] -- [config_server ? config_server : "[world.internet_address]:[world.port]"]" if(SERVICE_CMD_ADMIN_MSG) return IrcPm(params[SERVICE_CMD_PARAM_TARGET], params[SERVICE_CMD_PARAM_MESSAGE], params[SERVICE_CMD_PARAM_SENDER]) diff --git a/code/modules/shuttle/arrivals.dm b/code/modules/shuttle/arrivals.dm index 16aa279901..b42ee4e0e4 100644 --- a/code/modules/shuttle/arrivals.dm +++ b/code/modules/shuttle/arrivals.dm @@ -130,7 +130,7 @@ return FALSE /obj/docking_port/mobile/arrivals/proc/SendToStation() - var/dockTime = config.arrivals_shuttle_dock_window + var/dockTime = CONFIG_GET(number/arrivals_shuttle_dock_window) if(mode == SHUTTLE_CALL && timeLeft(1) > dockTime) if(console) console.say(damaged ? "Initiating emergency docking for repairs!" : "Now approaching: [station_name()].") diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm index b239e39576..f05a3a7e42 100644 --- a/code/modules/surgery/bodyparts/bodyparts.dm +++ b/code/modules/surgery/bodyparts/bodyparts.dm @@ -108,8 +108,9 @@ /obj/item/bodypart/proc/receive_damage(brute, burn, updating_health = 1) if(owner && (owner.status_flags & GODMODE)) return 0 //godmode - brute = max(brute * config.damage_multiplier,0) - burn = max(burn * config.damage_multiplier,0) + var/dmg_mlt = CONFIG_GET(number/damage_multiplier) + brute = max(brute * dmg_mlt, 0) + burn = max(burn * dmg_mlt, 0) if(status == BODYPART_ROBOTIC) //This makes robolimbs not damageable by chems and makes it stronger diff --git a/config/config.txt b/config/config.txt index 80a587885b..079ec0d9c6 100644 --- a/config/config.txt +++ b/config/config.txt @@ -300,8 +300,11 @@ ALLOW_MAP_VOTING 1 #MAPROTATIONCHANCEDELTA 0.75 ## AUTOADMIN +## The default admin rank +AUTOADMIN_RANK Game Master + ## Uncomment to automatically give that admin rank to all players -#AUTOADMIN Game Admin +#AUTOADMIN ## GENERATE_MINIMAPS ## Generating minimaps(For crew monitor) is slow and bogs down testing, so its disabled by default and must be enabled by uncommenting this config if you are running a production server. diff --git a/config/game_options.txt b/config/game_options.txt index b609f8b582..77e33fa873 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -85,7 +85,6 @@ PROBABILITY REVOLUTION 2 PROBABILITY CULT 2 PROBABILITY CHANGELING 2 PROBABILITY WIZARD 4 -PROBABILITY MALFUNCTION 1 PROBABILITY BLOB 2 PROBABILITY RAGINMAGES 2 PROBABILITY MONKEY 0 @@ -115,7 +114,6 @@ CONTINUOUS CULT CONTINUOUS CLOCKWORK_CULT CONTINUOUS CHANGELING CONTINUOUS WIZARD -CONTINUOUS MALFUNCTION CONTINUOUS BLOB CONTINUOUS ABDUCTION #CONTINUOUS RAGINMAGES @@ -141,7 +139,6 @@ MIDROUND_ANTAG CULT MIDROUND_ANTAG CLOCKWORK_CULT MIDROUND_ANTAG CHANGELING MIDROUND_ANTAG WIZARD -MIDROUND_ANTAG MALFUNCTION MIDROUND_ANTAG BLOB MIDROUND_ANTAG ABDUCTION #MIDROUND_ANTAG RAGINMAGES @@ -486,7 +483,7 @@ LAVALAND_BUDGET 60 Space_Budget 16 ## Time in ds from when a player latejoins till the arrival shuttle docks at the station -## Must be at least 30 to not break parallax I recommended at least 55 to be visually/aurally appropriate +## Must be at least 30. At least 55 recommended to be visually/aurally appropriate ARRIVALS_SHUTTLE_DOCK_WINDOW 55 ## Uncomment to require the arrivals shuttle to be in flight (if it can fly) before late join players can join diff --git a/interface/interface.dm b/interface/interface.dm index 9ee5309585..9d420e9821 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -3,12 +3,13 @@ set name = "wiki" set desc = "Type what you want to know about. This will open the wiki in your web browser. Type nothing to go to the main page." set hidden = 1 - if(config.wikiurl) + var/wikiurl = CONFIG_GET(string/wikiurl) + if(wikiurl) if(query) - var/output = config.wikiurl + "/index.php?title=Special%3ASearch&profile=default&search=" + query + var/output = wikiurl + "/index.php?title=Special%3ASearch&profile=default&search=" + query src << link(output) else if (query != null) - src << link(config.wikiurl) + src << link(wikiurl) else to_chat(src, "The wiki URL is not set in the server configuration.") return @@ -17,10 +18,11 @@ set name = "forum" set desc = "Visit the forum." set hidden = 1 - if(config.forumurl) + var/forumurl = CONFIG_GET(string/forumurl) + if(forumurl) if(alert("This will open the forum in your browser. Are you sure?",,"Yes","No")=="No") return - src << link(config.forumurl) + src << link(forumurl) else to_chat(src, "The forum URL is not set in the server configuration.") return @@ -29,10 +31,11 @@ set name = "rules" set desc = "Show Server Rules." set hidden = 1 - if(config.rulesurl) + var/rulesurl = CONFIG_GET(string/rulesurl) + if(rulesurl) if(alert("This will open the rules in your browser. Are you sure?",,"Yes","No")=="No") return - src << link(config.rulesurl) + src << link(rulesurl) else to_chat(src, "The rules URL is not set in the server configuration.") return @@ -41,10 +44,11 @@ set name = "github" set desc = "Visit Github" set hidden = 1 - if(config.githuburl) + var/githuburl = CONFIG_GET(string/githuburl) + if(githuburl) if(alert("This will open the Github repository in your browser. Are you sure?",,"Yes","No")=="No") return - src << link(config.githuburl) + src << link(githuburl) else to_chat(src, "The Github URL is not set in the server configuration.") return @@ -53,14 +57,15 @@ set name = "report-issue" set desc = "Report an issue" set hidden = 1 - if(config.githuburl) + var/githuburl = CONFIG_GET(string/githuburl) + if(githuburl) var/message = "This will open the Github issue reporter in your browser. Are you sure?" if(GLOB.revdata.testmerge.len) message += "
    The following experimental changes are active and are probably the cause of any new or sudden issues you may experience. If possible, please try to find a specific thread for your issue instead of posting to the general issue tracker:
    " message += GLOB.revdata.GetTestMergeInfo(FALSE) if(tgalert(src, message, "Report Issue","Yes","No")=="No") return - src << link("[config.githuburl]/issues/new") + src << link("[githuburl]/issues/new") else to_chat(src, "The Github URL is not set in the server configuration.") return diff --git a/tgstation.dme b/tgstation.dme index 525e30ca66..46b6dd1034 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -33,6 +33,7 @@ #include "code\__DEFINES\clockcult.dm" #include "code\__DEFINES\combat.dm" #include "code\__DEFINES\components.dm" +#include "code\__DEFINES\configuration.dm" #include "code\__DEFINES\construction.dm" #include "code\__DEFINES\contracts.dm" #include "code\__DEFINES\cult.dm" @@ -112,7 +113,6 @@ #include "code\_globalvars\genetics.dm" #include "code\_globalvars\logging.dm" #include "code\_globalvars\misc.dm" -#include "code\_globalvars\sensitive.dm" #include "code\_globalvars\lists\flavor_misc.dm" #include "code\_globalvars\lists\maintenance_loot.dm" #include "code\_globalvars\lists\mapping.dm" @@ -163,6 +163,7 @@ #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\screen_objects.dm" #include "code\_onclick\hud\swarmer.dm" +<<<<<<< HEAD #include "code\citadel\_cit_helpers.dm" #include "code\citadel\cit_areas.dm" #include "code\citadel\cit_arousal.dm" @@ -192,6 +193,15 @@ #include "code\controllers\admin.dm" #include "code\controllers\configuration.dm" #include "code\controllers\configuration_citadel.dm" +======= +#include "code\controllers\configuration\entries\comms.dm" +#include "code\controllers\configuration\entries\config.dm" +#include "code\controllers\configuration\entries\dbconfig.dm" +#include "code\controllers\configuration\entries\game_options.dm" +#include "code\controllers\configuration\config_entry.dm" +#include "code\controllers\configuration\configuration.dm" +#include "code\controllers\admin.dm" +>>>>>>> 4178c20... Configuration datum refactor (#30763) #include "code\controllers\controller.dm" #include "code\controllers\failsafe.dm" #include "code\controllers\globals.dm" From df16529ed34d26655ad7d5c9242ab43f46e13084 Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Thu, 28 Sep 2017 19:44:15 -0700 Subject: [PATCH 03/60] Adds steal research levels objectives to traitors+lings, makes it work for everyone not just ninjas. (#30722) * initial commit * bugfix * Update changeling.dm * Update datum_traitor.dm * Update datum_traitor.dm * Update objective.dm * compile --- code/datums/antagonists/datum_traitor.dm | 16 +++++--- code/game/gamemodes/changeling/changeling.dm | 14 +++++-- code/game/gamemodes/objective.dm | 43 ++++++++++++-------- 3 files changed, 46 insertions(+), 27 deletions(-) diff --git a/code/datums/antagonists/datum_traitor.dm b/code/datums/antagonists/datum_traitor.dm index eeb803ca1e..2832db720e 100644 --- a/code/datums/antagonists/datum_traitor.dm +++ b/code/datums/antagonists/datum_traitor.dm @@ -85,7 +85,7 @@ if(owner.assigned_role == "Clown") var/mob/living/carbon/human/traitor_mob = owner.current if(traitor_mob&&istype(traitor_mob)) - if(!silent) + if(!silent) to_chat(traitor_mob, "Your training has allowed you to overcome your clownish nature, allowing you to wield weapons without harming yourself.") traitor_mob.dna.remove_mutation(CLOWNMUT) @@ -216,10 +216,16 @@ kill_objective.find_target() add_objective(kill_objective) else - var/datum/objective/steal/steal_objective = new - steal_objective.owner = owner - steal_objective.find_target() - add_objective(steal_objective) + if(prob(15) && !(locate(/datum/objective/download in owner.objectives))) + var/datum/objective/download/download_objective = new + download_objective.owner = owner + download_objective.gen_amount_goal() + add_objective(download_objective) + else + var/datum/objective/steal/steal_objective = new + steal_objective.owner = owner + steal_objective.find_target() + add_objective(steal_objective) /datum/antagonist/traitor/AI/forge_single_objective() .=1 diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index e67ac26d3a..015b6d9521 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -131,10 +131,16 @@ GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "w changeling.objectives += absorb_objective if(prob(60)) - var/datum/objective/steal/steal_objective = new - steal_objective.owner = changeling - steal_objective.find_target() - changeling.objectives += steal_objective + if(prob(85)) + var/datum/objective/steal/steal_objective = new + steal_objective.owner = changeling + steal_objective.find_target() + changeling.objectives += steal_objective + else + var/datum/objective/download/download_objective = new + download_objective.owner = changeling + download_objective.gen_amount_goal() + changeling.objectives += download_objective var/list/active_ais = active_ais() if(active_ais.len && prob(100/GLOB.joined_player_list.len)) diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 75ed90d712..49332a443b 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -506,24 +506,31 @@ GLOBAL_LIST_EMPTY(possible_items_special) explanation_text = "Download [target_amount] research level\s." return target_amount -/datum/objective/download/check_completion()//NINJACODE. - var/current_amount = 0 +/datum/objective/download/check_completion() + var/list/current_tech = list() var/list/datum/mind/owners = get_owners() - for(var/datum/mind/M in owners) - if(!ishuman(owner.current)) - continue - var/mob/living/carbon/human/H = owner.current - if(!H || H.stat == DEAD || !istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja)) - continue - var/obj/item/clothing/suit/space/space_ninja/SN = H.wear_suit - if(!SN.s_initialized) - continue - for(var/datum/tech/current_data in SN.stored_research) - if(current_data.level) - current_amount += (current_data.level-1) - return current_amount >= target_amount - - + for(var/datum/mind/owner in owners) + if(ismob(owner.current)) + var/mob/M = owner.current //Yeah if you get morphed and you eat a quantum tech disk with the RD's latest backup good on you soldier. + if(ishuman(M)) + var/mob/living/carbon/human/H = M + if(H && (H.stat != DEAD) && istype(H.wear_suit, /obj/item/clothing/suit/space/space_ninja)) + var/obj/item/clothing/suit/space/space_ninja/S = H.wear_suit + for(var/datum/tech/T in S.stored_research) + current_tech[T.id] = T.level? T.level : 0 + var/list/otherwise = M.GetAllContents() + for(var/obj/item/disk/tech_disk/TD in otherwise) + for(var/datum/tech/T in TD.tech_stored) + if(!T.id || !T.level) + continue + else if(!current_tech[T.id]) + current_tech[T.id] = T.level + else if(T.level > current_tech[T.id]) + current_tech[T.id] = T.level + var/total = 0 + for(var/i in current_tech) + total += current_tech[i] + return total >= target_amount /datum/objective/capture @@ -586,7 +593,7 @@ GLOBAL_LIST_EMPTY(possible_items_special) for(var/datum/mind/M in owners) if(!owner || !owner.changeling || !owner.changeling.stored_profiles) continue - absorbedcount += M.changeling.absorbedcount + absorbedcount += M.changeling.absorbedcount return absorbedcount >= target_amount From 7621d1da917291d8e4498365a0eeab3830e91d3f Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 28 Sep 2017 22:56:02 -0400 Subject: [PATCH 05/60] Movement delay fixes and optimization --- code/modules/mob/living/living.dm | 2 +- code/modules/mob/living/simple_animal/simple_animal.dm | 8 ++++++++ code/modules/mob/mob.dm | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 649e19ba29..dd137c97c0 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -460,7 +460,7 @@ makeTrail(newloc, T, old_direction) /mob/living/movement_delay(ignorewalk = 0) - . = ..() + . = 0 if(isopenturf(loc) && !is_flying()) var/turf/open/T = loc . += T.slowdown diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 144fec4a4a..a7bab7ee26 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -271,11 +271,19 @@ /mob/living/simple_animal/movement_delay() +<<<<<<< HEAD . = ..() . = speed . += config.animal_delay +======= + var/static/config_animal_delay + if(isnull(config_animal_delay)) + config_animal_delay = CONFIG_GET(number/animal_delay) + . += config_animal_delay + return ..() + speed + config_animal_delay +>>>>>>> 3fb8828... Movement delay fixes and optimization (#31037) /mob/living/simple_animal/Stat() ..() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index f768cbe2d2..159b3f5ad1 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -162,7 +162,7 @@ for(var/mob/M in get_hearers_in_view(range, src)) M.show_message( message, 2, deaf_message, 1) -/mob/proc/movement_delay() +/mob/proc/movement_delay() //update /living/movement_delay() if you change this return 0 /mob/proc/Life() From e4b4860e44aca1e6e648545ccbfbf58880784714 Mon Sep 17 00:00:00 2001 From: Joan Lung <3886584+ChangelingRain@users.noreply.github.com> Date: Thu, 28 Sep 2017 22:58:45 -0400 Subject: [PATCH 06/60] Reebe is fancier now --- _maps/map_files/generic/City_of_Cogs.dmm | 65838 ++++++++++++++++ code/__DEFINES/layers.dm | 2 + code/game/objects/structures/lattice.dm | 54 +- code/game/turfs/simulated/floor/misc_floor.dm | 22 + code/game/turfs/simulated/reebe_void.dm | 47 + code/game/turfs/simulated/wall/misc_walls.dm | 6 + code/game/turfs/space/space.dm | 1 + .../smooth_structures/catwalk_clockwork.dmi | Bin 1839 -> 1403 bytes .../catwalk_clockwork_large.dmi | Bin 0 -> 1838 bytes tgstation.dme | 1 + 10 files changed, 65952 insertions(+), 19 deletions(-) create mode 100644 _maps/map_files/generic/City_of_Cogs.dmm create mode 100644 code/game/turfs/simulated/reebe_void.dm create mode 100644 icons/obj/smooth_structures/catwalk_clockwork_large.dmi diff --git a/_maps/map_files/generic/City_of_Cogs.dmm b/_maps/map_files/generic/City_of_Cogs.dmm new file mode 100644 index 0000000000..68f45f5472 --- /dev/null +++ b/_maps/map_files/generic/City_of_Cogs.dmm @@ -0,0 +1,65838 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aa" = ( +/turf/open/indestructible/reebe_void, +/area/reebe) +"ab" = ( +/turf/open/indestructible/reebe_void/spawning/lattices, +/area/reebe) +"ac" = ( +/obj/structure/lattice/clockwork, +/obj/structure/grille/ratvar, +/turf/open/indestructible/reebe_void, +/area/reebe) +"ad" = ( +/obj/structure/lattice/clockwork, +/obj/item/clockwork/component/belligerent_eye/blind_eye, +/turf/open/indestructible/reebe_void, +/area/reebe) +"ae" = ( +/obj/structure/lattice/clockwork, +/turf/open/indestructible/reebe_void, +/area/reebe) +"af" = ( +/obj/structure/lattice/clockwork, +/obj/item/clockwork/component/geis_capacitor/antennae, +/turf/open/indestructible/reebe_void, +/area/reebe) +"ag" = ( +/obj/structure/lattice/catwalk/clockwork, +/turf/open/indestructible/reebe_void, +/area/reebe) +"ah" = ( +/turf/closed/wall/clockwork, +/area/reebe/city_of_cogs) +"ai" = ( +/obj/structure/window/reinforced/clockwork/fulltile, +/obj/structure/grille/ratvar, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"aj" = ( +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"ak" = ( +/obj/structure/destructible/clockwork/massive/celestial_gateway, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"al" = ( +/obj/machinery/sleeper/clockwork, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"am" = ( +/obj/structure/table/reinforced/brass, +/obj/item/storage/firstaid, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"an" = ( +/obj/structure/noticeboard, +/obj/item/paper/fluff/ruins/djstation{ + name = "paper - 'Station Radio Frequencies'" + }, +/turf/closed/wall/clockwork, +/area/reebe/city_of_cogs) +"ao" = ( +/obj/machinery/telecomms/relay/preset/reebe, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"ap" = ( +/obj/machinery/door/airlock/clockwork/brass{ + name = "Ark Chamber" + }, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"aq" = ( +/obj/machinery/computer/camera_advanced/ratvar, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"ar" = ( +/obj/structure/closet/wardrobe/mixed, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"as" = ( +/obj/structure/dresser, +/obj/structure/mirror{ + pixel_y = 26 + }, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"at" = ( +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/slab, +/obj/item/clockwork/slab, +/obj/item/clockwork/slab, +/obj/item/clockwork/slab, +/obj/item/clockwork/slab, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"au" = ( +/obj/structure/table/reinforced/brass, +/obj/item/device/radio/intercom/ratvar, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"av" = ( +/obj/structure/chair/brass{ + dir = 8 + }, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"aw" = ( +/obj/structure/chair/brass{ + dir = 4 + }, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"ax" = ( +/obj/structure/chair/brass{ + dir = 1 + }, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"ay" = ( +/obj/machinery/door/airlock/clockwork/brass{ + name = "Dressing Room" + }, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"az" = ( +/obj/structure/destructible/clockwork/heralds_beacon, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"aA" = ( +/obj/machinery/door/airlock/clockwork/brass{ + name = "Infirmary" + }, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"aB" = ( +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/construct_chassis/cogscarab, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"aC" = ( +/obj/machinery/sleeper/clockwork{ + dir = 1 + }, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"aD" = ( +/obj/machinery/door/airlock/clockwork/brass{ + name = "Listening Station" + }, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"aE" = ( +/obj/machinery/door/airlock/clockwork/brass{ + name = "Observation Room" + }, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"aF" = ( +/turf/open/indestructible/reebe_void/spawning, +/area/reebe) +"aG" = ( +/turf/closed/wall/clockwork{ + opacity = 0 + }, +/area/reebe/city_of_cogs) +"aH" = ( +/obj/effect/landmark/servant_of_ratvar, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"aI" = ( +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/slab, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"aJ" = ( +/obj/structure/table/reinforced/brass, +/obj/item/screwdriver/brass, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"aK" = ( +/obj/structure/table/reinforced/brass, +/obj/item/crowbar/brass, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"aL" = ( +/obj/structure/table/reinforced/brass, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"aM" = ( +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/component/replicant_alloy, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"aN" = ( +/obj/structure/table/reinforced/brass, +/obj/item/weldingtool/experimental/brass, +/turf/open/floor/clockwork/reebe, +/area/reebe/city_of_cogs) +"aO" = ( +/obj/structure/lattice/catwalk/clockwork, +/obj/item/clockwork/component/belligerent_eye/lens_gem, +/turf/open/indestructible/reebe_void, +/area/reebe) +"aP" = ( +/obj/structure/lattice/catwalk/clockwork, +/obj/item/clockwork/component/hierophant_ansible/obelisk, +/turf/open/indestructible/reebe_void, +/area/reebe) +"aQ" = ( +/obj/structure/lattice/clockwork, +/obj/item/clockwork/alloy_shards/clockgolem_remains, +/turf/open/indestructible/reebe_void, +/area/reebe) +"aR" = ( +/obj/effect/clockwork/servant_blocker{ + dir = 1 + }, +/obj/structure/lattice/clockwork, +/turf/open/indestructible/reebe_void, +/area/reebe/city_of_cogs) +"aS" = ( +/obj/effect/clockwork/servant_blocker{ + dir = 1 + }, +/obj/structure/lattice/catwalk/clockwork, +/turf/open/indestructible/reebe_void, +/area/reebe/city_of_cogs) +"aT" = ( +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"aU" = ( +/obj/structure/grille/ratvar, +/obj/structure/window/reinforced/clockwork/fulltile, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"aV" = ( +/obj/machinery/door/airlock/clockwork/brass, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"aW" = ( +/obj/item/clockwork/component/replicant_alloy/replication_plate, +/turf/open/indestructible/reebe_void/spawning/lattices, +/area/reebe) +"aX" = ( +/obj/effect/landmark/city_of_cogs, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"aY" = ( +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/component/belligerent_eye/blind_eye, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"aZ" = ( +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/component/belligerent_eye, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"ba" = ( +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/component/belligerent_eye/lens_gem, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"bb" = ( +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/component/replicant_alloy, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"bc" = ( +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/component/replicant_alloy/smashed_anima_fragment, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"bd" = ( +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/component/replicant_alloy/replication_plate, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"be" = ( +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/component/geis_capacitor/antennae, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"bf" = ( +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/component/geis_capacitor/fallen_armor, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"bg" = ( +/obj/structure/table/reinforced/brass, +/obj/item/clockwork/component/geis_capacitor, +/turf/open/indestructible/clock_spawn_room, +/area/reebe/city_of_cogs) +"bh" = ( +/obj/structure/lattice/catwalk/clockwork, +/obj/item/clockwork/integration_cog, +/turf/open/indestructible/reebe_void, +/area/reebe) +"bi" = ( +/obj/structure/lattice/catwalk/clockwork, +/obj/item/clockwork/component/vanguard_cogwheel/onyx_prism, +/turf/open/indestructible/reebe_void, +/area/reebe) + +(1,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(2,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(3,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(4,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(5,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(6,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(7,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(8,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(9,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(10,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(11,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(12,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(13,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(14,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(15,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(16,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(17,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(18,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(19,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(20,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(21,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(22,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(23,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(24,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(25,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(26,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(27,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(28,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(29,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(30,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(31,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(32,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(33,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(34,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(35,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(36,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(37,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(38,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(39,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(40,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(41,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(42,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(43,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(44,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(45,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(46,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(47,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(48,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(49,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(50,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(51,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(52,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(53,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(54,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(55,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(56,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(57,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(58,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(59,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(60,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(61,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(62,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(63,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(64,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(65,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(66,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(67,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(68,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(69,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(70,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(71,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(72,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(73,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(74,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(75,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(76,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(77,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(78,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(79,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(80,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(81,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(82,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(83,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(84,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(85,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(86,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(87,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(88,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(89,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(90,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(91,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(92,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(93,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(94,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(95,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(96,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(97,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(98,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(99,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(100,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(101,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(102,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(103,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(104,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ae +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +aW +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(105,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ae +af +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ab +aP +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(106,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ac +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(107,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(108,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(109,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(110,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +ae +ae +ae +ae +ae +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(111,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ae +ah +ah +ai +ah +ah +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aR +ah +ah +ah +ah +ah +ae +ae +ae +ae +ae +ae +ae +ae +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(112,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ag +ag +ah +ar +aj +aj +ah +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +ah +ah +ai +ai +ai +ai +ai +ah +ah +ae +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(113,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ag +ag +ah +as +aj +aj +ay +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +ah +aT +aT +aT +aT +aT +aT +aT +ah +ag +ae +ab +ab +ab +ab +ab +ae +bi +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(114,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ag +ag +ah +at +aj +aj +ah +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +aU +aT +aT +aT +aT +aT +aT +aT +ah +ah +ah +ab +ab +ab +ab +ab +ab +ab +ae +ac +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(115,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ae +ah +ah +ay +ah +ah +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +aU +aT +aT +aX +aX +aX +aT +aT +ai +aY +ai +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(116,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +an +au +aj +au +ah +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +aV +aT +aT +aX +aX +aX +aT +aT +ai +aZ +ai +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(117,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ah +ah +av +aj +av +ah +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +aU +aT +aT +aX +aX +aX +aT +aT +ai +ba +ai +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(118,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ai +ao +aj +aj +aj +aD +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +aU +aT +aT +aT +aT +aT +aT +aT +ah +ah +ah +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(119,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ah +ah +aw +aj +aw +ai +aH +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +ah +aT +aT +aT +aT +aT +aT +aT +ah +ag +ae +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(120,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ae +ag +ag +an +au +aj +au +ai +aI +aK +aH +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +ah +ah +aU +aU +aV +aU +aU +ah +ah +ag +ae +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(121,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ah +ah +ah +ai +ah +ah +ah +ai +ap +ai +ah +aJ +aH +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +ah +aT +aT +aT +aT +aT +aT +aT +ah +ag +ae +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(122,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ah +aj +aj +aj +aj +aj +ai +aj +aj +aj +ai +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +aU +aT +aT +aT +aT +aT +aT +aT +ah +ah +ah +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(123,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ah +aj +aj +aj +aj +aj +ai +aj +aj +aj +ai +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +aU +aT +aT +aX +aX +aX +aT +aT +ai +bb +ai +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(124,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ag +ai +aj +aj +ak +aj +aj +ap +aj +az +aj +ap +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +aV +aT +aT +aX +aX +aX +aT +aT +ai +bc +ai +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(125,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ah +aj +aj +aj +aj +aj +ai +aj +aj +aj +ai +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +aU +aT +aT +aX +aX +aX +aT +aT +ai +bd +ai +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(126,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ah +aj +aj +aj +aj +aj +ai +aj +aj +aj +ai +aj +aj +aH +aH +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +aU +aT +aT +aT +aT +aT +aT +aT +ah +ah +ah +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(127,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ah +ah +ah +ai +ah +ah +ah +ai +ap +ai +ah +aj +aH +aL +aN +aH +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +ah +aT +aT +aT +aT +aT +aT +aT +ah +ag +ae +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(128,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ae +ag +ah +aq +ax +aj +aj +ai +aj +aH +aM +aL +aH +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +ah +ah +aU +aU +aV +aU +aU +ah +ah +ag +ae +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(129,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ai +aq +ax +aj +aj +ai +aj +aj +aH +aH +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +ah +aT +aT +aT +aT +aT +aT +aT +ah +ag +ae +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(130,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ai +aq +ax +aj +aj +aE +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +aU +aT +aT +aT +aT +aT +aT +aT +ah +ah +ah +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(131,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ac +ad +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ai +aq +ax +aj +aB +ah +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +aU +aT +aT +aX +aX +aX +aT +aT +ai +be +ai +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(132,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ah +aq +ax +aj +aB +ah +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +aV +aT +aT +aX +aX +aX +aT +aT +ai +bf +ai +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(133,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ah +ah +ah +ah +aA +ah +ah +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +aU +aT +aT +aX +aX +aX +aT +aT +ai +bg +ai +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(134,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ah +al +aj +aj +aj +aC +ah +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +aU +aT +aT +aT +aT +aT +aT +aT +ah +ah +ah +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(135,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ai +am +aj +aj +aj +aj +aA +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +ah +aT +aT +aT +aT +aT +aT +aT +ah +ag +ae +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(136,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ah +al +aj +aj +aj +aC +ah +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aj +aS +aT +aT +aT +aT +ah +ah +ai +ai +ai +ai +ai +ah +ah +ae +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(137,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ah +ah +ah +ai +ah +ah +ah +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aG +aR +ah +ah +ah +ah +ah +ae +ae +ae +ae +ae +ae +ae +ae +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(138,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +aF +ae +ae +ae +ae +ae +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(139,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(140,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ae +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(141,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +ac +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(142,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ac +bh +ae +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(143,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aO +ac +ab +ab +ab +ab +ab +ab +ab +aQ +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(144,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(145,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(146,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(147,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(148,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aF +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +ab +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(149,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(150,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(151,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(152,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(153,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(154,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(155,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(156,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(157,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(158,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(159,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(160,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(161,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(162,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(163,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(164,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(165,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(166,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(167,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(168,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(169,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(170,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(171,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(172,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(173,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(174,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(175,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(176,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(177,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(178,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(179,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(180,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(181,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(182,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(183,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(184,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(185,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(186,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(187,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(188,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(189,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(190,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(191,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(192,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(193,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(194,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(195,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(196,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(197,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(198,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(199,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(200,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(201,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(202,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(203,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(204,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(205,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(206,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(207,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(208,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(209,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(210,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(211,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(212,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(213,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(214,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(215,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(216,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(217,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(218,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(219,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(220,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(221,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(222,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(223,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(224,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(225,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(226,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(227,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(228,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(229,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(230,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(231,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(232,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(233,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(234,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(235,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(236,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(237,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(238,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(239,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(240,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(241,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(242,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(243,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(244,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(245,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(246,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(247,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(248,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(249,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(250,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(251,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(252,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(253,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(254,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} +(255,1,1) = {" +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +"} diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 830a25fb0a..d45416e371 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -7,6 +7,8 @@ #define PLANE_SPACE_PARALLAX -90 #define GAME_PLANE 0 +#define SPACE_LAYER 1.8 +#define ABOVE_SPACE_LAYER 1.9 //#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define #define MID_TURF_LAYER 2.02 #define HIGH_TURF_LAYER 2.03 diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index 225d634a7f..d578b307db 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -26,12 +26,11 @@ return /obj/structure/lattice/ratvar_act() - if(IsEven(x + y)) - new /obj/structure/lattice/clockwork(loc) - else - new /obj/structure/lattice/clockwork/large(loc) + new /obj/structure/lattice/clockwork(loc) /obj/structure/lattice/attackby(obj/item/C, mob/user, params) + if(resistance_flags & INDESTRUCTIBLE) + return if(istype(C, /obj/item/wirecutters)) to_chat(user, "Slicing [name] joints ...") deconstruct() @@ -45,7 +44,6 @@ qdel(src) /obj/structure/lattice/singularity_pull(S, current_size) - ..() if(current_size >= STAGE_FOUR) deconstruct() @@ -55,22 +53,22 @@ icon = 'icons/obj/smooth_structures/lattice_clockwork.dmi' /obj/structure/lattice/clockwork/Initialize(mapload) + canSmoothWith += /turf/open/indestructible/clock_spawn_room //list overrides are a terrible thing . = ..() ratvar_act() + if(z == ZLEVEL_CITYOFCOGS) + resistance_flags |= INDESTRUCTIBLE /obj/structure/lattice/clockwork/ratvar_act() if(IsOdd(x+y)) - new /obj/structure/lattice/clockwork/large(loc) // deletes old one - -/obj/structure/lattice/clockwork/large/Initialize(mapload) - . = ..() - icon = 'icons/obj/smooth_structures/lattice_clockwork_large.dmi' - pixel_x = -9 - pixel_y = -9 - -/obj/structure/lattice/clockwork/large/ratvar_act() - if(IsEven(x + y)) - new /obj/structure/lattice/clockwork(loc) + icon = 'icons/obj/smooth_structures/lattice_clockwork_large.dmi' + pixel_x = -9 + pixel_y = -9 + else + icon = 'icons/obj/smooth_structures/lattice_clockwork.dmi' + pixel_x = 0 + pixel_y = 0 + return TRUE /obj/structure/lattice/catwalk name = "catwalk" @@ -99,11 +97,29 @@ /obj/structure/lattice/catwalk/clockwork name = "clockwork catwalk" icon = 'icons/obj/smooth_structures/catwalk_clockwork.dmi' + canSmoothWith = list(/obj/structure/lattice, + /turf/open/floor, + /turf/open/indestructible/clock_spawn_room, + /turf/closed/wall, + /obj/structure/falsewall) + smooth = SMOOTH_MORE /obj/structure/lattice/catwalk/clockwork/Initialize(mapload) . = ..() - new /obj/effect/temp_visual/ratvar/floor/catwalk(loc) - new /obj/effect/temp_visual/ratvar/beam/catwalk(loc) + ratvar_act() + if(!mapload) + new /obj/effect/temp_visual/ratvar/floor/catwalk(loc) + new /obj/effect/temp_visual/ratvar/beam/catwalk(loc) + if(z == ZLEVEL_CITYOFCOGS) + resistance_flags |= INDESTRUCTIBLE /obj/structure/lattice/catwalk/clockwork/ratvar_act() - return + if(IsOdd(x+y)) + icon = 'icons/obj/smooth_structures/catwalk_clockwork_large.dmi' + pixel_x = -9 + pixel_y = -9 + else + icon = 'icons/obj/smooth_structures/catwalk_clockwork.dmi' + pixel_x = 0 + pixel_y = 0 + return TRUE diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm index 3656e146a6..a918f8b5a8 100644 --- a/code/game/turfs/simulated/floor/misc_floor.dm +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -142,10 +142,16 @@ name = "clockwork floor" desc = "Tightly-pressed brass tiles. They emit minute vibration." icon_state = "plating" +<<<<<<< HEAD +======= + baseturf = /turf/open/floor/clockwork + var/uses_overlay = TRUE +>>>>>>> 5b73196... Reebe is fancier now (#31045) var/obj/effect/clockwork/overlay/floor/realappearence /turf/open/floor/clockwork/Initialize() . = ..() +<<<<<<< HEAD new /obj/effect/temp_visual/ratvar/floor(src) new /obj/effect/temp_visual/ratvar/beam(src) realappearence = new /obj/effect/clockwork/overlay/floor(src) @@ -158,9 +164,23 @@ if(realappearence) qdel(realappearence) realappearence = null +======= + if(uses_overlay) + new /obj/effect/temp_visual/ratvar/floor(src) + new /obj/effect/temp_visual/ratvar/beam(src) + realappearence = new /obj/effect/clockwork/overlay/floor(src) + realappearence.linked = src + +/turf/open/floor/clockwork/Destroy() + STOP_PROCESSING(SSobj, src) + if(uses_overlay && realappearence) + QDEL_NULL(realappearence) +>>>>>>> 5b73196... Reebe is fancier now (#31045) return ..() /turf/open/floor/clockwork/ReplaceWithLattice() + if(baseturf == type) + return ..() for(var/obj/structure/lattice/L in src) L.ratvar_act() @@ -194,6 +214,8 @@ L.adjustToxLoss(-3, TRUE, TRUE) /turf/open/floor/clockwork/attackby(obj/item/I, mob/living/user, params) + if(baseturf == type) + return if(istype(I, /obj/item/crowbar)) user.visible_message("[user] begins slowly prying up [src]...", "You begin painstakingly prying up [src]...") playsound(src, I.usesound, 20, 1) diff --git a/code/game/turfs/simulated/reebe_void.dm b/code/game/turfs/simulated/reebe_void.dm new file mode 100644 index 0000000000..2e0246df83 --- /dev/null +++ b/code/game/turfs/simulated/reebe_void.dm @@ -0,0 +1,47 @@ +/turf/open/indestructible/reebe_void + name = "void" + icon_state = "reebemap" + layer = SPACE_LAYER + baseturf = /turf/open/indestructible/reebe_void + planetary_atmos = TRUE + +/turf/open/indestructible/reebe_void/Initialize(mapload) + . = ..() + icon_state = "reebegame" + +/turf/open/indestructible/reebe_void/spawning + icon_state = "reebespawn" + +/turf/open/indestructible/reebe_void/spawning/Initialize(mapload) + . = ..() + if(mapload) + for(var/i in 1 to 3) + if(prob(1)) + new /obj/item/clockwork/alloy_shards/large(src) + if(prob(2)) + new /obj/item/clockwork/alloy_shards/medium(src) + if(prob(3)) + new /obj/item/clockwork/alloy_shards/small(src) + +/turf/open/indestructible/reebe_void/spawning/lattices + icon_state = "reebelattice" + +/turf/open/indestructible/reebe_void/spawning/lattices/Initialize(mapload) + . = ..() + if(mapload) + if(prob(2.5)) + new /obj/structure/lattice/catwalk/clockwork(src) + else if(prob(5)) + new /obj/structure/lattice/clockwork(src) + +/turf/open/indestructible/reebe_void/Enter(atom/movable/AM, atom/old_loc) + if(!..()) + return FALSE + else + if(istype(AM, /obj/structure/window)) + return FALSE + if(istype(AM, /obj/item/projectile)) + return TRUE + if((locate(/obj/structure/lattice) in src)) + return TRUE + return FALSE diff --git a/code/game/turfs/simulated/wall/misc_walls.dm b/code/game/turfs/simulated/wall/misc_walls.dm index d0eaad34e3..7178dc3a65 100644 --- a/code/game/turfs/simulated/wall/misc_walls.dm +++ b/code/game/turfs/simulated/wall/misc_walls.dm @@ -55,6 +55,7 @@ sheet_type = /obj/item/stack/tile/brass sheet_amount = 1 girder_type = /obj/structure/destructible/clockwork/wall_gear + baseturf = /turf/open/floor/clockwork/reebe var/obj/effect/clockwork/overlay/wall/realappearence var/obj/structure/destructible/clockwork/cache/linkedcache @@ -64,6 +65,7 @@ new /obj/effect/temp_visual/ratvar/beam(src) realappearence = new /obj/effect/clockwork/overlay/wall(src) realappearence.linked = src +<<<<<<< HEAD change_construction_value(5) /turf/closed/wall/clockwork/examine(mob/user) @@ -76,6 +78,10 @@ linkedcache.linkedwall = null linkedcache = null change_construction_value(-5) +======= + +/turf/closed/wall/clockwork/Destroy() +>>>>>>> 5b73196... Reebe is fancier now (#31045) if(realappearence) qdel(realappearence) realappearence = null diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index b1b00b3e55..6e3717e9a6 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -14,6 +14,7 @@ var/global/datum/gas_mixture/immutable/space/space_gas = new plane = PLANE_SPACE + layer = SPACE_LAYER light_power = 0.25 dynamic_lighting = DYNAMIC_LIGHTING_DISABLED diff --git a/icons/obj/smooth_structures/catwalk_clockwork.dmi b/icons/obj/smooth_structures/catwalk_clockwork.dmi index 483fceee9a41ac5119bb6fd69b7df7fd9cd0ebe0..ecef1df38979fb1bccbede8e16b9b013c919af33 100644 GIT binary patch delta 1396 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 PF_fd7i|xycfp`B0e8j)D diff --git a/icons/obj/smooth_structures/catwalk_clockwork_large.dmi b/icons/obj/smooth_structures/catwalk_clockwork_large.dmi new file mode 100644 index 0000000000000000000000000000000000000000..675ebd91f6df950f6bdd5cc215b19933d92faa17 GIT binary patch literal 1838 zcmY*ac~sJA7e+#`LP9fphYRp*V_+tXiO3Ykn$w*@i<~=EF~uLzj2YYXb>pjb~f*cW|I|+ z_^REX{Sj$xhHh}rTnt_}l5|=`u+LOB(kceMY#tdTXmc;mj3f%Oc=Gbngw?B)h*45c zU!d*YcI09E>qy5w6`E-kCFt}Yh?)75wnNr~jN0t8K0<1WFdnj=?)?2HH9Ih=oelhX;u(~zH`w=U}K=>!nOHavcv7r+b z1X5ig5eejk+cWu2G^y+MG!m&&$=mLLp29@qrlWn%#gYQBFOMIMu0NCeI_b*#WX6h$ z-o!DzT}5XmuiEvTEuG72Lz(u(G!OJm_A~Ak{T1&13uSS+#-tyWGSs%~B*jwsX@m%S z&M@1Svph2i%dW=BKM2(KQp4uF=3Q<=|MsDX0+_wil+~#B!*A< z#bSq3tF5%Bvc4HGI#|sicL^HKZ*Izr-{Uuz>3vT6%thM*q?wF7#Rx{{_tFUf1 ziB}5+cRP|zoD#VQGElhO1$9MU$Ad5R4SY$lZ18huOLA<=P;?q+dG3@%B3`?*paFGw z!y}!$*bx{J-qm65IFZh1-KrSA*YTiwUj9Ns<)R`BJaJQ?zHZmZx80ozDijqH}+Y6<#YT{^k>ia{lp)fXI`4g9EJO}-qXbm_upDejn@(nNWOTS6SZbu;JfJ3 ze@}eGh;V2Qqzm_p|6^}q5a(LDRa&@|WSiSa=h{|vtx=>)Q}@@^EIada8b9m&z)$wD z{J8D;?86d*+Y;)imRK&m7sefaR>bp+QTR>BU*K+dUC4V-t-kf>l@Po!^magkWx&tS zO#9{v^p%(U8}jzonAgUBIM~|1Dxu?J#F+BXeRnJMqlnE(Y=Q1ONv5JQ1n+z*by^-n zgDu5uyFg{+)0hk&U0_ zNj*l${HoQ$-awm)33>e;{Y)fvAbfuSf;-cDC(5!Yrg1uh06Z9p2iJB$a7?GG6U#g* zRI@jGibSw)r1D^~nAJRk*s^UV)sQCpvEXb>mhL~0rinQifmmzp_6}mtN~cmd_u(;M zcy|l(D0b>dPi+@HD%;f^PNXtU3@sec#k10P)aH?U5ZF$L@y~#(IRkzgY{aKYZ^#x@ zLH4X1$wp^2#5u$;mYfB{LN3pY$}-?5!NuukE%W`EvIsc4B*dY)R#CpyI2}e{LrUJD zH^6dj8f18HHbzdDG2uiE3<6fZBw9x^^`B}&t<~>x9QIkA?~N>ef@jU0j^|*QgJ{CC z2p}M%|Bp)y@Q}(9q)GifoUIN4g6RUwxIPo56Oio7D~()bm@rdpIk+Ewl!O=(eB|Hq zYq-=E#-4@JZK>GwS|Q5eWbMM}>pl+3OIo8mYM6#PU&gCwwqq4ZDmOEx`${PXqU0Ljh6F?5;7ms%%!u_rU{7NrjCdRi zDNX&3Wo4g$h48+Dua$!=E8Hg7ls3Vpv;mrdyN0|o4`JrSRgGSWy?0B4bsr%k-*lW}iV4M<5mL(7DxqNOG0z>C zP_WT)o*MC!1!Sn0&&#}EK!8B;`AGR65a)!6$&uiovkcYnol5S2fiOE+ZGYqy3$|F` zeQROyTfzF(w}Roq=dUB){!)h5+GwpdiUJgL67FovN)-m&zy}m3t&-az8u)y>GY#kc zBA5D$H6HfYkt)tdu*zzpw@^_xF;Rcs0tcm;J&T<-d(u^`@u9blWJQl)IRbJPARhtb za6q01dyH3pSWoqpjeN`{xb-|DCsjUszD(m@)W&uHbJ$-@tBgCrjAz_w8+Mb{JEIlT b+me;9nX|sn&F!%QJ}?l;#hduRIhge?2IyEs literal 0 HcmV?d00001 diff --git a/tgstation.dme b/tgstation.dme index 525e30ca66..5087122864 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -1030,6 +1030,7 @@ #include "code\game\turfs\simulated\floor.dm" #include "code\game\turfs\simulated\lava.dm" #include "code\game\turfs\simulated\minerals.dm" +#include "code\game\turfs\simulated\reebe_void.dm" #include "code\game\turfs\simulated\river.dm" #include "code\game\turfs\simulated\walls.dm" #include "code\game\turfs\simulated\water.dm" From 116041d621d8ee37fbdca953aeadea36903e9a60 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Thu, 28 Sep 2017 23:19:50 -0400 Subject: [PATCH 07/60] Server tools API v3.1 --- README.md | 129 ++++++ TGS3.json | 22 + code/__DEFINES/server_tools.dm | 117 +++++- code/__HELPERS/unsorted.dm | 57 --- .../configuration/entries/config.dm | 384 ++++++++++++++++++ code/controllers/subsystem/ticker.dm | 2 + code/datums/helper_datums/getrev.dm | 26 +- code/game/world.dm | 47 +-- code/modules/admin/admin.dm | 15 +- code/modules/admin/chat_commands.dm | 63 +++ code/modules/admin/verbs/adminhelp.dm | 5 + code/modules/server_tools/st_commands.dm | 76 ++++ code/modules/server_tools/st_interface.dm | 125 ++++++ tgstation.dme | 4 +- 14 files changed, 948 insertions(+), 124 deletions(-) create mode 100644 TGS3.json create mode 100644 code/controllers/configuration/entries/config.dm create mode 100644 code/modules/admin/chat_commands.dm create mode 100644 code/modules/server_tools/st_commands.dm create mode 100644 code/modules/server_tools/st_interface.dm diff --git a/README.md b/README.md index d33438f606..3bd9c03c61 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Option 1: Follow this: http://www.tgstation13.org/wiki/Setting_up_git Option 2: Download the source code as a zip by clicking the ZIP button in the +<<<<<<< HEAD code tab of https://github.com/tgstation/tgstation (note: this will use a lot of bandwidth if you wish to update and is a lot of hassle if you want to make any changes at all, so it's not recommended.) @@ -145,3 +146,131 @@ See tgui/LICENSE.md for the MIT license. See tgui/assets/fonts/SIL-OFL-1.1-LICENSE.md for the SIL Open Font License. All assets including icons and sound are under a [Creative Commons 3.0 BY-SA license](http://creativecommons.org/licenses/by-sa/3.0/) unless otherwise indicated. +======= +code tab of https://github.com/tgstation/tgstation +(note: this will use a lot of bandwidth if you wish to update and is a lot of +hassle if you want to make any changes at all, so it's not recommended.) + +## INSTALLATION + +First-time installation should be fairly straightforward. First, you'll need +BYOND installed. You can get it from http://www.byond.com/. Once you've done +that, extract the game files to wherever you want to keep them. This is a +sourcecode-only release, so the next step is to compile the server files. +Open tgstation.dme by double-clicking it, open the Build menu, and click +compile. This'll take a little while, and if everything's done right you'll get +a message like this: + +``` +saving tgstation.dmb (DEBUG mode) +tgstation.dmb - 0 errors, 0 warnings +``` + +If you see any errors or warnings, something has gone wrong - possibly a corrupt +download or the files extracted wrong. If problems persist, ask for assistance +in irc://irc.rizon.net/coderbus + +Once that's done, open up the config folder. You'll want to edit config.txt to +set the probabilities for different gamemodes in Secret and to set your server +location so that all your players don't get disconnected at the end of each +round. It's recommended you don't turn on the gamemodes with probability 0, +except Extended, as they have various issues and aren't currently being tested, +so they may have unknown and bizarre bugs. Extended is essentially no mode, and +isn't in the Secret rotation by default as it's just not very fun. + +You'll also want to edit config/admins.txt to remove the default admins and add +your own. "Game Master" is the highest level of access, and probably the one +you'll want to use for now. You can set up your own ranks and find out more in +config/admin_ranks.txt + +The format is + +``` +byondkey = Rank +``` + +where the admin rank must be properly capitalised. + +Finally, to start the server, run Dream Daemon and enter the path to your +compiled tgstation.dmb file. Make sure to set the port to the one you +specified in the config.txt, and set the Security box to 'Safe'. Then press GO +and the server should start up and be ready to join. It is also recommended that +you set up the SQL backend (see below). + +## UPDATING + +To update an existing installation, first back up your /config and /data folders +as these store your server configuration, player preferences and banlist. + +Then, extract the new files (preferably into a clean directory, but updating in +place should work fine), copy your /config and /data folders back into the new +install, overwriting when prompted except if we've specified otherwise, and +recompile the game. Once you start the server up again, you should be running +the new version. + +## HOSTING + +If you'd like a more robust server hosting option for tgstation and its +derivatives. Check out our server tools suite at +https://github.com/tgstation/tgstation-server + +## MAPS + +/tg/station currently comes equipped with five maps. + +* [BoxStation (default)](http://tgstation13.org/wiki/Boxstation) +* [MetaStation](https://tgstation13.org/wiki/MetaStation) +* [DeltaStation](https://tgstation13.org/wiki/DeltaStation) +* [OmegaStation](https://tgstation13.org/wiki/OmegaStation) +* [PubbyStation](https://tgstation13.org/wiki/PubbyStation) + + +All maps have their own code file that is in the base of the _maps directory. Maps are loaded dynamically when the game starts. Follow this guideline when adding your own map, to your fork, for easy compatibility. + +The map that will be loaded for the upcoming round is determined by reading data/next_map.json, which is a copy of the json files found in the _maps tree. If this file does not exist, the default map from config/maps.txt will be loaded. Failing that, tgstation2 will be loaded. If you want to set a specific map to load next round you can use the Change Map verb in game before restarting the server or copy a json from _maps to data/next_map.json before starting the server. Also, for debugging purposes, ticking a corresponding map's code file in Dream Maker will force that map to load every round. + +If you are hosting a server, and want randomly picked maps to be played each round, you can enable map rotation in [config.txt](config/config.txt) and then set the maps to be picked in the [maps.txt](config/maps.txt) file. + +Anytime you want to make changes to a map it's imperative you use the [Map Merging tools](http://tgstation13.org/wiki/Map_Merger) + +## AWAY MISSIONS + +/tg/station supports loading away missions however they are disabled by default. + +Map files for away missions are located in the _maps/RandomZLevels directory. Each away mission includes it's own code definitions located in /code/modules/awaymissions/mission_code. These files must be included and compiled with the server beforehand otherwise the server will crash upon trying to load away missions that lack their code. + +To enable an away mission open `config/awaymissionconfig.txt` and uncomment one of the .dmm lines by removing the #. If more than one away mission is uncommented then the away mission loader will randomly select one the enabled ones to load. + +## SQL SETUP + +The SQL backend requires a MySQL server. SQL is required for the library, stats tracking, admin notes, and job-only bans, among other features, mostly related to server administration. Your server details go in /config/dbconfig.txt, and the SQL schema is in /SQL/tgstation_schema.sql and /SQL/tgstation_schema_prefix.sql depending on if you want table prefixes. More detailed setup instructions are located here: http://www.tgstation13.org/wiki/Downloading_the_source_code#Setting_up_the_database + +## IRC BOT SETUP + +Included in the repository is a python3 compatible IRC bot capable of relaying adminhelps to a specified +IRC channel/server, see the /tools/minibot folder for more + +## CONTRIBUTING + +Please see [CONTRIBUTING.md](.github/CONTRIBUTING.md) + +## LICENSE + +All code after [commit 333c566b88108de218d882840e61928a9b759d8f on 2014/31/12 at 4:38 PM PST](https://github.com/tgstation/tgstation/commit/333c566b88108de218d882840e61928a9b759d8f) is licensed under [GNU AGPL v3](http://www.gnu.org/licenses/agpl-3.0.html). + +All code before [commit 333c566b88108de218d882840e61928a9b759d8f on 2014/31/12 at 4:38 PM PST](https://github.com/tgstation/tgstation/commit/333c566b88108de218d882840e61928a9b759d8f) is licensed under [GNU GPL v3](https://www.gnu.org/licenses/gpl-3.0.html). +(Including tools unless their readme specifies otherwise.) + +See LICENSE-AGPLv3.txt and LICENSE-GPLv3.txt for more details. + +tgui clientside is licensed as a subproject under the MIT license. +Font Awesome font files, used by tgui, are licensed under the SIL Open Font License v1.1 +tgui assets are licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/). +The TGS3 API is licensed as a subproject under the MIT license. + +See tgui/LICENSE.md for the MIT license. +See tgui/assets/fonts/SIL-OFL-1.1-LICENSE.md for the SIL Open Font License. +See the footers of code/\_\_DEFINES/server\_tools.dm, code/modules/server\_tools/st\_commands.dm, and code/modules/server\_tools/st\_inteface.dm for the MIT license. + +All assets including icons and sound are under a [Creative Commons 3.0 BY-SA license](http://creativecommons.org/licenses/by-sa/3.0/) unless otherwise indicated. +>>>>>>> 62f788f... Server tools API v3.1 (#31000) diff --git a/TGS3.json b/TGS3.json new file mode 100644 index 0000000000..4fd41ab9f1 --- /dev/null +++ b/TGS3.json @@ -0,0 +1,22 @@ +{ + "documentation": "/tg/station server 3 configuration file", + "changelog": { + "script": "tools/ss13_genchangelog.py", + "arguments": "html/changelog.html html/changelogs", + "pip_dependancies": [ + "PyYaml", + "beautifulsoup4" + ] + }, + "synchronize_paths": [ + "html/changelog.html", + "html/changelogs/*" + ], + "static_directories": [ + "config", + "data" + ], + "dlls": [ + "libmysql.dll" + ] + } \ No newline at end of file diff --git a/code/__DEFINES/server_tools.dm b/code/__DEFINES/server_tools.dm index d2be3e578e..b86a54959f 100644 --- a/code/__DEFINES/server_tools.dm +++ b/code/__DEFINES/server_tools.dm @@ -1,34 +1,123 @@ +// /tg/station 13 server tools API v3.1 + +//CONFIGURATION +//use this define if you want to do configuration outside of this file +#ifndef SERVER_TOOLS_EXTERNAL_CONFIGURATION +//Comment this out once you've filled in the below +//#error /tg/station server tools interface unconfigured + +//Required interfaces (fill in with your codebase equivalent): + +//create a global variable named `Name` and set it to `Value` +//These globals must not be modifiable from anywhere outside of the server tools +#define SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name) +//Read the value in the global variable `Name` +#define SERVER_TOOLS_READ_GLOBAL(Name) GLOB.##Name +//Set the value in the global variable `Name` to `Value` +#define SERVER_TOOLS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value +//display an announcement `message` from the server to all players +#define SERVER_TOOLS_WORLD_ANNOUNCE(message) to_chat(world, "[html_encode(##message)]") +//Write a string `message` to a server log +#define SERVER_TOOLS_LOG(message) log_world("SERVICE: [##message]") +//Notify current in-game administrators of a string `event` +#define SERVER_TOOLS_NOTIFY_ADMINS(event) message_admins(##event) +#endif + +//Required hooks: + +//Put this somewhere in /world/New() that is always run +#define SERVER_TOOLS_ON_NEW ServiceInit() +//Put this somewhere in /world/Topic(T, Addr, Master, Keys) that is always run before T is modified +#define SERVER_TOOLS_ON_TOPIC var/service_topic_return = ServiceCommand(params2list(T)); if(service_topic_return) return service_topic_return +//Put at the beginning of world/Reboot(reason) +#define SERVER_TOOLS_ON_REBOOT ServiceReboot() + +//Optional callable functions: + +//Returns the string version of the API +#define SERVER_TOOLS_API_VERSION ServiceAPIVersion() +//Returns TRUE if the world was launched under the server tools and the API matches, FALSE otherwise +//No function below this succeed if this is FALSE +#define SERVER_TOOLS_PRESENT RunningService() +//Gets the current version of the service running the server +#define SERVER_TOOLS_VERSION ServiceVersion() +//Forces a hard reboot of BYOND by ending the process +//unlike del(world) clients will try to reconnect +//If the service has not requested a shutdown, the world will reboot shortly after +#define SERVER_TOOLS_REBOOT_BYOND world.ServiceEndProcess() +/* + Gets the list of any testmerged github pull requests + + "[PR Number]" => list( + "title" -> PR title + "commit" -> Full hash of commit merged + "author" -> Github username of the author of the PR + ) +*/ +#define SERVER_TOOLS_PR_LIST GetTestMerges() +//Sends a message to connected game chats +#define SERVER_TOOLS_CHAT_BROADCAST(message) world.ChatBroadcast(message) +//Sends a message to connected admin chats +#define SERVER_TOOLS_RELAY_BROADCAST(message) world.AdminBroadcast(message) + +//IMPLEMENTATION + +#define SERVICE_API_VERSION_STRING "3.1.0.0" + #define REBOOT_MODE_NORMAL 0 #define REBOOT_MODE_HARD 1 #define REBOOT_MODE_SHUTDOWN 2 -#define IRC_STATUS_THROTTLE 5 - -#define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round - //This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored - -//keep these in sync with TGS3 #define SERVICE_WORLD_PARAM "server_service" #define SERVICE_VERSION_PARAM "server_service_version" #define SERVICE_PR_TEST_JSON "prtestjob.json" -#define SERVICE_PR_TEST_JSON_OLD "..\\..\\[SERVICE_PR_TEST_JSON]" +#define SERVICE_INTERFACE_DLL "TGServiceInterface.dll" +#define SERVICE_INTERFACE_FUNCTION "DDEntryPoint" #define SERVICE_CMD_HARD_REBOOT "hard_reboot" #define SERVICE_CMD_GRACEFUL_SHUTDOWN "graceful_shutdown" #define SERVICE_CMD_WORLD_ANNOUNCE "world_announce" -#define SERVICE_CMD_IRC_CHECK "irc_check" -#define SERVICE_CMD_IRC_STATUS "irc_status" -#define SERVICE_CMD_ADMIN_MSG "adminmsg" -#define SERVICE_CMD_NAME_CHECK "namecheck" -#define SERVICE_CMD_ADMIN_WHO "adminwho" +#define SERVICE_CMD_LIST_CUSTOM "list_custom_commands" #define SERVICE_CMD_PARAM_KEY "serviceCommsKey" #define SERVICE_CMD_PARAM_COMMAND "command" -#define SERVICE_CMD_PARAM_MESSAGE "message" -#define SERVICE_CMD_PARAM_TARGET "target" #define SERVICE_CMD_PARAM_SENDER "sender" +#define SERVICE_CMD_PARAM_CUSTOM "custom" +#define SERVICE_CMD_API_COMPATIBLE "api_compat" + +#define SERVICE_JSON_PARAM_HELPTEXT "help_text" +#define SERVICE_JSON_PARAM_ADMINONLY "admin_only" +#define SERVICE_JSON_PARAM_REQUIREDPARAMETERS "required_parameters" #define SERVICE_REQUEST_KILL_PROCESS "killme" #define SERVICE_REQUEST_IRC_BROADCAST "irc" #define SERVICE_REQUEST_IRC_ADMIN_CHANNEL_MESSAGE "send2irc" #define SERVICE_REQUEST_WORLD_REBOOT "worldreboot" +#define SERVICE_REQUEST_API_VERSION "api_ver" + +/* +The MIT License + +Copyright (c) 2011 Dominic Tarr + +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index a20cad1cf2..e483357e57 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1380,63 +1380,6 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) return FALSE return TRUE -//WHATEVER YOU USE THIS FOR MUST BE SANITIZED TO SHIT, IT USES SHELL -//It also sleeps - -//Set this to TRUE before calling -//This prevents RCEs from badmins -//kevinz000 if you touch this I will hunt you down -GLOBAL_VAR_INIT(valid_HTTPSGet, FALSE) -GLOBAL_PROTECT(valid_HTTPSGet) -/proc/HTTPSGet(url) //tgs2 support - if(findtext(url, "\"")) - GLOB.valid_HTTPSGet = FALSE - - if(!GLOB.valid_HTTPSGet) - if(usr) - CRASH("[usr.ckey]([usr]) just attempted an invalid HTTPSGet on: [url]!") - else - CRASH("Invalid HTTPSGet call on: [url]") - GLOB.valid_HTTPSGet = FALSE - - //"This has got to be the ugliest hack I have ever done" - //warning, here be dragons - /* - | @___oo - /\ /\ / (__,,,,| - ) /^\) ^\/ _) - ) /^\/ _) - ) _ / / _) - /\ )/\/ || | )_) - < > |(,,) )__) - || / \)___)\ - | \____( )___) )___ - \______(_______;;; __;;; - */ - var/temp_file = "data/HTTPSGetOutput.txt" - var/command - if(world.system_type == MS_WINDOWS) - command = "powershell -Command \"wget [url] -OutFile [temp_file]\"" - else if(world.system_type == UNIX) - command = "wget -O [temp_file] [url]" - else - CRASH("Invalid world.system_type ([world.system_type])? Yell at Lummox.") - - log_world("HTTPSGet: [url]") - var/result = shell(command) - if(result != 0) - log_world("Download failed: shell exited with code: [result]") - return - - var/f = file(temp_file) - if(!f) - log_world("Download failed: Temp file not found") - return - - . = file2text(f) - f = null - fdel(temp_file) - #define UNTIL(X) while(!(X)) stoplag() /proc/pass() diff --git a/code/controllers/configuration/entries/config.dm b/code/controllers/configuration/entries/config.dm new file mode 100644 index 0000000000..ed09ca4a9c --- /dev/null +++ b/code/controllers/configuration/entries/config.dm @@ -0,0 +1,384 @@ +#define CURRENT_RESIDENT_FILE "config.txt" + +CONFIG_DEF(flag/autoadmin) // if autoadmin is enabled + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/autoadmin_rank) // the rank for autoadmins + value = "Game Master" + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/servername) // server name (the name of the game window) + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/serversqlname) // short form server name used for the DB + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/stationname) // station name (the name of the station in-game) + +CONFIG_DEF(number/lobby_countdown) // In between round countdown. + value = 120 + min_val = 0 + +CONFIG_DEF(number/round_end_countdown) // Post round murder death kill countdown + value = 25 + min_val = 0 + +CONFIG_DEF(flag/hub) // if the game appears on the hub or not + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_ooc) // log OOC channel + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_access) // log login/logout + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_say) // log client say + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_admin) // log admin actions + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_prayer) // log prayers + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_law) // log lawchanges + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_game) // log game events + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_vote) // log voting + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_whisper) // log client whisper + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_attack) // log attack messages + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_emote) // log emotes + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_adminchat) // log admin chat messages + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_pda) // log pda messages + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_twitter) // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases. + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/log_world_topic) // log all world.Topic() calls + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/allow_admin_ooccolor) // Allows admins with relevant permissions to have their own ooc colour + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/allow_vote_restart) // allow votes to restart + +CONFIG_DEF(flag/allow_vote_mode) // allow votes to change mode + +CONFIG_DEF(number/vote_delay) // minimum time between voting sessions (deciseconds, 10 minute default) + value = 6000 + min_val = 0 + +CONFIG_DEF(number/vote_period) // length of voting period (deciseconds, default 1 minute) + value = 600 + min_val = 0 + +CONFIG_DEF(flag/default_no_vote) // vote does not default to nochange/norestart + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/no_dead_vote) // dead people can't vote + +CONFIG_DEF(flag/allow_metadata) // Metadata is supported. + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/popup_admin_pm) // adminPMs to non-admins show in a pop-up 'reply' window when set + +CONFIG_DEF(number/fps) + value = 20 + min_val = 1 + max_val = 100 //byond will start crapping out at 50, so this is just ridic + var/sync_validate = FALSE + +/datum/config_entry/number/fps/ValidateAndSet(str_val) + . = ..() + if(.) + sync_validate = TRUE + var/datum/config_entry/number/ticklag/TL = config.entries_by_type[/datum/config_entry/number/ticklag] + if(!TL.sync_validate) + TL.ValidateAndSet(10 / value) + sync_validate = FALSE + +CONFIG_DEF(number/ticklag) + integer = FALSE + var/sync_validate = FALSE + +/datum/config_entry/number/ticklag/New() //ticklag weirdly just mirrors fps + var/datum/config_entry/CE = /datum/config_entry/number/fps + value = 10 / initial(CE.value) + ..() + +/datum/config_entry/number/ticklag/ValidateAndSet(str_val) + . = text2num(str_val) > 0 && ..() + if(.) + sync_validate = TRUE + var/datum/config_entry/number/fps/FPS = config.entries_by_type[/datum/config_entry/number/fps] + if(!FPS.sync_validate) + FPS.ValidateAndSet(10 / value) + sync_validate = FALSE + +CONFIG_DEF(flag/allow_holidays) + +CONFIG_DEF(number/tick_limit_mc_init) //SSinitialization throttling + value = TICK_LIMIT_MC_INIT_DEFAULT + min_val = 0 //oranges warned us + integer = FALSE + +CONFIG_DEF(flag/admin_legacy_system) //Defines whether the server uses the legacy admin system with admins.txt or the SQL system + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/hostedby) + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/norespawn) + +CONFIG_DEF(flag/guest_jobban) + +CONFIG_DEF(flag/usewhitelist) + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/ban_legacy_system) //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/use_age_restriction_for_jobs) //Do jobs use account age restrictions? --requires database + +CONFIG_DEF(flag/use_account_age_for_jobs) //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected. + +CONFIG_DEF(flag/use_exp_tracking) + +CONFIG_DEF(flag/use_exp_restrictions_heads) + +CONFIG_DEF(number/use_exp_restrictions_heads_hours) + value = 0 + min_val = 0 + +CONFIG_DEF(flag/use_exp_restrictions_heads_department) + +CONFIG_DEF(flag/use_exp_restrictions_other) + +CONFIG_DEF(flag/use_exp_restrictions_admin_bypass) + +CONFIG_DEF(string/server) + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/banappeals) + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(string/wikiurl) + protection = CONFIG_ENTRY_LOCKED + value = "http://www.tgstation13.org/wiki" + +CONFIG_DEF(string/forumurl) + protection = CONFIG_ENTRY_LOCKED + value = "http://tgstation13.org/phpBB/index.php" + +CONFIG_DEF(string/rulesurl) + protection = CONFIG_ENTRY_LOCKED + value = "http://www.tgstation13.org/wiki/Rules" + +CONFIG_DEF(string/githuburl) + protection = CONFIG_ENTRY_LOCKED + value = "https://www.github.com/tgstation/-tg-station" + +CONFIG_DEF(number/githubrepoid) + protection = CONFIG_ENTRY_LOCKED + value = null + min_val = 0 + +CONFIG_DEF(flag/guest_ban) + +CONFIG_DEF(number/id_console_jobslot_delay) + value = 30 + min_val = 0 + +CONFIG_DEF(number/inactivity_period) //time in ds until a player is considered inactive) + value = 3000 + min_val = 0 + +/datum/config_entry/number/inactivity_period/ValidateAndSet(str_val) + . = ..() + if(.) + value *= 10 //documented as seconds in config.txt + +CONFIG_DEF(number/afk_period) //time in ds until a player is considered inactive) + value = 3000 + min_val = 0 + +/datum/config_entry/number/afk_period/ValidateAndSet(str_val) + . = ..() + if(.) + value *= 10 //documented as seconds in config.txt + +CONFIG_DEF(flag/kick_inactive) //force disconnect for inactive players + +CONFIG_DEF(flag/load_jobs_from_txt) + +CONFIG_DEF(flag/forbid_singulo_possession) + +CONFIG_DEF(flag/automute_on) //enables automuting/spam prevention + +CONFIG_DEF(string/panic_server_name) + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/panic_server_name/ValidateAndSet(str_val) + return str_val != "\[Put the name here\]" && ..() + +CONFIG_DEF(string/panic_address) //Reconnect a player this linked server if this server isn't accepting new players + +/datum/config_entry/string/panic_address/ValidateAndSet(str_val) + return str_val != "byond://address:port" && ..() + +CONFIG_DEF(string/invoke_youtubedl) + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +CONFIG_DEF(flag/show_irc_name) + +CONFIG_DEF(flag/see_own_notes) //Can players see their own admin notes (read-only)? + +CONFIG_DEF(number/note_fresh_days) + value = null + min_val = 0 + integer = FALSE + +CONFIG_DEF(number/note_stale_days) + value = null + min_val = 0 + integer = FALSE + +CONFIG_DEF(flag/maprotation) + +CONFIG_DEF(number/maprotatechancedelta) + value = 0.75 + min_val = 0 + max_val = 1 + integer = FALSE + +CONFIG_DEF(number/soft_popcap) + value = null + min_val = 0 + +CONFIG_DEF(number/hard_popcap) + value = null + min_val = 0 + +CONFIG_DEF(number/extreme_popcap) + value = null + min_val = 0 + +CONFIG_DEF(string/soft_popcap_message) + value = "Be warned that the server is currently serving a high number of users, consider using alternative game servers." + +CONFIG_DEF(string/hard_popcap_message) + value = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers." + +CONFIG_DEF(string/extreme_popcap_message) + value = "The server is currently serving a high number of users, find alternative servers." + +CONFIG_DEF(flag/panic_bunker) // prevents people the server hasn't seen before from connecting + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(number/notify_new_player_age) // how long do we notify admins of a new player + min_val = -1 + +CONFIG_DEF(number/notify_new_player_account_age) // how long do we notify admins of a new byond account + min_val = 0 + +CONFIG_DEF(flag/irc_first_connection_alert) // do we notify the irc channel when somebody is connecting for the first time? + +CONFIG_DEF(flag/check_randomizer) + +CONFIG_DEF(string/ipintel_email) + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +/datum/config_entry/string/ipintel_email/ValidateAndSet(str_val) + return str_val != "ch@nge.me" && ..() + +CONFIG_DEF(number/ipintel_rating_bad) + value = 1 + integer = FALSE + min_val = 0 + max_val = 1 + +CONFIG_DEF(number/ipintel_save_good) + protection = CONFIG_ENTRY_LOCKED + value = 12 + min_val = 0 + +CONFIG_DEF(number/ipintel_save_bad) + protection = CONFIG_ENTRY_LOCKED + value = 1 + min_val = 0 + +CONFIG_DEF(string/ipintel_domain) + protection = CONFIG_ENTRY_LOCKED + value = "check.getipintel.net" + +CONFIG_DEF(flag/aggressive_changelog) + +CONFIG_DEF(flag/autoconvert_notes) //if all connecting player's notes should attempt to be converted to the database + protection = CONFIG_ENTRY_LOCKED + +CONFIG_DEF(flag/allow_webclient) + +CONFIG_DEF(flag/webclient_only_byond_members) + +CONFIG_DEF(flag/announce_admin_logout) + +CONFIG_DEF(flag/announce_admin_login) + +CONFIG_DEF(flag/allow_map_voting) + +CONFIG_DEF(flag/generate_minimaps) + +CONFIG_DEF(number/client_warn_version) + value = null + min_val = 500 + max_val = DM_VERSION - 1 + +CONFIG_DEF(string/client_warn_message) + value = "Your version of byond may have issues or be blocked from accessing this server in the future." + +CONFIG_DEF(number/client_error_version) + value = null + min_val = 500 + max_val = DM_VERSION - 1 + +CONFIG_DEF(string/client_error_message) + value = "Your version of byond is too old, may have issues, and is blocked from accessing this server." + +CONFIG_DEF(number/minute_topic_limit) + value = null + min_val = 0 + +CONFIG_DEF(number/second_topic_limit) + value = null + min_val = 0 + +CONFIG_DEF(number/error_cooldown) // The "cooldown" time for each occurrence of a unique error) + value = 600 + min_val = 0 + +CONFIG_DEF(number/error_limit) // How many occurrences before the next will silence them + value = 50 + +CONFIG_DEF(number/error_silence_time) // How long a unique error will be silenced for + value = 6000 + +CONFIG_DEF(number/error_msg_delay) // How long to wait between messaging admins about occurrences of a unique error + value = 50 + +CONFIG_DEF(flag/irc_announce_new_game) + +CONFIG_DEF(flag/debug_admin_hrefs) \ No newline at end of file diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 3932eada60..3e66c2459c 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -89,6 +89,8 @@ SUBSYSTEM_DEF(ticker) for(var/client/C in GLOB.clients) window_flash(C, ignorepref = TRUE) //let them know lobby has opened up. to_chat(world, "Welcome to [station_name()]!") + if(CONFIG_GET(flag/irc_announce_new_game)) + SERVER_TOOLS_CHAT_BROADCAST("New round starting on [SSmapping.config.map_name]!") current_state = GAME_STATE_PREGAME //Everyone who wants to be an observer is now spawned create_observers() diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm index c6958fa997..18db706757 100644 --- a/code/datums/helper_datums/getrev.dm +++ b/code/datums/helper_datums/getrev.dm @@ -2,10 +2,10 @@ var/originmastercommit var/commit var/list/testmerge = list() - var/has_pr_details = FALSE //tgs2 support var/date /datum/getrev/New() +<<<<<<< HEAD if(world.RunningService()) var/file_name if(ServiceVersion()) //will return null for versions < 3.0.91.0 @@ -21,6 +21,9 @@ if(I) testmerge |= I #endif +======= + testmerge = SERVER_TOOLS_PR_LIST +>>>>>>> 62f788f... Server tools API v3.1 (#31000) log_world("Running /tg/ revision:") var/list/logs = world.file2list(".git/logs/HEAD") if(logs) @@ -36,16 +39,13 @@ log_world(commit) for(var/line in testmerge) if(line) - if(world.RunningService()) - var/tmcommit = testmerge[line]["commit"] - log_world("Test merge active of PR #[line] commit [tmcommit]") - SSblackbox.add_details("testmerged_prs","[line]|[tmcommit]") - else //tgs2 support - log_world("Test merge active of PR #[line]") - SSblackbox.add_details("testmerged_prs","[line]") + var/tmcommit = testmerge[line]["commit"] + log_world("Test merge active of PR #[line] commit [tmcommit]") + SSblackbox.add_details("testmerged_prs","[line]|[tmcommit]") log_world("Based off origin/master commit [originmastercommit]") else log_world(originmastercommit) +<<<<<<< HEAD /datum/getrev/proc/DownloadPRDetails() if(!config.githubrepoid) if(testmerge.len) @@ -73,18 +73,16 @@ CHECK_TICK log_world("PR details successfully downloaded") has_pr_details = TRUE +======= +>>>>>>> 62f788f... Server tools API v3.1 (#31000) /datum/getrev/proc/GetTestMergeInfo(header = TRUE) if(!testmerge.len) return "" . = header ? "The following pull requests are currently test merged:
    " : "" for(var/line in testmerge) - var/details - if(world.RunningService()) - var/cm = testmerge[line]["commit"] - details = ": '" + html_encode(testmerge[line]["title"]) + "' by " + html_encode(testmerge[line]["author"]) + " at commit " + html_encode(copytext(cm, 1, min(length(cm), 7))) - else if(has_pr_details) //tgs2 support - details = ": '" + html_encode(testmerge[line]["title"]) + "' by " + html_encode(testmerge[line]["user"]["login"]) + var/cm = testmerge[line]["commit"] + var/details = ": '" + html_encode(testmerge[line]["title"]) + "' by " + html_encode(testmerge[line]["author"]) + " at commit " + html_encode(copytext(cm, 1, min(length(cm), 7))) if(details && findtext(details, "\[s\]") && (!usr || !usr.client.holder)) continue . += "#[line][details]
    " diff --git a/code/game/world.dm b/code/game/world.dm index 3763a408ac..05b6b442ef 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -1,3 +1,6 @@ +#define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round + //This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored + GLOBAL_VAR(security_mode) GLOBAL_PROTECT(security_mode) @@ -19,8 +22,7 @@ GLOBAL_PROTECT(security_mode) SetupLogs() - if(!RunningService()) //tgs2 support - GLOB.revdata.DownloadPRDetails() + SERVER_TOOLS_ON_NEW load_motd() load_admins() @@ -33,9 +35,12 @@ GLOBAL_PROTECT(security_mode) Master.Initialize(10, FALSE) +<<<<<<< HEAD if(config.irc_announce_new_game) IRCBroadcast("New round starting on [SSmapping.config.map_name]!") +======= +>>>>>>> 62f788f... Server tools API v3.1 (#31000) /world/proc/SetupExternalRSC() #if (PRELOAD_RSC == 0) external_rsc_urls = world.file2list("config/external_rsc_urls.txt","\n") @@ -125,9 +130,16 @@ GLOBAL_PROTECT(security_mode) if(!pinging && !playing && config && config.log_world_topic) WRITE_FILE(GLOB.world_game_log, "TOPIC: \"[T]\", from:[addr], master:[master], key:[key]") +<<<<<<< HEAD if(input[SERVICE_CMD_PARAM_KEY]) return ServiceCommand(input) var/key_valid = (global.comms_allowed && input["key"] == global.comms_key) +======= + SERVER_TOOLS_ON_TOPIC //redirect to server tools if necessary + + var/comms_key = CONFIG_GET(string/comms_key) + var/key_valid = (comms_key && input["key"] == comms_key) +>>>>>>> 62f788f... Server tools API v3.1 (#31000) if(pinging) var/x = 1 @@ -142,17 +154,6 @@ GLOBAL_PROTECT(security_mode) n++ return n - else if("ircstatus" in input) //tgs2 support - var/static/last_irc_status = 0 - if(world.time - last_irc_status < 50) - return - var/list/adm = get_admin_counts() - var/list/allmins = adm["total"] - var/status = "Admins: [allmins.len] (Active: [english_list(adm["present"])] AFK: [english_list(adm["afk"])] Stealth: [english_list(adm["stealth"])] Skipped: [english_list(adm["noflags"])]). " - status += "Players: [GLOB.clients.len] (Active: [get_active_player_count(0,1,0)]). Mode: [SSticker.mode.name]." - send2irc("Status", status) - last_irc_status = world.time - else if("status" in input) var/list/s = list() s["version"] = GLOB.game_version @@ -210,24 +211,6 @@ GLOBAL_PROTECT(security_mode) if(input["crossmessage"] == "News_Report") minor_announce(input["message"], "Breaking Update From [input["message_sender"]]") - else if("adminmsg" in input) //tgs2 support - if(!key_valid) - return "Bad Key" - else - return IrcPm(input["adminmsg"],input["msg"],input["sender"]) - - else if("namecheck" in input) //tgs2 support - if(!key_valid) - return "Bad Key" - else - log_admin("IRC Name Check: [input["sender"]] on [input["namecheck"]]") - message_admins("IRC name checking on [input["namecheck"]] from [input["sender"]]") - return keywords_lookup(input["namecheck"],1) - else if("adminwho" in input) //tgs2 support - if(!key_valid) - return "Bad Key" - else - return ircadminwho() else if("server_hop" in input) show_server_hop_transfer_screen(input["server_hop"]) @@ -246,7 +229,7 @@ GLOBAL_PROTECT(security_mode) C.AnnouncePR(final_composed) /world/Reboot(reason = 0, fast_track = FALSE) - ServiceReboot() //handles alternative actions if necessary + SERVER_TOOLS_ON_REBOOT if (reason || fast_track) //special reboot, do none of the normal stuff if (usr) log_admin("[key_name(usr)] Has requested an immediate world restart via client side debugging tools") diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index b56caa4e9a..6fbdec01d2 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -421,8 +421,8 @@ return var/list/options = list("Regular Restart", "Hard Restart (No Delay/Feeback Reason)", "Hardest Restart (No actions, just reboot)") - if(world.RunningService()) - options += "Service Restart (Force restart DD)"; + if(SERVER_TOOLS_PRESENT) + options += "Server Restart (Kill and restart DD)"; var/rebootconfirm if(SSticker.admin_delay_notice) @@ -434,16 +434,19 @@ var/result = input(usr, "Select reboot method", "World Reboot", options[1]) as null|anything in options if(result) SSblackbox.add_details("admin_verb","Reboot World") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + var/init_by = "Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key]." switch(result) if("Regular Restart") - SSticker.Reboot("Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key].", "admin reboot - by [usr.key] [usr.client.holder.fakekey ? "(stealth)" : ""]", 10) + SSticker.Reboot(init_by, "admin reboot - by [usr.key] [usr.client.holder.fakekey ? "(stealth)" : ""]", 10) if("Hard Restart (No Delay, No Feeback Reason)") + to_chat(world, "World reboot - [init_by]") world.Reboot() if("Hardest Restart (No actions, just reboot)") + to_chat(world, "Hard world reboot - [init_by]") world.Reboot(fast_track = TRUE) - if("Service Restart (Force restart DD)") - GLOB.reboot_mode = REBOOT_MODE_HARD - world.ServiceReboot() + if("Server Restart (Kill and restart DD)") + to_chat(world, "Server restart - [init_by]") + SERVER_TOOLS_REBOOT_BYOND /datum/admins/proc/end_round() set category = "Server" diff --git a/code/modules/admin/chat_commands.dm b/code/modules/admin/chat_commands.dm new file mode 100644 index 0000000000..e0d7f1315e --- /dev/null +++ b/code/modules/admin/chat_commands.dm @@ -0,0 +1,63 @@ +#define IRC_STATUS_THROTTLE 5 + +/datum/server_tools_command/ircstatus + name = "status" + help_text = "Gets the admincount, playercount, gamemode, and true game mode of the server" + admin_only = TRUE + var/static/last_irc_status = 0 + +/datum/server_tools_command/ircstatus/Run(sender, params) + var/rtod = REALTIMEOFDAY + if(rtod - last_irc_status < IRC_STATUS_THROTTLE) + return + last_irc_status = rtod + var/list/adm = get_admin_counts() + var/list/allmins = adm["total"] + var/status = "Admins: [allmins.len] (Active: [english_list(adm["present"])] AFK: [english_list(adm["afk"])] Stealth: [english_list(adm["stealth"])] Skipped: [english_list(adm["noflags"])]). " + status += "Players: [GLOB.clients.len] (Active: [get_active_player_count(0,1,0)]). Mode: [SSticker.mode ? SSticker.mode.name : "Not started"]." + return status + +/datum/server_tools_command/irccheck + name = "check" + help_text = "Gets the playercount, gamemode, and address of the server" + admin_only = TRUE + var/static/last_irc_check = 0 + +/datum/server_tools_command/irccheck/Run(sender, params) + var/rtod = REALTIMEOFDAY + if(rtod - last_irc_check < IRC_STATUS_THROTTLE) + return + last_irc_check = rtod + var/server = CONFIG_GET(string/server) + return "[GLOB.round_id ? "Round #[GLOB.round_id]: " : ""][GLOB.clients.len] players on [SSmapping.config.map_name], Mode: [GLOB.master_mode]; Round [SSticker.HasRoundStarted() ? (SSticker.IsRoundInProgress() ? "Active" : "Finishing") : "Starting"] -- [server ? server : "[world.internet_address]:[world.port]"]" + +/datum/server_tools_command/ahelp + name = "ahelp" + help_text = " |list>>" + required_parameters = 2 + admin_only = TRUE + +/datum/server_tools_command/ahelp/Run(sender, params) + var/list/all_params = splittext(params, " ") + var/target = all_params[1] + all_params.Cut(1, 2) + return IrcPm(target, all_params.Join(" "), sender) + +/datum/server_tools_command/namecheck + name = "namecheck" + help_text = "Returns info on the specified target" + required_parameters = 1 + admin_only = TRUE + +/datum/server_tools_command/namecheck/Run(sender, params) + log_admin("IRC Name Check: [sender] on [params]") + message_admins("IRC name checking on [params] from [sender]") + return keywords_lookup(params, 1) + +/datum/server_tools_command/adminwho + name = "adminwho" + help_text = "Lists administrators currently on the server" + admin_only = TRUE + +/datum/server_tools_command/adminwho/Run(sender, params) + return ircadminwho() diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 7922a89c80..f974ebda62 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -587,10 +587,15 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) /proc/send2irc(msg,msg2) +<<<<<<< HEAD if(world.RunningService()) world.ExportService("[SERVICE_REQUEST_IRC_ADMIN_CHANNEL_MESSAGE] [msg] | [msg2]") else if(config.useircbot) shell("python nudge.py [msg] [msg2]") +======= + if(SERVER_TOOLS_PRESENT) + SERVER_TOOLS_RELAY_BROADCAST("[msg] | [msg2]") +>>>>>>> 62f788f... Server tools API v3.1 (#31000) /proc/send2otherserver(source,msg,type = "Ahelp") if(config.cross_allowed) diff --git a/code/modules/server_tools/st_commands.dm b/code/modules/server_tools/st_commands.dm new file mode 100644 index 0000000000..9ec87a595c --- /dev/null +++ b/code/modules/server_tools/st_commands.dm @@ -0,0 +1,76 @@ +/datum/server_tools_command + var/name = "" //the string to trigger this command on a chat bot. e.g. TGS3_BOT: do_this_command + var/help_text = "" //help text for this command + var/required_parameters = 0 //number of parameters required for this command + var/admin_only = FALSE //set to TRUE if this command should only be usable by registered chat admins + +//override to implement command +//sender is the display name of who sent the command +//params is the trimmed string following the command name +/datum/server_tools_command/proc/Run(sender, params) + CRASH("[type] has no implementation for Run()") + +/world/proc/ListServiceCustomCommands(warnings_only) + if(!warnings_only) + . = list() + var/list/command_name_types = list() + var/list/warned_command_names = warnings_only ? list() : null + for(var/I in typesof(/datum/server_tools_command) - /datum/server_tools_command) + var/datum/server_tools_command/stc = I + var/command_name = initial(stc.name) + var/static/list/warned_server_tools_names = list() + if(!command_name || findtext(command_name, " ") || findtext(command_name, "'") || findtext(command_name, "\"")) + if(warnings_only && !warned_command_names[command_name]) + SERVER_TOOLS_LOG("WARNING: Custom command [command_name] can't be used as it is empty or contains illegal characters!") + warned_command_names[command_name] = TRUE + continue + + if(command_name_types[command_name]) + if(warnings_only) + SERVER_TOOLS_LOG("WARNING: Custom commands [command_name_types[command_name]] and [stc] have the same name, only [command_name_types[command_name]] will be available!") + continue + command_name_types[stc] = command_name + + if(!warnings_only) + .[command_name] = list(SERVICE_JSON_PARAM_HELPTEXT = initial(stc.help_text), SERVICE_JSON_PARAM_ADMINONLY = initial(stc.admin_only), SERVICE_JSON_PARAM_REQUIREDPARAMETERS = initial(stc.required_parameters)) + +/world/proc/HandleServiceCustomCommand(command, sender, params) + var/static/list/cached_custom_server_tools_commands + if(!cached_custom_server_tools_commands) + cached_custom_server_tools_commands = list() + for(var/I in typesof(/datum/server_tools_command) - /datum/server_tools_command) + var/datum/server_tools_command/stc = I + cached_custom_server_tools_commands[lowertext(initial(stc.name))] = stc + + var/command_type = cached_custom_server_tools_commands[command] + if(!command_type) + return FALSE + var/datum/server_tools_command/stc = new command_type + return stc.Run(sender, params) || TRUE + +/* +The MIT License + +Copyright (c) 2011 Dominic Tarr + +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ diff --git a/code/modules/server_tools/st_interface.dm b/code/modules/server_tools/st_interface.dm new file mode 100644 index 0000000000..12fb5a85c2 --- /dev/null +++ b/code/modules/server_tools/st_interface.dm @@ -0,0 +1,125 @@ +SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(reboot_mode, REBOOT_MODE_NORMAL) +SERVER_TOOLS_DEFINE_AND_SET_GLOBAL(server_tools_api_compatible, FALSE) + +/proc/GetTestMerges() + if(RunningService() && fexists(SERVICE_PR_TEST_JSON)) + . = json_decode(file2text(SERVICE_PR_TEST_JSON)) + if(.) + return + return list() + +/world/proc/ServiceInit() + if(!RunningService(TRUE)) + return + ListServiceCustomCommands(TRUE) + ExportService("[SERVICE_REQUEST_API_VERSION] [SERVER_TOOLS_API_VERSION]", TRUE) + +/proc/RunningService(skip_compat_check = FALSE) + return (skip_compat_check || SERVER_TOOLS_READ_GLOBAL(server_tools_api_compatible)) && world.params[SERVICE_WORLD_PARAM] != null + +/proc/ServiceVersion() + if(RunningService(TRUE)) + return world.params[SERVICE_VERSION_PARAM] + +/proc/ServiceAPIVersion() + return SERVICE_API_VERSION_STRING + +/world/proc/ExportService(command, skip_compat_check = FALSE) + . = FALSE + if(!RunningService(skip_compat_check)) + return + if(skip_compat_check && !fexists(SERVICE_INTERFACE_DLL)) + CRASH("Service parameter present but no interface DLL detected. This is symptomatic of running a service less than version 3.1! Please upgrade.") + call(SERVICE_INTERFACE_DLL, SERVICE_INTERFACE_FUNCTION)(command) //trust no retval + return TRUE + +/world/proc/ChatBroadcast(message) + ExportService("[SERVICE_REQUEST_IRC_BROADCAST] [message]") + +/world/proc/AdminBroadcast(message) + ExportService("[SERVICE_REQUEST_IRC_ADMIN_CHANNEL_MESSAGE] [message]") + +/world/proc/ServiceEndProcess() + SERVER_TOOLS_LOG("Sending shutdown request!"); + sleep(world.tick_lag) //flush the buffers + ExportService(SERVICE_REQUEST_KILL_PROCESS) + +//called at the exact moment the world is supposed to reboot +/world/proc/ServiceReboot() + switch(SERVER_TOOLS_READ_GLOBAL(reboot_mode)) + if(REBOOT_MODE_HARD) + SERVER_TOOLS_WORLD_ANNOUNCE("Hard reboot triggered, you will automatically reconnect...") + ServiceEndProcess() + if(REBOOT_MODE_SHUTDOWN) + SERVER_TOOLS_WORLD_ANNOUNCE("The server is shutting down...") + ServiceEndProcess() + else + ExportService(SERVICE_REQUEST_WORLD_REBOOT) //just let em know + +/world/proc/ServiceCommand(list/params) + var/their_sCK = params[SERVICE_CMD_PARAM_KEY] + if(!their_sCK || !RunningService(TRUE)) + return FALSE //continue world/Topic + + var/sCK = world.params[SERVICE_WORLD_PARAM] + if(their_sCK != sCK) + return "Invalid comms key!"; + + var/command = params[SERVICE_CMD_PARAM_COMMAND] + if(!command) + return "No command!" + + switch(command) + if(SERVICE_CMD_API_COMPATIBLE) + SERVER_TOOLS_WRITE_GLOBAL(server_tools_api_compatible, TRUE) + return "SUCCESS" + if(SERVICE_CMD_HARD_REBOOT) + if(SERVER_TOOLS_READ_GLOBAL(reboot_mode) != REBOOT_MODE_HARD) + SERVER_TOOLS_WRITE_GLOBAL(reboot_mode, REBOOT_MODE_HARD) + SERVER_TOOLS_LOG("Hard reboot requested by service") + SERVER_TOOLS_NOTIFY_ADMINS("The world will hard reboot at the end of the game. Requested by service.") + if(SERVICE_CMD_GRACEFUL_SHUTDOWN) + if(SERVER_TOOLS_READ_GLOBAL(reboot_mode) != REBOOT_MODE_SHUTDOWN) + SERVER_TOOLS_WRITE_GLOBAL(reboot_mode, REBOOT_MODE_SHUTDOWN) + SERVER_TOOLS_LOG("Shutdown requested by service") + message_admins("The world will shutdown at the end of the game. Requested by service.") + if(SERVICE_CMD_WORLD_ANNOUNCE) + var/msg = params["message"] + if(!istext(msg) || !msg) + return "No message set!" + SERVER_TOOLS_WORLD_ANNOUNCE(msg) + return "SUCCESS" + if(SERVICE_CMD_LIST_CUSTOM) + return json_encode(ListServiceCustomCommands(FALSE)) + else + var/custom_command_result = HandleServiceCustomCommand(lowertext(command), params[SERVICE_CMD_PARAM_SENDER], params[SERVICE_CMD_PARAM_CUSTOM]) + if(custom_command_result) + return istext(custom_command_result) ? custom_command_result : "SUCCESS" + return "Unknown command: [command]" + +/* +The MIT License + +Copyright (c) 2011 Dominic Tarr + +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ diff --git a/tgstation.dme b/tgstation.dme index 525e30ca66..de37ad4848 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -1054,6 +1054,7 @@ #include "code\modules\admin\admin_verbs.dm" #include "code\modules\admin\adminmenu.dm" #include "code\modules\admin\banjob.dm" +#include "code\modules\admin\chat_commands.dm" #include "code\modules\admin\create_mob.dm" #include "code\modules\admin\create_object.dm" #include "code\modules\admin\create_poll.dm" @@ -2128,7 +2129,8 @@ #include "code\modules\ruins\spaceruin_code\TheDerelict.dm" #include "code\modules\security_levels\keycard_authentication.dm" #include "code\modules\security_levels\security_levels.dm" -#include "code\modules\server_tools\server_tools.dm" +#include "code\modules\server_tools\st_interface.dm" +#include "code\modules\server_tools\st_commands.dm" #include "code\modules\shuttle\arrivals.dm" #include "code\modules\shuttle\assault_pod.dm" #include "code\modules\shuttle\computer.dm" From ba189c041b350557c4e96504280302a6728a8377 Mon Sep 17 00:00:00 2001 From: oranges Date: Fri, 29 Sep 2017 22:30:17 +1300 Subject: [PATCH 08/60] Fixes shade attackby --- .../modules/mob/living/simple_animal/shade.dm | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm index 802bd738e9..39107d8e65 100644 --- a/code/modules/mob/living/simple_animal/shade.dm +++ b/code/modules/mob/living/simple_animal/shade.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /mob/living/simple_animal/shade name = "Shade" real_name = "Shade" @@ -64,3 +65,71 @@ SS.transfer_soul("SHADE", src, user) else ..() +======= +/mob/living/simple_animal/shade + name = "Shade" + real_name = "Shade" + desc = "A bound spirit" + gender = PLURAL + icon = 'icons/mob/mob.dmi' + icon_state = "shade" + icon_living = "shade" + maxHealth = 50 + health = 50 + healable = 0 + speak_emote = list("hisses") + emote_hear = list("wails.","screeches.") + response_help = "puts their hand through" + response_disarm = "flails at" + response_harm = "punches" + speak_chance = 1 + melee_damage_lower = 5 + melee_damage_upper = 15 + attacktext = "metaphysically strikes" + minbodytemp = 0 + maxbodytemp = INFINITY + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + speed = -1 + stop_automated_movement = 1 + status_flags = 0 + faction = list("cult") + status_flags = CANPUSH + movement_type = FLYING + loot = list(/obj/item/ectoplasm) + del_on_death = TRUE + initial_language_holder = /datum/language_holder/construct + +/mob/living/simple_animal/shade/death() + deathmessage = "lets out a contented sigh as [p_their()] form unwinds." + ..() + +/mob/living/simple_animal/shade/canSuicide() + if(istype(loc, /obj/item/device/soulstone)) //do not suicide inside the soulstone + return 0 + return ..() + +/mob/living/simple_animal/shade/Process_Spacemove(movement_dir = 0) + return TRUE //this doesn't make much sense; you'd thing TRUE would mean it'd process spacemove but it means it doesn't + +/mob/living/simple_animal/shade/attack_animal(mob/living/simple_animal/M) + if(isconstruct(M)) + var/mob/living/simple_animal/hostile/construct/C = M + if(!C.can_repair_constructs) + return + if(health < maxHealth) + adjustHealth(-25) + Beam(M,icon_state="sendbeam",time=4) + M.visible_message("[M] heals \the [src].", \ + "You heal [src], leaving [src] at [health]/[maxHealth] health.") + else + to_chat(M, "You cannot heal [src], as [p_they()] [p_are()] unharmed!") + else if(src != M) + return ..() + +/mob/living/simple_animal/shade/attackby(obj/item/O, mob/user, params) //Marker -Agouri + if(istype(O, /obj/item/device/soulstone)) + var/obj/item/device/soulstone/SS = O + SS.transfer_soul("SHADE", src, user) + else + . = ..() +>>>>>>> 2ddc4aa... Merge pull request #31085 from AnturK/shadefix From a4992bae90cf390caa504a82421424d0580d6e40 Mon Sep 17 00:00:00 2001 From: oranges Date: Wed, 27 Sep 2017 22:45:07 +0000 Subject: [PATCH 09/60] Log attempted injections as well as successful ones --- .../reagents/reagent_containers/hypospray.dm | 167 ++++++++++++++++++ .../reagents/reagent_containers/syringes.dm | 12 +- 2 files changed, 174 insertions(+), 5 deletions(-) diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index ec34bf833f..c621285335 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /obj/item/reagent_containers/hypospray name = "hypospray" desc = "The DeForest Medical Corporation hypospray is a sterile, air-needle autoinjector for rapid administration of drugs to patients." @@ -159,3 +160,169 @@ volume = 1 amount_per_transfer_from_this = 1 list_reagents = list("unstablemutationtoxin" = 1) +======= +/obj/item/reagent_containers/hypospray + name = "hypospray" + desc = "The DeForest Medical Corporation hypospray is a sterile, air-needle autoinjector for rapid administration of drugs to patients." + icon = 'icons/obj/syringe.dmi' + item_state = "hypo" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + icon_state = "hypo" + amount_per_transfer_from_this = 5 + volume = 30 + possible_transfer_amounts = list() + resistance_flags = ACID_PROOF + container_type = OPENCONTAINER_1 + slot_flags = SLOT_BELT + var/ignore_flags = 0 + var/infinite = FALSE + +/obj/item/reagent_containers/hypospray/attack_paw(mob/user) + return attack_hand(user) + +/obj/item/reagent_containers/hypospray/attack(mob/living/M, mob/user) + if(!reagents.total_volume) + to_chat(user, "[src] is empty!") + return + if(!iscarbon(M)) + return + + //Always log attemped injects for admins + var/list/injected = list() + for(var/datum/reagent/R in reagents.reagent_list) + injected += R.name + var/contained = english_list(injected) + add_logs(user, M, "attempted to inject", src, "([contained])") + + if(reagents.total_volume && (ignore_flags || M.can_inject(user, 1))) // Ignore flag should be checked first or there will be an error message. + to_chat(M, "You feel a tiny prick!") + to_chat(user, "You inject [M] with [src].") + + var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1) + reagents.reaction(M, INJECT, fraction) + if(M.reagents) + var/trans = 0 + if(!infinite) + trans = reagents.trans_to(M, amount_per_transfer_from_this) + else + trans = reagents.copy_to(M, amount_per_transfer_from_this) + + to_chat(user, "[trans] unit\s injected. [reagents.total_volume] unit\s remaining in [src].") + + + add_logs(user, M, "injected", src, "([contained])") + +/obj/item/reagent_containers/hypospray/CMO + list_reagents = list("omnizine" = 30) + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + +/obj/item/reagent_containers/hypospray/combat + name = "combat stimulant injector" + desc = "A modified air-needle autoinjector, used by support operatives to quickly heal injuries in combat." + amount_per_transfer_from_this = 10 + icon_state = "combat_hypo" + volume = 90 + ignore_flags = 1 // So they can heal their comrades. + list_reagents = list("epinephrine" = 30, "omnizine" = 30, "leporazine" = 15, "atropine" = 15) + +/obj/item/reagent_containers/hypospray/combat/nanites + desc = "A modified air-needle autoinjector for use in combat situations. Prefilled with expensive medical nanites for rapid healing." + volume = 100 + list_reagents = list("nanites" = 80, "synaptizine" = 20) + +/obj/item/reagent_containers/hypospray/magillitis + name = "experimental autoinjector" + desc = "A modified air-needle autoinjector with a small single-use reservoir. It contains an experimental serum." + icon_state = "combat_hypo" + volume = 5 + container_type = NONE + list_reagents = list("magillitis" = 5) + +//MediPens + +/obj/item/reagent_containers/hypospray/medipen + name = "epinephrine medipen" + desc = "A rapid and safe way to stabilize patients in critical condition for personnel without advanced medical knowledge." + icon_state = "medipen" + item_state = "medipen" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + amount_per_transfer_from_this = 10 + volume = 10 + ignore_flags = 1 //so you can medipen through hardsuits + container_type = DRAWABLE_1 + flags_1 = null + list_reagents = list("epinephrine" = 10) + +/obj/item/reagent_containers/hypospray/medipen/attack(mob/M, mob/user) + if(!reagents.total_volume) + to_chat(user, "[src] is empty!") + return + ..() + if(!iscyborg(user)) + reagents.maximum_volume = 0 //Makes them useless afterwards + container_type = NONE + update_icon() + spawn(80) + if(iscyborg(user) && !reagents.total_volume) + var/mob/living/silicon/robot/R = user + if(R.cell.use(100)) + reagents.add_reagent_list(list_reagents) + update_icon() + return + +/obj/item/reagent_containers/hypospray/medipen/update_icon() + if(reagents.total_volume > 0) + icon_state = initial(icon_state) + else + icon_state = "[initial(icon_state)]0" + +/obj/item/reagent_containers/hypospray/medipen/examine() + ..() + if(reagents && reagents.reagent_list.len) + to_chat(usr, "It is currently loaded.") + else + to_chat(usr, "It is spent.") + +/obj/item/reagent_containers/hypospray/medipen/stimpack //goliath kiting + name = "stimpack medipen" + desc = "A rapid way to stimulate your body's adrenaline, allowing for freer movement in restrictive armor." + icon_state = "stimpen" + volume = 20 + amount_per_transfer_from_this = 20 + list_reagents = list("ephedrine" = 10, "coffee" = 10) + +/obj/item/reagent_containers/hypospray/medipen/stimpack/traitor + desc = "A modified stimulants autoinjector for use in combat situations. Has a mild healing effect." + list_reagents = list("stimulants" = 10, "omnizine" = 10) + +/obj/item/reagent_containers/hypospray/medipen/morphine + name = "morphine medipen" + desc = "A rapid way to get you out of a tight situation and fast! You'll feel rather drowsy, though." + list_reagents = list("morphine" = 10) + +/obj/item/reagent_containers/hypospray/medipen/tuberculosiscure + name = "BVAK autoinjector" + desc = "Bio Virus Antidote Kit autoinjector. Has a two use system for yourself, and someone else. Inject when infected." + icon_state = "stimpen" + volume = 60 + amount_per_transfer_from_this = 30 + list_reagents = list("atropine" = 10, "epinephrine" = 10, "salbutamol" = 20, "spaceacillin" = 20) + +/obj/item/reagent_containers/hypospray/medipen/survival + name = "survival medipen" + desc = "A medipen for surviving in the harshest of environments, heals and protects from environmental hazards. WARNING: Do not inject more than one pen in quick succession." + icon_state = "stimpen" + volume = 57 + amount_per_transfer_from_this = 57 + list_reagents = list("salbutamol" = 10, "leporazine" = 15, "tricordrazine" = 15, "epinephrine" = 10, "miningnanites" = 2, "omnizine" = 5) + +/obj/item/reagent_containers/hypospray/medipen/species_mutator + name = "species mutator medipen" + desc = "Embark on a whirlwind tour of racial insensitivity by \ + literally appropriating other races." + volume = 1 + amount_per_transfer_from_this = 1 + list_reagents = list("unstablemutationtoxin" = 1) +>>>>>>> eda8f7f... Log attempted injections as well as successful ones diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 324a7d7066..daf955d0ef 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -110,6 +110,13 @@ update_icon() if(SYRINGE_INJECT) + //Always log attemped injections for admins + var/list/rinject = list() + for(var/datum/reagent/R in reagents.reagent_list) + rinject += R.name + var/contained = english_list(rinject) + add_logs(user, L, "attemped to inject", src, addition="which had [contained]") + if(!reagents.total_volume) to_chat(user, "[src] is empty.") return @@ -137,11 +144,6 @@ L.visible_message("[user] injects [L] with the syringe!", \ "[user] injects [L] with the syringe!") - var/list/rinject = list() - for(var/datum/reagent/R in reagents.reagent_list) - rinject += R.name - var/contained = english_list(rinject) - if(L != user) add_logs(user, L, "injected", src, addition="which had [contained]") else From 114009d972bc5482222c2b8ee450ef69b2522e67 Mon Sep 17 00:00:00 2001 From: ShizCalev Date: Thu, 28 Sep 2017 14:44:08 -0400 Subject: [PATCH 10/60] Cleans up some unused code --- code/_onclick/observer.dm | 94 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 438b3b5142..679f9d7312 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /mob/dead/observer/DblClickOn(var/atom/A, var/params) if(client.click_intercept) if(call(client.click_intercept,"InterceptClickOn")(src,params,A)) @@ -102,3 +103,96 @@ attack_hand(user) */ +======= +/mob/dead/observer/DblClickOn(var/atom/A, var/params) + if(client.click_intercept) + if(call(client.click_intercept,"InterceptClickOn")(src,params,A)) + return + + if(can_reenter_corpse && mind && mind.current) + if(A == mind.current || (mind.current in A)) // double click your corpse or whatever holds it + reenter_corpse() // (cloning scanner, body bag, closet, mech, etc) + return // seems legit. + + // Things you might plausibly want to follow + if(ismovableatom(A)) + ManualFollow(A) + + // Otherwise jump + else if(A.loc) + loc = get_turf(A) + update_parallax_contents() + +/mob/dead/observer/ClickOn(var/atom/A, var/params) + if(client.click_intercept) + if(call(client.click_intercept,"InterceptClickOn")(src,params,A)) + return + + var/list/modifiers = params2list(params) + if(modifiers["shift"] && modifiers["middle"]) + ShiftMiddleClickOn(A) + return + if(modifiers["shift"] && modifiers["ctrl"]) + CtrlShiftClickOn(A) + return + if(modifiers["middle"]) + MiddleClickOn(A) + return + if(modifiers["shift"]) + ShiftClickOn(A) + return + if(modifiers["alt"]) + AltClickOn(A) + return + if(modifiers["ctrl"]) + CtrlClickOn(A) + return + + if(world.time <= next_move) + return + // You are responsible for checking config.ghost_interaction when you override this function + // Not all of them require checking, see below + A.attack_ghost(src) + +// Oh by the way this didn't work with old click code which is why clicking shit didn't spam you +/atom/proc/attack_ghost(mob/dead/observer/user) + if(user.client) + if(IsAdminGhost(user)) + attack_ai(user) + if(user.client.prefs.inquisitive_ghost) + user.examinate(src) + +// --------------------------------------- +// And here are some good things for free: +// Now you can click through portals, wormholes, gateways, and teleporters while observing. -Sayu + +/obj/machinery/teleport/hub/attack_ghost(mob/user) + var/atom/l = loc + var/obj/machinery/computer/teleporter/com = locate(/obj/machinery/computer/teleporter, locate(l.x - 2, l.y, l.z)) + if(com && com.locked) + user.forceMove(get_turf(com.locked)) + +/obj/effect/portal/attack_ghost(mob/user) + if(linked) + user.forceMove(get_turf(linked)) + +/obj/machinery/gateway/centerstation/attack_ghost(mob/user) + if(awaygate) + user.forceMove(awaygate.loc) + else + to_chat(user, "[src] has no destination.") + +/obj/machinery/gateway/centeraway/attack_ghost(mob/user) + if(stationgate) + user.forceMove(stationgate.loc) + else + to_chat(user, "[src] has no destination.") + +/obj/item/storage/attack_ghost(mob/user) + orient2hud(user) + show_to(user) + +/obj/machinery/teleport/hub/attack_ghost(mob/user) + if(power_station && power_station.engaged && power_station.teleporter_console && power_station.teleporter_console.target) + user.forceMove(get_turf(power_station.teleporter_console.target)) +>>>>>>> b4208c6... Old code From fdef7000012c90949df00cac567971219d2d47b2 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 29 Sep 2017 18:23:38 -0400 Subject: [PATCH 11/60] Fixes AI law weights infinite loop --- code/datums/ai_laws.dm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index 2222a959bc..2e5296cff7 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -243,9 +243,15 @@ /datum/ai_laws/proc/pick_weighted_lawset() var/datum/ai_laws/lawtype +<<<<<<< HEAD while(!lawtype && config.law_weights.len) var/possible_id = pickweight(config.law_weights) +======= + var/list/law_weights = CONFIG_GET(keyed_number_list/law_weight) + while(!lawtype && law_weights.len) + var/possible_id = pickweight(law_weights) +>>>>>>> f7171e7... Fixes AI law weights infinite loop lawtype = lawid_to_type(possible_id) if(!lawtype) config.law_weights -= possible_id From f8f599b17b797f31ca650c7523a7b8fc2bbcd2e2 Mon Sep 17 00:00:00 2001 From: ShizCalev Date: Fri, 29 Sep 2017 20:33:19 -0400 Subject: [PATCH 12/60] Stops putting RCD, bluespace bags, and staves into ORM --- code/__DEFINES/flags.dm | 3 + code/datums/components/material_container.dm | 5 +- code/game/mecha/equipment/tools/work_tools.dm | 1 + code/game/objects/items/RCD.dm | 1 + code/game/objects/items/bodybag.dm | 74 ++++ code/game/objects/items/storage/backpack.dm | 1 + code/game/objects/items/storage/bags.dm | 385 ++++++++++++++++++ code/modules/projectiles/guns/magic/staff.dm | 1 + 8 files changed, 470 insertions(+), 1 deletion(-) diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index b464ea130c..97bf61779f 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -53,6 +53,9 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 // TESLA_IGNORE grants immunity from being targeted by tesla-style electricity #define TESLA_IGNORE_2 512 +// Stops you from putting things like an RCD or other items into an ORM or protolathe for materials. +#define NO_MAT_REDEMPTION_2 1024 + //turf-only flags #define NOJAUNT_1 1 #define UNUSED_TRANSIT_TURF_1 2 diff --git a/code/datums/components/material_container.dm b/code/datums/components/material_container.dm index 55504d47d5..c1435b05a3 100644 --- a/code/datums/components/material_container.dm +++ b/code/datums/components/material_container.dm @@ -52,7 +52,10 @@ /datum/component/material_container/proc/OnAttackBy(obj/item/I, mob/living/user) var/list/tc = allowed_typecache - if(user.a_intent == INTENT_HARM || (I.flags_2 & HOLOGRAM_2) || (tc && !is_type_in_typecache(I, tc))) + if(user.a_intent == INTENT_HARM) + return FALSE + if((I.flags_2 & HOLOGRAM_2 | NO_MAT_REDEMPTION_2) || (tc && !is_type_in_typecache(I, tc))) + to_chat(user, "[parent] won't accept [I]!") return FALSE . = TRUE last_insert_success = FALSE diff --git a/code/game/mecha/equipment/tools/work_tools.dm b/code/game/mecha/equipment/tools/work_tools.dm index b82f02353c..1fcc54ac2a 100644 --- a/code/game/mecha/equipment/tools/work_tools.dm +++ b/code/game/mecha/equipment/tools/work_tools.dm @@ -196,6 +196,7 @@ equip_cooldown = 10 energy_drain = 250 range = MELEE|RANGED + flags_2 = NO_MAT_REDEMPTION_2 var/mode = 0 //0 - deconstruct, 1 - wall or floor, 2 - airlock. /obj/item/mecha_parts/mecha_equipment/rcd/New() diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index 6e094a5bbb..a2f80a94a9 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -123,6 +123,7 @@ obj/item/construction lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' max_matter = 160 + flags_2 = NO_MAT_REDEMPTION_2 var/mode = 1 var/canRturf = 0 var/ranged = FALSE diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index 2cb6c5b93f..f711aaba59 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /obj/item/bodybag name = "body bag" @@ -68,3 +69,76 @@ return loc.visible_message("[user] suddenly appears in front of [loc]!", "[user] breaks free of [src]!") qdel(src) +======= + +/obj/item/bodybag + name = "body bag" + desc = "A folded bag designed for the storage and transportation of cadavers." + icon = 'icons/obj/bodybag.dmi' + icon_state = "bodybag_folded" + var/unfoldedbag_path = /obj/structure/closet/body_bag + w_class = WEIGHT_CLASS_SMALL + +/obj/item/bodybag/attack_self(mob/user) + deploy_bodybag(user, user.loc) + +/obj/item/bodybag/afterattack(atom/target, mob/user, proximity) + if(proximity) + if(isopenturf(target)) + deploy_bodybag(user, target) + +/obj/item/bodybag/proc/deploy_bodybag(mob/user, atom/location) + var/obj/structure/closet/body_bag/R = new unfoldedbag_path(location) + R.open(user) + R.add_fingerprint(user) + qdel(src) + + +// Bluespace bodybag + +/obj/item/bodybag/bluespace + name = "bluespace body bag" + desc = "A folded bluespace body bag designed for the storage and transportation of cadavers." + icon = 'icons/obj/bodybag.dmi' + icon_state = "bluebodybag_folded" + unfoldedbag_path = /obj/structure/closet/body_bag/bluespace + w_class = WEIGHT_CLASS_SMALL + flags_2 = NO_MAT_REDEMPTION_2 + origin_tech = "bluespace=4;materials=4;plasmatech=4" + +/obj/item/bodybag/bluespace/examine(mob/user) + ..() + if(contents.len) + to_chat(user, "You can make out the shapes of [contents.len] objects through the fabric.") + +/obj/item/bodybag/bluespace/Destroy() + for(var/atom/movable/A in contents) + A.forceMove(get_turf(src)) + if(isliving(A)) + to_chat(A, "You suddenly feel the space around you torn apart! You're free!") + return ..() + +/obj/item/bodybag/bluespace/deploy_bodybag(mob/user, atom/location) + var/obj/structure/closet/body_bag/R = new unfoldedbag_path(location) + for(var/atom/movable/A in contents) + A.forceMove(R) + if(isliving(A)) + to_chat(A, "You suddenly feel air around you! You're free!") + R.open(user) + R.add_fingerprint(user) + qdel(src) + +/obj/item/bodybag/bluespace/container_resist(mob/living/user) + if(user.incapacitated()) + to_chat(user, "You can't get out while you're restrained like this!") + return + user.changeNext_move(CLICK_CD_BREAKOUT) + user.last_special = world.time + CLICK_CD_BREAKOUT + to_chat(user, "You claw at the fabric of [src], trying to tear it open...") + to_chat(loc, "Someone starts trying to break free of [src]!") + if(!do_after(user, 200, target = src)) + to_chat(loc, "The pressure subsides. It seems that they've stopped resisting...") + return + loc.visible_message("[user] suddenly appears in front of [loc]!", "[user] breaks free of [src]!") + qdel(src) +>>>>>>> 51c4840... Stops putting RCD, bluespace bags, and staves into ORM (#31093) diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index 2290ea91d3..3e9231f562 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -40,6 +40,7 @@ max_w_class = WEIGHT_CLASS_GIGANTIC max_combined_w_class = 35 resistance_flags = FIRE_PROOF + flags_2 = NO_MAT_REDEMPTION_2 var/pshoom = 'sound/items/pshoom.ogg' var/alt_sound = 'sound/items/pshoom_2.ogg' armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 60, acid = 50) diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm index 8615e1cf8c..1a28e08297 100644 --- a/code/game/objects/items/storage/bags.dm +++ b/code/game/objects/items/storage/bags.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /* * These absorb the functionality of the plant bag, ore satchel, etc. * They use the use_to_pickup, quick_gather, and quick_empty functions @@ -379,3 +380,387 @@ preposition = "in" can_hold = list(/obj/item/slime_extract, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/blood, /obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/food/snacks/deadmouse, /obj/item/reagent_containers/food/snacks/monkeycube) resistance_flags = FLAMMABLE +======= +/* + * These absorb the functionality of the plant bag, ore satchel, etc. + * They use the use_to_pickup, quick_gather, and quick_empty functions + * that were already defined in weapon/storage, but which had been + * re-implemented in other classes. + * + * Contains: + * Trash Bag + * Mining Satchel + * Plant Bag + * Sheet Snatcher + * Book Bag + * Biowaste Bag + * + * -Sayu + */ + +// Generic non-item +/obj/item/storage/bag + allow_quick_gather = 1 + allow_quick_empty = 1 + display_contents_with_number = 1 // should work fine now + use_to_pickup = 1 + slot_flags = SLOT_BELT + +// ----------------------------- +// Trash bag +// ----------------------------- +/obj/item/storage/bag/trash + name = "trash bag" + desc = "It's the heavy-duty black polymer kind. Time to take out the trash!" + icon = 'icons/obj/janitor.dmi' + icon_state = "trashbag" + item_state = "trashbag" + lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi' + + w_class = WEIGHT_CLASS_BULKY + max_w_class = WEIGHT_CLASS_SMALL + max_combined_w_class = 30 + storage_slots = 30 + can_hold = list() // any + cant_hold = list(/obj/item/disk/nuclear) + +/obj/item/storage/bag/trash/suicide_act(mob/user) + user.visible_message("[user] puts [src] over [user.p_their()] head and starts chomping at the insides! Disgusting!") + playsound(loc, 'sound/items/eatfood.ogg', 50, 1, -1) + return (TOXLOSS) + +/obj/item/storage/bag/trash/update_icon() + if(contents.len == 0) + icon_state = "[initial(icon_state)]" + else if(contents.len < 12) + icon_state = "[initial(icon_state)]1" + else if(contents.len < 21) + icon_state = "[initial(icon_state)]2" + else icon_state = "[initial(icon_state)]3" + +/obj/item/storage/bag/trash/cyborg + +/obj/item/storage/bag/trash/proc/janicart_insert(mob/user, obj/structure/janitorialcart/J) + J.put_in_cart(src, user) + J.mybag=src + J.update_icon() + +/obj/item/storage/bag/trash/cyborg/janicart_insert(mob/user, obj/structure/janitorialcart/J) + return + +/obj/item/storage/bag/trash/bluespace + name = "trash bag of holding" + desc = "The latest and greatest in custodial convenience, a trashbag that is capable of holding vast quantities of garbage." + icon_state = "bluetrashbag" + origin_tech = "materials=4;bluespace=4;engineering=4;plasmatech=3" + max_combined_w_class = 60 + storage_slots = 60 + flags_2 = NO_MAT_REDEMPTION_2 + +// ----------------------------- +// Mining Satchel +// ----------------------------- + +/obj/item/storage/bag/ore + name = "mining satchel" + desc = "This little bugger can be used to store and transport ores." + icon = 'icons/obj/mining.dmi' + icon_state = "satchel" + origin_tech = "engineering=2" + slot_flags = SLOT_BELT | SLOT_POCKET + w_class = WEIGHT_CLASS_NORMAL + storage_slots = 50 + max_combined_w_class = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * ore.w_class + max_w_class = WEIGHT_CLASS_NORMAL + can_hold = list(/obj/item/ore) + var/spam_protection = FALSE //If this is TRUE, the holder won't receive any messages when they fail to pick up ore through crossing it + +/obj/item/storage/bag/ore/cyborg + name = "cyborg mining satchel" + +/obj/item/storage/bag/ore/holding //miners, your messiah has arrived + name = "mining satchel of holding" + desc = "A revolution in convenience, this satchel allows for huge amounts of ore storage. It's been outfitted with anti-malfunction safety measures." + storage_slots = INFINITY + max_combined_w_class = INFINITY + origin_tech = "bluespace=4;materials=3;engineering=3" + icon_state = "satchel_bspace" + +// ----------------------------- +// Plant bag +// ----------------------------- + +/obj/item/storage/bag/plants + name = "plant bag" + icon = 'icons/obj/hydroponics/equipment.dmi' + icon_state = "plantbag" + storage_slots = 100; //the number of plant pieces it can carry. + max_combined_w_class = 100 //Doesn't matter what this is, so long as it's more or equal to storage_slots * plants.w_class + max_w_class = WEIGHT_CLASS_NORMAL + w_class = WEIGHT_CLASS_TINY + can_hold = list(/obj/item/reagent_containers/food/snacks/grown, /obj/item/seeds, /obj/item/grown, /obj/item/reagent_containers/honeycomb) + resistance_flags = FLAMMABLE + +//////// + +/obj/item/storage/bag/plants/portaseeder + name = "portable seed extractor" + desc = "For the enterprising botanist on the go. Less efficient than the stationary model, it creates one seed per plant." + icon_state = "portaseeder" + origin_tech = "biotech=3;engineering=2" + +/obj/item/storage/bag/plants/portaseeder/verb/dissolve_contents() + set name = "Activate Seed Extraction" + set category = "Object" + set desc = "Activate to convert your plants into plantable seeds." + if(usr.stat || !usr.canmove || usr.restrained()) + return + for(var/obj/item/O in contents) + seedify(O, 1) + close_all() + + +// ----------------------------- +// Sheet Snatcher +// ----------------------------- +// Because it stacks stacks, this doesn't operate normally. +// However, making it a storage/bag allows us to reuse existing code in some places. -Sayu + +/obj/item/storage/bag/sheetsnatcher + name = "sheet snatcher" + desc = "A patented Nanotrasen storage system designed for any kind of mineral sheet." + icon = 'icons/obj/mining.dmi' + icon_state = "sheetsnatcher" + + var/capacity = 300; //the number of sheets it can carry. + w_class = WEIGHT_CLASS_NORMAL + + allow_quick_empty = 1 // this function is superceded + +/obj/item/storage/bag/sheetsnatcher/can_be_inserted(obj/item/W, stop_messages = 0) + if(!istype(W, /obj/item/stack/sheet) || istype(W, /obj/item/stack/sheet/mineral/sandstone) || istype(W, /obj/item/stack/sheet/mineral/wood)) + if(!stop_messages) + to_chat(usr, "The snatcher does not accept [W].") + return 0 //I don't care, but the existing code rejects them for not being "sheets" *shrug* -Sayu + var/current = 0 + for(var/obj/item/stack/sheet/S in contents) + current += S.amount + if(capacity == current)//If it's full, you're done + if(!stop_messages) + to_chat(usr, "The snatcher is full.") + return 0 + return 1 + + +// Modified handle_item_insertion. Would prefer not to, but... +/obj/item/storage/bag/sheetsnatcher/handle_item_insertion(obj/item/W, prevent_warning = 0) + var/obj/item/stack/sheet/S = W + if(!istype(S)) return 0 + + var/amount + var/inserted = 0 + var/current = 0 + for(var/obj/item/stack/sheet/S2 in contents) + current += S2.amount + if(capacity < current + S.amount)//If the stack will fill it up + amount = capacity - current + else + amount = S.amount + + for(var/obj/item/stack/sheet/sheet in contents) + if(S.type == sheet.type) // we are violating the amount limitation because these are not sane objects + sheet.amount += amount // they should only be removed through procs in this file, which split them up. + S.amount -= amount + inserted = 1 + break + + if(!inserted || !S.amount) + usr.dropItemToGround(S) + if (usr.client && usr.s_active != src) + usr.client.screen -= S + S.dropped(usr) + if(!S.amount) + qdel(S) + else + if(S.pulledby) + S.pulledby.stop_pulling() + S.loc = src + + orient2hud(usr) + if(usr.s_active) + usr.s_active.show_to(usr) + update_icon() + return 1 + + +// Sets up numbered display to show the stack size of each stored mineral +// NOTE: numbered display is turned off currently because it's broken +/obj/item/storage/bag/sheetsnatcher/orient2hud(mob/user) + var/adjusted_contents = contents.len + + //Numbered contents display + var/list/datum/numbered_display/numbered_contents + if(display_contents_with_number) + numbered_contents = list() + adjusted_contents = 0 + for(var/obj/item/stack/sheet/I in contents) + adjusted_contents++ + var/datum/numbered_display/D = new/datum/numbered_display(I) + D.number = I.amount + numbered_contents.Add( D ) + + var/row_num = 0 + var/col_count = min(7,storage_slots) -1 + if (adjusted_contents > 7) + row_num = round((adjusted_contents-1) / 7) // 7 is the maximum allowed width. + src.standard_orient_objs(row_num, col_count, numbered_contents) + return + + +// Modified quick_empty verb drops appropriate sized stacks +/obj/item/storage/bag/sheetsnatcher/quick_empty() + var/location = get_turf(src) + for(var/obj/item/stack/sheet/S in contents) + while(S.amount) + var/obj/item/stack/sheet/N = new S.type(location) + var/stacksize = min(S.amount,N.max_amount) + N.amount = stacksize + S.amount -= stacksize + if(!S.amount) + qdel(S)// todo: there's probably something missing here + orient2hud(usr) + if(usr.s_active) + usr.s_active.show_to(usr) + update_icon() + +// Instead of removing +/obj/item/storage/bag/sheetsnatcher/remove_from_storage(obj/item/W, atom/new_location) + var/obj/item/stack/sheet/S = W + if(!istype(S)) return 0 + + //I would prefer to drop a new stack, but the item/attack_hand code + // that calls this can't recieve a different object than you clicked on. + //Therefore, make a new stack internally that has the remainder. + // -Sayu + + if(S.amount > S.max_amount) + var/obj/item/stack/sheet/temp = new S.type(src) + temp.amount = S.amount - S.max_amount + S.amount = S.max_amount + + return ..(S,new_location) + +// ----------------------------- +// Sheet Snatcher (Cyborg) +// ----------------------------- + +/obj/item/storage/bag/sheetsnatcher/borg + name = "sheet snatcher 9000" + desc = "" + capacity = 500//Borgs get more because >specialization + + +// ----------------------------- +// Book bag +// ----------------------------- + +/obj/item/storage/bag/books + name = "book bag" + desc = "A bag for books." + icon = 'icons/obj/library.dmi' + icon_state = "bookbag" + display_contents_with_number = 0 //This would look really stupid otherwise + storage_slots = 7 + max_combined_w_class = 21 + max_w_class = WEIGHT_CLASS_NORMAL + w_class = WEIGHT_CLASS_BULKY //Bigger than a book because physics + can_hold = list(/obj/item/book, /obj/item/storage/book, /obj/item/spellbook) + resistance_flags = FLAMMABLE + +/* + * Trays - Agouri + */ +/obj/item/storage/bag/tray + name = "tray" + icon = 'icons/obj/food/containers.dmi' + icon_state = "tray" + desc = "A metal tray to lay food on." + force = 5 + throwforce = 10 + throw_speed = 3 + throw_range = 5 + w_class = WEIGHT_CLASS_BULKY + flags_1 = CONDUCT_1 + materials = list(MAT_METAL=3000) + preposition = "on" + +/obj/item/storage/bag/tray/attack(mob/living/M, mob/living/user) + ..() + // Drop all the things. All of them. + var/list/obj/item/oldContents = contents.Copy() + quick_empty() + + // Make each item scatter a bit + for(var/obj/item/I in oldContents) + spawn() + for(var/i = 1, i <= rand(1,2), i++) + if(I) + step(I, pick(NORTH,SOUTH,EAST,WEST)) + sleep(rand(2,4)) + + if(prob(50)) + playsound(M, 'sound/items/trayhit1.ogg', 50, 1) + else + playsound(M, 'sound/items/trayhit2.ogg', 50, 1) + + if(ishuman(M) || ismonkey(M)) + if(prob(10)) + M.Knockdown(40) + +/obj/item/storage/bag/tray/proc/rebuild_overlays() + cut_overlays() + for(var/obj/item/I in contents) + add_overlay(mutable_appearance(I.icon, I.icon_state)) + +/obj/item/storage/bag/tray/remove_from_storage(obj/item/W as obj, atom/new_location) + ..() + rebuild_overlays() + +/obj/item/storage/bag/tray/handle_item_insertion(obj/item/I, prevent_warning = 0) + add_overlay(mutable_appearance(I.icon, I.icon_state)) + . = ..() + + +/* + * Chemistry bag + */ + +/obj/item/storage/bag/chemistry + name = "chemistry bag" + icon = 'icons/obj/chemical.dmi' + icon_state = "bag" + desc = "A bag for storing pills, patches, and bottles." + storage_slots = 50 + max_combined_w_class = 200 + w_class = WEIGHT_CLASS_TINY + preposition = "in" + can_hold = list(/obj/item/reagent_containers/pill, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle) + resistance_flags = FLAMMABLE + +/* + * Biowaste bag (mostly for xenobiologists) + */ + +/obj/item/storage/bag/bio + name = "bio bag" + icon = 'icons/obj/chemical.dmi' + icon_state = "biobag" + desc = "A bag for the safe transportation and disposal of biowaste and other biological materials." + storage_slots = 25 + max_combined_w_class = 200 + w_class = WEIGHT_CLASS_TINY + preposition = "in" + can_hold = list(/obj/item/slime_extract, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/blood, /obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/food/snacks/deadmouse, /obj/item/reagent_containers/food/snacks/monkeycube) + resistance_flags = FLAMMABLE +>>>>>>> 51c4840... Stops putting RCD, bluespace bags, and staves into ORM (#31093) diff --git a/code/modules/projectiles/guns/magic/staff.dm b/code/modules/projectiles/guns/magic/staff.dm index 1f2285cdf5..3c8460b57d 100644 --- a/code/modules/projectiles/guns/magic/staff.dm +++ b/code/modules/projectiles/guns/magic/staff.dm @@ -2,6 +2,7 @@ slot_flags = SLOT_BACK lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi' + flags_2 = NO_MAT_REDEMPTION_2 /obj/item/gun/magic/staff/change name = "staff of change" From 70d75ffa985e7bc3721b8ba39b29981e2b8472b1 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Fri, 29 Sep 2017 23:36:09 -0500 Subject: [PATCH 13/60] Update global_lists.dm --- code/__HELPERS/global_lists.dm | 147 +++++++-------------------------- 1 file changed, 28 insertions(+), 119 deletions(-) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index c1afe0e345..75f9fbd3d0 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -1,121 +1,3 @@ -<<<<<<< HEAD -////////////////////////// -/////Initial Building///// -////////////////////////// - -/proc/make_datum_references_lists() - //hair - init_sprite_accessory_subtypes(/datum/sprite_accessory/hair, GLOB.hair_styles_list, GLOB.hair_styles_male_list, GLOB.hair_styles_female_list) - //facial hair - init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, GLOB.facial_hair_styles_list, GLOB.facial_hair_styles_male_list, GLOB.facial_hair_styles_female_list) - //underwear - init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f) - //undershirt - init_sprite_accessory_subtypes(/datum/sprite_accessory/undershirt, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f) - //socks - init_sprite_accessory_subtypes(/datum/sprite_accessory/socks, GLOB.socks_list) - //lizard bodyparts (blizzard intensifies) - init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, GLOB.body_markings_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard, GLOB.tails_list_lizard) - init_sprite_accessory_subtypes(/datum/sprite_accessory/tails_animated/lizard, GLOB.animated_tails_list_lizard) - init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, GLOB.tails_list_human) - init_sprite_accessory_subtypes(/datum/sprite_accessory/tails_animated/human, GLOB.animated_tails_list_human) - init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts, GLOB.snouts_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/horns,GLOB.horns_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, GLOB.ears_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.wings_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/wings_open, GLOB.wings_open_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, GLOB.frills_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/spines, GLOB.spines_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/spines_animated, GLOB.animated_spines_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/legs, GLOB.legs_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.r_wings_list,roundstart = TRUE) - - //citadel code - //mammal bodyparts (fucking furries) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_body_markings, GLOB.mam_body_markings_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails, GLOB.mam_tails_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_ears, GLOB.mam_ears_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails_animated, GLOB.mam_tails_animated_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/taur, GLOB.taur_list) - //avian bodyparts (i swear this isn't starbound) -// init_sprite_accessory_subtypes(/datum/sprite_accessory/beaks/avian, GLOB.avian_beaks_list) -// init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/avian, GLOB.avian_tails_list) -// init_sprite_accessory_subtypes(/datum/sprite_accessory/avian_wings, GLOB.avian_wings_list) -// init_sprite_accessory_subtypes(/datum/sprite_accessory/avian_open_wings, GLOB.avian_open_wings_list) - //xeno parts (hiss?) - init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_head, GLOB.xeno_head_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_tail, GLOB.xeno_tail_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_dorsal, GLOB.xeno_dorsal_list) - //genitals - init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, GLOB.cock_shapes_list) - - for(var/K in GLOB.cock_shapes_list) - var/datum/sprite_accessory/penis/value = GLOB.cock_shapes_list[K] - GLOB.cock_shapes_icons[K] = value.icon_state - - init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list) - GLOB.breasts_size_list = list("a","b","c","d","e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing. - - //Species - for(var/spath in subtypesof(/datum/species)) - var/datum/species/S = new spath() - if(S.roundstart) - GLOB.roundstart_species[S.id] = S.type - GLOB.species_list[S.id] = S.type - - //Surgeries - for(var/path in subtypesof(/datum/surgery)) - GLOB.surgeries_list += new path() - - //Materials - for(var/path in subtypesof(/datum/material)) - var/datum/material/D = new path() - GLOB.materials_list[D.id] = D - - //Techs - for(var/path in subtypesof(/datum/tech)) - var/datum/tech/D = new path() - GLOB.tech_list[D.id] = D - - //Emotes - for(var/path in subtypesof(/datum/emote)) - var/datum/emote/E = new path() - E.emote_list[E.key] = E - - init_subtypes(/datum/crafting_recipe, GLOB.crafting_recipes) - -/* // Uncomment to debug chemical reaction list. -/client/verb/debug_chemical_list() - - for (var/reaction in chemical_reactions_list) - . += "chemical_reactions_list\[\"[reaction]\"\] = \"[chemical_reactions_list[reaction]]\"\n" - if(islist(chemical_reactions_list[reaction])) - var/list/L = chemical_reactions_list[reaction] - for(var/t in L) - . += " has: [t]\n" - to_chat(world, .) -*/ - -//creates every subtype of prototype (excluding prototype) and adds it to list L. -//if no list/L is provided, one is created. -/proc/init_subtypes(prototype, list/L) - if(!istype(L)) - L = list() - for(var/path in subtypesof(prototype)) - L += new path() - return L - -//returns a list of paths to every subtype of prototype (excluding prototype) -//if no list/L is provided, one is created. -/proc/init_paths(prototype, list/L) - if(!istype(L)) - L = list() - for(var/path in subtypesof(prototype)) - L+= path - return L -======= ////////////////////////// /////Initial Building///// ////////////////////////// @@ -147,6 +29,33 @@ init_sprite_accessory_subtypes(/datum/sprite_accessory/spines_animated, GLOB.animated_spines_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/legs, GLOB.legs_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.r_wings_list,roundstart = TRUE) + + //citadel code + //mammal bodyparts (fucking furries) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_body_markings, GLOB.mam_body_markings_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails, GLOB.mam_tails_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_ears, GLOB.mam_ears_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails_animated, GLOB.mam_tails_animated_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/taur, GLOB.taur_list) + //avian bodyparts (i swear this isn't starbound) +// init_sprite_accessory_subtypes(/datum/sprite_accessory/beaks/avian, GLOB.avian_beaks_list) +// init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/avian, GLOB.avian_tails_list) +// init_sprite_accessory_subtypes(/datum/sprite_accessory/avian_wings, GLOB.avian_wings_list) +// init_sprite_accessory_subtypes(/datum/sprite_accessory/avian_open_wings, GLOB.avian_open_wings_list) + //xeno parts (hiss?) + init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_head, GLOB.xeno_head_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_tail, GLOB.xeno_tail_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_dorsal, GLOB.xeno_dorsal_list) + //genitals + init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, GLOB.cock_shapes_list) + + for(var/K in GLOB.cock_shapes_list) + var/datum/sprite_accessory/penis/value = GLOB.cock_shapes_list[K] + GLOB.cock_shapes_icons[K] = value.icon_state + + init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list) + GLOB.breasts_size_list = list("a","b","c","d","e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing. //Species @@ -204,4 +113,4 @@ for(var/path in subtypesof(prototype)) L+= path return L ->>>>>>> 4178c20... Configuration datum refactor (#30763) +>>>>>>> 4178c20... Configuration datum refactor (#30763) From 9d40ab978ab73108b35def7ba8fbea5f024e1f92 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Fri, 29 Sep 2017 23:38:41 -0500 Subject: [PATCH 14/60] Update names.dm --- code/__HELPERS/names.dm | 249 ---------------------------------------- 1 file changed, 249 deletions(-) diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm index f2c24dd557..bfcfd23f50 100644 --- a/code/__HELPERS/names.dm +++ b/code/__HELPERS/names.dm @@ -1,251 +1,3 @@ -<<<<<<< HEAD -#define ION_FILE "ion_laws.json" - -/proc/lizard_name(gender) - if(gender == MALE) - return "[pick(GLOB.lizard_names_male)]-[pick(GLOB.lizard_names_male)]" - else - return "[pick(GLOB.lizard_names_female)]-[pick(GLOB.lizard_names_female)]" - -/proc/plasmaman_name() - return "[pick(GLOB.plasmaman_names)] \Roman[rand(1,99)]" - -/proc/church_name() - var/static/church_name - if (church_name) - return church_name - - var/name = "" - - name += pick("Holy", "United", "First", "Second", "Last") - - if (prob(20)) - name += " Space" - - name += " " + pick("Church", "Cathedral", "Body", "Worshippers", "Movement", "Witnesses") - name += " of [religion_name()]" - - return name - -GLOBAL_VAR(command_name) -/proc/command_name() - if (GLOB.command_name) - return GLOB.command_name - - var/name = "Central Command" - - GLOB.command_name = name - return name - -/proc/change_command_name(name) - - GLOB.command_name = name - - return name - -/proc/religion_name() - var/static/religion_name - if (religion_name) - return religion_name - - var/name = "" - - name += pick("bee", "science", "edu", "captain", "assistant", "monkey", "alien", "space", "unit", "sprocket", "gadget", "bomb", "revolution", "beyond", "station", "goon", "robot", "ivor", "hobnob") - name += pick("ism", "ia", "ology", "istism", "ites", "ick", "ian", "ity") - - return capitalize(name) - -/proc/station_name() - if(!GLOB.station_name) - var/newname - if(config && config.station_name) - newname = config.station_name - else - newname = new_station_name() - - set_station_name(newname) - - return GLOB.station_name - -/proc/set_station_name(newname) - GLOB.station_name = newname - - if(config && config.server_name) - world.name = "[config.server_name][config.server_name==GLOB.station_name ? "" : ": [GLOB.station_name]"]" - else - world.name = GLOB.station_name - - -/proc/new_station_name() - var/random = rand(1,5) - var/name = "" - var/new_station_name = "" - - //Rare: Pre-Prefix - if (prob(10)) - name = pick(GLOB.station_prefixes) - new_station_name = name + " " - name = "" - - // Prefix - for(var/holiday_name in SSevents.holidays) - if(holiday_name == "Friday the 13th") - random = 13 - var/datum/holiday/holiday = SSevents.holidays[holiday_name] - name = holiday.getStationPrefix() - //get normal name - if(!name) - name = pick(GLOB.station_names) - if(name) - new_station_name += name + " " - - // Suffix - name = pick(GLOB.station_suffixes) - new_station_name += name + " " - - // ID Number - switch(random) - if(1) - new_station_name += "[rand(1, 99)]" - if(2) - new_station_name += pick(GLOB.greek_letters) - if(3) - new_station_name += "\Roman[rand(1,99)]" - if(4) - new_station_name += pick(GLOB.phonetic_alphabet) - if(5) - new_station_name += pick(GLOB.numbers_as_words) - if(13) - new_station_name += pick("13","XIII","Thirteen") - return new_station_name - -/proc/syndicate_name() - var/static/syndicate_name - if (syndicate_name) - return syndicate_name - - var/name = "" - - // Prefix - name += pick("Clandestine", "Prima", "Blue", "Zero-G", "Max", "Blasto", "Waffle", "North", "Omni", "Newton", "Cyber", "Bonk", "Gene", "Gib") - - // Suffix - if (prob(80)) - name += " " - - // Full - if (prob(60)) - name += pick("Syndicate", "Consortium", "Collective", "Corporation", "Group", "Holdings", "Biotech", "Industries", "Systems", "Products", "Chemicals", "Enterprises", "Family", "Creations", "International", "Intergalactic", "Interplanetary", "Foundation", "Positronics", "Hive") - // Broken - else - name += pick("Syndi", "Corp", "Bio", "System", "Prod", "Chem", "Inter", "Hive") - name += pick("", "-") - name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Code") - // Small - else - name += pick("-", "*", "") - name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Gen", "Star", "Dyne", "Code", "Hive") - - syndicate_name = name - return name - - -//Traitors and traitor silicons will get these. Revs will not. -GLOBAL_VAR(syndicate_code_phrase) //Code phrase for traitors. -GLOBAL_VAR(syndicate_code_response) //Code response for traitors. - - /* - Should be expanded. - How this works: - Instead of "I'm looking for James Smith," the traitor would say "James Smith" as part of a conversation. - Another traitor may then respond with: "They enjoy running through the void-filled vacuum of the derelict." - The phrase should then have the words: James Smith. - The response should then have the words: run, void, and derelict. - This way assures that the code is suited to the conversation and is unpredicatable. - Obviously, some people will be better at this than others but in theory, everyone should be able to do it and it only enhances roleplay. - Can probably be done through "{ }" but I don't really see the practical benefit. - One example of an earlier system is commented below. - /N - */ - -/proc/generate_code_phrase(return_list=FALSE)//Proc is used for phrase and response in master_controller.dm - - if(!return_list) - . = "" - else - . = list() - - var/words = pick(//How many words there will be. Minimum of two. 2, 4 and 5 have a lesser chance of being selected. 3 is the most likely. - 50; 2, - 200; 3, - 50; 4, - 25; 5 - ) - - var/list/safety = list(1,2,3)//Tells the proc which options to remove later on. - var/nouns = strings(ION_FILE, "ionabstract") - var/objects = strings(ION_FILE, "ionobjects") - var/adjectives = strings(ION_FILE, "ionadjectives") - var/threats = strings(ION_FILE, "ionthreats") - var/foods = strings(ION_FILE, "ionfood") - var/drinks = strings(ION_FILE, "iondrinks") - var/list/locations = GLOB.teleportlocs.len ? GLOB.teleportlocs : drinks //if null, defaults to drinks instead. - - var/list/names = list() - for(var/datum/data/record/t in GLOB.data_core.general)//Picks from crew manifest. - names += t.fields["name"] - - var/maxwords = words//Extra var to check for duplicates. - - for(words,words>0,words--)//Randomly picks from one of the choices below. - - if(words==1&&(1 in safety)&&(2 in safety))//If there is only one word remaining and choice 1 or 2 have not been selected. - safety = list(pick(1,2))//Select choice 1 or 2. - else if(words==1&&maxwords==2)//Else if there is only one word remaining (and there were two originally), and 1 or 2 were chosen, - safety = list(3)//Default to list 3 - - switch(pick(safety))//Chance based on the safety list. - if(1)//1 and 2 can only be selected once each to prevent more than two specific names/places/etc. - switch(rand(1,2))//Mainly to add more options later. - if(1) - if(names.len&&prob(70)) - . += pick(names) - else - if(prob(10)) - . += pick(lizard_name(MALE),lizard_name(FEMALE)) - else - var/new_name = pick(pick(GLOB.first_names_male,GLOB.first_names_female)) - new_name += " " - new_name += pick(GLOB.last_names) - . += new_name - if(2) - . += pick(get_all_jobs())//Returns a job. - safety -= 1 - if(2) - switch(rand(1,3))//Food, drinks, or things. Only selectable once. - if(1) - . += lowertext(pick(drinks)) - if(2) - . += lowertext(pick(foods)) - if(3) - . += lowertext(pick(locations)) - safety -= 2 - if(3) - switch(rand(1,4))//Abstract nouns, objects, adjectives, threats. Can be selected more than once. - if(1) - . += lowertext(pick(nouns)) - if(2) - . += lowertext(pick(objects)) - if(3) - . += lowertext(pick(adjectives)) - if(4) - . += lowertext(pick(threats)) - if(!return_list) - if(words==1) - . += "." - else - . += ", " -======= #define ION_FILE "ion_laws.json" /proc/lizard_name(gender) @@ -494,4 +246,3 @@ GLOBAL_VAR(syndicate_code_response) //Code response for traitors. . += "." else . += ", " ->>>>>>> 4178c20... Configuration datum refactor (#30763) From e515151610c2c180d5b6f3a60700716ceb70c36a Mon Sep 17 00:00:00 2001 From: LetterJay Date: Fri, 29 Sep 2017 23:39:34 -0500 Subject: [PATCH 15/60] Update h_sandbox.dm --- code/game/gamemodes/sandbox/h_sandbox.dm | 328 ++--------------------- 1 file changed, 27 insertions(+), 301 deletions(-) diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm index 8d9396da71..f6c53a07f4 100644 --- a/code/game/gamemodes/sandbox/h_sandbox.dm +++ b/code/game/gamemodes/sandbox/h_sandbox.dm @@ -1,308 +1,35 @@ - - -GLOBAL_VAR_INIT(hsboxspawn, TRUE) - -/mob - var/datum/hSB/sandbox = null -/mob/proc/CanBuild() - sandbox = new/datum/hSB - sandbox.owner = src.ckey - if(src.client.holder) - sandbox.admin = 1 - verbs += new/mob/proc/sandbox_panel -/mob/proc/sandbox_panel() - set name = "Sandbox Panel" - if(sandbox) - sandbox.update() - -/datum/hSB - var/owner = null - var/admin = 0 - + + +GLOBAL_VAR_INIT(hsboxspawn, TRUE) + +/mob + var/datum/hSB/sandbox = null +/mob/proc/CanBuild() + sandbox = new/datum/hSB + sandbox.owner = src.ckey + if(src.client.holder) + sandbox.admin = 1 + verbs += new/mob/proc/sandbox_panel +/mob/proc/sandbox_panel() + set name = "Sandbox Panel" + if(sandbox) + sandbox.update() + +/datum/hSB + var/owner = null + var/admin = 0 + var/static/clothinfo = null var/static/reaginfo = null var/static/objinfo = null - var/canisterinfo = null - var/hsbinfo = null - //items that shouldn't spawn on the floor because they would bug or act weird - var/global/list/spawn_forbidden = list( - /obj/item/tk_grab, /obj/item/implant, // not implanter, the actual thing that is inside you + var/canisterinfo = null + var/hsbinfo = null + //items that shouldn't spawn on the floor because they would bug or act weird + var/global/list/spawn_forbidden = list( + /obj/item/tk_grab, /obj/item/implant, // not implanter, the actual thing that is inside you /obj/item/assembly, /obj/item/device/onetankbomb, /obj/item/radio, /obj/item/device/pda/ai, - /obj/item/device/uplink, /obj/item/smallDelivery, /obj/item/projectile, + /obj/item/device/uplink, /obj/item/smallDelivery, /obj/item/projectile, /obj/item/borg/sight, /obj/item/borg/stun, /obj/item/robot_module) -<<<<<<< HEAD - -/datum/hSB/proc/update() - var/global/list/hrefs = list( - "Space Gear", - "Suit Up (Space Travel Gear)" = "hsbsuit", - "Spawn Gas Mask" = "hsbspawn&path=[/obj/item/clothing/mask/gas]", - "Spawn Emergency Air Tank" = "hsbspawn&path=[/obj/item/tank/internals/emergency_oxygen/double]", - - "Standard Tools", - "Spawn Flashlight" = "hsbspawn&path=[/obj/item/device/flashlight]", - "Spawn Toolbox" = "hsbspawn&path=[/obj/item/storage/toolbox/mechanical]", - "Spawn Light Replacer" = "hsbspawn&path=[/obj/item/device/lightreplacer]", - "Spawn Medical Kit" = "hsbspawn&path=[/obj/item/storage/firstaid/regular]", - "Spawn All-Access ID" = "hsbaaid", - - "Building Supplies", - "Spawn 50 Wood" = "hsbwood", - "Spawn 50 Metal" = "hsbmetal", - "Spawn 50 Plasteel" = "hsbplasteel", - "Spawn 50 Reinforced Glass" = "hsbrglass", - "Spawn 50 Glass" = "hsbglass", - "Spawn Full Cable Coil" = "hsbspawn&path=[/obj/item/stack/cable_coil]", - "Spawn Hyper Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/hyper]", - "Spawn Inf. Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/infinite]", - "Spawn Rapid Construction Device" = "hsbrcd", - "Spawn RCD Ammo" = "hsb_safespawn&path=[/obj/item/rcd_ammo]", - "Spawn Airlock" = "hsbairlock", - - "Miscellaneous", - "Spawn Air Scrubber" = "hsbscrubber", - "Spawn Welding Fuel Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/fueltank]", - "Spawn Water Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/watertank]", - - "Bots", - "Spawn Cleanbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/cleanbot]", - "Spawn Floorbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/floorbot]", - "Spawn Medbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/medbot]", - - "Canisters", - "Spawn O2 Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/oxygen]", - "Spawn Air Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/air]") - - - if(!hsbinfo) - hsbinfo = "
    Sandbox Panel

    " - if(admin) - hsbinfo += "Administration
    " - hsbinfo += "- Toggle Object Spawning
    " - hsbinfo += "- Toggle Item Spawn Panel Auto-close
    " - hsbinfo += "Canister Spawning
    " - hsbinfo += "- Spawn Plasma Canister
    " - hsbinfo += "- Spawn CO2 Canister
    " - hsbinfo += "- Spawn Nitrogen Canister
    " - hsbinfo += "- Spawn N2O Canister
    " - else - hsbinfo += "Some item spawning may be disabled by the administrators.
    " - hsbinfo += "Only administrators may spawn dangerous canisters.
    " - for(var/T in hrefs) - var/href = hrefs[T] - if(href) - hsbinfo += "- [T]
    " - else - hsbinfo += "
    [T]
    " - hsbinfo += "
    " - hsbinfo += "- Spawn Clothing...
    " - hsbinfo += "- Spawn Reagent Container...
    " - hsbinfo += "- Spawn Other Item...

    " - - usr << browse(hsbinfo, "window=hsbpanel") - -/datum/hSB/Topic(href, href_list) - if(!usr || !src || !(src.owner == usr.ckey)) - if(usr) - usr << browse(null,"window=sandbox") - return - - if(href_list["hsb"]) - switch(href_list["hsb"]) - // - // Admin: toggle spawning - // - if("hsbtobj") - if(!admin) return - if(GLOB.hsboxspawn) - to_chat(world, "Sandbox: \black[usr.key] has disabled object spawning!") - GLOB.hsboxspawn = FALSE - return - else - to_chat(world, "Sandbox: \black[usr.key] has enabled object spawning!") - GLOB.hsboxspawn = TRUE - return - // - // Admin: Toggle auto-close - // - if("hsbtac") - if(!admin) return - if(config.sandbox_autoclose) - to_chat(world, "Sandbox: \black [usr.key] has removed the object spawn limiter.") - config.sandbox_autoclose = FALSE - else - to_chat(world, "Sandbox: \black [usr.key] has added a limiter to object spawning. The window will now auto-close after use.") - config.sandbox_autoclose = TRUE - return - // - // Spacesuit with full air jetpack set as internals - // - if("hsbsuit") - var/mob/living/carbon/human/P = usr - if(!istype(P)) return - if(P.wear_suit) - P.wear_suit.loc = P.loc - P.wear_suit.layer = initial(P.wear_suit.layer) - P.wear_suit.plane = initial(P.wear_suit.plane) - P.wear_suit = null - P.wear_suit = new/obj/item/clothing/suit/space(P) - P.wear_suit.layer = ABOVE_HUD_LAYER - P.wear_suit.plane = ABOVE_HUD_PLANE - P.update_inv_wear_suit() - if(P.head) - P.head.loc = P.loc - P.head.layer = initial(P.head.layer) - P.head.plane = initial(P.head.plane) - P.head = null - P.head = new/obj/item/clothing/head/helmet/space(P) - P.head.layer = ABOVE_HUD_LAYER - P.head.plane = ABOVE_HUD_PLANE - P.update_inv_head() - if(P.wear_mask) - P.wear_mask.loc = P.loc - P.wear_mask.layer = initial(P.wear_mask.layer) - P.wear_mask.plane = initial(P.wear_mask.plane) - P.wear_mask = null - P.wear_mask = new/obj/item/clothing/mask/gas(P) - P.wear_mask.layer = ABOVE_HUD_LAYER - P.wear_mask.plane = ABOVE_HUD_PLANE - P.update_inv_wear_mask() - if(P.back) - P.back.loc = P.loc - P.back.layer = initial(P.back.layer) - P.back.plane = initial(P.back.plane) - P.back = null - P.back = new/obj/item/tank/jetpack/oxygen(P) - P.back.layer = ABOVE_HUD_LAYER - P.back.plane = ABOVE_HUD_PLANE - P.update_inv_back() - P.internal = P.back - P.update_internals_hud_icon(1) - - if("hsbscrubber") // This is beyond its normal capability but this is sandbox and you spawned one, I assume you need it - var/obj/hsb = new/obj/machinery/portable_atmospherics/scrubber{volume_rate=50*ONE_ATMOSPHERE;on=1}(usr.loc) - hsb.update_icon() // hackish but it wasn't meant to be spawned I guess? - - // - // Stacked Materials - // - - if("hsbrglass") - new/obj/item/stack/sheet/rglass{amount=50}(usr.loc) - - if("hsbmetal") - new/obj/item/stack/sheet/metal{amount=50}(usr.loc) - - if("hsbplasteel") - new/obj/item/stack/sheet/plasteel{amount=50}(usr.loc) - - if("hsbglass") - new/obj/item/stack/sheet/glass{amount=50}(usr.loc) - - if("hsbwood") - new/obj/item/stack/sheet/mineral/wood{amount=50}(usr.loc) - - // - // All access ID - // - if("hsbaaid") - var/obj/item/card/id/gold/ID = new(usr.loc) - ID.registered_name = usr.real_name - ID.assignment = "Sandbox" - ID.access = get_all_accesses() - ID.update_label() - - // - // RCD - starts with full clip - // Spawn check due to grief potential (destroying floors, walls, etc) - // - if("hsbrcd") - if(!GLOB.hsboxspawn) return - - new/obj/item/construction/rcd/combat(usr.loc) - - // - // New sandbox airlock maker - // - if("hsbairlock") - new /datum/airlock_maker(usr.loc) - - // - // Object spawn window - // - - // Clothing - if("hsbcloth") - if(!GLOB.hsboxspawn) return - - if(!clothinfo) - clothinfo = "Clothing (Reagent Containers) (Other Items)

    " - var/list/all_items = subtypesof(/obj/item/clothing) - for(var/typekey in spawn_forbidden) - all_items -= typesof(typekey) - for(var/O in reverseRange(all_items)) - clothinfo += "[O]
    " - - usr << browse(clothinfo,"window=sandbox") - - // Reagent containers - if("hsbreag") - if(!GLOB.hsboxspawn) return - - if(!reaginfo) - reaginfo = "Reagent Containers (Clothing) (Other Items)

    " - var/list/all_items = subtypesof(/obj/item/reagent_containers) - for(var/typekey in spawn_forbidden) - all_items -= typesof(typekey) - for(var/O in reverseRange(all_items)) - reaginfo += "[O]
    " - - usr << browse(reaginfo,"window=sandbox") - - // Other items - if("hsbobj") - if(!GLOB.hsboxspawn) return - - if(!objinfo) - objinfo = "Other Items (Clothing) (Reagent Containers)

    " - var/list/all_items = subtypesof(/obj/item/) - typesof(/obj/item/clothing) - typesof(/obj/item/reagent_containers) - for(var/typekey in spawn_forbidden) - all_items -= typesof(typekey) - - for(var/O in reverseRange(all_items)) - objinfo += "[O]
    " - - usr << browse(objinfo,"window=sandbox") - - // - // Safespawn checks to see if spawning is disabled. - // - if("hsb_safespawn") - if(!GLOB.hsboxspawn) - usr << browse(null,"window=sandbox") - return - - var/typepath = text2path(href_list["path"]) - if(!typepath) - to_chat(usr, "Bad path: \"[href_list["path"]]\"") - return - new typepath(usr.loc) - - if(config.sandbox_autoclose) - usr << browse(null,"window=sandbox") - // - // For everything else in the href list - // - if("hsbspawn") - var/typepath = text2path(href_list["path"]) - if(!typepath) - to_chat(usr, "Bad path: \"[href_list["path"]]\"") - return - new typepath(usr.loc) - - if(config.sandbox_autoclose) - usr << browse(null,"window=sandbox") -======= /datum/hSB/proc/update() var/global/list/hrefs = list( @@ -574,4 +301,3 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE) if(CONFIG_GET(flag/sandbox_autoclose)) usr << browse(null,"window=sandbox") ->>>>>>> 4178c20... Configuration datum refactor (#30763) From 7df3c80a395ef3f4c094feae7d6279b8016aad3a Mon Sep 17 00:00:00 2001 From: LetterJay Date: Fri, 29 Sep 2017 23:41:44 -0500 Subject: [PATCH 16/60] Update cloning.dm --- code/game/machinery/computer/cloning.dm | 812 +++++++++--------------- 1 file changed, 312 insertions(+), 500 deletions(-) diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 2c3757fb61..ffd3091605 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -1,507 +1,320 @@ -/obj/machinery/computer/cloning - name = "cloning console" - desc = "Used to clone people and manage DNA." - icon_screen = "dna" - icon_keyboard = "med_key" - circuit = /obj/item/circuitboard/computer/cloning +/obj/machinery/computer/cloning + name = "cloning console" + desc = "Used to clone people and manage DNA." + icon_screen = "dna" + icon_keyboard = "med_key" + circuit = /obj/item/circuitboard/computer/cloning req_access = list(ACCESS_HEADS) //ONLY USED FOR RECORD DELETION RIGHT NOW. - var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning. - var/list/pods //Linked cloning pods - var/temp = "Inactive" - var/scantemp_ckey - var/scantemp = "Ready to Scan" - var/menu = 1 //Which menu screen to display - var/list/records = list() - var/datum/data/record/active_record = null - var/obj/item/disk/data/diskette = null //Mostly so the geneticist can steal everything. - var/loading = 0 // Nice loading text - var/autoprocess = 0 - - light_color = LIGHT_COLOR_BLUE - -/obj/machinery/computer/cloning/Initialize() + var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning. + var/list/pods //Linked cloning pods + var/temp = "Inactive" + var/scantemp_ckey + var/scantemp = "Ready to Scan" + var/menu = 1 //Which menu screen to display + var/list/records = list() + var/datum/data/record/active_record = null + var/obj/item/disk/data/diskette = null //Mostly so the geneticist can steal everything. + var/loading = 0 // Nice loading text + var/autoprocess = 0 + + light_color = LIGHT_COLOR_BLUE + +/obj/machinery/computer/cloning/Initialize() . = ..() - updatemodules(TRUE) - -/obj/machinery/computer/cloning/Destroy() - if(pods) - for(var/P in pods) - DetachCloner(P) - pods = null - return ..() - -/obj/machinery/computer/cloning/proc/GetAvailablePod(mind = null) - if(pods) - for(var/P in pods) - var/obj/machinery/clonepod/pod = P - if(pod.occupant && pod.clonemind == mind) - return null - if(pod.is_operational() && !(pod.occupant || pod.mess)) - return pod - -/obj/machinery/computer/cloning/proc/HasEfficientPod() - if(pods) - for(var/P in pods) - var/obj/machinery/clonepod/pod = P - if(pod.is_operational() && pod.efficiency > 5) - return TRUE - -/obj/machinery/computer/cloning/proc/GetAvailableEfficientPod(mind = null) - if(pods) - for(var/P in pods) - var/obj/machinery/clonepod/pod = P - if(pod.occupant && pod.clonemind == mind) - return pod - else if(!. && pod.is_operational() && !(pod.occupant || pod.mess) && pod.efficiency > 5) - . = pod - -/obj/machinery/computer/cloning/process() - if(!(scanner && LAZYLEN(pods) && autoprocess)) - return - - if(scanner.occupant && scanner.scan_level > 2) - scan_occupant(scanner.occupant) - - for(var/datum/data/record/R in records) - var/obj/machinery/clonepod/pod = GetAvailableEfficientPod(R.fields["mind"]) - - if(!pod) - return - - if(pod.occupant) - continue //how though? - - if(pod.growclone(R.fields["ckey"], R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mind"], R.fields["mrace"], R.fields["features"], R.fields["factions"])) - records -= R - -/obj/machinery/computer/cloning/proc/updatemodules(findfirstcloner) - src.scanner = findscanner() - if(findfirstcloner && !LAZYLEN(pods)) - findcloner() - -/obj/machinery/computer/cloning/proc/findscanner() - var/obj/machinery/dna_scannernew/scannerf = null - - // Loop through every direction - for(dir in list(NORTH,EAST,SOUTH,WEST)) - - // Try to find a scanner in that direction - scannerf = locate(/obj/machinery/dna_scannernew, get_step(src, dir)) - - // If found and operational, return the scanner - if (!isnull(scannerf) && scannerf.is_operational()) - return scannerf - - // If no scanner was found, it will return null - return null - -/obj/machinery/computer/cloning/proc/findcloner() - var/obj/machinery/clonepod/podf = null - - for(dir in list(NORTH,EAST,SOUTH,WEST)) - - podf = locate(/obj/machinery/clonepod, get_step(src, dir)) - - if (!isnull(podf) && podf.is_operational()) - AttachCloner(podf) - -/obj/machinery/computer/cloning/proc/AttachCloner(obj/machinery/clonepod/pod) - if(!pod.connected) - pod.connected = src - LAZYADD(pods, pod) - -/obj/machinery/computer/cloning/proc/DetachCloner(obj/machinery/clonepod/pod) - pod.connected = null - LAZYREMOVE(pods, pod) - -/obj/machinery/computer/cloning/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/disk/data)) //INSERT SOME DISKETTES - if (!src.diskette) - if(!user.drop_item()) - return - W.loc = src - src.diskette = W - to_chat(user, "You insert [W].") - playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) - src.updateUsrDialog() + updatemodules(TRUE) + +/obj/machinery/computer/cloning/Destroy() + if(pods) + for(var/P in pods) + DetachCloner(P) + pods = null + return ..() + +/obj/machinery/computer/cloning/proc/GetAvailablePod(mind = null) + if(pods) + for(var/P in pods) + var/obj/machinery/clonepod/pod = P + if(pod.occupant && pod.clonemind == mind) + return null + if(pod.is_operational() && !(pod.occupant || pod.mess)) + return pod + +/obj/machinery/computer/cloning/proc/HasEfficientPod() + if(pods) + for(var/P in pods) + var/obj/machinery/clonepod/pod = P + if(pod.is_operational() && pod.efficiency > 5) + return TRUE + +/obj/machinery/computer/cloning/proc/GetAvailableEfficientPod(mind = null) + if(pods) + for(var/P in pods) + var/obj/machinery/clonepod/pod = P + if(pod.occupant && pod.clonemind == mind) + return pod + else if(!. && pod.is_operational() && !(pod.occupant || pod.mess) && pod.efficiency > 5) + . = pod + +/obj/machinery/computer/cloning/process() + if(!(scanner && LAZYLEN(pods) && autoprocess)) + return + + if(scanner.occupant && scanner.scan_level > 2) + scan_occupant(scanner.occupant) + + for(var/datum/data/record/R in records) + var/obj/machinery/clonepod/pod = GetAvailableEfficientPod(R.fields["mind"]) + + if(!pod) + return + + if(pod.occupant) + continue //how though? + + if(pod.growclone(R.fields["ckey"], R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mind"], R.fields["mrace"], R.fields["features"], R.fields["factions"])) + records -= R + +/obj/machinery/computer/cloning/proc/updatemodules(findfirstcloner) + src.scanner = findscanner() + if(findfirstcloner && !LAZYLEN(pods)) + findcloner() + +/obj/machinery/computer/cloning/proc/findscanner() + var/obj/machinery/dna_scannernew/scannerf = null + + // Loop through every direction + for(dir in list(NORTH,EAST,SOUTH,WEST)) + + // Try to find a scanner in that direction + scannerf = locate(/obj/machinery/dna_scannernew, get_step(src, dir)) + + // If found and operational, return the scanner + if (!isnull(scannerf) && scannerf.is_operational()) + return scannerf + + // If no scanner was found, it will return null + return null + +/obj/machinery/computer/cloning/proc/findcloner() + var/obj/machinery/clonepod/podf = null + + for(dir in list(NORTH,EAST,SOUTH,WEST)) + + podf = locate(/obj/machinery/clonepod, get_step(src, dir)) + + if (!isnull(podf) && podf.is_operational()) + AttachCloner(podf) + +/obj/machinery/computer/cloning/proc/AttachCloner(obj/machinery/clonepod/pod) + if(!pod.connected) + pod.connected = src + LAZYADD(pods, pod) + +/obj/machinery/computer/cloning/proc/DetachCloner(obj/machinery/clonepod/pod) + pod.connected = null + LAZYREMOVE(pods, pod) + +/obj/machinery/computer/cloning/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/disk/data)) //INSERT SOME DISKETTES + if (!src.diskette) + if(!user.drop_item()) + return + W.loc = src + src.diskette = W + to_chat(user, "You insert [W].") + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) + src.updateUsrDialog() else if(istype(W, /obj/item/device/multitool)) - var/obj/item/device/multitool/P = W - - if(istype(P.buffer, /obj/machinery/clonepod)) - if(get_area(P.buffer) != get_area(src)) - to_chat(user, "-% Cannot link machines across power zones. Buffer cleared %-") - P.buffer = null - return - to_chat(user, "-% Successfully linked [P.buffer] with [src] %-") - var/obj/machinery/clonepod/pod = P.buffer - if(pod.connected) - pod.connected.DetachCloner(pod) - AttachCloner(pod) - else - P.buffer = src - to_chat(user, "-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %-") - return - else - return ..() - -/obj/machinery/computer/cloning/attack_hand(mob/user) - if(..()) - return - interact(user) - -/obj/machinery/computer/cloning/interact(mob/user) - user.set_machine(src) - add_fingerprint(user) - - if(..()) - return - - updatemodules(TRUE) - - var/dat = "" - dat += "Refresh" - - if(scanner && HasEfficientPod() && scanner.scan_level > 2) - if(!autoprocess) - dat += "Autoprocess" - else - dat += "Stop autoprocess" - else - dat += "Autoprocess" - dat += "

    Cloning Pod Status

    " - dat += "
    [temp] 
    " - - switch(src.menu) - if(1) - // Modules - if (isnull(src.scanner) || !LAZYLEN(pods)) - dat += "

    Modules

    " - //dat += "Reload Modules" - if (isnull(src.scanner)) - dat += "ERROR: No Scanner detected!
    " - if (!LAZYLEN(pods)) - dat += "ERROR: No Pod detected
    " - - // Scanner - if (!isnull(src.scanner)) - var/mob/living/scanner_occupant = get_mob_or_brainmob(scanner.occupant) - - dat += "

    Scanner Functions

    " - - dat += "
    " - if(!scanner_occupant) - dat += "Scanner Unoccupied" - else if(loading) - dat += "[scanner_occupant] => Scanning..." - else - if(scanner_occupant.ckey != scantemp_ckey) - scantemp = "Ready to Scan" - scantemp_ckey = scanner_occupant.ckey - dat += "[scanner_occupant] => [scantemp]" - dat += "
    " - - if(scanner_occupant) - dat += "Start Scan" - dat += "
    [src.scanner.locked ? "Unlock Scanner" : "Lock Scanner"]" - else - dat += "Start Scan" - - // Database - dat += "

    Database Functions

    " - if (src.records.len && src.records.len > 0) - dat += "View Records ([src.records.len])
    " - else - dat += "View Records (0)
    " - if (src.diskette) - dat += "Eject Disk
    " - - - - if(2) - dat += "

    Current records

    " - dat += "<< Back

    " - for(var/datum/data/record/R in records) - dat += "

    [R.fields["name"]]

    Scan ID [R.fields["id"]] View Record" - if(3) - dat += "

    Selected Record

    " - dat += "<< Back
    " - - if (!src.active_record) - dat += "Record not found." - else - dat += "

    [src.active_record.fields["name"]]

    " - dat += "Scan ID [src.active_record.fields["id"]] Clone
    " - - var/obj/item/implant/health/H = locate(src.active_record.fields["imp"]) - - if ((H) && (istype(H))) - dat += "Health Implant Data:
    [H.sensehealth()]

    " - else - dat += "Unable to locate Health Implant.

    " - - dat += "Unique Identifier:
    [src.active_record.fields["UI"]]
    " - dat += "Structural Enzymes:
    [src.active_record.fields["SE"]]
    " - - if(diskette && diskette.fields) - dat += "
    " - dat += "

    Inserted Disk

    " - dat += "Contents: " - var/list/L = list() - if(diskette.fields["UI"]) - L += "Unique Identifier" - if(diskette.fields["UE"] && diskette.fields["name"] && diskette.fields["blood_type"]) - L += "Unique Enzymes" - if(diskette.fields["SE"]) - L += "Structural Enzymes" - dat += english_list(L, "Empty", " + ", " + ") - dat += "
    Load from Disk" - - dat += "
    Save to Disk" - dat += "
    " - - dat += "Delete Record" - - if(4) - if (!src.active_record) - src.menu = 2 - dat = "[src.temp]
    " - dat += "

    Confirm Record Deletion

    " - - dat += "Scan card to confirm.
    " - dat += "Cancel" - - - var/datum/browser/popup = new(user, "cloning", "Cloning System Control") - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - -/obj/machinery/computer/cloning/Topic(href, href_list) - if(..()) - return - - if(loading) - return - - if(href_list["task"]) - switch(href_list["task"]) - if("autoprocess") - autoprocess = 1 - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - if("stopautoprocess") - autoprocess = 0 - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - - else if ((href_list["scan"]) && !isnull(scanner) && scanner.is_operational()) - scantemp = "" - - loading = 1 - src.updateUsrDialog() - playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) - say("Initiating scan...") - - spawn(20) - src.scan_occupant(scanner.occupant) - - loading = 0 - src.updateUsrDialog() - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - - - //No locking an open scanner. - else if ((href_list["lock"]) && !isnull(scanner) && scanner.is_operational()) - if ((!scanner.locked) && (scanner.occupant)) + var/obj/item/device/multitool/P = W + + if(istype(P.buffer, /obj/machinery/clonepod)) + if(get_area(P.buffer) != get_area(src)) + to_chat(user, "-% Cannot link machines across power zones. Buffer cleared %-") + P.buffer = null + return + to_chat(user, "-% Successfully linked [P.buffer] with [src] %-") + var/obj/machinery/clonepod/pod = P.buffer + if(pod.connected) + pod.connected.DetachCloner(pod) + AttachCloner(pod) + else + P.buffer = src + to_chat(user, "-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %-") + return + else + return ..() + +/obj/machinery/computer/cloning/attack_hand(mob/user) + if(..()) + return + interact(user) + +/obj/machinery/computer/cloning/interact(mob/user) + user.set_machine(src) + add_fingerprint(user) + + if(..()) + return + + updatemodules(TRUE) + + var/dat = "" + dat += "Refresh" + + if(scanner && HasEfficientPod() && scanner.scan_level > 2) + if(!autoprocess) + dat += "Autoprocess" + else + dat += "Stop autoprocess" + else + dat += "Autoprocess" + dat += "

    Cloning Pod Status

    " + dat += "
    [temp] 
    " + + switch(src.menu) + if(1) + // Modules + if (isnull(src.scanner) || !LAZYLEN(pods)) + dat += "

    Modules

    " + //dat += "Reload Modules" + if (isnull(src.scanner)) + dat += "ERROR: No Scanner detected!
    " + if (!LAZYLEN(pods)) + dat += "ERROR: No Pod detected
    " + + // Scanner + if (!isnull(src.scanner)) + var/mob/living/scanner_occupant = get_mob_or_brainmob(scanner.occupant) + + dat += "

    Scanner Functions

    " + + dat += "
    " + if(!scanner_occupant) + dat += "Scanner Unoccupied" + else if(loading) + dat += "[scanner_occupant] => Scanning..." + else + if(scanner_occupant.ckey != scantemp_ckey) + scantemp = "Ready to Scan" + scantemp_ckey = scanner_occupant.ckey + dat += "[scanner_occupant] => [scantemp]" + dat += "
    " + + if(scanner_occupant) + dat += "Start Scan" + dat += "
    [src.scanner.locked ? "Unlock Scanner" : "Lock Scanner"]" + else + dat += "Start Scan" + + // Database + dat += "

    Database Functions

    " + if (src.records.len && src.records.len > 0) + dat += "View Records ([src.records.len])
    " + else + dat += "View Records (0)
    " + if (src.diskette) + dat += "Eject Disk
    " + + + + if(2) + dat += "

    Current records

    " + dat += "<< Back

    " + for(var/datum/data/record/R in records) + dat += "

    [R.fields["name"]]

    Scan ID [R.fields["id"]] View Record" + if(3) + dat += "

    Selected Record

    " + dat += "<< Back
    " + + if (!src.active_record) + dat += "Record not found." + else + dat += "

    [src.active_record.fields["name"]]

    " + dat += "Scan ID [src.active_record.fields["id"]] Clone
    " + + var/obj/item/implant/health/H = locate(src.active_record.fields["imp"]) + + if ((H) && (istype(H))) + dat += "Health Implant Data:
    [H.sensehealth()]

    " + else + dat += "Unable to locate Health Implant.

    " + + dat += "Unique Identifier:
    [src.active_record.fields["UI"]]
    " + dat += "Structural Enzymes:
    [src.active_record.fields["SE"]]
    " + + if(diskette && diskette.fields) + dat += "
    " + dat += "

    Inserted Disk

    " + dat += "Contents: " + var/list/L = list() + if(diskette.fields["UI"]) + L += "Unique Identifier" + if(diskette.fields["UE"] && diskette.fields["name"] && diskette.fields["blood_type"]) + L += "Unique Enzymes" + if(diskette.fields["SE"]) + L += "Structural Enzymes" + dat += english_list(L, "Empty", " + ", " + ") + dat += "
    Load from Disk" + + dat += "
    Save to Disk" + dat += "
    " + + dat += "Delete Record" + + if(4) + if (!src.active_record) + src.menu = 2 + dat = "[src.temp]
    " + dat += "

    Confirm Record Deletion

    " + + dat += "Scan card to confirm.
    " + dat += "Cancel" + + + var/datum/browser/popup = new(user, "cloning", "Cloning System Control") + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + +/obj/machinery/computer/cloning/Topic(href, href_list) + if(..()) + return + + if(loading) + return + + if(href_list["task"]) + switch(href_list["task"]) + if("autoprocess") + autoprocess = 1 + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + if("stopautoprocess") + autoprocess = 0 + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + + else if ((href_list["scan"]) && !isnull(scanner) && scanner.is_operational()) + scantemp = "" + + loading = 1 + src.updateUsrDialog() + playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) + say("Initiating scan...") + + spawn(20) + src.scan_occupant(scanner.occupant) + + loading = 0 + src.updateUsrDialog() + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + + + //No locking an open scanner. + else if ((href_list["lock"]) && !isnull(scanner) && scanner.is_operational()) + if ((!scanner.locked) && (scanner.occupant)) scanner.locked = TRUE - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else scanner.locked = FALSE -<<<<<<< HEAD - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - - else if(href_list["view_rec"]) - playsound(src, "terminal_type", 25, 0) - src.active_record = find_record("id", href_list["view_rec"], records) - if(active_record) - if(!active_record.fields["ckey"]) - records -= active_record - active_record = null - src.temp = "Record Corrupt" - else - src.menu = 3 - else - src.temp = "Record missing." - - else if (href_list["del_rec"]) - if ((!src.active_record) || (src.menu < 3)) - return - if (src.menu == 3) //If we are viewing a record, confirm deletion - src.temp = "Delete record?" - src.menu = 4 - playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) - - else if (src.menu == 4) - var/obj/item/card/id/C = usr.get_active_held_item() - if (istype(C)||istype(C, /obj/item/device/pda)) - if(src.check_access(C)) - src.temp = "[src.active_record.fields["name"]] => Record deleted." - src.records.Remove(active_record) - active_record = null - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - src.menu = 2 - else - src.temp = "Access Denied." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - - else if (href_list["disk"]) //Load or eject. - switch(href_list["disk"]) - if("load") - if (!diskette || !istype(diskette.fields) || !diskette.fields["name"] || !diskette.fields) - src.temp = "Load error." - src.updateUsrDialog() - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - if (!src.active_record) - src.temp = "Record error." - src.menu = 1 - src.updateUsrDialog() - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - - for(var/key in diskette.fields) - src.active_record.fields[key] = diskette.fields[key] - src.temp = "Load successful." - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - - if("eject") - if(src.diskette) - src.diskette.loc = src.loc - src.diskette = null - playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) - if("save") - if(!diskette || diskette.read_only || !active_record || !active_record.fields) - src.temp = "Save error." - src.updateUsrDialog() - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - - diskette.fields = active_record.fields.Copy() - diskette.name = "data disk - '[src.diskette.fields["name"]]'" - src.temp = "Save successful." - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - - else if (href_list["refresh"]) - src.updateUsrDialog() - playsound(src, "terminal_type", 25, 0) - - else if (href_list["clone"]) - var/datum/data/record/C = find_record("id", href_list["clone"], records) - //Look for that player! They better be dead! - if(C) - var/obj/machinery/clonepod/pod = GetAvailablePod() - //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs. - if(!LAZYLEN(pods)) - temp = "No Clonepods detected." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else if(!pod) - temp = "No Clonepods available." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else if(!config.revival_cloning) - temp = "Unable to initiate cloning cycle." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else if(pod.occupant) - temp = "Cloning cycle already in progress." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["mrace"], C.fields["features"], C.fields["factions"])) - temp = "[C.fields["name"]] => Cloning cycle in progress..." - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - records.Remove(C) - if(active_record == C) - active_record = null - menu = 1 - else - temp = "[C.fields["name"]] => Initialisation failure." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - - else - temp = "Data corruption." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - - else if (href_list["menu"]) - src.menu = text2num(href_list["menu"]) - playsound(src, "terminal_type", 25, 0) - - src.add_fingerprint(usr) - src.updateUsrDialog() - return - -/obj/machinery/computer/cloning/proc/scan_occupant(occupant) - var/mob/living/mob_occupant = get_mob_or_brainmob(occupant) - var/datum/dna/dna - if(iscarbon(mob_occupant)) - var/mob/living/carbon/C = mob_occupant - dna = C.has_dna() - if(isbrain(mob_occupant)) - var/mob/living/brain/B = mob_occupant - dna = B.stored_dna - - if(!istype(dna)) - scantemp = "Unable to locate valid genetic data." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - if(mob_occupant.suiciding || mob_occupant.hellbound) - scantemp = "Subject's brain is not responding to scanning stimuli." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - if((mob_occupant.disabilities & NOCLONE) && (src.scanner.scan_level < 2)) - scantemp = "Subject no longer contains the fundamental materials required to create a living clone." - playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0) - return - if ((!mob_occupant.ckey) || (!mob_occupant.client)) - scantemp = "Mental interface failure." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - if (find_record("ckey", mob_occupant.ckey, records)) - scantemp = "Subject already in database." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - - var/datum/data/record/R = new() - if(dna.species) - // We store the instance rather than the path, because some - // species (abductors, slimepeople) store state in their - // species datums - R.fields["mrace"] = dna.species - else - var/datum/species/rando_race = pick(config.roundstart_races) - R.fields["mrace"] = rando_race.type - - R.fields["ckey"] = mob_occupant.ckey - R.fields["name"] = mob_occupant.real_name - R.fields["id"] = copytext(md5(mob_occupant.real_name), 2, 6) - R.fields["UE"] = dna.unique_enzymes - R.fields["UI"] = dna.uni_identity - R.fields["SE"] = dna.struc_enzymes - R.fields["blood_type"] = dna.blood_type - R.fields["features"] = dna.features - R.fields["factions"] = mob_occupant.faction - - if (!isnull(mob_occupant.mind)) //Save that mind so traitors can continue traitoring after cloning. - R.fields["mind"] = "\ref[mob_occupant.mind]" - - //Add an implant if needed - var/obj/item/implant/health/imp - for(var/obj/item/implant/health/HI in mob_occupant.implants) - imp = HI - break - if(!imp) - imp = new /obj/item/implant/health(mob_occupant) - imp.implant(mob_occupant) - R.fields["imp"] = "\ref[imp]" - - src.records += R - scantemp = "Subject successfully scanned." - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) -======= playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) else if(href_list["view_rec"]) @@ -687,4 +500,3 @@ src.records += R scantemp = "Subject successfully scanned." playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) ->>>>>>> 4178c20... Configuration datum refactor (#30763) From be08e0c29f4d751fc900f69adbeebe43e603df4b Mon Sep 17 00:00:00 2001 From: LetterJay Date: Fri, 29 Sep 2017 23:42:12 -0500 Subject: [PATCH 17/60] Update mirror.dm --- code/game/objects/structures/mirror.dm | 228 ------------------------- 1 file changed, 228 deletions(-) diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index c2e082810f..296e4ba757 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -1,230 +1,3 @@ -<<<<<<< HEAD -//wip wip wup -/obj/structure/mirror - name = "mirror" - desc = "Mirror mirror on the wall, who's the most robust of them all?" - icon = 'icons/obj/watercloset.dmi' - icon_state = "mirror" - density = FALSE - anchored = TRUE - max_integrity = 200 - integrity_failure = 100 - - -/obj/structure/mirror/attack_hand(mob/user) - if(broken || !Adjacent(user)) - return - - if(ishuman(user)) - var/mob/living/carbon/human/H = user - - var/userloc = H.loc - - //see code/modules/mob/dead/new_player/preferences.dm at approx line 545 for comments! - //this is largely copypasted from there. - - //handle facial hair (if necessary) - if(H.gender == MALE) - var/new_style = input(user, "Select a facial hair style", "Grooming") as null|anything in GLOB.facial_hair_styles_list - if(userloc != H.loc) - return //no tele-grooming - if(new_style) - H.facial_hair_style = new_style - else - H.facial_hair_style = "Shaved" - - //handle normal hair - var/new_style = input(user, "Select a hair style", "Grooming") as null|anything in GLOB.hair_styles_list - if(userloc != H.loc) - return //no tele-grooming - if(new_style) - H.hair_style = new_style - - H.update_hair() - -/obj/structure/mirror/examine_status(mob/user) - if(broken) - return // no message spam - ..() - -/obj/structure/mirror/obj_break(damage_flag) - if(!broken && !(flags_1 & NODECONSTRUCT_1)) - icon_state = "mirror_broke" - playsound(src, "shatter", 70, 1) - desc = "Oh no, seven years of bad luck!" - broken = 1 - -/obj/structure/mirror/deconstruct(disassembled = TRUE) - if(!(flags_1 & NODECONSTRUCT_1)) - if(!disassembled) - new /obj/item/shard( src.loc ) - qdel(src) - -/obj/structure/mirror/attackby(obj/item/I, mob/living/user, params) - if(istype(I, /obj/item/weldingtool) && user.a_intent != INTENT_HARM) - var/obj/item/weldingtool/WT = I - if(broken) - user.changeNext_move(CLICK_CD_MELEE) - if(WT.remove_fuel(0, user)) - to_chat(user, "You begin repairing [src]...") - playsound(src, 'sound/items/welder.ogg', 100, 1) - if(do_after(user, 10*I.toolspeed, target = src)) - if(!user || !WT || !WT.isOn()) - return - to_chat(user, "You repair [src].") - broken = 0 - icon_state = initial(icon_state) - desc = initial(desc) - else - return ..() - -/obj/structure/mirror/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) - switch(damage_type) - if(BRUTE) - playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) - if(BURN) - playsound(src.loc, 'sound/effects/hit_on_shattered_glass.ogg', 70, 1) - - -/obj/structure/mirror/magic - name = "magic mirror" - desc = "Turn and face the strange... face." - icon_state = "magic_mirror" - var/list/races_blacklist = list("skeleton", "agent", "angel", "military_synth", "memezombie") - var/list/choosable_races = list() - -/obj/structure/mirror/magic/New() - if(!choosable_races.len) - for(var/speciestype in subtypesof(/datum/species)) - var/datum/species/S = new speciestype() - if(!(S.id in races_blacklist)) - choosable_races += S.id - ..() - -/obj/structure/mirror/magic/lesser/New() - choosable_races = GLOB.roundstart_species - ..() - -/obj/structure/mirror/magic/badmin/New() - for(var/speciestype in subtypesof(/datum/species)) - var/datum/species/S = new speciestype() - choosable_races += S.id - ..() - -/obj/structure/mirror/magic/attack_hand(mob/user) - if(!ishuman(user)) - return - - var/mob/living/carbon/human/H = user - - var/choice = input(user, "Something to change?", "Magical Grooming") as null|anything in list("name", "race", "gender", "hair", "eyes") - - if(!Adjacent(user)) - return - - switch(choice) - if("name") - var/newname = copytext(sanitize(input(H, "Who are we again?", "Name change", H.name) as null|text),1,MAX_NAME_LEN) - - if(!newname) - return - if(!Adjacent(user)) - return - H.real_name = newname - H.name = newname - if(H.dna) - H.dna.real_name = newname - if(H.mind) - H.mind.name = newname - - if("race") - var/newrace - var/racechoice = input(H, "What are we again?", "Race change") as null|anything in choosable_races - newrace = GLOB.species_list[racechoice] - - if(!newrace) - return - if(!Adjacent(user)) - return - H.set_species(newrace, icon_update=0) - - if(H.dna.species.use_skintones) - var/new_s_tone = input(user, "Choose your skin tone:", "Race change") as null|anything in GLOB.skin_tones - - if(new_s_tone) - H.skin_tone = new_s_tone - H.dna.update_ui_block(DNA_SKIN_TONE_BLOCK) - - if(MUTCOLORS in H.dna.species.species_traits) - var/new_mutantcolor = input(user, "Choose your skin color:", "Race change") as color|null - if(new_mutantcolor) - var/temp_hsv = RGBtoHSV(new_mutantcolor) - - if(ReadHSV(temp_hsv)[3] >= ReadHSV("#7F7F7F")[3]) // mutantcolors must be bright - H.dna.features["mcolor"] = sanitize_hexcolor(new_mutantcolor) - - else - to_chat(H, "Invalid color. Your color is not bright enough.") - - H.update_body() - H.update_hair() - H.update_body_parts() - H.update_mutations_overlay() // no hulk lizard - - if("gender") - if(!(H.gender in list("male", "female"))) //blame the patriarchy - return - if(!Adjacent(user)) - return - if(H.gender == "male") - if(alert(H, "Become a Witch?", "Confirmation", "Yes", "No") == "Yes") - H.gender = "female" - to_chat(H, "Man, you feel like a woman!") - else - return - - else - if(alert(H, "Become a Warlock?", "Confirmation", "Yes", "No") == "Yes") - H.gender = "male" - to_chat(H, "Whoa man, you feel like a man!") - else - return - H.dna.update_ui_block(DNA_GENDER_BLOCK) - H.update_body() - H.update_mutations_overlay() //(hulk male/female) - - if("hair") - var/hairchoice = alert(H, "Hair style or hair color?", "Change Hair", "Style", "Color") - if(!Adjacent(user)) - return - if(hairchoice == "Style") //So you just want to use a mirror then? - ..() - else - var/new_hair_color = input(H, "Choose your hair color", "Hair Color") as null|color - if(new_hair_color) - H.hair_color = sanitize_hexcolor(new_hair_color) - H.dna.update_ui_block(DNA_HAIR_COLOR_BLOCK) - if(H.gender == "male") - var/new_face_color = input(H, "Choose your facial hair color", "Hair Color") as null|color - if(new_face_color) - H.facial_hair_color = sanitize_hexcolor(new_face_color) - H.dna.update_ui_block(DNA_FACIAL_HAIR_COLOR_BLOCK) - H.update_hair() - - if("eyes") - var/new_eye_color = input(H, "Choose your eye color", "Eye Color") as null|color - if(!Adjacent(user)) - return - if(new_eye_color) - H.eye_color = sanitize_hexcolor(new_eye_color) - H.dna.update_ui_block(DNA_EYE_COLOR_BLOCK) - H.update_body() - if(choice) - curse(user) - -/obj/structure/mirror/magic/proc/curse(mob/living/user) - return -======= //wip wip wup /obj/structure/mirror name = "mirror" @@ -451,4 +224,3 @@ /obj/structure/mirror/magic/proc/curse(mob/living/user) return ->>>>>>> 4178c20... Configuration datum refactor (#30763) From 6fe6cfd68efbcba08a2b37b3a5947d6e70c9cfba Mon Sep 17 00:00:00 2001 From: LetterJay Date: Fri, 29 Sep 2017 23:42:35 -0500 Subject: [PATCH 18/60] Update ipintel.dm --- code/modules/admin/ipintel.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/modules/admin/ipintel.dm b/code/modules/admin/ipintel.dm index d048b71170..fa9951f276 100644 --- a/code/modules/admin/ipintel.dm +++ b/code/modules/admin/ipintel.dm @@ -78,11 +78,7 @@ if (!SSipintel.enabled) return -<<<<<<< HEAD - var/list/http[] = world.Export("http://[config.ipintel_domain]/check.php?ip=[ip]&contact=[config.ipintel_email]&format=json&flags_1=f") -======= var/list/http[] = world.Export("http://[CONFIG_GET(string/ipintel_domain)]/check.php?ip=[ip]&contact=[CONFIG_GET(string/ipintel_email)]&format=json&flags=f") ->>>>>>> 4178c20... Configuration datum refactor (#30763) if (http) var/status = text2num(http["STATUS"]) From 03ee5a9303744358e2aec20d96980e737499a91d Mon Sep 17 00:00:00 2001 From: LetterJay Date: Fri, 29 Sep 2017 23:43:39 -0500 Subject: [PATCH 19/60] Update preferences.dm --- code/modules/client/preferences.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index b576829240..ad0e9ba50e 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -274,10 +274,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "
    " dat += "
    " @@ -295,7 +461,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Ghost pda: [(chat_toggles & CHAT_GHOSTPDA) ? "All Messages" : "Nearest Creatures"]
    " dat += "Pull requests: [(chat_toggles & CHAT_PULLR) ? "Yes" : "No"]
    " dat += "Midround Antagonist: [(toggles & MIDROUND_ANTAG) ? "Yes" : "No"]
    " - if(config.allow_Metadata) + if(CONFIG_GET(flag/allow_metadata)) dat += "OOC Notes: Edit
    " if(user.client) @@ -332,7 +498,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Ghosts of Others: [button_name]
    " - if (config.maprotation) + if (CONFIG_GET(flag/maprotation)) var/p_map = preferred_map if (!p_map) p_map = "Default" @@ -347,7 +513,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) p_map = VM.map_name else p_map += " (No longer exists)" - if(config.allow_map_voting) + if(CONFIG_GET(flag/allow_map_voting)) dat += "Preferred Map: [p_map]
    " dat += "FPS: [clientfps]
    " @@ -385,7 +551,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "Be [capitalize(i)]: BANNED
    " else var/days_remaining = null - if(config.use_age_restriction_for_jobs && ispath(GLOB.special_roles[i])) //If it's a game mode antag, check if the player meets the minimum age + if(ispath(GLOB.special_roles[i]) && CONFIG_GET(flag/use_age_restriction_for_jobs)) //If it's a game mode antag, check if the player meets the minimum age var/mode_path = GLOB.special_roles[i] var/datum/game_mode/temp_mode = new mode_path days_remaining = temp_mode.get_remaining_days(user.client) @@ -599,7 +765,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if((job_civilian_low & ASSISTANT) && (rank != "Assistant") && !jobban_isbanned(user, "Assistant")) HTML += "[rank]
    \[MUTANT\]
    " -<<<<<<< HEAD // dat += "Size: [character_size]
    " dat += "
    " -======= dat += "

    Body

    " dat += "Random Body " @@ -441,8 +439,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "" ->>>>>>> 4178c20... Configuration datum refactor (#30763) - if (1) // Game Preferences dat += "
    " dat += "

    General Settings

    " From 9da34705219ad084a20126eba336b8e99cef2a93 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Fri, 29 Sep 2017 23:44:08 -0500 Subject: [PATCH 20/60] Update preferences_savefile.dm --- code/modules/client/preferences_savefile.dm | 5 ----- 1 file changed, 5 deletions(-) diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index e2612ebf4b..d58d1cec77 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -328,17 +328,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["feature_lizard_spines"] >> features["spines"] S["feature_lizard_body_markings"] >> features["body_markings"] S["feature_lizard_legs"] >> features["legs"] -<<<<<<< HEAD - S["feature_human_tail"] >> features["tail_human"] - S["feature_human_ears"] >> features["ears"] -======= if(!CONFIG_GET(flag/join_with_mutant_humans)) features["tail_human"] = "none" features["ears"] = "none" else S["feature_human_tail"] >> features["tail_human"] S["feature_human_ears"] >> features["ears"] ->>>>>>> 4178c20... Configuration datum refactor (#30763) S["clown_name"] >> custom_names["clown"] S["mime_name"] >> custom_names["mime"] S["ai_name"] >> custom_names["ai"] From 8e1cbb68cae92205452994e117a14bdf7eb7efb2 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Fri, 29 Sep 2017 23:44:23 -0500 Subject: [PATCH 21/60] Update assistant.dm --- code/modules/jobs/job_types/assistant.dm | 45 ------------------------ 1 file changed, 45 deletions(-) diff --git a/code/modules/jobs/job_types/assistant.dm b/code/modules/jobs/job_types/assistant.dm index 6c8b050394..26d57d1e76 100644 --- a/code/modules/jobs/job_types/assistant.dm +++ b/code/modules/jobs/job_types/assistant.dm @@ -1,47 +1,3 @@ -<<<<<<< HEAD -/* -Assistant -*/ -/datum/job/assistant - title = "Assistant" - flag = ASSISTANT - department_flag = CIVILIAN - faction = "Station" - total_positions = -1 - spawn_positions = -1 - supervisors = "absolutely everyone" - selection_color = "#dddddd" - access = list() //See /datum/job/assistant/get_access() - minimal_access = list() //See /datum/job/assistant/get_access() - outfit = /datum/outfit/job/assistant - - -/datum/job/assistant/get_access() - if((config.jobs_have_maint_access & ASSISTANTS_HAVE_MAINT_ACCESS) || !config.jobs_have_minimal_access) //Config has assistant maint access set - . = ..() - . |= list(ACCESS_MAINT_TUNNELS) - else - return ..() - -/datum/job/assistant/config_check() - if(config && !(config.assistant_cap == 0)) - total_positions = config.assistant_cap - spawn_positions = config.assistant_cap - return 1 - return 0 - - -/datum/outfit/job/assistant - name = "Assistant" - jobtype = /datum/job/assistant - -/datum/outfit/job/assistant/pre_equip(mob/living/carbon/human/H) - ..() - if (config.grey_assistants) - uniform = /obj/item/clothing/under/color/grey - else - uniform = /obj/item/clothing/under/color/random -======= /* Assistant */ @@ -85,4 +41,3 @@ Assistant uniform = /obj/item/clothing/under/color/grey else uniform = /obj/item/clothing/under/color/random ->>>>>>> 4178c20... Configuration datum refactor (#30763) From 6cd4e67f36d93ff9a75f8975e2e902d3c48c0bdf Mon Sep 17 00:00:00 2001 From: LetterJay Date: Fri, 29 Sep 2017 23:44:43 -0500 Subject: [PATCH 22/60] Update silicon.dm --- code/modules/jobs/job_types/silicon.dm | 73 ++++++-------------------- 1 file changed, 15 insertions(+), 58 deletions(-) diff --git a/code/modules/jobs/job_types/silicon.dm b/code/modules/jobs/job_types/silicon.dm index d6cd75ee7b..bc3b31b2bf 100644 --- a/code/modules/jobs/job_types/silicon.dm +++ b/code/modules/jobs/job_types/silicon.dm @@ -1,61 +1,19 @@ -/* -AI -*/ -/datum/job/ai - title = "AI" - flag = AI_JF - department_flag = ENGSEC - faction = "Station" - total_positions = 0 - spawn_positions = 1 - selection_color = "#ccffcc" - supervisors = "your laws" - req_admin_notify = 1 - minimal_player_age = 30 +/* +AI +*/ +/datum/job/ai + title = "AI" + flag = AI_JF + department_flag = ENGSEC + faction = "Station" + total_positions = 0 + spawn_positions = 1 + selection_color = "#ccffcc" + supervisors = "your laws" + req_admin_notify = 1 + minimal_player_age = 30 exp_requirements = 180 exp_type = EXP_TYPE_CREW -<<<<<<< HEAD - -/datum/job/ai/equip(mob/living/carbon/human/H) - return H.AIize(FALSE) - -/datum/job/ai/after_spawn(mob/living/silicon/ai/AI, mob/M) - AI.rename_self("ai", M.client) - - //we may have been created after our borg - if(SSticker.current_state == GAME_STATE_SETTING_UP) - for(var/mob/living/silicon/robot/R in GLOB.silicon_mobs) - if(!R.connected_ai) - R.TryConnectToAI() - - -/datum/job/ai/config_check() - if(config && config.allow_ai) - return 1 - return 0 - -/* -Cyborg -*/ -/datum/job/cyborg - title = "Cyborg" - flag = CYBORG - department_flag = ENGSEC - faction = "Station" - total_positions = 0 - spawn_positions = 1 - supervisors = "your laws and the AI" //Nodrak - selection_color = "#ddffdd" - minimal_player_age = 21 - exp_requirements = 120 - exp_type = EXP_TYPE_CREW - -/datum/job/cyborg/equip(mob/living/carbon/human/H) - return H.Robotize(FALSE, FALSE) - -/datum/job/cyborg/after_spawn(mob/living/silicon/robot/R, mob/M) - if(config.rename_cyborg) //name can't be set in robot/New without the client -======= /datum/job/ai/equip(mob/living/carbon/human/H) return H.AIize(FALSE) @@ -94,5 +52,4 @@ Cyborg /datum/job/cyborg/after_spawn(mob/living/silicon/robot/R, mob/M) if(CONFIG_GET(flag/rename_cyborg)) //name can't be set in robot/New without the client ->>>>>>> 4178c20... Configuration datum refactor (#30763) - R.rename_self("cyborg", M.client) \ No newline at end of file + R.rename_self("cyborg", M.client) From 7b3f91131b7ef0cd7a0d08e276ed10e6d3178446 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Fri, 29 Sep 2017 23:45:07 -0500 Subject: [PATCH 23/60] Update datum_traitor.dm --- code/datums/antagonists/datum_traitor.dm | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/code/datums/antagonists/datum_traitor.dm b/code/datums/antagonists/datum_traitor.dm index fe965efe45..874e6c00f1 100644 --- a/code/datums/antagonists/datum_traitor.dm +++ b/code/datums/antagonists/datum_traitor.dm @@ -174,26 +174,11 @@ if(prob(30)) objective_count += forge_single_objective() - -<<<<<<< HEAD - for(var/i = objective_count, i < config.traitor_objectives_amount, i++) - if(prob(20)) //AI's are less likely to look for a late-joiner than normal traitors - var/datum/objective/assassinate/late/late_objective = new - late_objective.owner = owner - late_objective.find_target() - add_objective(late_objective) - else - var/datum/objective/assassinate/kill_objective = new - kill_objective.owner = owner - kill_objective.find_target() - add_objective(kill_objective) -======= for(var/i = objective_count, i < CONFIG_GET(number/traitor_objectives_amount), i++) var/datum/objective/assassinate/kill_objective = new kill_objective.owner = owner kill_objective.find_target() add_objective(kill_objective) ->>>>>>> 4178c20... Configuration datum refactor (#30763) var/datum/objective/survive/exist/exist_objective = new exist_objective.owner = owner From 7e2873cd460a1ac28992d74f552f30e80d038117 Mon Sep 17 00:00:00 2001 From: ShizCalev Date: Sat, 30 Sep 2017 01:58:40 -0400 Subject: [PATCH 24/60] Corrected shuttle refuel time --- code/controllers/subsystem/shuttle.dm | 6 ++++++ tgstation.dme | 14 ++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index 2b1080049e..c59cc0161f 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -176,9 +176,15 @@ SUBSYSTEM_DEF(shuttle) Good luck.") return emergency = backup_shuttle +<<<<<<< HEAD if(world.time - SSticker.round_start_time < config.shuttle_refuel_delay) to_chat(user, "The emergency shuttle is refueling. Please wait [DisplayTimeText((world.time - SSticker.round_start_time) - config.shuttle_refuel_delay)] before trying again.") +======= + var/srd = CONFIG_GET(number/shuttle_refuel_delay) + if(world.time - SSticker.round_start_time < srd) + to_chat(user, "The emergency shuttle is refueling. Please wait [DisplayTimeText(srd - (world.time - SSticker.round_start_time))] before trying again.") +>>>>>>> ced1e24... Corrected shuttle refuel time (#31108) return switch(emergency.mode) diff --git a/tgstation.dme b/tgstation.dme index dbfeb68502..627244c246 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -163,6 +163,7 @@ #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\screen_objects.dm" #include "code\_onclick\hud\swarmer.dm" +<<<<<<< HEAD #include "code\citadel\_cit_helpers.dm" #include "code\citadel\cit_areas.dm" #include "code\citadel\cit_arousal.dm" @@ -189,6 +190,8 @@ #include "code\citadel\organs\vagina.dm" #include "code\citadel\organs\womb.dm" #include "code\citadel\toys\dildos.dm" +======= +>>>>>>> ced1e24... Corrected shuttle refuel time (#31108) #include "code\controllers\admin.dm" #include "code\controllers\configuration.dm" #include "code\controllers\configuration_citadel.dm" @@ -198,6 +201,12 @@ #include "code\controllers\hooks.dm" #include "code\controllers\master.dm" #include "code\controllers\subsystem.dm" +#include "code\controllers\configuration\config_entry.dm" +#include "code\controllers\configuration\configuration.dm" +#include "code\controllers\configuration\entries\comms.dm" +#include "code\controllers\configuration\entries\config.dm" +#include "code\controllers\configuration\entries\dbconfig.dm" +#include "code\controllers\configuration\entries\game_options.dm" #include "code\controllers\subsystem\acid.dm" #include "code\controllers\subsystem\air.dm" #include "code\controllers\subsystem\assets.dm" @@ -2130,7 +2139,12 @@ #include "code\modules\ruins\spaceruin_code\TheDerelict.dm" #include "code\modules\security_levels\keycard_authentication.dm" #include "code\modules\security_levels\security_levels.dm" +<<<<<<< HEAD #include "code\modules\server_tools\server_tools.dm" +======= +#include "code\modules\server_tools\st_commands.dm" +#include "code\modules\server_tools\st_interface.dm" +>>>>>>> ced1e24... Corrected shuttle refuel time (#31108) #include "code\modules\shuttle\arrivals.dm" #include "code\modules\shuttle\assault_pod.dm" #include "code\modules\shuttle\computer.dm" From d3c37c83de3f64219c1145e533572e1f01c7863f Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Sat, 30 Sep 2017 00:59:11 -0500 Subject: [PATCH 25/60] Removes step throwers from cult altar (#31083) --- .../LavaRuins/lavaland_surface_cultaltar.dmm | 39 ------------------- 1 file changed, 39 deletions(-) diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm index 8ca77f7dd2..49e1dd8484 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm @@ -24,15 +24,6 @@ /area/ruin/unpowered) "g" = ( /obj/effect/decal/cleanable/blood/old, -/obj/effect/step_trigger/thrower{ - name = "south"; - tiles = 5 - }, -/obj/effect/step_trigger/sound_effect{ - name = "turn around"; - sound = 'sound/hallucinations/turn_around1.ogg'; - triggerer_only = 1 - }, /turf/open/floor/engine/cult{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, @@ -79,16 +70,6 @@ /area/ruin/unpowered) "n" = ( /obj/effect/decal/cleanable/blood/old, -/obj/effect/step_trigger/thrower{ - direction = 4; - name = "east"; - tiles = 5 - }, -/obj/effect/step_trigger/sound_effect{ - name = "turn around"; - sound = 'sound/hallucinations/turn_around1.ogg'; - triggerer_only = 1 - }, /turf/open/floor/engine/cult{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, @@ -117,16 +98,6 @@ /area/ruin/unpowered) "p" = ( /obj/effect/decal/cleanable/blood/old, -/obj/effect/step_trigger/thrower{ - direction = 8; - name = "west"; - tiles = 5 - }, -/obj/effect/step_trigger/sound_effect{ - name = "turn around"; - sound = 'sound/hallucinations/turn_around1.ogg'; - triggerer_only = 1 - }, /turf/open/floor/engine/cult{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, @@ -142,16 +113,6 @@ /area/ruin/unpowered) "r" = ( /obj/effect/decal/cleanable/blood/old, -/obj/effect/step_trigger/thrower{ - direction = 1; - name = "north"; - tiles = 5 - }, -/obj/effect/step_trigger/sound_effect{ - name = "turn around"; - sound = 'sound/hallucinations/turn_around1.ogg'; - triggerer_only = 1 - }, /turf/open/floor/engine/cult{ initial_gas_mix = "o2=14;n2=23;TEMP=300" }, From 8048ce1842a26e74bbcfe219bb85d387c97f343e Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 01:37:32 -0500 Subject: [PATCH 27/60] Update humanoid.dm --- .../living/carbon/alien/humanoid/humanoid.dm | 128 +----------------- 1 file changed, 1 insertion(+), 127 deletions(-) diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index b9bfc277c0..b29f39ad40 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -1,129 +1,4 @@ -<<<<<<< HEAD -/mob/living/carbon/alien/humanoid - name = "alien" - icon_state = "alien" - pass_flags = PASSTABLE - butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/xeno = 5, /obj/item/stack/sheet/animalhide/xeno = 1) - possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM) - limb_destroyer = 1 - var/obj/item/r_store = null - var/obj/item/l_store = null - var/caste = "" - var/alt_icon = 'icons/mob/alienleap.dmi' //used to switch between the two alien icon files. - var/leap_on_click = 0 - var/pounce_cooldown = 0 - var/pounce_cooldown_time = 30 - var/custom_pixel_x_offset = 0 //for admin fuckery. - var/custom_pixel_y_offset = 0 - var/sneaking = 0 //For sneaky-sneaky mode and appropriate slowdown - var/drooling = 0 //For Neruotoxic spit overlays - bodyparts = list(/obj/item/bodypart/chest/alien, /obj/item/bodypart/head/alien, /obj/item/bodypart/l_arm/alien, - /obj/item/bodypart/r_arm/alien, /obj/item/bodypart/r_leg/alien, /obj/item/bodypart/l_leg/alien) - devourable = TRUE - - -//This is fine right now, if we're adding organ specific damage this needs to be updated -/mob/living/carbon/alien/humanoid/Initialize() - AddAbility(new/obj/effect/proc_holder/alien/regurgitate(null)) - . = ..() - -/mob/living/carbon/alien/humanoid/movement_delay() - . = ..() - . += move_delay_add + config.alien_delay + sneaking //move_delay_add is used to slow aliens with stun - -/mob/living/carbon/alien/humanoid/restrained(ignore_grab) - . = handcuffed - - -/mob/living/carbon/alien/humanoid/show_inv(mob/user) - user.set_machine(src) - var/list/dat = list() - dat += {" -
    - [name] -
    "} - for(var/i in 1 to held_items.len) - var/obj/item/I = get_item_for_held_index(i) - dat += "
    [get_held_index_name(i)]:[(I && !(I.flags_1 & ABSTRACT_1)) ? I : "Empty"]" - dat += "
    Empty Pouches" - - if(handcuffed) - dat += "
    Handcuffed" - if(legcuffed) - dat += "
    Legcuffed" - - dat += {" -
    -
    Close - "} - user << browse(dat.Join(), "window=mob\ref[src];size=325x500") - onclose(user, "mob\ref[src]") - - -/mob/living/carbon/alien/humanoid/Topic(href, href_list) - ..() - //strip panel - if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) - if(href_list["pouches"]) - visible_message("[usr] tries to empty [src]'s pouches.", \ - "[usr] tries to empty [src]'s pouches.") - if(do_mob(usr, src, POCKET_STRIP_DELAY * 0.5)) - dropItemToGround(r_store) - dropItemToGround(l_store) - -/mob/living/carbon/alien/humanoid/cuff_resist(obj/item/I) - playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free - ..(I, cuff_break = INSTANT_CUFFBREAK) - -/mob/living/carbon/alien/humanoid/resist_grab(moving_resist) - if(pulledby.grab_state) - visible_message("[src] has broken free of [pulledby]'s grip!") - pulledby.stop_pulling() - . = 0 - -/mob/living/carbon/alien/humanoid/get_standard_pixel_y_offset(lying = 0) - if(leaping) - return -32 - else if(custom_pixel_y_offset) - return custom_pixel_y_offset - else - return initial(pixel_y) - -/mob/living/carbon/alien/humanoid/get_standard_pixel_x_offset(lying = 0) - if(leaping) - return -32 - else if(custom_pixel_x_offset) - return custom_pixel_x_offset - else - return initial(pixel_x) - -/mob/living/carbon/alien/humanoid/get_permeability_protection() - return 0.8 - -/mob/living/carbon/alien/humanoid/alien_evolve(mob/living/carbon/alien/humanoid/new_xeno) - drop_all_held_items() - for(var/atom/movable/A in stomach_contents) - stomach_contents.Remove(A) - new_xeno.stomach_contents.Add(A) - A.loc = new_xeno - ..() - -//For alien evolution/promotion/queen finder procs. Checks for an active alien of that type -/proc/get_alien_type(var/alienpath) - for(var/mob/living/carbon/alien/humanoid/A in GLOB.living_mob_list) - if(!istype(A, alienpath)) - continue - if(!A.key || A.stat == DEAD) //Only living aliens with a ckey are valid. - continue - return A - return FALSE - - -/mob/living/carbon/alien/humanoid/check_breath(datum/gas_mixture/breath) - if(breath && breath.total_moles() > 0 && !sneaking) - playsound(get_turf(src), pick('sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg'), 50, 0, -5) - ..() -======= +<<<<<<< HEAD /mob/living/carbon/alien/humanoid name = "alien" icon_state = "alien" @@ -250,4 +125,3 @@ if(breath && breath.total_moles() > 0 && !sneaking) playsound(get_turf(src), pick('sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg'), 50, 0, -5) ..() ->>>>>>> 4178c20... Configuration datum refactor (#30763) From b728fd61606c24e939b3051f8787472663d0cc7c Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 01:38:27 -0500 Subject: [PATCH 28/60] Update global_lists.dm --- code/__HELPERS/global_lists.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 75f9fbd3d0..0b79afb941 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -113,4 +113,3 @@ for(var/path in subtypesof(prototype)) L+= path return L ->>>>>>> 4178c20... Configuration datum refactor (#30763) From ee0c45751b41448fe6d28da5b72e723f2a14effe Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 01:45:46 -0500 Subject: [PATCH 29/60] Update simple_animal.dm --- code/modules/mob/living/simple_animal/simple_animal.dm | 8 -------- 1 file changed, 8 deletions(-) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index a7bab7ee26..4e988c482c 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -271,19 +271,11 @@ /mob/living/simple_animal/movement_delay() -<<<<<<< HEAD - . = ..() - - . = speed - - . += config.animal_delay -======= var/static/config_animal_delay if(isnull(config_animal_delay)) config_animal_delay = CONFIG_GET(number/animal_delay) . += config_animal_delay return ..() + speed + config_animal_delay ->>>>>>> 3fb8828... Movement delay fixes and optimization (#31037) /mob/living/simple_animal/Stat() ..() From d7db5f23cbeb76a669e55706568531434e2535e2 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 02:13:33 -0500 Subject: [PATCH 30/60] Update humanoid.dm --- code/modules/mob/living/carbon/alien/humanoid/humanoid.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index b29f39ad40..9d9e327fec 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -1,4 +1,3 @@ -<<<<<<< HEAD /mob/living/carbon/alien/humanoid name = "alien" icon_state = "alien" From 0987619a55fad6d4fb8a6fe76998053b7e372721 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 02:56:33 -0500 Subject: [PATCH 31/60] Update tgstation.dme --- tgstation.dme | 2 -- 1 file changed, 2 deletions(-) diff --git a/tgstation.dme b/tgstation.dme index 46b6dd1034..bc8af51b99 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -193,7 +193,6 @@ #include "code\controllers\admin.dm" #include "code\controllers\configuration.dm" #include "code\controllers\configuration_citadel.dm" -======= #include "code\controllers\configuration\entries\comms.dm" #include "code\controllers\configuration\entries\config.dm" #include "code\controllers\configuration\entries\dbconfig.dm" @@ -201,7 +200,6 @@ #include "code\controllers\configuration\config_entry.dm" #include "code\controllers\configuration\configuration.dm" #include "code\controllers\admin.dm" ->>>>>>> 4178c20... Configuration datum refactor (#30763) #include "code\controllers\controller.dm" #include "code\controllers\failsafe.dm" #include "code\controllers\globals.dm" From 4f4fe9824004b69d290839b3c8ca1814217532fc Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 02:57:20 -0500 Subject: [PATCH 32/60] Update tgstation.dme --- tgstation.dme | 1 - 1 file changed, 1 deletion(-) diff --git a/tgstation.dme b/tgstation.dme index bc8af51b99..3d6a9e1a2d 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -163,7 +163,6 @@ #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\screen_objects.dm" #include "code\_onclick\hud\swarmer.dm" -<<<<<<< HEAD #include "code\citadel\_cit_helpers.dm" #include "code\citadel\cit_areas.dm" #include "code\citadel\cit_arousal.dm" From 98d6927eb6d79a007fc36f7b9375ee2621854bca Mon Sep 17 00:00:00 2001 From: vuonojenmustaturska Date: Sat, 30 Sep 2017 16:09:15 +0300 Subject: [PATCH 33/60] Cleanup to various loc assignments and nearby code --- code/_onclick/hud/alert.dm | 2 +- code/_onclick/telekinesis.dm | 2 +- code/datums/antagonists/devil.dm | 4 +- code/datums/diseases/parrotpossession.dm | 2 +- code/datums/diseases/wizarditis.dm | 118 +++++++ code/datums/wires/wires.dm | 46 +++ code/game/gamemodes/blob/blob.dm | 2 +- code/game/gamemodes/blob/powers.dm | 2 +- code/game/gamemodes/blob/theblob.dm | 2 +- .../gamemodes/changeling/powers/headcrab.dm | 2 +- .../abduction/machinery/dispenser.dm | 3 +- .../gamemodes/miniantags/bot_swarm/swarmer.dm | 4 +- code/game/gamemodes/miniantags/morph/morph.dm | 4 +- code/game/gamemodes/nuclear/nuclear.dm | 2 +- code/game/gamemodes/sandbox/h_sandbox.dm | 274 ++++++++++++++++ code/game/gamemodes/wizard/artefact.dm | 9 +- code/game/gamemodes/wizard/soulstone.dm | 2 +- code/game/gamemodes/wizard/wizard.dm | 2 +- code/game/machinery/Beacon.dm | 4 +- code/game/machinery/_machinery.dm | 2 +- code/game/machinery/bank_machine.dm | 2 +- code/game/machinery/buttons.dm | 4 +- code/game/machinery/camera/camera.dm | 2 +- code/game/machinery/camera/camera_assembly.dm | 63 ++++ code/game/machinery/cell_charger.dm | 11 +- code/game/machinery/computer/aifixer.dm | 149 +++++++++ .../game/machinery/computer/buildandrepair.dm | 13 +- code/game/machinery/computer/card.dm | 23 +- code/game/machinery/computer/cloning.dm | 293 ++++++++++++++++++ code/game/machinery/computer/dna_console.dm | 5 +- .../machinery/computer/gulag_teleporter.dm | 3 +- 31 files changed, 994 insertions(+), 62 deletions(-) diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index b361ef1a78..0e02bebb47 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -627,7 +627,7 @@ so as to remain in compliance with the most up-to-date laws." if(NOTIFY_JUMP) var/turf/T = get_turf(target) if(T && isturf(T)) - G.loc = T + G.forceMove(T) if(NOTIFY_ORBIT) G.ManualFollow(target) diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm index b0ab260d63..903f3c0790 100644 --- a/code/_onclick/telekinesis.dm +++ b/code/_onclick/telekinesis.dm @@ -92,7 +92,7 @@ /obj/item/tk_grab/dropped(mob/user) if(focus && user && loc != user && loc != user.loc) // drop_item() gets called when you tk-attack a table/closet with an item if(focus.Adjacent(loc)) - focus.loc = loc + focus.forceMove(loc) . = ..() //stops TK grabs being equipped anywhere but into hands diff --git a/code/datums/antagonists/devil.dm b/code/datums/antagonists/devil.dm index 14c92f3263..f66fc5a3b2 100644 --- a/code/datums/antagonists/devil.dm +++ b/code/datums/antagonists/devil.dm @@ -205,7 +205,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", /datum/antagonist/devil/proc/regress_blood_lizard() var/mob/living/carbon/true_devil/D = owner.current to_chat(D, "Your powers weaken, have more contracts be signed to regain power.") - D.oldform.loc = D.loc + D.oldform.forceMove(D.drop_location()) owner.transfer_to(D.oldform) give_appropriate_spells() qdel(D) @@ -236,7 +236,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master", sleep(50) var/mob/living/carbon/true_devil/A = new /mob/living/carbon/true_devil(owner.current.loc) A.faction |= "hell" - owner.current.loc = A + owner.current.forceMove(A) A.oldform = owner.current owner.transfer_to(A) A.set_name() diff --git a/code/datums/diseases/parrotpossession.dm b/code/datums/diseases/parrotpossession.dm index 0df7e0f7d3..a5d87be980 100644 --- a/code/datums/diseases/parrotpossession.dm +++ b/code/datums/diseases/parrotpossession.dm @@ -22,6 +22,6 @@ /datum/disease/parrot_possession/cure() if(parrot && parrot.loc == affected_mob) - parrot.loc = affected_mob.loc + parrot.forceMove(affected_mob.drop_location()) affected_mob.visible_message("[parrot] is violently driven out of [affected_mob]!", "[parrot] bursts out of your chest!") ..() \ No newline at end of file diff --git a/code/datums/diseases/wizarditis.dm b/code/datums/diseases/wizarditis.dm index fbdb107c83..485a5ea2c4 100644 --- a/code/datums/diseases/wizarditis.dm +++ b/code/datums/diseases/wizarditis.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /datum/disease/wizarditis name = "Wizarditis" max_stages = 4 @@ -113,3 +114,120 @@ STI KALY - blind affected_mob.loc = pick(L) return +======= +/datum/disease/wizarditis + name = "Wizarditis" + max_stages = 4 + spread_text = "Airborne" + cure_text = "The Manly Dorf" + cures = list("manlydorf") + cure_chance = 100 + agent = "Rincewindus Vulgaris" + viable_mobtypes = list(/mob/living/carbon/human) + disease_flags = CAN_CARRY|CAN_RESIST|CURABLE + permeability_mod = 0.75 + desc = "Some speculate that this virus is the cause of the Space Wizard Federation's existence. Subjects affected show the signs of mental retardation, yelling obscure sentences or total gibberish. On late stages subjects sometime express the feelings of inner power, and, cite, 'the ability to control the forces of cosmos themselves!' A gulp of strong, manly spirits usually reverts them to normal, humanlike, condition." + severity = HARMFUL + required_organs = list(/obj/item/bodypart/head) + +/* +BIRUZ BENNAR +SCYAR NILA - teleport +NEC CANTIO - dis techno +EI NATH - shocking grasp +AULIE OXIN FIERA - knock +TARCOL MINTI ZHERI - forcewall +STI KALY - blind +*/ + +/datum/disease/wizarditis/stage_act() + ..() + + switch(stage) + if(2) + if(prob(1)&&prob(50)) + affected_mob.say(pick("You shall not pass!", "Expeliarmus!", "By Merlins beard!", "Feel the power of the Dark Side!")) + if(prob(1)&&prob(50)) + to_chat(affected_mob, "You feel [pick("that you don't have enough mana", "that the winds of magic are gone", "an urge to summon familiar")].") + + + if(3) + if(prob(1)&&prob(50)) + affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!", "STI KALY!", "TARCOL MINTI ZHERI!")) + if(prob(1)&&prob(50)) + to_chat(affected_mob, "You feel [pick("the magic bubbling in your veins","that this location gives you a +1 to INT","an urge to summon familiar")].") + + if(4) + + if(prob(1)) + affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!","STI KALY!","EI NATH!")) + return + if(prob(1)&&prob(50)) + to_chat(affected_mob, "You feel [pick("the tidal wave of raw power building inside","that this location gives you a +2 to INT and +1 to WIS","an urge to teleport")].") + spawn_wizard_clothes(50) + if(prob(1)&&prob(1)) + teleport() + return + + + +/datum/disease/wizarditis/proc/spawn_wizard_clothes(chance = 0) + if(ishuman(affected_mob)) + var/mob/living/carbon/human/H = affected_mob + if(prob(chance)) + if(!istype(H.head, /obj/item/clothing/head/wizard)) + if(!H.dropItemToGround(H.head)) + qdel(H.head) + H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(H), slot_head) + return + if(prob(chance)) + if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe)) + if(!H.dropItemToGround(H.wear_suit)) + qdel(H.wear_suit) + H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(H), slot_wear_suit) + return + if(prob(chance)) + if(!istype(H.shoes, /obj/item/clothing/shoes/sandal/magic)) + if(!H.dropItemToGround(H.shoes)) + qdel(H.shoes) + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(H), slot_shoes) + return + else + var/mob/living/carbon/H = affected_mob + if(prob(chance)) + var/obj/item/staff/S = new(H) + if(!H.put_in_hands(S)) + qdel(S) + + +/datum/disease/wizarditis/proc/teleport() + var/list/theareas = get_areas_in_range(80, affected_mob) + for(var/area/space/S in theareas) + theareas -= S + + if(!theareas||!theareas.len) + return + + var/area/thearea = pick(theareas) + + var/list/L = list() + for(var/turf/T in get_area_turfs(thearea.type)) + if(T.z != affected_mob.z) continue + if(T.name == "space") continue + if(!T.density) + var/clear = 1 + for(var/obj/O in T) + if(O.density) + clear = 0 + break + if(clear) + L+=T + + if(!L) + return + + affected_mob.say("SCYAR NILA [uppertext(thearea.name)]!") + affected_mob.forceMove(pick(L)) + + return +>>>>>>> 8b54685... Cleanup to various loc assignments and nearby code (#31069) diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm index 95267cf927..b51c020a03 100644 --- a/code/datums/wires/wires.dm +++ b/code/datums/wires/wires.dm @@ -134,6 +134,7 @@ /datum/wires/proc/pulse_color(color, mob/living/user) pulse(get_wire(color), user) +<<<<<<< HEAD /datum/wires/proc/pulse_assembly(obj/item/device/assembly/S) for(var/color in assemblies) @@ -177,6 +178,51 @@ /datum/wires/proc/on_cut(wire, mend = FALSE) return +======= + +/datum/wires/proc/pulse_assembly(obj/item/device/assembly/S) + for(var/color in assemblies) + if(S == assemblies[color]) + pulse_color(color) + return TRUE + +/datum/wires/proc/attach_assembly(color, obj/item/device/assembly/S) + if(S && istype(S) && S.attachable && !is_attached(color)) + assemblies[color] = S + S.forceMove(holder) + S.connected = src + return S + +/datum/wires/proc/detach_assembly(color) + var/obj/item/device/assembly/S = get_attached(color) + if(S && istype(S)) + assemblies -= color + S.connected = null + S.forceMove(holder.drop_location()) + return S + +/datum/wires/proc/emp_pulse() + var/list/possible_wires = shuffle(wires) + var/remaining_pulses = MAXIMUM_EMP_WIRES + + for(var/wire in possible_wires) + if(prob(33)) + pulse(wire) + remaining_pulses-- + if(remaining_pulses >= 0) + break + +// Overridable Procs +/datum/wires/proc/interactable(mob/user) + return TRUE + +/datum/wires/proc/get_status() + return list() + +/datum/wires/proc/on_cut(wire, mend = FALSE) + return + +>>>>>>> 8b54685... Cleanup to various loc assignments and nearby code (#31069) /datum/wires/proc/on_pulse(wire, user) return // End Overridable Procs diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm index 36a23b2bd1..ddb87e20f6 100644 --- a/code/game/gamemodes/blob/blob.dm +++ b/code/game/gamemodes/blob/blob.dm @@ -78,7 +78,7 @@ GLOBAL_LIST_EMPTY(blobs_legit) //used for win-score calculations, contains only var/mob/camera/blob/B = blob.current.become_overmind(TRUE, round(blob_base_starting_points/blob_overminds.len)) B.mind.name = B.name var/turf/T = pick(GLOB.blobstart) - B.loc = T + B.forceMove(T) B.base_point_rate = blob_point_rate SSshuttle.registerHostileEnvironment(src) diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index 026183d951..865a58fd81 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -59,7 +59,7 @@ set name = "Jump to Core" set desc = "Move your camera to your core." if(blob_core) - src.loc = blob_core.loc + forceMove(blob_core.drop_location()) /mob/camera/blob/verb/jump_to_node() set category = "Blob" diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index 8443f3d6f1..183ec88b23 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -190,7 +190,7 @@ B.density = TRUE if(T.Enter(B,src)) //NOW we can attempt to move into the tile B.density = initial(B.density) - B.loc = T + B.forceMove(T) B.update_icon() if(B.overmind && expand_reaction) B.overmind.blob_reagent_datum.expand_reaction(src, B, T, controller) diff --git a/code/game/gamemodes/changeling/powers/headcrab.dm b/code/game/gamemodes/changeling/powers/headcrab.dm index 94d83e2520..e7f23bc07b 100644 --- a/code/game/gamemodes/changeling/powers/headcrab.dm +++ b/code/game/gamemodes/changeling/powers/headcrab.dm @@ -30,7 +30,7 @@ sleep(5) // So it's not killed in explosion var/mob/living/simple_animal/hostile/headcrab/crab = new(turf) for(var/obj/item/organ/I in organs) - I.loc = crab + I.forceMove(crab) crab.origin = M if(crab.origin) crab.origin.active = 1 diff --git a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm index 88bb84fc4a..2b012e5f81 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/dispenser.dm @@ -60,9 +60,8 @@ /obj/machinery/abductor/gland_dispenser/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/organ/heart/gland)) - if(!user.drop_item()) + if(!user.transferItemToLoc(W, src)) return - W.loc = src for(var/i=1,i<=gland_colors.len,i++) if(gland_types[i] == W.type) amounts[i]++ diff --git a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm index 8979fb8c78..d919d5d277 100644 --- a/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm +++ b/code/game/gamemodes/miniantags/bot_swarm/swarmer.dm @@ -502,7 +502,7 @@ var/obj/item/stack/sheet/metal/M = new /obj/item/stack/sheet/metal(target.loc) M.amount = 5 for(var/obj/item/I in target.component_parts) - I.loc = M.loc + I.forceMove(M.drop_location()) var/obj/effect/temp_visual/swarmer/disintegration/N = new /obj/effect/temp_visual/swarmer/disintegration(get_turf(target)) N.pixel_x = target.pixel_x N.pixel_y = target.pixel_y @@ -511,7 +511,7 @@ if(istype(target, /obj/machinery/computer)) var/obj/machinery/computer/C = target if(C.circuit) - C.circuit.loc = M.loc + C.circuit.forceMove(M.drop_location()) qdel(target) diff --git a/code/game/gamemodes/miniantags/morph/morph.dm b/code/game/gamemodes/miniantags/morph/morph.dm index f763f742f7..5e1a97675b 100644 --- a/code/game/gamemodes/miniantags/morph/morph.dm +++ b/code/game/gamemodes/miniantags/morph/morph.dm @@ -77,7 +77,7 @@ /mob/living/simple_animal/hostile/morph/proc/eat(atom/movable/A) if(A && A.loc != src) visible_message("[src] swallows [A] whole!") - A.loc = src + A.forceMove(src) return 1 return 0 @@ -153,7 +153,7 @@ /mob/living/simple_animal/hostile/morph/proc/barf_contents() for(var/atom/movable/AM in src) - AM.loc = loc + AM.forceMove(loc) if(prob(90)) step(AM, pick(GLOB.alldirs)) diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm index acf55e4036..2179177fc1 100644 --- a/code/game/gamemodes/nuclear/nuclear.dm +++ b/code/game/gamemodes/nuclear/nuclear.dm @@ -110,7 +110,7 @@ P.info = "The nuclear authorization code is: [nuke_code]" P.name = "nuclear bomb code" var/mob/living/carbon/human/H = synd_mind.current - P.loc = H.loc + P.forceMove(H.drop_location()) H.put_in_hands_or_del(P) H.update_icons() else diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm index 7a17d54b4c..9d51ff7b36 100644 --- a/code/game/gamemodes/sandbox/h_sandbox.dm +++ b/code/game/gamemodes/sandbox/h_sandbox.dm @@ -30,6 +30,7 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE) /obj/item/assembly, /obj/item/device/onetankbomb, /obj/item/radio, /obj/item/device/pda/ai, /obj/item/device/uplink, /obj/item/smallDelivery, /obj/item/projectile, /obj/item/borg/sight, /obj/item/borg/stun, /obj/item/robot_module) +<<<<<<< HEAD /datum/hSB/proc/update() var/global/list/hrefs = list( @@ -301,3 +302,276 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE) if(config.sandbox_autoclose) usr << browse(null,"window=sandbox") +======= + +/datum/hSB/proc/update() + var/global/list/hrefs = list( + "Space Gear", + "Suit Up (Space Travel Gear)" = "hsbsuit", + "Spawn Gas Mask" = "hsbspawn&path=[/obj/item/clothing/mask/gas]", + "Spawn Emergency Air Tank" = "hsbspawn&path=[/obj/item/tank/internals/emergency_oxygen/double]", + + "Standard Tools", + "Spawn Flashlight" = "hsbspawn&path=[/obj/item/device/flashlight]", + "Spawn Toolbox" = "hsbspawn&path=[/obj/item/storage/toolbox/mechanical]", + "Spawn Light Replacer" = "hsbspawn&path=[/obj/item/device/lightreplacer]", + "Spawn Medical Kit" = "hsbspawn&path=[/obj/item/storage/firstaid/regular]", + "Spawn All-Access ID" = "hsbaaid", + + "Building Supplies", + "Spawn 50 Wood" = "hsbwood", + "Spawn 50 Metal" = "hsbmetal", + "Spawn 50 Plasteel" = "hsbplasteel", + "Spawn 50 Reinforced Glass" = "hsbrglass", + "Spawn 50 Glass" = "hsbglass", + "Spawn Full Cable Coil" = "hsbspawn&path=[/obj/item/stack/cable_coil]", + "Spawn Hyper Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/hyper]", + "Spawn Inf. Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/infinite]", + "Spawn Rapid Construction Device" = "hsbrcd", + "Spawn RCD Ammo" = "hsb_safespawn&path=[/obj/item/rcd_ammo]", + "Spawn Airlock" = "hsbairlock", + + "Miscellaneous", + "Spawn Air Scrubber" = "hsbscrubber", + "Spawn Welding Fuel Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/fueltank]", + "Spawn Water Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/watertank]", + + "Bots", + "Spawn Cleanbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/cleanbot]", + "Spawn Floorbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/floorbot]", + "Spawn Medbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/medbot]", + + "Canisters", + "Spawn O2 Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/oxygen]", + "Spawn Air Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/air]") + + + if(!hsbinfo) + hsbinfo = "
    Sandbox Panel

    " + if(admin) + hsbinfo += "Administration
    " + hsbinfo += "- Toggle Object Spawning
    " + hsbinfo += "- Toggle Item Spawn Panel Auto-close
    " + hsbinfo += "Canister Spawning
    " + hsbinfo += "- Spawn Plasma Canister
    " + hsbinfo += "- Spawn CO2 Canister
    " + hsbinfo += "- Spawn Nitrogen Canister
    " + hsbinfo += "- Spawn N2O Canister
    " + else + hsbinfo += "Some item spawning may be disabled by the administrators.
    " + hsbinfo += "Only administrators may spawn dangerous canisters.
    " + for(var/T in hrefs) + var/href = hrefs[T] + if(href) + hsbinfo += "- [T]
    " + else + hsbinfo += "
    [T]
    " + hsbinfo += "
    " + hsbinfo += "- Spawn Clothing...
    " + hsbinfo += "- Spawn Reagent Container...
    " + hsbinfo += "- Spawn Other Item...

    " + + usr << browse(hsbinfo, "window=hsbpanel") + +/datum/hSB/Topic(href, href_list) + if(!usr || !src || !(src.owner == usr.ckey)) + if(usr) + usr << browse(null,"window=sandbox") + return + + if(href_list["hsb"]) + switch(href_list["hsb"]) + // + // Admin: toggle spawning + // + if("hsbtobj") + if(!admin) return + if(GLOB.hsboxspawn) + to_chat(world, "Sandbox: \black[usr.key] has disabled object spawning!") + GLOB.hsboxspawn = FALSE + return + else + to_chat(world, "Sandbox: \black[usr.key] has enabled object spawning!") + GLOB.hsboxspawn = TRUE + return + // + // Admin: Toggle auto-close + // + if("hsbtac") + if(!admin) return + var/sbac = CONFIG_GET(flag/sandbox_autoclose) + if(sbac) + to_chat(world, "Sandbox: \black [usr.key] has removed the object spawn limiter.") + else + to_chat(world, "Sandbox: \black [usr.key] has added a limiter to object spawning. The window will now auto-close after use.") + CONFIG_SET(flag/sandbox_autoclose, !sbac) + return + // + // Spacesuit with full air jetpack set as internals + // + if("hsbsuit") + var/mob/living/carbon/human/P = usr + if(!istype(P)) return + if(P.wear_suit) + P.wear_suit.forceMove(P.drop_location()) + P.wear_suit.layer = initial(P.wear_suit.layer) + P.wear_suit.plane = initial(P.wear_suit.plane) + P.wear_suit = null + P.wear_suit = new/obj/item/clothing/suit/space(P) + P.wear_suit.layer = ABOVE_HUD_LAYER + P.wear_suit.plane = ABOVE_HUD_PLANE + P.update_inv_wear_suit() + if(P.head) + P.head.forceMove(P.drop_location()) + P.head.layer = initial(P.head.layer) + P.head.plane = initial(P.head.plane) + P.head = null + P.head = new/obj/item/clothing/head/helmet/space(P) + P.head.layer = ABOVE_HUD_LAYER + P.head.plane = ABOVE_HUD_PLANE + P.update_inv_head() + if(P.wear_mask) + P.wear_mask.forceMove(P.drop_location()) + P.wear_mask.layer = initial(P.wear_mask.layer) + P.wear_mask.plane = initial(P.wear_mask.plane) + P.wear_mask = null + P.wear_mask = new/obj/item/clothing/mask/gas(P) + P.wear_mask.layer = ABOVE_HUD_LAYER + P.wear_mask.plane = ABOVE_HUD_PLANE + P.update_inv_wear_mask() + if(P.back) + P.back.forceMove(P.drop_location()) + P.back.layer = initial(P.back.layer) + P.back.plane = initial(P.back.plane) + P.back = null + P.back = new/obj/item/tank/jetpack/oxygen(P) + P.back.layer = ABOVE_HUD_LAYER + P.back.plane = ABOVE_HUD_PLANE + P.update_inv_back() + P.internal = P.back + P.update_internals_hud_icon(1) + + if("hsbscrubber") // This is beyond its normal capability but this is sandbox and you spawned one, I assume you need it + var/obj/hsb = new/obj/machinery/portable_atmospherics/scrubber{volume_rate=50*ONE_ATMOSPHERE;on=1}(usr.loc) + hsb.update_icon() // hackish but it wasn't meant to be spawned I guess? + + // + // Stacked Materials + // + + if("hsbrglass") + new/obj/item/stack/sheet/rglass{amount=50}(usr.loc) + + if("hsbmetal") + new/obj/item/stack/sheet/metal{amount=50}(usr.loc) + + if("hsbplasteel") + new/obj/item/stack/sheet/plasteel{amount=50}(usr.loc) + + if("hsbglass") + new/obj/item/stack/sheet/glass{amount=50}(usr.loc) + + if("hsbwood") + new/obj/item/stack/sheet/mineral/wood{amount=50}(usr.loc) + + // + // All access ID + // + if("hsbaaid") + var/obj/item/card/id/gold/ID = new(usr.loc) + ID.registered_name = usr.real_name + ID.assignment = "Sandbox" + ID.access = get_all_accesses() + ID.update_label() + + // + // RCD - starts with full clip + // Spawn check due to grief potential (destroying floors, walls, etc) + // + if("hsbrcd") + if(!GLOB.hsboxspawn) return + + new/obj/item/construction/rcd/combat(usr.loc) + + // + // New sandbox airlock maker + // + if("hsbairlock") + new /datum/airlock_maker(usr.loc) + + // + // Object spawn window + // + + // Clothing + if("hsbcloth") + if(!GLOB.hsboxspawn) return + + if(!clothinfo) + clothinfo = "Clothing (Reagent Containers) (Other Items)

    " + var/list/all_items = subtypesof(/obj/item/clothing) + for(var/typekey in spawn_forbidden) + all_items -= typesof(typekey) + for(var/O in reverseRange(all_items)) + clothinfo += "[O]
    " + + usr << browse(clothinfo,"window=sandbox") + + // Reagent containers + if("hsbreag") + if(!GLOB.hsboxspawn) return + + if(!reaginfo) + reaginfo = "Reagent Containers (Clothing) (Other Items)

    " + var/list/all_items = subtypesof(/obj/item/reagent_containers) + for(var/typekey in spawn_forbidden) + all_items -= typesof(typekey) + for(var/O in reverseRange(all_items)) + reaginfo += "[O]
    " + + usr << browse(reaginfo,"window=sandbox") + + // Other items + if("hsbobj") + if(!GLOB.hsboxspawn) return + + if(!objinfo) + objinfo = "Other Items (Clothing) (Reagent Containers)

    " + var/list/all_items = subtypesof(/obj/item/) - typesof(/obj/item/clothing) - typesof(/obj/item/reagent_containers) + for(var/typekey in spawn_forbidden) + all_items -= typesof(typekey) + + for(var/O in reverseRange(all_items)) + objinfo += "[O]
    " + + usr << browse(objinfo,"window=sandbox") + + // + // Safespawn checks to see if spawning is disabled. + // + if("hsb_safespawn") + if(!GLOB.hsboxspawn) + usr << browse(null,"window=sandbox") + return + + var/typepath = text2path(href_list["path"]) + if(!typepath) + to_chat(usr, "Bad path: \"[href_list["path"]]\"") + return + new typepath(usr.loc) + + if(CONFIG_GET(flag/sandbox_autoclose)) + usr << browse(null,"window=sandbox") + // + // For everything else in the href list + // + if("hsbspawn") + var/typepath = text2path(href_list["path"]) + if(!typepath) + to_chat(usr, "Bad path: \"[href_list["path"]]\"") + return + new typepath(usr.loc) + + if(CONFIG_GET(flag/sandbox_autoclose)) + usr << browse(null,"window=sandbox") +>>>>>>> 8b54685... Cleanup to various loc assignments and nearby code (#31069) diff --git a/code/game/gamemodes/wizard/artefact.dm b/code/game/gamemodes/wizard/artefact.dm index f4847e30a7..42d676c29b 100644 --- a/code/game/gamemodes/wizard/artefact.dm +++ b/code/game/gamemodes/wizard/artefact.dm @@ -234,11 +234,10 @@ if(!link) if(I.loc == user && istype(I) && I.w_class <= WEIGHT_CLASS_SMALL) - user.drop_item() - I.loc = src - link = I - to_chat(user, "You attach [I] to the doll.") - update_targets() + if (user.transferItemToLoc(I,src)) + link = I + to_chat(user, "You attach [I] to the doll.") + update_targets() /obj/item/voodoo/check_eye(mob/user) if(loc != user) diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index aae0261320..df57ded774 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -164,7 +164,7 @@ if(contents.len) to_chat(user, "Capture failed!: The soulstone is full! Free an existing soul to make room.") else - T.loc = src //put shade in stone + T.forceMove(src) //put shade in stone T.status_flags |= GODMODE T.canmove = 0 T.health = T.maxHealth diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index eea7afcb4b..69528b686c 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -30,7 +30,7 @@ to_chat(wizard.current, "A starting location for you could not be found, please report this bug!") return 0 for(var/datum/mind/wiz in wizards) - wiz.current.loc = pick(GLOB.wizardstart) + wiz.current.forceMove(pick(GLOB.wizardstart)) return 1 diff --git a/code/game/machinery/Beacon.dm b/code/game/machinery/Beacon.dm index 80400fee05..48eafce3c5 100644 --- a/code/game/machinery/Beacon.dm +++ b/code/game/machinery/Beacon.dm @@ -44,10 +44,10 @@ var/turf/T = loc Beacon = new /obj/item/device/radio/beacon Beacon.invisibility = INVISIBILITY_MAXIMUM - Beacon.loc = T + Beacon.forceMove(T) if(Beacon) if(Beacon.loc != loc) - Beacon.loc = loc + Beacon.forceMove(loc) updateicon() diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index b070de1b1c..054bf07f70 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -429,7 +429,7 @@ Class Procs: W.handle_item_insertion(A, 1) component_parts -= A component_parts += B - B.loc = null + B.moveToNullspace() to_chat(user, "[A.name] replaced with [B.name].") shouldplaysound = 1 //Only play the sound when parts are actually replaced! break diff --git a/code/game/machinery/bank_machine.dm b/code/game/machinery/bank_machine.dm index de07fc9c2d..9d446aa77c 100644 --- a/code/game/machinery/bank_machine.dm +++ b/code/game/machinery/bank_machine.dm @@ -43,7 +43,7 @@ say("Station funds depleted. Halting siphon.") siphoning = FALSE else - new /obj/item/stack/spacecash/c200(get_turf(src)) // will autostack + new /obj/item/stack/spacecash/c200(drop_location()) // will autostack playsound(src.loc, 'sound/items/poster_being_created.ogg', 100, 1) SSshuttle.points -= 200 if(next_warning < world.time && prob(15)) diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 7c1904d2fe..8a118b8d08 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -127,10 +127,10 @@ if(panel_open) if(device || board) if(device) - device.loc = get_turf(src) + device.forceMove(drop_location()) device = null if(board) - board.loc = get_turf(src) + board.forceMove(drop_location()) req_access = list() req_one_access = list() board = null diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index d7832622c5..7d3c40a0d9 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -246,7 +246,7 @@ if(disassembled) if(!assembly) assembly = new() - assembly.loc = src.loc + assembly.forceMove(drop_location()) assembly.state = 1 assembly.setDir(dir) assembly = null diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index 340277b441..b5343aa3ad 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -80,6 +80,7 @@ playsound(src.loc, W.usesound, 50, 1) var/input = stripped_input(user, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13") +<<<<<<< HEAD if(!input) to_chat(user, "No input found, please hang up and try your call again!") return @@ -140,6 +141,68 @@ return 0 /obj/structure/camera_assembly/deconstruct(disassembled = TRUE) +======= + if(!input) + to_chat(user, "No input found, please hang up and try your call again!") + return + + var/list/tempnetwork = splittext(input, ",") + if(tempnetwork.len < 1) + to_chat(user, "No network found, please hang up and try your call again!") + return + + state = 4 + var/obj/machinery/camera/C = new(src.loc) + forceMove(C) + C.assembly = src + C.setDir(src.dir) + + C.network = tempnetwork + var/area/A = get_area(src) + C.c_tag = "[A.name] ([rand(1, 999)])" + + + else if(istype(W, /obj/item/wirecutters)) + new/obj/item/stack/cable_coil(get_turf(src), 2) + playsound(src.loc, W.usesound, 50, 1) + to_chat(user, "You cut the wires from the circuits.") + state = 2 + return + + // Upgrades! + if(is_type_in_typecache(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already. + if(!user.drop_item(W)) + return + to_chat(user, "You attach \the [W] into the assembly inner circuits.") + upgrades += W + W.forceMove(src) + return + + // Taking out upgrades + else if(istype(W, /obj/item/crowbar) && upgrades.len) + var/obj/U = locate(/obj) in upgrades + if(U) + to_chat(user, "You unattach an upgrade from the assembly.") + playsound(src.loc, W.usesound, 50, 1) + U.forceMove(drop_location()) + upgrades -= U + return + + return ..() + +/obj/structure/camera_assembly/proc/weld(obj/item/weldingtool/WT, mob/living/user) + if(!WT.remove_fuel(0, user)) + return 0 + to_chat(user, "You start to weld \the [src]...") + playsound(src.loc, WT.usesound, 50, 1) + if(do_after(user, 20*WT.toolspeed, target = src)) + if(WT.isOn()) + playsound(loc, 'sound/items/welder2.ogg', 50, 1) + return 1 + return 0 + +/obj/structure/camera_assembly/deconstruct(disassembled = TRUE) +>>>>>>> 8b54685... Cleanup to various loc assignments and nearby code (#31069) if(!(flags_1 & NODECONSTRUCT_1)) new /obj/item/stack/sheet/metal(loc) qdel(src) diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index 3f95d2a780..63c63ce120 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -45,14 +45,13 @@ if(!isarea(a)) return if(a.power_equip == 0) // There's no APC in this area, don't try to cheat power! - to_chat(user, "The [name] blinks red as you try to insert the cell!") + to_chat(user, "The [src] blinks red as you try to insert the cell!") return - if(!user.drop_item()) + if(!user.transferItemToLoc(W,src)) return - W.loc = src charging = W - user.visible_message("[user] inserts a cell into the charger.", "You insert a cell into the charger.") + user.visible_message("[user] inserts a cell into [src].", "You insert a cell into [src].") chargelevel = -1 updateicon() else if(istype(W, /obj/item/wrench)) @@ -61,7 +60,7 @@ return anchored = !anchored - to_chat(user, "You [anchored ? "attach" : "detach"] the cell charger [anchored ? "to" : "from"] the ground") + to_chat(user, "You [anchored ? "attach" : "detach"] [src] [anchored ? "to" : "from"] the ground") playsound(src.loc, W.usesound, 75, 1) else return ..() @@ -80,7 +79,7 @@ user.put_in_hands(charging) charging.add_fingerprint(user) - user.visible_message("[user] removes the cell from the charger.", "You remove the cell from the charger.") + user.visible_message("[user] removes [charging] from [src].", "You remove [charging] from [src].") removecell() diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index d9371d5678..485d56ced2 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /obj/machinery/computer/aifixer name = "\improper AI system integrity restorer" desc = "Used with intelliCards containing nonfunctioning AIs to restore them to working order." @@ -144,3 +145,151 @@ to_chat(user, "ERROR: Reconstruction in progress.") else if (!occupier) to_chat(user, "ERROR: Unable to locate artificial intelligence.") +======= +/obj/machinery/computer/aifixer + name = "\improper AI system integrity restorer" + desc = "Used with intelliCards containing nonfunctioning AIs to restore them to working order." + req_access = list(ACCESS_CAPTAIN, ACCESS_ROBOTICS, ACCESS_HEADS) + var/mob/living/silicon/ai/occupier = null + var/active = 0 + circuit = /obj/item/circuitboard/computer/aifixer + icon_keyboard = "tech_key" + icon_screen = "ai-fixer" + light_color = LIGHT_COLOR_PINK + +/obj/machinery/computer/aifixer/attackby(obj/I, mob/user, params) + if(occupier && istype(I, /obj/item/screwdriver)) + if(stat & (NOPOWER|BROKEN)) + to_chat(user, "The screws on [name]'s screen won't budge.") + else + to_chat(user, "The screws on [name]'s screen won't budge and it emits a warning beep.") + else + return ..() + +/obj/machinery/computer/aifixer/attack_hand(mob/user) + if(..()) + return + interact(user) + +/obj/machinery/computer/aifixer/interact(mob/user) + + var/dat = "" + + if (src.occupier) + var/laws + dat += "

    Stored AI: [src.occupier.name]

    " + dat += "System integrity: [(src.occupier.health+100)/2]%
    " + + if (src.occupier.laws.zeroth) + laws += "0: [src.occupier.laws.zeroth]
    " + + for (var/index = 1, index <= src.occupier.laws.ion.len, index++) + var/law = src.occupier.laws.ion[index] + if (length(law) > 0) + var/num = ionnum() + laws += "[num]: [law]
    " + + var/number = 1 + for (var/index = 1, index <= src.occupier.laws.inherent.len, index++) + var/law = src.occupier.laws.inherent[index] + if (length(law) > 0) + laws += "[number]: [law]
    " + number++ + + for (var/index = 1, index <= src.occupier.laws.supplied.len, index++) + var/law = src.occupier.laws.supplied[index] + if (length(law) > 0) + laws += "[number]: [law]
    " + number++ + + dat += "Laws:
    [laws]
    " + + if (src.occupier.stat == DEAD) + dat += "AI non-functional" + else + dat += "AI functional" + if (!src.active) + dat += {"

    Begin Reconstruction"} + else + dat += "

    Reconstruction in process, please wait.
    " + dat += {"
    Close"} + var/datum/browser/popup = new(user, "computer", "AI System Integrity Restorer", 400, 500) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + return + +/obj/machinery/computer/aifixer/proc/Fix() + use_power(1000) + occupier.adjustOxyLoss(-1, 0) + occupier.adjustFireLoss(-1, 0) + occupier.adjustToxLoss(-1, 0) + occupier.adjustBruteLoss(-1, 0) + occupier.updatehealth() + occupier.updatehealth() + if(occupier.health >= 0 && occupier.stat == DEAD) + occupier.revive() + return occupier.health < 100 + +/obj/machinery/computer/aifixer/process() + if(..()) + if(active) + active = Fix() + updateDialog() + update_icon() + +/obj/machinery/computer/aifixer/Topic(href, href_list) + if(..()) + return + if(href_list["fix"]) + to_chat(usr, "Reconstruction in progress. This will take several minutes.") + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0) + active = TRUE + add_fingerprint(usr) + +/obj/machinery/computer/aifixer/update_icon() + ..() + if(stat & (NOPOWER|BROKEN)) + return + else + if(active) + add_overlay("ai-fixer-on") + if (occupier) + switch (occupier.stat) + if (0) + add_overlay("ai-fixer-full") + if (2) + add_overlay("ai-fixer-404") + else + add_overlay("ai-fixer-empty") + +/obj/machinery/computer/aifixer/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/device/aicard/card) + if(!..()) + return + //Downloading AI from card to terminal. + if(interaction == AI_TRANS_FROM_CARD) + if(stat & (NOPOWER|BROKEN)) + to_chat(user, "[src] is offline and cannot take an AI at this time!") + return + AI.forceMove(src) + occupier = AI + AI.control_disabled = 1 + AI.radio_enabled = 0 + to_chat(AI, "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here.") + to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.") + card.AI = null + update_icon() + + else //Uploading AI from terminal to card + if(occupier && !active) + to_chat(occupier, "You have been downloaded to a mobile storage device. Still no remote access.") + to_chat(user, "Transfer successful: [occupier.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory.") + occupier.forceMove(card) + card.AI = occupier + occupier = null + update_icon() + else if (active) + to_chat(user, "ERROR: Reconstruction in progress.") + else if (!occupier) + to_chat(user, "ERROR: Unable to locate artificial intelligence.") +>>>>>>> 8b54685... Cleanup to various loc assignments and nearby code (#31069) diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index db2bfedd7c..209bf5e47f 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -19,7 +19,7 @@ var/obj/item/weldingtool/WT = P if(!WT.remove_fuel(0, user)) if(!WT.isOn()) - to_chat(user, "The welding tool must be on to complete this task!") + to_chat(user, "[WT] must be on to complete this task!") return playsound(src.loc, P.usesound, 50, 1) to_chat(user, "You start deconstructing the frame...") @@ -40,14 +40,13 @@ state = 0 return if(istype(P, /obj/item/circuitboard/computer) && !circuit) - if(!user.drop_item()) + if(!user.transferItemToLoc(P, null)) return playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) - to_chat(user, "You place the circuit board inside the frame.") + to_chat(user, "You place [P] inside the frame.") icon_state = "1" circuit = P circuit.add_fingerprint(user) - P.loc = null return else if(istype(P, /obj/item/circuitboard) && !circuit) @@ -55,16 +54,16 @@ return if(istype(P, /obj/item/screwdriver) && circuit) playsound(src.loc, P.usesound, 50, 1) - to_chat(user, "You screw the circuit board into place.") + to_chat(user, "You screw [circuit] into place.") state = 2 icon_state = "2" return if(istype(P, /obj/item/crowbar) && circuit) playsound(src.loc, P.usesound, 50, 1) - to_chat(user, "You remove the circuit board.") + to_chat(user, "You remove [circuit].") state = 1 icon_state = "0" - circuit.loc = src.loc + circuit.forceMove(drop_location()) circuit.add_fingerprint(user) circuit = null return diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index 0548d94f3d..8a54bf3d86 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -54,22 +54,19 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) var/obj/item/card/id/idcard = O if(check_access(idcard)) if(!scan) - if(!usr.drop_item()) + if (!user.transferItemToLoc(idcard,src)) return - idcard.loc = src scan = idcard playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) else if(!modify) - if(!usr.drop_item()) + if (!user.transferItemToLoc(idcard,src)) return - idcard.loc = src modify = idcard playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) else if(!modify) - if(!usr.drop_item()) + if (!user.transferItemToLoc(idcard,src)) return - idcard.loc = src modify = idcard playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) else @@ -95,10 +92,10 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) /obj/machinery/computer/card/on_deconstruction() if(scan) - scan.forceMove(loc) + scan.forceMove(drop_location()) scan = null if(modify) - modify.forceMove(loc) + modify.forceMove(drop_location()) modify = null //Check if you can't open a new position for a certain job @@ -355,7 +352,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) if (modify) GLOB.data_core.manifest_modify(modify.registered_name, modify.assignment) modify.update_label() - modify.loc = loc + modify.forceMove(drop_location()) modify.verb_pickup() playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) modify = null @@ -364,26 +361,24 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0) else var/obj/item/I = usr.get_active_held_item() if (istype(I, /obj/item/card/id)) - if(!usr.drop_item()) + if (!usr.transferItemToLoc(I,src)) return playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) - I.loc = src modify = I authenticated = 0 if ("scan") if (scan) - scan.loc = src.loc + scan.forceMove(drop_location()) scan.verb_pickup() playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) scan = null else var/obj/item/I = usr.get_active_held_item() if (istype(I, /obj/item/card/id)) - if(!usr.drop_item()) + if (!usr.transferItemToLoc(I,src)) return playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) - I.loc = src scan = I authenticated = 0 if ("auth") diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index ab7a639818..755a030565 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -21,6 +21,7 @@ /obj/machinery/computer/cloning/Initialize() . = ..() +<<<<<<< HEAD updatemodules(TRUE) /obj/machinery/computer/cloning/Destroy() @@ -124,6 +125,110 @@ to_chat(user, "You insert [W].") playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) src.updateUsrDialog() +======= + updatemodules(TRUE) + +/obj/machinery/computer/cloning/Destroy() + if(pods) + for(var/P in pods) + DetachCloner(P) + pods = null + return ..() + +/obj/machinery/computer/cloning/proc/GetAvailablePod(mind = null) + if(pods) + for(var/P in pods) + var/obj/machinery/clonepod/pod = P + if(pod.occupant && pod.clonemind == mind) + return null + if(pod.is_operational() && !(pod.occupant || pod.mess)) + return pod + +/obj/machinery/computer/cloning/proc/HasEfficientPod() + if(pods) + for(var/P in pods) + var/obj/machinery/clonepod/pod = P + if(pod.is_operational() && pod.efficiency > 5) + return TRUE + +/obj/machinery/computer/cloning/proc/GetAvailableEfficientPod(mind = null) + if(pods) + for(var/P in pods) + var/obj/machinery/clonepod/pod = P + if(pod.occupant && pod.clonemind == mind) + return pod + else if(!. && pod.is_operational() && !(pod.occupant || pod.mess) && pod.efficiency > 5) + . = pod + +/obj/machinery/computer/cloning/process() + if(!(scanner && LAZYLEN(pods) && autoprocess)) + return + + if(scanner.occupant && scanner.scan_level > 2) + scan_occupant(scanner.occupant) + + for(var/datum/data/record/R in records) + var/obj/machinery/clonepod/pod = GetAvailableEfficientPod(R.fields["mind"]) + + if(!pod) + return + + if(pod.occupant) + continue //how though? + + if(pod.growclone(R.fields["ckey"], R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mind"], R.fields["mrace"], R.fields["features"], R.fields["factions"])) + records -= R + +/obj/machinery/computer/cloning/proc/updatemodules(findfirstcloner) + src.scanner = findscanner() + if(findfirstcloner && !LAZYLEN(pods)) + findcloner() + +/obj/machinery/computer/cloning/proc/findscanner() + var/obj/machinery/dna_scannernew/scannerf = null + + // Loop through every direction + for(dir in list(NORTH,EAST,SOUTH,WEST)) + + // Try to find a scanner in that direction + scannerf = locate(/obj/machinery/dna_scannernew, get_step(src, dir)) + + // If found and operational, return the scanner + if (!isnull(scannerf) && scannerf.is_operational()) + return scannerf + + // If no scanner was found, it will return null + return null + +/obj/machinery/computer/cloning/proc/findcloner() + var/obj/machinery/clonepod/podf = null + + for(dir in list(NORTH,EAST,SOUTH,WEST)) + + podf = locate(/obj/machinery/clonepod, get_step(src, dir)) + + if (!isnull(podf) && podf.is_operational()) + AttachCloner(podf) + +/obj/machinery/computer/cloning/proc/AttachCloner(obj/machinery/clonepod/pod) + if(!pod.connected) + pod.connected = src + LAZYADD(pods, pod) + +/obj/machinery/computer/cloning/proc/DetachCloner(obj/machinery/clonepod/pod) + pod.connected = null + LAZYREMOVE(pods, pod) + +/obj/machinery/computer/cloning/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/disk/data)) //INSERT SOME DISKETTES + if (!src.diskette) + if (!user.transferItemToLoc(W,src)) + return + src.diskette = W + to_chat(user, "You insert [W].") + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) + src.updateUsrDialog() +>>>>>>> 8b54685... Cleanup to various loc assignments and nearby code (#31069) else if(istype(W, /obj/item/device/multitool)) var/obj/item/device/multitool/P = W @@ -315,6 +420,7 @@ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) else scanner.locked = FALSE +<<<<<<< HEAD playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) else if(href_list["view_rec"]) @@ -500,3 +606,190 @@ src.records += R scantemp = "Subject successfully scanned." playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) +======= + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + + else if(href_list["view_rec"]) + playsound(src, "terminal_type", 25, 0) + src.active_record = find_record("id", href_list["view_rec"], records) + if(active_record) + if(!active_record.fields["ckey"]) + records -= active_record + active_record = null + src.temp = "Record Corrupt" + else + src.menu = 3 + else + src.temp = "Record missing." + + else if (href_list["del_rec"]) + if ((!src.active_record) || (src.menu < 3)) + return + if (src.menu == 3) //If we are viewing a record, confirm deletion + src.temp = "Delete record?" + src.menu = 4 + playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) + + else if (src.menu == 4) + var/obj/item/card/id/C = usr.get_active_held_item() + if (istype(C)||istype(C, /obj/item/device/pda)) + if(src.check_access(C)) + src.temp = "[src.active_record.fields["name"]] => Record deleted." + src.records.Remove(active_record) + active_record = null + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + src.menu = 2 + else + src.temp = "Access Denied." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + + else if (href_list["disk"]) //Load or eject. + switch(href_list["disk"]) + if("load") + if (!diskette || !istype(diskette.fields) || !diskette.fields["name"] || !diskette.fields) + src.temp = "Load error." + src.updateUsrDialog() + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + if (!src.active_record) + src.temp = "Record error." + src.menu = 1 + src.updateUsrDialog() + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + + for(var/key in diskette.fields) + src.active_record.fields[key] = diskette.fields[key] + src.temp = "Load successful." + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + + if("eject") + if(src.diskette) + src.diskette.forceMove(drop_location()) + src.diskette = null + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) + if("save") + if(!diskette || diskette.read_only || !active_record || !active_record.fields) + src.temp = "Save error." + src.updateUsrDialog() + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + + diskette.fields = active_record.fields.Copy() + diskette.name = "data disk - '[src.diskette.fields["name"]]'" + src.temp = "Save successful." + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + + else if (href_list["refresh"]) + src.updateUsrDialog() + playsound(src, "terminal_type", 25, 0) + + else if (href_list["clone"]) + var/datum/data/record/C = find_record("id", href_list["clone"], records) + //Look for that player! They better be dead! + if(C) + var/obj/machinery/clonepod/pod = GetAvailablePod() + //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs. + if(!LAZYLEN(pods)) + temp = "No Clonepods detected." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else if(!pod) + temp = "No Clonepods available." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else if(!CONFIG_GET(flag/revival_cloning)) + temp = "Unable to initiate cloning cycle." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else if(pod.occupant) + temp = "Cloning cycle already in progress." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["mrace"], C.fields["features"], C.fields["factions"])) + temp = "[C.fields["name"]] => Cloning cycle in progress..." + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + records.Remove(C) + if(active_record == C) + active_record = null + menu = 1 + else + temp = "[C.fields["name"]] => Initialisation failure." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + + else + temp = "Data corruption." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + + else if (href_list["menu"]) + src.menu = text2num(href_list["menu"]) + playsound(src, "terminal_type", 25, 0) + + src.add_fingerprint(usr) + src.updateUsrDialog() + return + +/obj/machinery/computer/cloning/proc/scan_occupant(occupant) + var/mob/living/mob_occupant = get_mob_or_brainmob(occupant) + var/datum/dna/dna + if(iscarbon(mob_occupant)) + var/mob/living/carbon/C = mob_occupant + dna = C.has_dna() + if(isbrain(mob_occupant)) + var/mob/living/brain/B = mob_occupant + dna = B.stored_dna + + if(!istype(dna)) + scantemp = "Unable to locate valid genetic data." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + if(mob_occupant.suiciding || mob_occupant.hellbound) + scantemp = "Subject's brain is not responding to scanning stimuli." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + if((mob_occupant.disabilities & NOCLONE) && (src.scanner.scan_level < 2)) + scantemp = "Subject no longer contains the fundamental materials required to create a living clone." + playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0) + return + if ((!mob_occupant.ckey) || (!mob_occupant.client)) + scantemp = "Mental interface failure." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + if (find_record("ckey", mob_occupant.ckey, records)) + scantemp = "Subject already in database." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + + var/datum/data/record/R = new() + if(dna.species) + // We store the instance rather than the path, because some + // species (abductors, slimepeople) store state in their + // species datums + R.fields["mrace"] = dna.species + else + var/datum/species/rando_race = pick(CONFIG_GET(keyed_flag_list/roundstart_races)) + R.fields["mrace"] = rando_race.type + + R.fields["ckey"] = mob_occupant.ckey + R.fields["name"] = mob_occupant.real_name + R.fields["id"] = copytext(md5(mob_occupant.real_name), 2, 6) + R.fields["UE"] = dna.unique_enzymes + R.fields["UI"] = dna.uni_identity + R.fields["SE"] = dna.struc_enzymes + R.fields["blood_type"] = dna.blood_type + R.fields["features"] = dna.features + R.fields["factions"] = mob_occupant.faction + + if (!isnull(mob_occupant.mind)) //Save that mind so traitors can continue traitoring after cloning. + R.fields["mind"] = "\ref[mob_occupant.mind]" + + //Add an implant if needed + var/obj/item/implant/health/imp + for(var/obj/item/implant/health/HI in mob_occupant.implants) + imp = HI + break + if(!imp) + imp = new /obj/item/implant/health(mob_occupant) + imp.implant(mob_occupant) + R.fields["imp"] = "\ref[imp]" + + src.records += R + scantemp = "Subject successfully scanned." + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) +>>>>>>> 8b54685... Cleanup to various loc assignments and nearby code (#31069) diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm index 105fb64042..5f2324f236 100644 --- a/code/game/machinery/computer/dna_console.dm +++ b/code/game/machinery/computer/dna_console.dm @@ -43,9 +43,8 @@ /obj/machinery/computer/scan_consolenew/attackby(obj/item/I, mob/user, params) if (istype(I, /obj/item/disk/data)) //INSERT SOME DISKETTES if (!src.diskette) - if(!user.drop_item()) + if (!user.transferItemToLoc(I,src)) return - I.loc = src src.diskette = I to_chat(user, "You insert [I].") src.updateUsrDialog() @@ -448,7 +447,7 @@ diskette.fields = buffer_slot.Copy() if("ejectdisk") if(diskette) - diskette.loc = get_turf(src) + diskette.forceMove(drop_location()) diskette = null if("setdelayed") if(num) diff --git a/code/game/machinery/computer/gulag_teleporter.dm b/code/game/machinery/computer/gulag_teleporter.dm index c416d93e58..d80dc73f15 100644 --- a/code/game/machinery/computer/gulag_teleporter.dm +++ b/code/game/machinery/computer/gulag_teleporter.dm @@ -27,9 +27,8 @@ /obj/machinery/computer/gulag_teleporter_computer/attackby(obj/item/W, mob/user) if(istype(W, /obj/item/card/id/prisoner)) if(!id) - if(!user.drop_item()) + if (!user.transferItemToLoc(W,src)) return - W.forceMove(src) id = W to_chat(user, "You insert [W].") return From d4cdba3297d0866d6cf46b4dc2945653e78a80d4 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 14:18:02 -0500 Subject: [PATCH 34/60] Update parrot.dm --- code/modules/mob/living/simple_animal/parrot.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 3c1a5771c3..09d9f66f61 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -1003,9 +1003,6 @@ loc = H H.ContractDisease(P) parrot_interest = null -<<<<<<< HEAD - H.visible_message("[src] dive bombs into [H]'s chest and vanishes!", "[src] dive bombs into your chest, vanishing! This can't be good!") -======= H.visible_message("[src] dive bombs into [H]'s chest and vanishes!", "[src] dive bombs into your chest, vanishing! This can't be good!") @@ -1026,4 +1023,3 @@ /mob/living/simple_animal/parrot/clock_hawk/ratvar_act() return ->>>>>>> 60d3ce5... Adds Nars-Ian and clock hawks (#30856) From b88081e1068ff1305c95c4566885418a218a7a6d Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 14:19:27 -0500 Subject: [PATCH 35/60] Update misc_floor.dm --- code/game/turfs/simulated/floor/misc_floor.dm | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm index a918f8b5a8..bbe38d0ea8 100644 --- a/code/game/turfs/simulated/floor/misc_floor.dm +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -151,20 +151,6 @@ /turf/open/floor/clockwork/Initialize() . = ..() -<<<<<<< HEAD - new /obj/effect/temp_visual/ratvar/floor(src) - new /obj/effect/temp_visual/ratvar/beam(src) - realappearence = new /obj/effect/clockwork/overlay/floor(src) - realappearence.linked = src - change_construction_value(1) - -/turf/open/floor/clockwork/Destroy() - STOP_PROCESSING(SSobj, src) - change_construction_value(-1) - if(realappearence) - qdel(realappearence) - realappearence = null -======= if(uses_overlay) new /obj/effect/temp_visual/ratvar/floor(src) new /obj/effect/temp_visual/ratvar/beam(src) @@ -175,7 +161,6 @@ STOP_PROCESSING(SSobj, src) if(uses_overlay && realappearence) QDEL_NULL(realappearence) ->>>>>>> 5b73196... Reebe is fancier now (#31045) return ..() /turf/open/floor/clockwork/ReplaceWithLattice() From 6d59f3b06f2f6eb87fa6f0debc667fb540e7dcd5 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 14:19:40 -0500 Subject: [PATCH 36/60] Update misc_walls.dm --- code/game/turfs/simulated/wall/misc_walls.dm | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/code/game/turfs/simulated/wall/misc_walls.dm b/code/game/turfs/simulated/wall/misc_walls.dm index 7178dc3a65..abb56f443a 100644 --- a/code/game/turfs/simulated/wall/misc_walls.dm +++ b/code/game/turfs/simulated/wall/misc_walls.dm @@ -65,23 +65,8 @@ new /obj/effect/temp_visual/ratvar/beam(src) realappearence = new /obj/effect/clockwork/overlay/wall(src) realappearence.linked = src -<<<<<<< HEAD - change_construction_value(5) - -/turf/closed/wall/clockwork/examine(mob/user) - ..() - if((is_servant_of_ratvar(user) || isobserver(user)) && linkedcache) - to_chat(user, "It is linked to a Tinkerer's Cache, generating components!") /turf/closed/wall/clockwork/Destroy() - if(linkedcache) - linkedcache.linkedwall = null - linkedcache = null - change_construction_value(-5) -======= - -/turf/closed/wall/clockwork/Destroy() ->>>>>>> 5b73196... Reebe is fancier now (#31045) if(realappearence) qdel(realappearence) realappearence = null From 4fd4d77eb134cf53241be5e4eb9f01a15e1a6751 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 14:20:01 -0500 Subject: [PATCH 37/60] Update shade.dm --- .../modules/mob/living/simple_animal/shade.dm | 69 ------------------- 1 file changed, 69 deletions(-) diff --git a/code/modules/mob/living/simple_animal/shade.dm b/code/modules/mob/living/simple_animal/shade.dm index 39107d8e65..809e8b80d4 100644 --- a/code/modules/mob/living/simple_animal/shade.dm +++ b/code/modules/mob/living/simple_animal/shade.dm @@ -1,71 +1,3 @@ -<<<<<<< HEAD -/mob/living/simple_animal/shade - name = "Shade" - real_name = "Shade" - desc = "A bound spirit" - gender = PLURAL - icon = 'icons/mob/mob.dmi' - icon_state = "shade" - icon_living = "shade" - maxHealth = 50 - health = 50 - healable = 0 - speak_emote = list("hisses") - emote_hear = list("wails.","screeches.") - response_help = "puts their hand through" - response_disarm = "flails at" - response_harm = "punches" - speak_chance = 1 - melee_damage_lower = 5 - melee_damage_upper = 15 - attacktext = "metaphysically strikes" - minbodytemp = 0 - maxbodytemp = INFINITY - atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) - speed = -1 - stop_automated_movement = 1 - status_flags = 0 - faction = list("cult") - status_flags = CANPUSH - movement_type = FLYING - loot = list(/obj/item/ectoplasm) - del_on_death = TRUE - initial_language_holder = /datum/language_holder/construct - -/mob/living/simple_animal/shade/death() - deathmessage = "lets out a contented sigh as [p_their()] form unwinds." - ..() - -/mob/living/simple_animal/shade/canSuicide() - if(istype(loc, /obj/item/device/soulstone)) //do not suicide inside the soulstone - return 0 - return ..() - -/mob/living/simple_animal/shade/Process_Spacemove(movement_dir = 0) - return TRUE //this doesn't make much sense; you'd thing TRUE would mean it'd process spacemove but it means it doesn't - -/mob/living/simple_animal/shade/attack_animal(mob/living/simple_animal/M) - if(isconstruct(M)) - var/mob/living/simple_animal/hostile/construct/C = M - if(!C.can_repair_constructs) - return - if(health < maxHealth) - adjustHealth(-25) - Beam(M,icon_state="sendbeam",time=4) - M.visible_message("[M] heals \the [src].", \ - "You heal [src], leaving [src] at [health]/[maxHealth] health.") - else - to_chat(M, "You cannot heal [src], as [p_they()] [p_are()] unharmed!") - else if(src != M) - return ..() - -/mob/living/simple_animal/shade/attackby(obj/item/O, mob/user, params) //Marker -Agouri - if(istype(O, /obj/item/device/soulstone)) - var/obj/item/device/soulstone/SS = O - SS.transfer_soul("SHADE", src, user) - else - ..() -======= /mob/living/simple_animal/shade name = "Shade" real_name = "Shade" @@ -132,4 +64,3 @@ SS.transfer_soul("SHADE", src, user) else . = ..() ->>>>>>> 2ddc4aa... Merge pull request #31085 from AnturK/shadefix From 9f01bf378d88bd124f937e040d482ec31d742503 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 14:20:25 -0500 Subject: [PATCH 38/60] Update hypospray.dm --- .../reagents/reagent_containers/hypospray.dm | 164 ------------------ 1 file changed, 164 deletions(-) diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index c621285335..f236b83fa3 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -1,166 +1,3 @@ -<<<<<<< HEAD -/obj/item/reagent_containers/hypospray - name = "hypospray" - desc = "The DeForest Medical Corporation hypospray is a sterile, air-needle autoinjector for rapid administration of drugs to patients." - icon = 'icons/obj/syringe.dmi' - item_state = "hypo" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - icon_state = "hypo" - amount_per_transfer_from_this = 5 - volume = 30 - possible_transfer_amounts = list() - resistance_flags = ACID_PROOF - container_type = OPENCONTAINER_1 - slot_flags = SLOT_BELT - var/ignore_flags = 0 - var/infinite = FALSE - -/obj/item/reagent_containers/hypospray/attack_paw(mob/user) - return attack_hand(user) - -/obj/item/reagent_containers/hypospray/attack(mob/living/M, mob/user) - if(!reagents.total_volume) - to_chat(user, "[src] is empty!") - return - if(!iscarbon(M)) - return - - if(reagents.total_volume && (ignore_flags || M.can_inject(user, 1))) // Ignore flag should be checked first or there will be an error message. - to_chat(M, "You feel a tiny prick!") - to_chat(user, "You inject [M] with [src].") - - var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1) - reagents.reaction(M, INJECT, fraction) - if(M.reagents) - var/list/injected = list() - for(var/datum/reagent/R in reagents.reagent_list) - injected += R.name - var/trans = 0 - if(!infinite) - trans = reagents.trans_to(M, amount_per_transfer_from_this) - else - trans = reagents.copy_to(M, amount_per_transfer_from_this) - - to_chat(user, "[trans] unit\s injected. [reagents.total_volume] unit\s remaining in [src].") - - var/contained = english_list(injected) - - add_logs(user, M, "injected", src, "([contained])") - -/obj/item/reagent_containers/hypospray/CMO - list_reagents = list("omnizine" = 30) - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF - -/obj/item/reagent_containers/hypospray/combat - name = "combat stimulant injector" - desc = "A modified air-needle autoinjector, used by support operatives to quickly heal injuries in combat." - amount_per_transfer_from_this = 10 - icon_state = "combat_hypo" - volume = 90 - ignore_flags = 1 // So they can heal their comrades. - list_reagents = list("epinephrine" = 30, "omnizine" = 30, "leporazine" = 15, "atropine" = 15) - -/obj/item/reagent_containers/hypospray/combat/nanites - desc = "A modified air-needle autoinjector for use in combat situations. Prefilled with expensive medical nanites for rapid healing." - volume = 100 - list_reagents = list("nanites" = 80, "synaptizine" = 20) - -/obj/item/reagent_containers/hypospray/magillitis - name = "experimental autoinjector" - desc = "A modified air-needle autoinjector with a small single-use reservoir. It contains an experimental serum." - icon_state = "combat_hypo" - volume = 5 - container_type = NONE - list_reagents = list("magillitis" = 5) - -//MediPens - -/obj/item/reagent_containers/hypospray/medipen - name = "epinephrine medipen" - desc = "A rapid and safe way to stabilize patients in critical condition for personnel without advanced medical knowledge." - icon_state = "medipen" - item_state = "medipen" - lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' - amount_per_transfer_from_this = 10 - volume = 10 - ignore_flags = 1 //so you can medipen through hardsuits - container_type = DRAWABLE_1 - flags_1 = null - list_reagents = list("epinephrine" = 10) - -/obj/item/reagent_containers/hypospray/medipen/attack(mob/M, mob/user) - if(!reagents.total_volume) - to_chat(user, "[src] is empty!") - return - ..() - if(!iscyborg(user)) - reagents.maximum_volume = 0 //Makes them useless afterwards - container_type = NONE - update_icon() - spawn(80) - if(iscyborg(user) && !reagents.total_volume) - var/mob/living/silicon/robot/R = user - if(R.cell.use(100)) - reagents.add_reagent_list(list_reagents) - update_icon() - return - -/obj/item/reagent_containers/hypospray/medipen/update_icon() - if(reagents.total_volume > 0) - icon_state = initial(icon_state) - else - icon_state = "[initial(icon_state)]0" - -/obj/item/reagent_containers/hypospray/medipen/examine() - ..() - if(reagents && reagents.reagent_list.len) - to_chat(usr, "It is currently loaded.") - else - to_chat(usr, "It is spent.") - -/obj/item/reagent_containers/hypospray/medipen/stimpack //goliath kiting - name = "stimpack medipen" - desc = "A rapid way to stimulate your body's adrenaline, allowing for freer movement in restrictive armor." - icon_state = "stimpen" - volume = 20 - amount_per_transfer_from_this = 20 - list_reagents = list("ephedrine" = 10, "coffee" = 10) - -/obj/item/reagent_containers/hypospray/medipen/stimpack/traitor - desc = "A modified stimulants autoinjector for use in combat situations. Has a mild healing effect." - list_reagents = list("stimulants" = 10, "omnizine" = 10) - -/obj/item/reagent_containers/hypospray/medipen/morphine - name = "morphine medipen" - desc = "A rapid way to get you out of a tight situation and fast! You'll feel rather drowsy, though." - list_reagents = list("morphine" = 10) - -/obj/item/reagent_containers/hypospray/medipen/tuberculosiscure - name = "BVAK autoinjector" - desc = "Bio Virus Antidote Kit autoinjector. Has a two use system for yourself, and someone else. Inject when infected." - icon_state = "stimpen" - volume = 60 - amount_per_transfer_from_this = 30 - list_reagents = list("atropine" = 10, "epinephrine" = 10, "salbutamol" = 20, "spaceacillin" = 20) - -/obj/item/reagent_containers/hypospray/medipen/survival - name = "survival medipen" - desc = "A medipen for surviving in the harshest of environments, heals and protects from environmental hazards. WARNING: Do not inject more than one pen in quick succession." - icon_state = "stimpen" - volume = 57 - amount_per_transfer_from_this = 57 - list_reagents = list("salbutamol" = 10, "leporazine" = 15, "tricordrazine" = 15, "epinephrine" = 10, "miningnanites" = 2, "omnizine" = 5) - -/obj/item/reagent_containers/hypospray/medipen/species_mutator - name = "species mutator medipen" - desc = "Embark on a whirlwind tour of racial insensitivity by \ - literally appropriating other races." - volume = 1 - amount_per_transfer_from_this = 1 - list_reagents = list("unstablemutationtoxin" = 1) -======= /obj/item/reagent_containers/hypospray name = "hypospray" desc = "The DeForest Medical Corporation hypospray is a sterile, air-needle autoinjector for rapid administration of drugs to patients." @@ -325,4 +162,3 @@ volume = 1 amount_per_transfer_from_this = 1 list_reagents = list("unstablemutationtoxin" = 1) ->>>>>>> eda8f7f... Log attempted injections as well as successful ones From 6ec50aeae2e9e9315fc564c036444b35f3087cc7 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 14:20:50 -0500 Subject: [PATCH 39/60] Update observer.dm --- code/_onclick/observer.dm | 107 -------------------------------------- 1 file changed, 107 deletions(-) diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 679f9d7312..55f3e83b61 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -1,109 +1,3 @@ -<<<<<<< HEAD -/mob/dead/observer/DblClickOn(var/atom/A, var/params) - if(client.click_intercept) - if(call(client.click_intercept,"InterceptClickOn")(src,params,A)) - return - - if(can_reenter_corpse && mind && mind.current) - if(A == mind.current || (mind.current in A)) // double click your corpse or whatever holds it - reenter_corpse() // (cloning scanner, body bag, closet, mech, etc) - return // seems legit. - - // Things you might plausibly want to follow - if(ismovableatom(A)) - ManualFollow(A) - - // Otherwise jump - else if(A.loc) - loc = get_turf(A) - update_parallax_contents() - -/mob/dead/observer/ClickOn(var/atom/A, var/params) - if(client.click_intercept) - if(call(client.click_intercept,"InterceptClickOn")(src,params,A)) - return - - var/list/modifiers = params2list(params) - if(modifiers["shift"] && modifiers["middle"]) - ShiftMiddleClickOn(A) - return - if(modifiers["shift"] && modifiers["ctrl"]) - CtrlShiftClickOn(A) - return - if(modifiers["middle"]) - MiddleClickOn(A) - return - if(modifiers["shift"]) - ShiftClickOn(A) - return - if(modifiers["alt"]) - AltClickOn(A) - return - if(modifiers["ctrl"]) - CtrlClickOn(A) - return - - if(world.time <= next_move) - return - // You are responsible for checking config.ghost_interaction when you override this function - // Not all of them require checking, see below - A.attack_ghost(src) - -// Oh by the way this didn't work with old click code which is why clicking shit didn't spam you -/atom/proc/attack_ghost(mob/dead/observer/user) - if(user.client) - if(IsAdminGhost(user)) - attack_ai(user) - if(user.client.prefs.inquisitive_ghost) - user.examinate(src) - -// --------------------------------------- -// And here are some good things for free: -// Now you can click through portals, wormholes, gateways, and teleporters while observing. -Sayu - -/obj/machinery/teleport/hub/attack_ghost(mob/user) - var/atom/l = loc - var/obj/machinery/computer/teleporter/com = locate(/obj/machinery/computer/teleporter, locate(l.x - 2, l.y, l.z)) - if(com && com.locked) - user.forceMove(get_turf(com.locked)) - -/obj/effect/portal/attack_ghost(mob/user) - if(linked) - user.forceMove(get_turf(linked)) - -/obj/machinery/gateway/centerstation/attack_ghost(mob/user) - if(awaygate) - user.forceMove(awaygate.loc) - else - to_chat(user, "[src] has no destination.") - -/obj/machinery/gateway/centeraway/attack_ghost(mob/user) - if(stationgate) - user.forceMove(stationgate.loc) - else - to_chat(user, "[src] has no destination.") - -/obj/item/storage/attack_ghost(mob/user) - orient2hud(user) - show_to(user) - -/obj/machinery/teleport/hub/attack_ghost(mob/user) - if(power_station && power_station.engaged && power_station.teleporter_console && power_station.teleporter_console.target) - user.forceMove(get_turf(power_station.teleporter_console.target)) - -// ------------------------------------------- -// This was supposed to be used by adminghosts -// I think it is a *terrible* idea -// but I'm leaving it here anyway -// commented out, of course. -/* -/atom/proc/attack_admin(mob/user as mob) - if(!user || !user.client || !user.client.holder) - return - attack_hand(user) - -*/ -======= /mob/dead/observer/DblClickOn(var/atom/A, var/params) if(client.click_intercept) if(call(client.click_intercept,"InterceptClickOn")(src,params,A)) @@ -195,4 +89,3 @@ /obj/machinery/teleport/hub/attack_ghost(mob/user) if(power_station && power_station.engaged && power_station.teleporter_console && power_station.teleporter_console.target) user.forceMove(get_turf(power_station.teleporter_console.target)) ->>>>>>> b4208c6... Old code From 6c4934a34ac8e80828a0abd9977d5b145250c6b5 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 14:22:12 -0500 Subject: [PATCH 40/60] Update ai_laws.dm --- code/datums/ai_laws.dm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index 2e5296cff7..0a0ac72411 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -243,15 +243,9 @@ /datum/ai_laws/proc/pick_weighted_lawset() var/datum/ai_laws/lawtype -<<<<<<< HEAD - - while(!lawtype && config.law_weights.len) - var/possible_id = pickweight(config.law_weights) -======= var/list/law_weights = CONFIG_GET(keyed_number_list/law_weight) while(!lawtype && law_weights.len) var/possible_id = pickweight(law_weights) ->>>>>>> f7171e7... Fixes AI law weights infinite loop lawtype = lawid_to_type(possible_id) if(!lawtype) config.law_weights -= possible_id From fdb101596de63015da69beacc61ec9976a186258 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 14:22:39 -0500 Subject: [PATCH 41/60] Update bodybag.dm --- code/game/objects/items/bodybag.dm | 75 +----------------------------- 1 file changed, 1 insertion(+), 74 deletions(-) diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index f711aaba59..d0dc220d4d 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -1,76 +1,3 @@ -<<<<<<< HEAD - -/obj/item/bodybag - name = "body bag" - desc = "A folded bag designed for the storage and transportation of cadavers." - icon = 'icons/obj/bodybag.dmi' - icon_state = "bodybag_folded" - var/unfoldedbag_path = /obj/structure/closet/body_bag - w_class = WEIGHT_CLASS_SMALL - -/obj/item/bodybag/attack_self(mob/user) - deploy_bodybag(user, user.loc) - -/obj/item/bodybag/afterattack(atom/target, mob/user, proximity) - if(proximity) - if(isopenturf(target)) - deploy_bodybag(user, target) - -/obj/item/bodybag/proc/deploy_bodybag(mob/user, atom/location) - var/obj/structure/closet/body_bag/R = new unfoldedbag_path(location) - R.open(user) - R.add_fingerprint(user) - qdel(src) - - -// Bluespace bodybag - -/obj/item/bodybag/bluespace - name = "bluespace body bag" - desc = "A folded bluespace body bag designed for the storage and transportation of cadavers." - icon = 'icons/obj/bodybag.dmi' - icon_state = "bluebodybag_folded" - unfoldedbag_path = /obj/structure/closet/body_bag/bluespace - w_class = WEIGHT_CLASS_SMALL - origin_tech = "bluespace=4;materials=4;plasmatech=4" - -/obj/item/bodybag/bluespace/examine(mob/user) - ..() - if(contents.len) - to_chat(user, "You can make out the shapes of [contents.len] objects through the fabric.") - -/obj/item/bodybag/bluespace/Destroy() - for(var/atom/movable/A in contents) - A.forceMove(get_turf(src)) - if(isliving(A)) - to_chat(A, "You suddenly feel the space around you torn apart! You're free!") - return ..() - -/obj/item/bodybag/bluespace/deploy_bodybag(mob/user, atom/location) - var/obj/structure/closet/body_bag/R = new unfoldedbag_path(location) - for(var/atom/movable/A in contents) - A.forceMove(R) - if(isliving(A)) - to_chat(A, "You suddenly feel air around you! You're free!") - R.open(user) - R.add_fingerprint(user) - qdel(src) - -/obj/item/bodybag/bluespace/container_resist(mob/living/user) - if(user.incapacitated()) - to_chat(user, "You can't get out while you're restrained like this!") - return - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT - to_chat(user, "You claw at the fabric of [src], trying to tear it open...") - to_chat(loc, "Someone starts trying to break free of [src]!") - if(!do_after(user, 200, target = src)) - to_chat(loc, "The pressure subsides. It seems that they've stopped resisting...") - return - loc.visible_message("[user] suddenly appears in front of [loc]!", "[user] breaks free of [src]!") - qdel(src) -======= - /obj/item/bodybag name = "body bag" desc = "A folded bag designed for the storage and transportation of cadavers." @@ -141,4 +68,4 @@ return loc.visible_message("[user] suddenly appears in front of [loc]!", "[user] breaks free of [src]!") qdel(src) ->>>>>>> 51c4840... Stops putting RCD, bluespace bags, and staves into ORM (#31093) + From dddf85a7df95381d4f02bccd3bd8ab07cd72cdb4 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 14:23:03 -0500 Subject: [PATCH 42/60] Update bags.dm --- code/game/objects/items/storage/bags.dm | 384 ------------------------ 1 file changed, 384 deletions(-) diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm index 1a28e08297..638313386e 100644 --- a/code/game/objects/items/storage/bags.dm +++ b/code/game/objects/items/storage/bags.dm @@ -1,386 +1,3 @@ -<<<<<<< HEAD -/* - * These absorb the functionality of the plant bag, ore satchel, etc. - * They use the use_to_pickup, quick_gather, and quick_empty functions - * that were already defined in weapon/storage, but which had been - * re-implemented in other classes. - * - * Contains: - * Trash Bag - * Mining Satchel - * Plant Bag - * Sheet Snatcher - * Book Bag - * Biowaste Bag - * - * -Sayu - */ - -// Generic non-item -/obj/item/storage/bag - allow_quick_gather = 1 - allow_quick_empty = 1 - display_contents_with_number = 1 // should work fine now - use_to_pickup = 1 - slot_flags = SLOT_BELT - -// ----------------------------- -// Trash bag -// ----------------------------- -/obj/item/storage/bag/trash - name = "trash bag" - desc = "It's the heavy-duty black polymer kind. Time to take out the trash!" - icon = 'icons/obj/janitor.dmi' - icon_state = "trashbag" - item_state = "trashbag" - lefthand_file = 'icons/mob/inhands/equipment/custodial_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/custodial_righthand.dmi' - - w_class = WEIGHT_CLASS_BULKY - max_w_class = WEIGHT_CLASS_SMALL - max_combined_w_class = 30 - storage_slots = 30 - can_hold = list() // any - cant_hold = list(/obj/item/disk/nuclear) - -/obj/item/storage/bag/trash/suicide_act(mob/user) - user.visible_message("[user] puts [src] over [user.p_their()] head and starts chomping at the insides! Disgusting!") - playsound(loc, 'sound/items/eatfood.ogg', 50, 1, -1) - return (TOXLOSS) - -/obj/item/storage/bag/trash/update_icon() - if(contents.len == 0) - icon_state = "[initial(icon_state)]" - else if(contents.len < 12) - icon_state = "[initial(icon_state)]1" - else if(contents.len < 21) - icon_state = "[initial(icon_state)]2" - else icon_state = "[initial(icon_state)]3" - -/obj/item/storage/bag/trash/cyborg - -/obj/item/storage/bag/trash/proc/janicart_insert(mob/user, obj/structure/janitorialcart/J) - J.put_in_cart(src, user) - J.mybag=src - J.update_icon() - -/obj/item/storage/bag/trash/cyborg/janicart_insert(mob/user, obj/structure/janitorialcart/J) - return - -/obj/item/storage/bag/trash/bluespace - name = "trash bag of holding" - desc = "The latest and greatest in custodial convenience, a trashbag that is capable of holding vast quantities of garbage." - icon_state = "bluetrashbag" - origin_tech = "materials=4;bluespace=4;engineering=4;plasmatech=3" - max_combined_w_class = 60 - storage_slots = 60 - -// ----------------------------- -// Mining Satchel -// ----------------------------- - -/obj/item/storage/bag/ore - name = "mining satchel" - desc = "This little bugger can be used to store and transport ores." - icon = 'icons/obj/mining.dmi' - icon_state = "satchel" - origin_tech = "engineering=2" - slot_flags = SLOT_BELT | SLOT_POCKET - w_class = WEIGHT_CLASS_NORMAL - storage_slots = 50 - max_combined_w_class = 200 //Doesn't matter what this is, so long as it's more or equal to storage_slots * ore.w_class - max_w_class = WEIGHT_CLASS_NORMAL - can_hold = list(/obj/item/ore) - var/spam_protection = FALSE //If this is TRUE, the holder won't receive any messages when they fail to pick up ore through crossing it - -/obj/item/storage/bag/ore/cyborg - name = "cyborg mining satchel" - -/obj/item/storage/bag/ore/holding //miners, your messiah has arrived - name = "mining satchel of holding" - desc = "A revolution in convenience, this satchel allows for huge amounts of ore storage. It's been outfitted with anti-malfunction safety measures." - storage_slots = INFINITY - max_combined_w_class = INFINITY - origin_tech = "bluespace=4;materials=3;engineering=3" - icon_state = "satchel_bspace" - -// ----------------------------- -// Plant bag -// ----------------------------- - -/obj/item/storage/bag/plants - name = "plant bag" - icon = 'icons/obj/hydroponics/equipment.dmi' - icon_state = "plantbag" - storage_slots = 100; //the number of plant pieces it can carry. - max_combined_w_class = 100 //Doesn't matter what this is, so long as it's more or equal to storage_slots * plants.w_class - max_w_class = WEIGHT_CLASS_NORMAL - w_class = WEIGHT_CLASS_TINY - can_hold = list(/obj/item/reagent_containers/food/snacks/grown, /obj/item/seeds, /obj/item/grown, /obj/item/reagent_containers/honeycomb) - resistance_flags = FLAMMABLE - -//////// - -/obj/item/storage/bag/plants/portaseeder - name = "portable seed extractor" - desc = "For the enterprising botanist on the go. Less efficient than the stationary model, it creates one seed per plant." - icon_state = "portaseeder" - origin_tech = "biotech=3;engineering=2" - -/obj/item/storage/bag/plants/portaseeder/verb/dissolve_contents() - set name = "Activate Seed Extraction" - set category = "Object" - set desc = "Activate to convert your plants into plantable seeds." - if(usr.stat || !usr.canmove || usr.restrained()) - return - for(var/obj/item/O in contents) - seedify(O, 1) - close_all() - - -// ----------------------------- -// Sheet Snatcher -// ----------------------------- -// Because it stacks stacks, this doesn't operate normally. -// However, making it a storage/bag allows us to reuse existing code in some places. -Sayu - -/obj/item/storage/bag/sheetsnatcher - name = "sheet snatcher" - desc = "A patented Nanotrasen storage system designed for any kind of mineral sheet." - icon = 'icons/obj/mining.dmi' - icon_state = "sheetsnatcher" - - var/capacity = 300; //the number of sheets it can carry. - w_class = WEIGHT_CLASS_NORMAL - - allow_quick_empty = 1 // this function is superceded - -/obj/item/storage/bag/sheetsnatcher/can_be_inserted(obj/item/W, stop_messages = 0) - if(!istype(W, /obj/item/stack/sheet) || istype(W, /obj/item/stack/sheet/mineral/sandstone) || istype(W, /obj/item/stack/sheet/mineral/wood)) - if(!stop_messages) - to_chat(usr, "The snatcher does not accept [W].") - return 0 //I don't care, but the existing code rejects them for not being "sheets" *shrug* -Sayu - var/current = 0 - for(var/obj/item/stack/sheet/S in contents) - current += S.amount - if(capacity == current)//If it's full, you're done - if(!stop_messages) - to_chat(usr, "The snatcher is full.") - return 0 - return 1 - - -// Modified handle_item_insertion. Would prefer not to, but... -/obj/item/storage/bag/sheetsnatcher/handle_item_insertion(obj/item/W, prevent_warning = 0) - var/obj/item/stack/sheet/S = W - if(!istype(S)) return 0 - - var/amount - var/inserted = 0 - var/current = 0 - for(var/obj/item/stack/sheet/S2 in contents) - current += S2.amount - if(capacity < current + S.amount)//If the stack will fill it up - amount = capacity - current - else - amount = S.amount - - for(var/obj/item/stack/sheet/sheet in contents) - if(S.type == sheet.type) // we are violating the amount limitation because these are not sane objects - sheet.amount += amount // they should only be removed through procs in this file, which split them up. - S.amount -= amount - inserted = 1 - break - - if(!inserted || !S.amount) - usr.dropItemToGround(S) - if (usr.client && usr.s_active != src) - usr.client.screen -= S - S.dropped(usr) - if(!S.amount) - qdel(S) - else - if(S.pulledby) - S.pulledby.stop_pulling() - S.loc = src - - orient2hud(usr) - if(usr.s_active) - usr.s_active.show_to(usr) - update_icon() - return 1 - - -// Sets up numbered display to show the stack size of each stored mineral -// NOTE: numbered display is turned off currently because it's broken -/obj/item/storage/bag/sheetsnatcher/orient2hud(mob/user) - var/adjusted_contents = contents.len - - //Numbered contents display - var/list/datum/numbered_display/numbered_contents - if(display_contents_with_number) - numbered_contents = list() - adjusted_contents = 0 - for(var/obj/item/stack/sheet/I in contents) - adjusted_contents++ - var/datum/numbered_display/D = new/datum/numbered_display(I) - D.number = I.amount - numbered_contents.Add( D ) - - var/row_num = 0 - var/col_count = min(7,storage_slots) -1 - if (adjusted_contents > 7) - row_num = round((adjusted_contents-1) / 7) // 7 is the maximum allowed width. - src.standard_orient_objs(row_num, col_count, numbered_contents) - return - - -// Modified quick_empty verb drops appropriate sized stacks -/obj/item/storage/bag/sheetsnatcher/quick_empty() - var/location = get_turf(src) - for(var/obj/item/stack/sheet/S in contents) - while(S.amount) - var/obj/item/stack/sheet/N = new S.type(location) - var/stacksize = min(S.amount,N.max_amount) - N.amount = stacksize - S.amount -= stacksize - if(!S.amount) - qdel(S)// todo: there's probably something missing here - orient2hud(usr) - if(usr.s_active) - usr.s_active.show_to(usr) - update_icon() - -// Instead of removing -/obj/item/storage/bag/sheetsnatcher/remove_from_storage(obj/item/W, atom/new_location) - var/obj/item/stack/sheet/S = W - if(!istype(S)) return 0 - - //I would prefer to drop a new stack, but the item/attack_hand code - // that calls this can't recieve a different object than you clicked on. - //Therefore, make a new stack internally that has the remainder. - // -Sayu - - if(S.amount > S.max_amount) - var/obj/item/stack/sheet/temp = new S.type(src) - temp.amount = S.amount - S.max_amount - S.amount = S.max_amount - - return ..(S,new_location) - -// ----------------------------- -// Sheet Snatcher (Cyborg) -// ----------------------------- - -/obj/item/storage/bag/sheetsnatcher/borg - name = "sheet snatcher 9000" - desc = "" - capacity = 500//Borgs get more because >specialization - - -// ----------------------------- -// Book bag -// ----------------------------- - -/obj/item/storage/bag/books - name = "book bag" - desc = "A bag for books." - icon = 'icons/obj/library.dmi' - icon_state = "bookbag" - display_contents_with_number = 0 //This would look really stupid otherwise - storage_slots = 7 - max_combined_w_class = 21 - max_w_class = WEIGHT_CLASS_NORMAL - w_class = WEIGHT_CLASS_BULKY //Bigger than a book because physics - can_hold = list(/obj/item/book, /obj/item/storage/book, /obj/item/spellbook) - resistance_flags = FLAMMABLE - -/* - * Trays - Agouri - */ -/obj/item/storage/bag/tray - name = "tray" - icon = 'icons/obj/food/containers.dmi' - icon_state = "tray" - desc = "A metal tray to lay food on." - force = 5 - throwforce = 10 - throw_speed = 3 - throw_range = 5 - w_class = WEIGHT_CLASS_BULKY - flags_1 = CONDUCT_1 - materials = list(MAT_METAL=3000) - preposition = "on" - -/obj/item/storage/bag/tray/attack(mob/living/M, mob/living/user) - ..() - // Drop all the things. All of them. - var/list/obj/item/oldContents = contents.Copy() - quick_empty() - - // Make each item scatter a bit - for(var/obj/item/I in oldContents) - spawn() - for(var/i = 1, i <= rand(1,2), i++) - if(I) - step(I, pick(NORTH,SOUTH,EAST,WEST)) - sleep(rand(2,4)) - - if(prob(50)) - playsound(M, 'sound/items/trayhit1.ogg', 50, 1) - else - playsound(M, 'sound/items/trayhit2.ogg', 50, 1) - - if(ishuman(M) || ismonkey(M)) - if(prob(10)) - M.Knockdown(40) - -/obj/item/storage/bag/tray/proc/rebuild_overlays() - cut_overlays() - for(var/obj/item/I in contents) - add_overlay(mutable_appearance(I.icon, I.icon_state)) - -/obj/item/storage/bag/tray/remove_from_storage(obj/item/W as obj, atom/new_location) - ..() - rebuild_overlays() - -/obj/item/storage/bag/tray/handle_item_insertion(obj/item/I, prevent_warning = 0) - add_overlay(mutable_appearance(I.icon, I.icon_state)) - . = ..() - - -/* - * Chemistry bag - */ - -/obj/item/storage/bag/chemistry - name = "chemistry bag" - icon = 'icons/obj/chemical.dmi' - icon_state = "bag" - desc = "A bag for storing pills, patches, and bottles." - storage_slots = 50 - max_combined_w_class = 200 - w_class = WEIGHT_CLASS_TINY - preposition = "in" - can_hold = list(/obj/item/reagent_containers/pill, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle) - resistance_flags = FLAMMABLE - -/* - * Biowaste bag (mostly for xenobiologists) - */ - -/obj/item/storage/bag/bio - name = "bio bag" - icon = 'icons/obj/chemical.dmi' - icon_state = "biobag" - desc = "A bag for the safe transportation and disposal of biowaste and other biological materials." - storage_slots = 25 - max_combined_w_class = 200 - w_class = WEIGHT_CLASS_TINY - preposition = "in" - can_hold = list(/obj/item/slime_extract, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/blood, /obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/food/snacks/deadmouse, /obj/item/reagent_containers/food/snacks/monkeycube) - resistance_flags = FLAMMABLE -======= /* * These absorb the functionality of the plant bag, ore satchel, etc. * They use the use_to_pickup, quick_gather, and quick_empty functions @@ -763,4 +380,3 @@ preposition = "in" can_hold = list(/obj/item/slime_extract, /obj/item/reagent_containers/syringe, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/blood, /obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/food/snacks/deadmouse, /obj/item/reagent_containers/food/snacks/monkeycube) resistance_flags = FLAMMABLE ->>>>>>> 51c4840... Stops putting RCD, bluespace bags, and staves into ORM (#31093) From 99319f5d4dbb0cc97f2bcea4aebfcdb5bb78858d Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 14:23:40 -0500 Subject: [PATCH 43/60] Update shuttle.dm --- code/controllers/subsystem/shuttle.dm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index c59cc0161f..705f0dbd81 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -176,15 +176,9 @@ SUBSYSTEM_DEF(shuttle) Good luck.") return emergency = backup_shuttle -<<<<<<< HEAD - - if(world.time - SSticker.round_start_time < config.shuttle_refuel_delay) - to_chat(user, "The emergency shuttle is refueling. Please wait [DisplayTimeText((world.time - SSticker.round_start_time) - config.shuttle_refuel_delay)] before trying again.") -======= var/srd = CONFIG_GET(number/shuttle_refuel_delay) if(world.time - SSticker.round_start_time < srd) to_chat(user, "The emergency shuttle is refueling. Please wait [DisplayTimeText(srd - (world.time - SSticker.round_start_time))] before trying again.") ->>>>>>> ced1e24... Corrected shuttle refuel time (#31108) return switch(emergency.mode) From 9bfbeafcf9d4fb0bb4c3f27781d4ab38e11be264 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 14:24:17 -0500 Subject: [PATCH 44/60] Update tgstation.dme --- tgstation.dme | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tgstation.dme b/tgstation.dme index 627244c246..4649448e1d 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -163,7 +163,6 @@ #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\screen_objects.dm" #include "code\_onclick\hud\swarmer.dm" -<<<<<<< HEAD #include "code\citadel\_cit_helpers.dm" #include "code\citadel\cit_areas.dm" #include "code\citadel\cit_arousal.dm" @@ -190,8 +189,6 @@ #include "code\citadel\organs\vagina.dm" #include "code\citadel\organs\womb.dm" #include "code\citadel\toys\dildos.dm" -======= ->>>>>>> ced1e24... Corrected shuttle refuel time (#31108) #include "code\controllers\admin.dm" #include "code\controllers\configuration.dm" #include "code\controllers\configuration_citadel.dm" @@ -2139,12 +2136,9 @@ #include "code\modules\ruins\spaceruin_code\TheDerelict.dm" #include "code\modules\security_levels\keycard_authentication.dm" #include "code\modules\security_levels\security_levels.dm" -<<<<<<< HEAD #include "code\modules\server_tools\server_tools.dm" -======= #include "code\modules\server_tools\st_commands.dm" #include "code\modules\server_tools\st_interface.dm" ->>>>>>> ced1e24... Corrected shuttle refuel time (#31108) #include "code\modules\shuttle\arrivals.dm" #include "code\modules\shuttle\assault_pod.dm" #include "code\modules\shuttle\computer.dm" From cae6983aea5063e3ac012b618cc9684a88da5c57 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 14:25:05 -0500 Subject: [PATCH 45/60] Update wizarditis.dm --- code/datums/diseases/wizarditis.dm | 118 ----------------------------- 1 file changed, 118 deletions(-) diff --git a/code/datums/diseases/wizarditis.dm b/code/datums/diseases/wizarditis.dm index 485a5ea2c4..66663162ee 100644 --- a/code/datums/diseases/wizarditis.dm +++ b/code/datums/diseases/wizarditis.dm @@ -1,120 +1,3 @@ -<<<<<<< HEAD -/datum/disease/wizarditis - name = "Wizarditis" - max_stages = 4 - spread_text = "Airborne" - cure_text = "The Manly Dorf" - cures = list("manlydorf") - cure_chance = 100 - agent = "Rincewindus Vulgaris" - viable_mobtypes = list(/mob/living/carbon/human) - disease_flags = CAN_CARRY|CAN_RESIST|CURABLE - permeability_mod = 0.75 - desc = "Some speculate that this virus is the cause of the Space Wizard Federation's existence. Subjects affected show the signs of mental retardation, yelling obscure sentences or total gibberish. On late stages subjects sometime express the feelings of inner power, and, cite, 'the ability to control the forces of cosmos themselves!' A gulp of strong, manly spirits usually reverts them to normal, humanlike, condition." - severity = HARMFUL - required_organs = list(/obj/item/bodypart/head) - -/* -BIRUZ BENNAR -SCYAR NILA - teleport -NEC CANTIO - dis techno -EI NATH - shocking grasp -AULIE OXIN FIERA - knock -TARCOL MINTI ZHERI - forcewall -STI KALY - blind -*/ - -/datum/disease/wizarditis/stage_act() - ..() - - switch(stage) - if(2) - if(prob(1)&&prob(50)) - affected_mob.say(pick("You shall not pass!", "Expeliarmus!", "By Merlins beard!", "Feel the power of the Dark Side!")) - if(prob(1)&&prob(50)) - to_chat(affected_mob, "You feel [pick("that you don't have enough mana", "that the winds of magic are gone", "an urge to summon familiar")].") - - - if(3) - if(prob(1)&&prob(50)) - affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!", "STI KALY!", "TARCOL MINTI ZHERI!")) - if(prob(1)&&prob(50)) - to_chat(affected_mob, "You feel [pick("the magic bubbling in your veins","that this location gives you a +1 to INT","an urge to summon familiar")].") - - if(4) - - if(prob(1)) - affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!","STI KALY!","EI NATH!")) - return - if(prob(1)&&prob(50)) - to_chat(affected_mob, "You feel [pick("the tidal wave of raw power building inside","that this location gives you a +2 to INT and +1 to WIS","an urge to teleport")].") - spawn_wizard_clothes(50) - if(prob(1)&&prob(1)) - teleport() - return - - - -/datum/disease/wizarditis/proc/spawn_wizard_clothes(chance = 0) - if(ishuman(affected_mob)) - var/mob/living/carbon/human/H = affected_mob - if(prob(chance)) - if(!istype(H.head, /obj/item/clothing/head/wizard)) - if(!H.dropItemToGround(H.head)) - qdel(H.head) - H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(H), slot_head) - return - if(prob(chance)) - if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe)) - if(!H.dropItemToGround(H.wear_suit)) - qdel(H.wear_suit) - H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(H), slot_wear_suit) - return - if(prob(chance)) - if(!istype(H.shoes, /obj/item/clothing/shoes/sandal/magic)) - if(!H.dropItemToGround(H.shoes)) - qdel(H.shoes) - H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(H), slot_shoes) - return - else - var/mob/living/carbon/H = affected_mob - if(prob(chance)) - var/obj/item/staff/S = new(H) - if(!H.put_in_hands(S)) - qdel(S) - - -/datum/disease/wizarditis/proc/teleport() - var/list/theareas = get_areas_in_range(80, affected_mob) - for(var/area/space/S in theareas) - theareas -= S - - if(!theareas||!theareas.len) - return - - var/area/thearea = pick(theareas) - - var/list/L = list() - for(var/turf/T in get_area_turfs(thearea.type)) - if(T.z != affected_mob.z) continue - if(T.name == "space") continue - if(!T.density) - var/clear = 1 - for(var/obj/O in T) - if(O.density) - clear = 0 - break - if(clear) - L+=T - - if(!L) - return - - affected_mob.say("SCYAR NILA [uppertext(thearea.name)]!") - affected_mob.loc = pick(L) - - return -======= /datum/disease/wizarditis name = "Wizarditis" max_stages = 4 @@ -230,4 +113,3 @@ STI KALY - blind affected_mob.forceMove(pick(L)) return ->>>>>>> 8b54685... Cleanup to various loc assignments and nearby code (#31069) From 7193e9da83308907dacdf5f359db35ef6deb7805 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 14:25:29 -0500 Subject: [PATCH 46/60] Update wires.dm --- code/datums/wires/wires.dm | 466 +++++++++++++++++-------------------- 1 file changed, 210 insertions(+), 256 deletions(-) diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm index b51c020a03..ae938f18ce 100644 --- a/code/datums/wires/wires.dm +++ b/code/datums/wires/wires.dm @@ -1,184 +1,139 @@ -#define MAXIMUM_EMP_WIRES 3 - -/proc/is_wire_tool(obj/item/I) - if(istype(I, /obj/item/device/multitool)) - return TRUE - if(istype(I, /obj/item/wirecutters)) - return TRUE - if(istype(I, /obj/item/device/assembly)) - var/obj/item/device/assembly/A = I - if(A.attachable) - return TRUE - return - -/atom - var/datum/wires/wires = null - -/datum/wires - var/atom/holder = null // The holder (atom that contains these wires). - var/holder_type = null // The holder's typepath (used to make wire colors common to all holders). - var/proper_name = "Unknown" // The display name for the wire set shown in station blueprints. Not used if randomize is true or it's an item NT wouldn't know about (Explosives/Nuke) - - var/list/wires = list() // List of wires. - var/list/cut_wires = list() // List of wires that have been cut. - var/list/colors = list() // Dictionary of colors to wire. - var/list/assemblies = list() // List of attached assemblies. - var/randomize = 0 // If every instance of these wires should be random. - // Prevents wires from showing up in station blueprints - -/datum/wires/New(atom/holder) - ..() - if(!istype(holder, holder_type)) - CRASH("Wire holder is not of the expected type!") - return - - src.holder = holder - if(randomize) - randomize() - else - if(!GLOB.wire_color_directory[holder_type]) - randomize() - GLOB.wire_color_directory[holder_type] = colors - GLOB.wire_name_directory[holder_type] = proper_name - else - colors = GLOB.wire_color_directory[holder_type] - -/datum/wires/Destroy() - holder = null - assemblies = list() - return ..() - -/datum/wires/proc/add_duds(duds) - while(duds) - var/dud = WIRE_DUD_PREFIX + "[--duds]" - if(dud in wires) - continue - wires += dud - -/datum/wires/proc/randomize() - var/static/list/possible_colors = list( - "blue", - "brown", - "crimson", - "cyan", - "gold", - "grey", - "green", - "magenta", - "orange", - "pink", - "purple", - "red", - "silver", - "violet", - "white", - "yellow" - ) - - var/list/my_possible_colors = possible_colors.Copy() - - for(var/wire in shuffle(wires)) - colors[pick_n_take(my_possible_colors)] = wire - -/datum/wires/proc/shuffle_wires() - colors.Cut() - randomize() - -/datum/wires/proc/repair() - cut_wires.Cut() - -/datum/wires/proc/get_wire(color) - return colors[color] - -/datum/wires/proc/get_attached(color) - if(assemblies[color]) - return assemblies[color] - return null - -/datum/wires/proc/is_attached(color) - if(assemblies[color]) - return TRUE - -/datum/wires/proc/is_cut(wire) - return (wire in cut_wires) - -/datum/wires/proc/is_color_cut(color) - return is_cut(get_wire(color)) - -/datum/wires/proc/is_all_cut() - if(cut_wires.len == wires.len) - return TRUE - -/datum/wires/proc/cut(wire) - if(is_cut(wire)) - cut_wires -= wire - on_cut(wire, mend = TRUE) - else - cut_wires += wire - on_cut(wire, mend = FALSE) - -/datum/wires/proc/cut_color(color) - cut(get_wire(color)) - -/datum/wires/proc/cut_random() - cut(wires[rand(1, wires.len)]) - -/datum/wires/proc/cut_all() - for(var/wire in wires) - cut(wire) - +#define MAXIMUM_EMP_WIRES 3 + +/proc/is_wire_tool(obj/item/I) + if(istype(I, /obj/item/device/multitool)) + return TRUE + if(istype(I, /obj/item/wirecutters)) + return TRUE + if(istype(I, /obj/item/device/assembly)) + var/obj/item/device/assembly/A = I + if(A.attachable) + return TRUE + return + +/atom + var/datum/wires/wires = null + +/datum/wires + var/atom/holder = null // The holder (atom that contains these wires). + var/holder_type = null // The holder's typepath (used to make wire colors common to all holders). + var/proper_name = "Unknown" // The display name for the wire set shown in station blueprints. Not used if randomize is true or it's an item NT wouldn't know about (Explosives/Nuke) + + var/list/wires = list() // List of wires. + var/list/cut_wires = list() // List of wires that have been cut. + var/list/colors = list() // Dictionary of colors to wire. + var/list/assemblies = list() // List of attached assemblies. + var/randomize = 0 // If every instance of these wires should be random. + // Prevents wires from showing up in station blueprints + +/datum/wires/New(atom/holder) + ..() + if(!istype(holder, holder_type)) + CRASH("Wire holder is not of the expected type!") + return + + src.holder = holder + if(randomize) + randomize() + else + if(!GLOB.wire_color_directory[holder_type]) + randomize() + GLOB.wire_color_directory[holder_type] = colors + GLOB.wire_name_directory[holder_type] = proper_name + else + colors = GLOB.wire_color_directory[holder_type] + +/datum/wires/Destroy() + holder = null + assemblies = list() + return ..() + +/datum/wires/proc/add_duds(duds) + while(duds) + var/dud = WIRE_DUD_PREFIX + "[--duds]" + if(dud in wires) + continue + wires += dud + +/datum/wires/proc/randomize() + var/static/list/possible_colors = list( + "blue", + "brown", + "crimson", + "cyan", + "gold", + "grey", + "green", + "magenta", + "orange", + "pink", + "purple", + "red", + "silver", + "violet", + "white", + "yellow" + ) + + var/list/my_possible_colors = possible_colors.Copy() + + for(var/wire in shuffle(wires)) + colors[pick_n_take(my_possible_colors)] = wire + +/datum/wires/proc/shuffle_wires() + colors.Cut() + randomize() + +/datum/wires/proc/repair() + cut_wires.Cut() + +/datum/wires/proc/get_wire(color) + return colors[color] + +/datum/wires/proc/get_attached(color) + if(assemblies[color]) + return assemblies[color] + return null + +/datum/wires/proc/is_attached(color) + if(assemblies[color]) + return TRUE + +/datum/wires/proc/is_cut(wire) + return (wire in cut_wires) + +/datum/wires/proc/is_color_cut(color) + return is_cut(get_wire(color)) + +/datum/wires/proc/is_all_cut() + if(cut_wires.len == wires.len) + return TRUE + +/datum/wires/proc/cut(wire) + if(is_cut(wire)) + cut_wires -= wire + on_cut(wire, mend = TRUE) + else + cut_wires += wire + on_cut(wire, mend = FALSE) + +/datum/wires/proc/cut_color(color) + cut(get_wire(color)) + +/datum/wires/proc/cut_random() + cut(wires[rand(1, wires.len)]) + +/datum/wires/proc/cut_all() + for(var/wire in wires) + cut(wire) + /datum/wires/proc/pulse(wire, user) - if(is_cut(wire)) - return + if(is_cut(wire)) + return on_pulse(wire, user) - + /datum/wires/proc/pulse_color(color, mob/living/user) pulse(get_wire(color), user) -<<<<<<< HEAD - -/datum/wires/proc/pulse_assembly(obj/item/device/assembly/S) - for(var/color in assemblies) - if(S == assemblies[color]) - pulse_color(color) - return TRUE - -/datum/wires/proc/attach_assembly(color, obj/item/device/assembly/S) - if(S && istype(S) && S.attachable && !is_attached(color)) - assemblies[color] = S - S.loc = holder - S.connected = src - return S - -/datum/wires/proc/detach_assembly(color) - var/obj/item/device/assembly/S = get_attached(color) - if(S && istype(S)) - assemblies -= color - S.connected = null - S.loc = holder.loc - return S - -/datum/wires/proc/emp_pulse() - var/list/possible_wires = shuffle(wires) - var/remaining_pulses = MAXIMUM_EMP_WIRES - - for(var/wire in possible_wires) - if(prob(33)) - pulse(wire) - remaining_pulses-- - if(remaining_pulses >= 0) - break - -// Overridable Procs -/datum/wires/proc/interactable(mob/user) - return TRUE - -/datum/wires/proc/get_status() - return list() - -/datum/wires/proc/on_cut(wire, mend = FALSE) - return - -======= /datum/wires/proc/pulse_assembly(obj/item/device/assembly/S) for(var/color in assemblies) @@ -222,85 +177,84 @@ /datum/wires/proc/on_cut(wire, mend = FALSE) return ->>>>>>> 8b54685... Cleanup to various loc assignments and nearby code (#31069) /datum/wires/proc/on_pulse(wire, user) - return -// End Overridable Procs - -/datum/wires/proc/interact(mob/user) - if(!interactable(user)) - return - ui_interact(user) - for(var/A in assemblies) - var/obj/item/I = assemblies[A] - if(istype(I) && I.on_found(user)) - return - -/datum/wires/ui_host() - return holder - -/datum/wires/ui_status(mob/user) - if(interactable(user)) - return ..() - return UI_CLOSE - + return +// End Overridable Procs + +/datum/wires/proc/interact(mob/user) + if(!interactable(user)) + return + ui_interact(user) + for(var/A in assemblies) + var/obj/item/I = assemblies[A] + if(istype(I) && I.on_found(user)) + return + +/datum/wires/ui_host() + return holder + +/datum/wires/ui_status(mob/user) + if(interactable(user)) + return ..() + return UI_CLOSE + /datum/wires/ui_interact(mob/user, ui_key = "wires", datum/tgui/ui = null, force_open = FALSE, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if (!ui) - ui = new(user, src, ui_key, "wires", "[holder.name] wires", 350, 150 + wires.len * 30, master_ui, state) - ui.open() - -/datum/wires/ui_data(mob/user) - var/list/data = list() - var/list/payload = list() - for(var/color in colors) - payload.Add(list(list( - "color" = color, - "wire" = (IsAdminGhost(user) || (user.is_holding_item_of_type(/obj/item/device/multitool/abductor)) ? get_wire(color) : null), - "cut" = is_color_cut(color), - "attached" = is_attached(color) - ))) - data["wires"] = payload - data["status"] = get_status() - return data - -/datum/wires/ui_act(action, params) - if(..() || !interactable(usr)) - return - var/target_wire = params["wire"] - var/mob/living/L = usr - var/obj/item/I = L.get_active_held_item() - switch(action) - if("cut") - if(istype(I, /obj/item/wirecutters) || IsAdminGhost(usr)) - playsound(holder, I.usesound, 20, 1) - cut_color(target_wire) - . = TRUE - else - to_chat(L, "You need wirecutters!") - if("pulse") - if(istype(I, /obj/item/device/multitool) || IsAdminGhost(usr)) - playsound(holder, 'sound/weapons/empty.ogg', 20, 1) + datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if (!ui) + ui = new(user, src, ui_key, "wires", "[holder.name] wires", 350, 150 + wires.len * 30, master_ui, state) + ui.open() + +/datum/wires/ui_data(mob/user) + var/list/data = list() + var/list/payload = list() + for(var/color in colors) + payload.Add(list(list( + "color" = color, + "wire" = (IsAdminGhost(user) || (user.is_holding_item_of_type(/obj/item/device/multitool/abductor)) ? get_wire(color) : null), + "cut" = is_color_cut(color), + "attached" = is_attached(color) + ))) + data["wires"] = payload + data["status"] = get_status() + return data + +/datum/wires/ui_act(action, params) + if(..() || !interactable(usr)) + return + var/target_wire = params["wire"] + var/mob/living/L = usr + var/obj/item/I = L.get_active_held_item() + switch(action) + if("cut") + if(istype(I, /obj/item/wirecutters) || IsAdminGhost(usr)) + playsound(holder, I.usesound, 20, 1) + cut_color(target_wire) + . = TRUE + else + to_chat(L, "You need wirecutters!") + if("pulse") + if(istype(I, /obj/item/device/multitool) || IsAdminGhost(usr)) + playsound(holder, 'sound/weapons/empty.ogg', 20, 1) pulse_color(target_wire, L) - . = TRUE - else - to_chat(L, "You need a multitool!") - if("attach") - if(is_attached(target_wire)) - var/obj/item/O = detach_assembly(target_wire) - if(O) - L.put_in_hands(O) - . = TRUE - else - if(istype(I, /obj/item/device/assembly)) - var/obj/item/device/assembly/A = I - if(A.attachable) - if(!L.drop_item()) - return - attach_assembly(target_wire, A) - . = TRUE - else - to_chat(L, "You need an attachable assembly!") - -#undef MAXIMUM_EMP_WIRES + . = TRUE + else + to_chat(L, "You need a multitool!") + if("attach") + if(is_attached(target_wire)) + var/obj/item/O = detach_assembly(target_wire) + if(O) + L.put_in_hands(O) + . = TRUE + else + if(istype(I, /obj/item/device/assembly)) + var/obj/item/device/assembly/A = I + if(A.attachable) + if(!L.drop_item()) + return + attach_assembly(target_wire, A) + . = TRUE + else + to_chat(L, "You need an attachable assembly!") + +#undef MAXIMUM_EMP_WIRES From 410ca14e17b4c0881d4e0a408c35f2521a837ca1 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 14:25:58 -0500 Subject: [PATCH 47/60] Update h_sandbox.dm --- code/game/gamemodes/sandbox/h_sandbox.dm | 328 ++--------------------- 1 file changed, 27 insertions(+), 301 deletions(-) diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm index 9d51ff7b36..15cd346b2d 100644 --- a/code/game/gamemodes/sandbox/h_sandbox.dm +++ b/code/game/gamemodes/sandbox/h_sandbox.dm @@ -1,308 +1,35 @@ - - -GLOBAL_VAR_INIT(hsboxspawn, TRUE) - -/mob - var/datum/hSB/sandbox = null -/mob/proc/CanBuild() - sandbox = new/datum/hSB - sandbox.owner = src.ckey - if(src.client.holder) - sandbox.admin = 1 - verbs += new/mob/proc/sandbox_panel -/mob/proc/sandbox_panel() - set name = "Sandbox Panel" - if(sandbox) - sandbox.update() - -/datum/hSB - var/owner = null - var/admin = 0 - + + +GLOBAL_VAR_INIT(hsboxspawn, TRUE) + +/mob + var/datum/hSB/sandbox = null +/mob/proc/CanBuild() + sandbox = new/datum/hSB + sandbox.owner = src.ckey + if(src.client.holder) + sandbox.admin = 1 + verbs += new/mob/proc/sandbox_panel +/mob/proc/sandbox_panel() + set name = "Sandbox Panel" + if(sandbox) + sandbox.update() + +/datum/hSB + var/owner = null + var/admin = 0 + var/static/clothinfo = null var/static/reaginfo = null var/static/objinfo = null - var/canisterinfo = null - var/hsbinfo = null - //items that shouldn't spawn on the floor because they would bug or act weird - var/global/list/spawn_forbidden = list( - /obj/item/tk_grab, /obj/item/implant, // not implanter, the actual thing that is inside you + var/canisterinfo = null + var/hsbinfo = null + //items that shouldn't spawn on the floor because they would bug or act weird + var/global/list/spawn_forbidden = list( + /obj/item/tk_grab, /obj/item/implant, // not implanter, the actual thing that is inside you /obj/item/assembly, /obj/item/device/onetankbomb, /obj/item/radio, /obj/item/device/pda/ai, - /obj/item/device/uplink, /obj/item/smallDelivery, /obj/item/projectile, + /obj/item/device/uplink, /obj/item/smallDelivery, /obj/item/projectile, /obj/item/borg/sight, /obj/item/borg/stun, /obj/item/robot_module) -<<<<<<< HEAD - -/datum/hSB/proc/update() - var/global/list/hrefs = list( - "Space Gear", - "Suit Up (Space Travel Gear)" = "hsbsuit", - "Spawn Gas Mask" = "hsbspawn&path=[/obj/item/clothing/mask/gas]", - "Spawn Emergency Air Tank" = "hsbspawn&path=[/obj/item/tank/internals/emergency_oxygen/double]", - - "Standard Tools", - "Spawn Flashlight" = "hsbspawn&path=[/obj/item/device/flashlight]", - "Spawn Toolbox" = "hsbspawn&path=[/obj/item/storage/toolbox/mechanical]", - "Spawn Light Replacer" = "hsbspawn&path=[/obj/item/device/lightreplacer]", - "Spawn Medical Kit" = "hsbspawn&path=[/obj/item/storage/firstaid/regular]", - "Spawn All-Access ID" = "hsbaaid", - - "Building Supplies", - "Spawn 50 Wood" = "hsbwood", - "Spawn 50 Metal" = "hsbmetal", - "Spawn 50 Plasteel" = "hsbplasteel", - "Spawn 50 Reinforced Glass" = "hsbrglass", - "Spawn 50 Glass" = "hsbglass", - "Spawn Full Cable Coil" = "hsbspawn&path=[/obj/item/stack/cable_coil]", - "Spawn Hyper Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/hyper]", - "Spawn Inf. Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/infinite]", - "Spawn Rapid Construction Device" = "hsbrcd", - "Spawn RCD Ammo" = "hsb_safespawn&path=[/obj/item/rcd_ammo]", - "Spawn Airlock" = "hsbairlock", - - "Miscellaneous", - "Spawn Air Scrubber" = "hsbscrubber", - "Spawn Welding Fuel Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/fueltank]", - "Spawn Water Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/watertank]", - - "Bots", - "Spawn Cleanbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/cleanbot]", - "Spawn Floorbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/floorbot]", - "Spawn Medbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/medbot]", - - "Canisters", - "Spawn O2 Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/oxygen]", - "Spawn Air Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/air]") - - - if(!hsbinfo) - hsbinfo = "
    Sandbox Panel

    " - if(admin) - hsbinfo += "Administration
    " - hsbinfo += "- Toggle Object Spawning
    " - hsbinfo += "- Toggle Item Spawn Panel Auto-close
    " - hsbinfo += "Canister Spawning
    " - hsbinfo += "- Spawn Plasma Canister
    " - hsbinfo += "- Spawn CO2 Canister
    " - hsbinfo += "- Spawn Nitrogen Canister
    " - hsbinfo += "- Spawn N2O Canister
    " - else - hsbinfo += "Some item spawning may be disabled by the administrators.
    " - hsbinfo += "Only administrators may spawn dangerous canisters.
    " - for(var/T in hrefs) - var/href = hrefs[T] - if(href) - hsbinfo += "- [T]
    " - else - hsbinfo += "
    [T]
    " - hsbinfo += "
    " - hsbinfo += "- Spawn Clothing...
    " - hsbinfo += "- Spawn Reagent Container...
    " - hsbinfo += "- Spawn Other Item...

    " - - usr << browse(hsbinfo, "window=hsbpanel") - -/datum/hSB/Topic(href, href_list) - if(!usr || !src || !(src.owner == usr.ckey)) - if(usr) - usr << browse(null,"window=sandbox") - return - - if(href_list["hsb"]) - switch(href_list["hsb"]) - // - // Admin: toggle spawning - // - if("hsbtobj") - if(!admin) return - if(GLOB.hsboxspawn) - to_chat(world, "Sandbox: \black[usr.key] has disabled object spawning!") - GLOB.hsboxspawn = FALSE - return - else - to_chat(world, "Sandbox: \black[usr.key] has enabled object spawning!") - GLOB.hsboxspawn = TRUE - return - // - // Admin: Toggle auto-close - // - if("hsbtac") - if(!admin) return - if(config.sandbox_autoclose) - to_chat(world, "Sandbox: \black [usr.key] has removed the object spawn limiter.") - config.sandbox_autoclose = FALSE - else - to_chat(world, "Sandbox: \black [usr.key] has added a limiter to object spawning. The window will now auto-close after use.") - config.sandbox_autoclose = TRUE - return - // - // Spacesuit with full air jetpack set as internals - // - if("hsbsuit") - var/mob/living/carbon/human/P = usr - if(!istype(P)) return - if(P.wear_suit) - P.wear_suit.loc = P.loc - P.wear_suit.layer = initial(P.wear_suit.layer) - P.wear_suit.plane = initial(P.wear_suit.plane) - P.wear_suit = null - P.wear_suit = new/obj/item/clothing/suit/space(P) - P.wear_suit.layer = ABOVE_HUD_LAYER - P.wear_suit.plane = ABOVE_HUD_PLANE - P.update_inv_wear_suit() - if(P.head) - P.head.loc = P.loc - P.head.layer = initial(P.head.layer) - P.head.plane = initial(P.head.plane) - P.head = null - P.head = new/obj/item/clothing/head/helmet/space(P) - P.head.layer = ABOVE_HUD_LAYER - P.head.plane = ABOVE_HUD_PLANE - P.update_inv_head() - if(P.wear_mask) - P.wear_mask.loc = P.loc - P.wear_mask.layer = initial(P.wear_mask.layer) - P.wear_mask.plane = initial(P.wear_mask.plane) - P.wear_mask = null - P.wear_mask = new/obj/item/clothing/mask/gas(P) - P.wear_mask.layer = ABOVE_HUD_LAYER - P.wear_mask.plane = ABOVE_HUD_PLANE - P.update_inv_wear_mask() - if(P.back) - P.back.loc = P.loc - P.back.layer = initial(P.back.layer) - P.back.plane = initial(P.back.plane) - P.back = null - P.back = new/obj/item/tank/jetpack/oxygen(P) - P.back.layer = ABOVE_HUD_LAYER - P.back.plane = ABOVE_HUD_PLANE - P.update_inv_back() - P.internal = P.back - P.update_internals_hud_icon(1) - - if("hsbscrubber") // This is beyond its normal capability but this is sandbox and you spawned one, I assume you need it - var/obj/hsb = new/obj/machinery/portable_atmospherics/scrubber{volume_rate=50*ONE_ATMOSPHERE;on=1}(usr.loc) - hsb.update_icon() // hackish but it wasn't meant to be spawned I guess? - - // - // Stacked Materials - // - - if("hsbrglass") - new/obj/item/stack/sheet/rglass{amount=50}(usr.loc) - - if("hsbmetal") - new/obj/item/stack/sheet/metal{amount=50}(usr.loc) - - if("hsbplasteel") - new/obj/item/stack/sheet/plasteel{amount=50}(usr.loc) - - if("hsbglass") - new/obj/item/stack/sheet/glass{amount=50}(usr.loc) - - if("hsbwood") - new/obj/item/stack/sheet/mineral/wood{amount=50}(usr.loc) - - // - // All access ID - // - if("hsbaaid") - var/obj/item/card/id/gold/ID = new(usr.loc) - ID.registered_name = usr.real_name - ID.assignment = "Sandbox" - ID.access = get_all_accesses() - ID.update_label() - - // - // RCD - starts with full clip - // Spawn check due to grief potential (destroying floors, walls, etc) - // - if("hsbrcd") - if(!GLOB.hsboxspawn) return - - new/obj/item/construction/rcd/combat(usr.loc) - - // - // New sandbox airlock maker - // - if("hsbairlock") - new /datum/airlock_maker(usr.loc) - - // - // Object spawn window - // - - // Clothing - if("hsbcloth") - if(!GLOB.hsboxspawn) return - - if(!clothinfo) - clothinfo = "Clothing (Reagent Containers) (Other Items)

    " - var/list/all_items = subtypesof(/obj/item/clothing) - for(var/typekey in spawn_forbidden) - all_items -= typesof(typekey) - for(var/O in reverseRange(all_items)) - clothinfo += "[O]
    " - - usr << browse(clothinfo,"window=sandbox") - - // Reagent containers - if("hsbreag") - if(!GLOB.hsboxspawn) return - - if(!reaginfo) - reaginfo = "Reagent Containers (Clothing) (Other Items)

    " - var/list/all_items = subtypesof(/obj/item/reagent_containers) - for(var/typekey in spawn_forbidden) - all_items -= typesof(typekey) - for(var/O in reverseRange(all_items)) - reaginfo += "[O]
    " - - usr << browse(reaginfo,"window=sandbox") - - // Other items - if("hsbobj") - if(!GLOB.hsboxspawn) return - - if(!objinfo) - objinfo = "Other Items (Clothing) (Reagent Containers)

    " - var/list/all_items = subtypesof(/obj/item/) - typesof(/obj/item/clothing) - typesof(/obj/item/reagent_containers) - for(var/typekey in spawn_forbidden) - all_items -= typesof(typekey) - - for(var/O in reverseRange(all_items)) - objinfo += "[O]
    " - - usr << browse(objinfo,"window=sandbox") - - // - // Safespawn checks to see if spawning is disabled. - // - if("hsb_safespawn") - if(!GLOB.hsboxspawn) - usr << browse(null,"window=sandbox") - return - - var/typepath = text2path(href_list["path"]) - if(!typepath) - to_chat(usr, "Bad path: \"[href_list["path"]]\"") - return - new typepath(usr.loc) - - if(config.sandbox_autoclose) - usr << browse(null,"window=sandbox") - // - // For everything else in the href list - // - if("hsbspawn") - var/typepath = text2path(href_list["path"]) - if(!typepath) - to_chat(usr, "Bad path: \"[href_list["path"]]\"") - return - new typepath(usr.loc) - - if(config.sandbox_autoclose) - usr << browse(null,"window=sandbox") -======= /datum/hSB/proc/update() var/global/list/hrefs = list( @@ -574,4 +301,3 @@ GLOBAL_VAR_INIT(hsboxspawn, TRUE) if(CONFIG_GET(flag/sandbox_autoclose)) usr << browse(null,"window=sandbox") ->>>>>>> 8b54685... Cleanup to various loc assignments and nearby code (#31069) From cc9e46298872beb7f391017e2b790ef5b0ece222 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 14:26:22 -0500 Subject: [PATCH 48/60] Update camera_assembly.dm --- code/game/machinery/camera/camera_assembly.dm | 225 +++++++----------- 1 file changed, 81 insertions(+), 144 deletions(-) diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index b5343aa3ad..1e6fe4c532 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -1,147 +1,85 @@ -/obj/item/wallframe/camera - name = "camera assembly" - desc = "The basic construction for Nanotrasen-Always-Watching-You cameras." - icon = 'icons/obj/monitors.dmi' - icon_state = "cameracase" - materials = list(MAT_METAL=400, MAT_GLASS=250) - result_path = /obj/structure/camera_assembly - - -/obj/structure/camera_assembly - name = "camera assembly" - desc = "The basic construction for Nanotrasen-Always-Watching-You cameras." - icon = 'icons/obj/monitors.dmi' - icon_state = "camera1" - max_integrity = 150 - // Motion, EMP-Proof, X-Ray - var/static/list/possible_upgrades = typecacheof(list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/sheet/mineral/plasma, /obj/item/device/analyzer)) - var/list/upgrades - var/state = 1 - - /* - 1 = Wrenched in place - 2 = Welded in place - 3 = Wires attached to it (you can now attach/dettach upgrades) - 4 = Screwdriver panel closed and is fully built (you cannot attach upgrades) - */ - -/obj/structure/camera_assembly/Initialize(mapload, ndir, building) - . = ..() - if(building) - setDir(ndir) - upgrades = list() - -/obj/structure/camera_assembly/Destroy() - QDEL_LIST(upgrades) - return ..() - -/obj/structure/camera_assembly/attackby(obj/item/W, mob/living/user, params) - switch(state) - if(1) - // State 1 - if(istype(W, /obj/item/weldingtool)) - if(weld(W, user)) - to_chat(user, "You weld the assembly securely into place.") +/obj/item/wallframe/camera + name = "camera assembly" + desc = "The basic construction for Nanotrasen-Always-Watching-You cameras." + icon = 'icons/obj/monitors.dmi' + icon_state = "cameracase" + materials = list(MAT_METAL=400, MAT_GLASS=250) + result_path = /obj/structure/camera_assembly + + +/obj/structure/camera_assembly + name = "camera assembly" + desc = "The basic construction for Nanotrasen-Always-Watching-You cameras." + icon = 'icons/obj/monitors.dmi' + icon_state = "camera1" + max_integrity = 150 + // Motion, EMP-Proof, X-Ray + var/static/list/possible_upgrades = typecacheof(list(/obj/item/device/assembly/prox_sensor, /obj/item/stack/sheet/mineral/plasma, /obj/item/device/analyzer)) + var/list/upgrades + var/state = 1 + + /* + 1 = Wrenched in place + 2 = Welded in place + 3 = Wires attached to it (you can now attach/dettach upgrades) + 4 = Screwdriver panel closed and is fully built (you cannot attach upgrades) + */ + +/obj/structure/camera_assembly/Initialize(mapload, ndir, building) + . = ..() + if(building) + setDir(ndir) + upgrades = list() + +/obj/structure/camera_assembly/Destroy() + QDEL_LIST(upgrades) + return ..() + +/obj/structure/camera_assembly/attackby(obj/item/W, mob/living/user, params) + switch(state) + if(1) + // State 1 + if(istype(W, /obj/item/weldingtool)) + if(weld(W, user)) + to_chat(user, "You weld the assembly securely into place.") anchored = TRUE - state = 2 - return - - else if(istype(W, /obj/item/wrench)) - playsound(src.loc, W.usesound, 50, 1) - to_chat(user, "You unattach the assembly from its place.") - new /obj/item/wallframe/camera(get_turf(src)) - qdel(src) - return - - if(2) - // State 2 - if(istype(W, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/C = W - if(C.use(2)) - to_chat(user, "You add wires to the assembly.") - state = 3 - else - to_chat(user, "You need two lengths of cable to wire a camera!") - return - return - - else if(istype(W, /obj/item/weldingtool)) - - if(weld(W, user)) - to_chat(user, "You unweld the assembly from its place.") - state = 1 + state = 2 + return + + else if(istype(W, /obj/item/wrench)) + playsound(src.loc, W.usesound, 50, 1) + to_chat(user, "You unattach the assembly from its place.") + new /obj/item/wallframe/camera(get_turf(src)) + qdel(src) + return + + if(2) + // State 2 + if(istype(W, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/C = W + if(C.use(2)) + to_chat(user, "You add wires to the assembly.") + state = 3 + else + to_chat(user, "You need two lengths of cable to wire a camera!") + return + return + + else if(istype(W, /obj/item/weldingtool)) + + if(weld(W, user)) + to_chat(user, "You unweld the assembly from its place.") + state = 1 anchored = TRUE - return - - - if(3) - // State 3 - if(istype(W, /obj/item/screwdriver)) - playsound(src.loc, W.usesound, 50, 1) - + return + + + if(3) + // State 3 + if(istype(W, /obj/item/screwdriver)) + playsound(src.loc, W.usesound, 50, 1) + var/input = stripped_input(user, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13") -<<<<<<< HEAD - if(!input) - to_chat(user, "No input found, please hang up and try your call again!") - return - - var/list/tempnetwork = splittext(input, ",") - if(tempnetwork.len < 1) - to_chat(user, "No network found, please hang up and try your call again!") - return - - state = 4 - var/obj/machinery/camera/C = new(src.loc) - src.loc = C - C.assembly = src - C.setDir(src.dir) - - C.network = tempnetwork - var/area/A = get_area(src) - C.c_tag = "[A.name] ([rand(1, 999)])" - - - else if(istype(W, /obj/item/wirecutters)) - new/obj/item/stack/cable_coil(get_turf(src), 2) - playsound(src.loc, W.usesound, 50, 1) - to_chat(user, "You cut the wires from the circuits.") - state = 2 - return - - // Upgrades! - if(is_type_in_typecache(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already. - if(!user.drop_item(W)) - return - to_chat(user, "You attach \the [W] into the assembly inner circuits.") - upgrades += W - W.forceMove(src) - return - - // Taking out upgrades - else if(istype(W, /obj/item/crowbar) && upgrades.len) - var/obj/U = locate(/obj) in upgrades - if(U) - to_chat(user, "You unattach an upgrade from the assembly.") - playsound(src.loc, W.usesound, 50, 1) - U.loc = get_turf(src) - upgrades -= U - return - - return ..() - -/obj/structure/camera_assembly/proc/weld(obj/item/weldingtool/WT, mob/living/user) - if(!WT.remove_fuel(0, user)) - return 0 - to_chat(user, "You start to weld \the [src]...") - playsound(src.loc, WT.usesound, 50, 1) - if(do_after(user, 20*WT.toolspeed, target = src)) - if(WT.isOn()) - playsound(loc, 'sound/items/welder2.ogg', 50, 1) - return 1 - return 0 - -/obj/structure/camera_assembly/deconstruct(disassembled = TRUE) -======= if(!input) to_chat(user, "No input found, please hang up and try your call again!") return @@ -202,7 +140,6 @@ return 0 /obj/structure/camera_assembly/deconstruct(disassembled = TRUE) ->>>>>>> 8b54685... Cleanup to various loc assignments and nearby code (#31069) if(!(flags_1 & NODECONSTRUCT_1)) - new /obj/item/stack/sheet/metal(loc) - qdel(src) + new /obj/item/stack/sheet/metal(loc) + qdel(src) From 07c95ef168aa120879dd5f4b4e45ae8928c3079d Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 14:26:41 -0500 Subject: [PATCH 49/60] Update aifixer.dm --- code/game/machinery/computer/aifixer.dm | 149 ------------------------ 1 file changed, 149 deletions(-) diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index 485d56ced2..b590763ffe 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -1,151 +1,3 @@ -<<<<<<< HEAD -/obj/machinery/computer/aifixer - name = "\improper AI system integrity restorer" - desc = "Used with intelliCards containing nonfunctioning AIs to restore them to working order." - req_access = list(ACCESS_CAPTAIN, ACCESS_ROBOTICS, ACCESS_HEADS) - var/mob/living/silicon/ai/occupier = null - var/active = 0 - circuit = /obj/item/circuitboard/computer/aifixer - icon_keyboard = "tech_key" - icon_screen = "ai-fixer" - light_color = LIGHT_COLOR_PINK - -/obj/machinery/computer/aifixer/attackby(obj/I, mob/user, params) - if(occupier && istype(I, /obj/item/screwdriver)) - if(stat & (NOPOWER|BROKEN)) - to_chat(user, "The screws on [name]'s screen won't budge.") - else - to_chat(user, "The screws on [name]'s screen won't budge and it emits a warning beep.") - else - return ..() - -/obj/machinery/computer/aifixer/attack_hand(mob/user) - if(..()) - return - interact(user) - -/obj/machinery/computer/aifixer/interact(mob/user) - - var/dat = "" - - if (src.occupier) - var/laws - dat += "

    Stored AI: [src.occupier.name]

    " - dat += "System integrity: [(src.occupier.health+100)/2]%
    " - - if (src.occupier.laws.zeroth) - laws += "0: [src.occupier.laws.zeroth]
    " - - for (var/index = 1, index <= src.occupier.laws.ion.len, index++) - var/law = src.occupier.laws.ion[index] - if (length(law) > 0) - var/num = ionnum() - laws += "[num]: [law]
    " - - var/number = 1 - for (var/index = 1, index <= src.occupier.laws.inherent.len, index++) - var/law = src.occupier.laws.inherent[index] - if (length(law) > 0) - laws += "[number]: [law]
    " - number++ - - for (var/index = 1, index <= src.occupier.laws.supplied.len, index++) - var/law = src.occupier.laws.supplied[index] - if (length(law) > 0) - laws += "[number]: [law]
    " - number++ - - dat += "Laws:
    [laws]
    " - - if (src.occupier.stat == DEAD) - dat += "AI non-functional" - else - dat += "AI functional" - if (!src.active) - dat += {"

    Begin Reconstruction"} - else - dat += "

    Reconstruction in process, please wait.
    " - dat += {"
    Close"} - var/datum/browser/popup = new(user, "computer", "AI System Integrity Restorer", 400, 500) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - return - -/obj/machinery/computer/aifixer/proc/Fix() - use_power(1000) - occupier.adjustOxyLoss(-1, 0) - occupier.adjustFireLoss(-1, 0) - occupier.adjustToxLoss(-1, 0) - occupier.adjustBruteLoss(-1, 0) - occupier.updatehealth() - occupier.updatehealth() - if(occupier.health >= 0 && occupier.stat == DEAD) - occupier.revive() - return occupier.health < 100 - -/obj/machinery/computer/aifixer/process() - if(..()) - if(active) - active = Fix() - updateDialog() - update_icon() - -/obj/machinery/computer/aifixer/Topic(href, href_list) - if(..()) - return - if(href_list["fix"]) - to_chat(usr, "Reconstruction in progress. This will take several minutes.") - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0) - active = TRUE - add_fingerprint(usr) - -/obj/machinery/computer/aifixer/update_icon() - ..() - if(stat & (NOPOWER|BROKEN)) - return - else - if(active) - add_overlay("ai-fixer-on") - if (occupier) - switch (occupier.stat) - if (0) - add_overlay("ai-fixer-full") - if (2) - add_overlay("ai-fixer-404") - else - add_overlay("ai-fixer-empty") - -/obj/machinery/computer/aifixer/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/device/aicard/card) - if(!..()) - return - //Downloading AI from card to terminal. - if(interaction == AI_TRANS_FROM_CARD) - if(stat & (NOPOWER|BROKEN)) - to_chat(user, "[src] is offline and cannot take an AI at this time!") - return - AI.forceMove(src) - occupier = AI - AI.control_disabled = 1 - AI.radio_enabled = 0 - to_chat(AI, "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here.") - to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.") - card.AI = null - update_icon() - - else //Uploading AI from terminal to card - if(occupier && !active) - to_chat(occupier, "You have been downloaded to a mobile storage device. Still no remote access.") - to_chat(user, "Transfer successful: [occupier.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory.") - occupier.loc = card - card.AI = occupier - occupier = null - update_icon() - else if (active) - to_chat(user, "ERROR: Reconstruction in progress.") - else if (!occupier) - to_chat(user, "ERROR: Unable to locate artificial intelligence.") -======= /obj/machinery/computer/aifixer name = "\improper AI system integrity restorer" desc = "Used with intelliCards containing nonfunctioning AIs to restore them to working order." @@ -292,4 +144,3 @@ to_chat(user, "ERROR: Reconstruction in progress.") else if (!occupier) to_chat(user, "ERROR: Unable to locate artificial intelligence.") ->>>>>>> 8b54685... Cleanup to various loc assignments and nearby code (#31069) From 9e4831163298f3ae2275c1958562861b29de05d9 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 14:27:04 -0500 Subject: [PATCH 50/60] Update cloning.dm --- code/game/machinery/computer/cloning.dm | 894 +++++++++++------------- 1 file changed, 394 insertions(+), 500 deletions(-) diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 755a030565..6ec2fdf566 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -1,131 +1,26 @@ -/obj/machinery/computer/cloning - name = "cloning console" - desc = "Used to clone people and manage DNA." - icon_screen = "dna" - icon_keyboard = "med_key" - circuit = /obj/item/circuitboard/computer/cloning +/obj/machinery/computer/cloning + name = "cloning console" + desc = "Used to clone people and manage DNA." + icon_screen = "dna" + icon_keyboard = "med_key" + circuit = /obj/item/circuitboard/computer/cloning req_access = list(ACCESS_HEADS) //ONLY USED FOR RECORD DELETION RIGHT NOW. - var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning. - var/list/pods //Linked cloning pods - var/temp = "Inactive" - var/scantemp_ckey - var/scantemp = "Ready to Scan" - var/menu = 1 //Which menu screen to display - var/list/records = list() - var/datum/data/record/active_record = null - var/obj/item/disk/data/diskette = null //Mostly so the geneticist can steal everything. - var/loading = 0 // Nice loading text - var/autoprocess = 0 - - light_color = LIGHT_COLOR_BLUE - -/obj/machinery/computer/cloning/Initialize() + var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning. + var/list/pods //Linked cloning pods + var/temp = "Inactive" + var/scantemp_ckey + var/scantemp = "Ready to Scan" + var/menu = 1 //Which menu screen to display + var/list/records = list() + var/datum/data/record/active_record = null + var/obj/item/disk/data/diskette = null //Mostly so the geneticist can steal everything. + var/loading = 0 // Nice loading text + var/autoprocess = 0 + + light_color = LIGHT_COLOR_BLUE + +/obj/machinery/computer/cloning/Initialize() . = ..() -<<<<<<< HEAD - updatemodules(TRUE) - -/obj/machinery/computer/cloning/Destroy() - if(pods) - for(var/P in pods) - DetachCloner(P) - pods = null - return ..() - -/obj/machinery/computer/cloning/proc/GetAvailablePod(mind = null) - if(pods) - for(var/P in pods) - var/obj/machinery/clonepod/pod = P - if(pod.occupant && pod.clonemind == mind) - return null - if(pod.is_operational() && !(pod.occupant || pod.mess)) - return pod - -/obj/machinery/computer/cloning/proc/HasEfficientPod() - if(pods) - for(var/P in pods) - var/obj/machinery/clonepod/pod = P - if(pod.is_operational() && pod.efficiency > 5) - return TRUE - -/obj/machinery/computer/cloning/proc/GetAvailableEfficientPod(mind = null) - if(pods) - for(var/P in pods) - var/obj/machinery/clonepod/pod = P - if(pod.occupant && pod.clonemind == mind) - return pod - else if(!. && pod.is_operational() && !(pod.occupant || pod.mess) && pod.efficiency > 5) - . = pod - -/obj/machinery/computer/cloning/process() - if(!(scanner && LAZYLEN(pods) && autoprocess)) - return - - if(scanner.occupant && scanner.scan_level > 2) - scan_occupant(scanner.occupant) - - for(var/datum/data/record/R in records) - var/obj/machinery/clonepod/pod = GetAvailableEfficientPod(R.fields["mind"]) - - if(!pod) - return - - if(pod.occupant) - continue //how though? - - if(pod.growclone(R.fields["ckey"], R.fields["name"], R.fields["UI"], R.fields["SE"], R.fields["mind"], R.fields["mrace"], R.fields["features"], R.fields["factions"])) - records -= R - -/obj/machinery/computer/cloning/proc/updatemodules(findfirstcloner) - src.scanner = findscanner() - if(findfirstcloner && !LAZYLEN(pods)) - findcloner() - -/obj/machinery/computer/cloning/proc/findscanner() - var/obj/machinery/dna_scannernew/scannerf = null - - // Loop through every direction - for(dir in list(NORTH,EAST,SOUTH,WEST)) - - // Try to find a scanner in that direction - scannerf = locate(/obj/machinery/dna_scannernew, get_step(src, dir)) - - // If found and operational, return the scanner - if (!isnull(scannerf) && scannerf.is_operational()) - return scannerf - - // If no scanner was found, it will return null - return null - -/obj/machinery/computer/cloning/proc/findcloner() - var/obj/machinery/clonepod/podf = null - - for(dir in list(NORTH,EAST,SOUTH,WEST)) - - podf = locate(/obj/machinery/clonepod, get_step(src, dir)) - - if (!isnull(podf) && podf.is_operational()) - AttachCloner(podf) - -/obj/machinery/computer/cloning/proc/AttachCloner(obj/machinery/clonepod/pod) - if(!pod.connected) - pod.connected = src - LAZYADD(pods, pod) - -/obj/machinery/computer/cloning/proc/DetachCloner(obj/machinery/clonepod/pod) - pod.connected = null - LAZYREMOVE(pods, pod) - -/obj/machinery/computer/cloning/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/disk/data)) //INSERT SOME DISKETTES - if (!src.diskette) - if(!user.drop_item()) - return - W.loc = src - src.diskette = W - to_chat(user, "You insert [W].") - playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) - src.updateUsrDialog() -======= updatemodules(TRUE) /obj/machinery/computer/cloning/Destroy() @@ -228,384 +123,383 @@ to_chat(user, "You insert [W].") playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) src.updateUsrDialog() ->>>>>>> 8b54685... Cleanup to various loc assignments and nearby code (#31069) else if(istype(W, /obj/item/device/multitool)) - var/obj/item/device/multitool/P = W - - if(istype(P.buffer, /obj/machinery/clonepod)) - if(get_area(P.buffer) != get_area(src)) - to_chat(user, "-% Cannot link machines across power zones. Buffer cleared %-") - P.buffer = null - return - to_chat(user, "-% Successfully linked [P.buffer] with [src] %-") - var/obj/machinery/clonepod/pod = P.buffer - if(pod.connected) - pod.connected.DetachCloner(pod) - AttachCloner(pod) - else - P.buffer = src - to_chat(user, "-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %-") - return - else - return ..() - -/obj/machinery/computer/cloning/attack_hand(mob/user) - if(..()) - return - interact(user) - -/obj/machinery/computer/cloning/interact(mob/user) - user.set_machine(src) - add_fingerprint(user) - - if(..()) - return - - updatemodules(TRUE) - - var/dat = "" - dat += "Refresh" - - if(scanner && HasEfficientPod() && scanner.scan_level > 2) - if(!autoprocess) - dat += "Autoprocess" - else - dat += "Stop autoprocess" - else - dat += "Autoprocess" - dat += "

    Cloning Pod Status

    " - dat += "
    [temp] 
    " - - switch(src.menu) - if(1) - // Modules - if (isnull(src.scanner) || !LAZYLEN(pods)) - dat += "

    Modules

    " - //dat += "Reload Modules" - if (isnull(src.scanner)) - dat += "ERROR: No Scanner detected!
    " - if (!LAZYLEN(pods)) - dat += "ERROR: No Pod detected
    " - - // Scanner - if (!isnull(src.scanner)) - var/mob/living/scanner_occupant = get_mob_or_brainmob(scanner.occupant) - - dat += "

    Scanner Functions

    " - - dat += "
    " - if(!scanner_occupant) - dat += "Scanner Unoccupied" - else if(loading) - dat += "[scanner_occupant] => Scanning..." - else - if(scanner_occupant.ckey != scantemp_ckey) - scantemp = "Ready to Scan" - scantemp_ckey = scanner_occupant.ckey - dat += "[scanner_occupant] => [scantemp]" - dat += "
    " - - if(scanner_occupant) - dat += "Start Scan" - dat += "
    [src.scanner.locked ? "Unlock Scanner" : "Lock Scanner"]" - else - dat += "Start Scan" - - // Database - dat += "

    Database Functions

    " - if (src.records.len && src.records.len > 0) - dat += "View Records ([src.records.len])
    " - else - dat += "View Records (0)
    " - if (src.diskette) - dat += "Eject Disk
    " - - - - if(2) - dat += "

    Current records

    " - dat += "<< Back

    " - for(var/datum/data/record/R in records) - dat += "

    [R.fields["name"]]

    Scan ID [R.fields["id"]] View Record" - if(3) - dat += "

    Selected Record

    " - dat += "<< Back
    " - - if (!src.active_record) - dat += "Record not found." - else - dat += "

    [src.active_record.fields["name"]]

    " - dat += "Scan ID [src.active_record.fields["id"]] Clone
    " - - var/obj/item/implant/health/H = locate(src.active_record.fields["imp"]) - - if ((H) && (istype(H))) - dat += "Health Implant Data:
    [H.sensehealth()]

    " - else - dat += "Unable to locate Health Implant.

    " - - dat += "Unique Identifier:
    [src.active_record.fields["UI"]]
    " - dat += "Structural Enzymes:
    [src.active_record.fields["SE"]]
    " - - if(diskette && diskette.fields) - dat += "
    " - dat += "

    Inserted Disk

    " - dat += "Contents: " - var/list/L = list() - if(diskette.fields["UI"]) - L += "Unique Identifier" - if(diskette.fields["UE"] && diskette.fields["name"] && diskette.fields["blood_type"]) - L += "Unique Enzymes" - if(diskette.fields["SE"]) - L += "Structural Enzymes" - dat += english_list(L, "Empty", " + ", " + ") - dat += "
    Load from Disk" - - dat += "
    Save to Disk" - dat += "
    " - - dat += "Delete Record" - - if(4) - if (!src.active_record) - src.menu = 2 - dat = "[src.temp]
    " - dat += "

    Confirm Record Deletion

    " - - dat += "Scan card to confirm.
    " - dat += "Cancel" - - - var/datum/browser/popup = new(user, "cloning", "Cloning System Control") - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - -/obj/machinery/computer/cloning/Topic(href, href_list) - if(..()) - return - - if(loading) - return - - if(href_list["task"]) - switch(href_list["task"]) - if("autoprocess") - autoprocess = 1 - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - if("stopautoprocess") - autoprocess = 0 - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - - else if ((href_list["scan"]) && !isnull(scanner) && scanner.is_operational()) - scantemp = "" - - loading = 1 - src.updateUsrDialog() - playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) - say("Initiating scan...") - - spawn(20) - src.scan_occupant(scanner.occupant) - - loading = 0 - src.updateUsrDialog() - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - - - //No locking an open scanner. - else if ((href_list["lock"]) && !isnull(scanner) && scanner.is_operational()) - if ((!scanner.locked) && (scanner.occupant)) + var/obj/item/device/multitool/P = W + + if(istype(P.buffer, /obj/machinery/clonepod)) + if(get_area(P.buffer) != get_area(src)) + to_chat(user, "-% Cannot link machines across power zones. Buffer cleared %-") + P.buffer = null + return + to_chat(user, "-% Successfully linked [P.buffer] with [src] %-") + var/obj/machinery/clonepod/pod = P.buffer + if(pod.connected) + pod.connected.DetachCloner(pod) + AttachCloner(pod) + else + P.buffer = src + to_chat(user, "-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %-") + return + else + return ..() + +/obj/machinery/computer/cloning/attack_hand(mob/user) + if(..()) + return + interact(user) + +/obj/machinery/computer/cloning/interact(mob/user) + user.set_machine(src) + add_fingerprint(user) + + if(..()) + return + + updatemodules(TRUE) + + var/dat = "" + dat += "Refresh" + + if(scanner && HasEfficientPod() && scanner.scan_level > 2) + if(!autoprocess) + dat += "Autoprocess" + else + dat += "Stop autoprocess" + else + dat += "Autoprocess" + dat += "

    Cloning Pod Status

    " + dat += "
    [temp] 
    " + + switch(src.menu) + if(1) + // Modules + if (isnull(src.scanner) || !LAZYLEN(pods)) + dat += "

    Modules

    " + //dat += "Reload Modules" + if (isnull(src.scanner)) + dat += "ERROR: No Scanner detected!
    " + if (!LAZYLEN(pods)) + dat += "ERROR: No Pod detected
    " + + // Scanner + if (!isnull(src.scanner)) + var/mob/living/scanner_occupant = get_mob_or_brainmob(scanner.occupant) + + dat += "

    Scanner Functions

    " + + dat += "
    " + if(!scanner_occupant) + dat += "Scanner Unoccupied" + else if(loading) + dat += "[scanner_occupant] => Scanning..." + else + if(scanner_occupant.ckey != scantemp_ckey) + scantemp = "Ready to Scan" + scantemp_ckey = scanner_occupant.ckey + dat += "[scanner_occupant] => [scantemp]" + dat += "
    " + + if(scanner_occupant) + dat += "Start Scan" + dat += "
    [src.scanner.locked ? "Unlock Scanner" : "Lock Scanner"]" + else + dat += "Start Scan" + + // Database + dat += "

    Database Functions

    " + if (src.records.len && src.records.len > 0) + dat += "View Records ([src.records.len])
    " + else + dat += "View Records (0)
    " + if (src.diskette) + dat += "Eject Disk
    " + + + + if(2) + dat += "

    Current records

    " + dat += "<< Back

    " + for(var/datum/data/record/R in records) + dat += "

    [R.fields["name"]]

    Scan ID [R.fields["id"]] View Record" + if(3) + dat += "

    Selected Record

    " + dat += "<< Back
    " + + if (!src.active_record) + dat += "Record not found." + else + dat += "

    [src.active_record.fields["name"]]

    " + dat += "Scan ID [src.active_record.fields["id"]] Clone
    " + + var/obj/item/implant/health/H = locate(src.active_record.fields["imp"]) + + if ((H) && (istype(H))) + dat += "Health Implant Data:
    [H.sensehealth()]

    " + else + dat += "Unable to locate Health Implant.

    " + + dat += "Unique Identifier:
    [src.active_record.fields["UI"]]
    " + dat += "Structural Enzymes:
    [src.active_record.fields["SE"]]
    " + + if(diskette && diskette.fields) + dat += "
    " + dat += "

    Inserted Disk

    " + dat += "Contents: " + var/list/L = list() + if(diskette.fields["UI"]) + L += "Unique Identifier" + if(diskette.fields["UE"] && diskette.fields["name"] && diskette.fields["blood_type"]) + L += "Unique Enzymes" + if(diskette.fields["SE"]) + L += "Structural Enzymes" + dat += english_list(L, "Empty", " + ", " + ") + dat += "
    Load from Disk" + + dat += "
    Save to Disk" + dat += "
    " + + dat += "Delete Record" + + if(4) + if (!src.active_record) + src.menu = 2 + dat = "[src.temp]
    " + dat += "

    Confirm Record Deletion

    " + + dat += "Scan card to confirm.
    " + dat += "Cancel" + + + var/datum/browser/popup = new(user, "cloning", "Cloning System Control") + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + +/obj/machinery/computer/cloning/Topic(href, href_list) + if(..()) + return + + if(loading) + return + + if(href_list["task"]) + switch(href_list["task"]) + if("autoprocess") + autoprocess = 1 + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + if("stopautoprocess") + autoprocess = 0 + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + + else if ((href_list["scan"]) && !isnull(scanner) && scanner.is_operational()) + scantemp = "" + + loading = 1 + src.updateUsrDialog() + playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) + say("Initiating scan...") + + spawn(20) + src.scan_occupant(scanner.occupant) + + loading = 0 + src.updateUsrDialog() + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + + + //No locking an open scanner. + else if ((href_list["lock"]) && !isnull(scanner) && scanner.is_operational()) + if ((!scanner.locked) && (scanner.occupant)) scanner.locked = TRUE - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else scanner.locked = FALSE <<<<<<< HEAD - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - - else if(href_list["view_rec"]) - playsound(src, "terminal_type", 25, 0) - src.active_record = find_record("id", href_list["view_rec"], records) - if(active_record) - if(!active_record.fields["ckey"]) - records -= active_record - active_record = null - src.temp = "Record Corrupt" - else - src.menu = 3 - else - src.temp = "Record missing." - - else if (href_list["del_rec"]) - if ((!src.active_record) || (src.menu < 3)) - return - if (src.menu == 3) //If we are viewing a record, confirm deletion - src.temp = "Delete record?" - src.menu = 4 - playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) - - else if (src.menu == 4) - var/obj/item/card/id/C = usr.get_active_held_item() - if (istype(C)||istype(C, /obj/item/device/pda)) - if(src.check_access(C)) - src.temp = "[src.active_record.fields["name"]] => Record deleted." - src.records.Remove(active_record) - active_record = null - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - src.menu = 2 - else - src.temp = "Access Denied." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - - else if (href_list["disk"]) //Load or eject. - switch(href_list["disk"]) - if("load") - if (!diskette || !istype(diskette.fields) || !diskette.fields["name"] || !diskette.fields) - src.temp = "Load error." - src.updateUsrDialog() - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - if (!src.active_record) - src.temp = "Record error." - src.menu = 1 - src.updateUsrDialog() - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - - for(var/key in diskette.fields) - src.active_record.fields[key] = diskette.fields[key] - src.temp = "Load successful." - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - - if("eject") - if(src.diskette) - src.diskette.loc = src.loc - src.diskette = null - playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) - if("save") - if(!diskette || diskette.read_only || !active_record || !active_record.fields) - src.temp = "Save error." - src.updateUsrDialog() - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - - diskette.fields = active_record.fields.Copy() - diskette.name = "data disk - '[src.diskette.fields["name"]]'" - src.temp = "Save successful." - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - - else if (href_list["refresh"]) - src.updateUsrDialog() - playsound(src, "terminal_type", 25, 0) - - else if (href_list["clone"]) - var/datum/data/record/C = find_record("id", href_list["clone"], records) - //Look for that player! They better be dead! - if(C) - var/obj/machinery/clonepod/pod = GetAvailablePod() - //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs. - if(!LAZYLEN(pods)) - temp = "No Clonepods detected." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else if(!pod) - temp = "No Clonepods available." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else if(!config.revival_cloning) - temp = "Unable to initiate cloning cycle." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else if(pod.occupant) - temp = "Cloning cycle already in progress." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["mrace"], C.fields["features"], C.fields["factions"])) - temp = "[C.fields["name"]] => Cloning cycle in progress..." - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - records.Remove(C) - if(active_record == C) - active_record = null - menu = 1 - else - temp = "[C.fields["name"]] => Initialisation failure." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - - else - temp = "Data corruption." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - - else if (href_list["menu"]) - src.menu = text2num(href_list["menu"]) - playsound(src, "terminal_type", 25, 0) - - src.add_fingerprint(usr) - src.updateUsrDialog() - return - -/obj/machinery/computer/cloning/proc/scan_occupant(occupant) - var/mob/living/mob_occupant = get_mob_or_brainmob(occupant) - var/datum/dna/dna - if(iscarbon(mob_occupant)) - var/mob/living/carbon/C = mob_occupant - dna = C.has_dna() - if(isbrain(mob_occupant)) - var/mob/living/brain/B = mob_occupant - dna = B.stored_dna - - if(!istype(dna)) - scantemp = "Unable to locate valid genetic data." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - if(mob_occupant.suiciding || mob_occupant.hellbound) - scantemp = "Subject's brain is not responding to scanning stimuli." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - if((mob_occupant.disabilities & NOCLONE) && (src.scanner.scan_level < 2)) - scantemp = "Subject no longer contains the fundamental materials required to create a living clone." - playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0) - return - if ((!mob_occupant.ckey) || (!mob_occupant.client)) - scantemp = "Mental interface failure." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - if (find_record("ckey", mob_occupant.ckey, records)) - scantemp = "Subject already in database." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - - var/datum/data/record/R = new() - if(dna.species) - // We store the instance rather than the path, because some - // species (abductors, slimepeople) store state in their - // species datums - R.fields["mrace"] = dna.species - else - var/datum/species/rando_race = pick(config.roundstart_races) - R.fields["mrace"] = rando_race.type - - R.fields["ckey"] = mob_occupant.ckey - R.fields["name"] = mob_occupant.real_name - R.fields["id"] = copytext(md5(mob_occupant.real_name), 2, 6) - R.fields["UE"] = dna.unique_enzymes - R.fields["UI"] = dna.uni_identity - R.fields["SE"] = dna.struc_enzymes - R.fields["blood_type"] = dna.blood_type - R.fields["features"] = dna.features - R.fields["factions"] = mob_occupant.faction - - if (!isnull(mob_occupant.mind)) //Save that mind so traitors can continue traitoring after cloning. - R.fields["mind"] = "\ref[mob_occupant.mind]" - - //Add an implant if needed - var/obj/item/implant/health/imp - for(var/obj/item/implant/health/HI in mob_occupant.implants) - imp = HI - break - if(!imp) - imp = new /obj/item/implant/health(mob_occupant) - imp.implant(mob_occupant) - R.fields["imp"] = "\ref[imp]" - - src.records += R - scantemp = "Subject successfully scanned." - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + + else if(href_list["view_rec"]) + playsound(src, "terminal_type", 25, 0) + src.active_record = find_record("id", href_list["view_rec"], records) + if(active_record) + if(!active_record.fields["ckey"]) + records -= active_record + active_record = null + src.temp = "Record Corrupt" + else + src.menu = 3 + else + src.temp = "Record missing." + + else if (href_list["del_rec"]) + if ((!src.active_record) || (src.menu < 3)) + return + if (src.menu == 3) //If we are viewing a record, confirm deletion + src.temp = "Delete record?" + src.menu = 4 + playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) + + else if (src.menu == 4) + var/obj/item/card/id/C = usr.get_active_held_item() + if (istype(C)||istype(C, /obj/item/device/pda)) + if(src.check_access(C)) + src.temp = "[src.active_record.fields["name"]] => Record deleted." + src.records.Remove(active_record) + active_record = null + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + src.menu = 2 + else + src.temp = "Access Denied." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + + else if (href_list["disk"]) //Load or eject. + switch(href_list["disk"]) + if("load") + if (!diskette || !istype(diskette.fields) || !diskette.fields["name"] || !diskette.fields) + src.temp = "Load error." + src.updateUsrDialog() + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + if (!src.active_record) + src.temp = "Record error." + src.menu = 1 + src.updateUsrDialog() + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + + for(var/key in diskette.fields) + src.active_record.fields[key] = diskette.fields[key] + src.temp = "Load successful." + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + + if("eject") + if(src.diskette) + src.diskette.loc = src.loc + src.diskette = null + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) + if("save") + if(!diskette || diskette.read_only || !active_record || !active_record.fields) + src.temp = "Save error." + src.updateUsrDialog() + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + + diskette.fields = active_record.fields.Copy() + diskette.name = "data disk - '[src.diskette.fields["name"]]'" + src.temp = "Save successful." + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + + else if (href_list["refresh"]) + src.updateUsrDialog() + playsound(src, "terminal_type", 25, 0) + + else if (href_list["clone"]) + var/datum/data/record/C = find_record("id", href_list["clone"], records) + //Look for that player! They better be dead! + if(C) + var/obj/machinery/clonepod/pod = GetAvailablePod() + //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs. + if(!LAZYLEN(pods)) + temp = "No Clonepods detected." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else if(!pod) + temp = "No Clonepods available." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else if(!config.revival_cloning) + temp = "Unable to initiate cloning cycle." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else if(pod.occupant) + temp = "Cloning cycle already in progress." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["mrace"], C.fields["features"], C.fields["factions"])) + temp = "[C.fields["name"]] => Cloning cycle in progress..." + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + records.Remove(C) + if(active_record == C) + active_record = null + menu = 1 + else + temp = "[C.fields["name"]] => Initialisation failure." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + + else + temp = "Data corruption." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + + else if (href_list["menu"]) + src.menu = text2num(href_list["menu"]) + playsound(src, "terminal_type", 25, 0) + + src.add_fingerprint(usr) + src.updateUsrDialog() + return + +/obj/machinery/computer/cloning/proc/scan_occupant(occupant) + var/mob/living/mob_occupant = get_mob_or_brainmob(occupant) + var/datum/dna/dna + if(iscarbon(mob_occupant)) + var/mob/living/carbon/C = mob_occupant + dna = C.has_dna() + if(isbrain(mob_occupant)) + var/mob/living/brain/B = mob_occupant + dna = B.stored_dna + + if(!istype(dna)) + scantemp = "Unable to locate valid genetic data." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + if(mob_occupant.suiciding || mob_occupant.hellbound) + scantemp = "Subject's brain is not responding to scanning stimuli." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + if((mob_occupant.disabilities & NOCLONE) && (src.scanner.scan_level < 2)) + scantemp = "Subject no longer contains the fundamental materials required to create a living clone." + playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0) + return + if ((!mob_occupant.ckey) || (!mob_occupant.client)) + scantemp = "Mental interface failure." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + if (find_record("ckey", mob_occupant.ckey, records)) + scantemp = "Subject already in database." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + + var/datum/data/record/R = new() + if(dna.species) + // We store the instance rather than the path, because some + // species (abductors, slimepeople) store state in their + // species datums + R.fields["mrace"] = dna.species + else + var/datum/species/rando_race = pick(config.roundstart_races) + R.fields["mrace"] = rando_race.type + + R.fields["ckey"] = mob_occupant.ckey + R.fields["name"] = mob_occupant.real_name + R.fields["id"] = copytext(md5(mob_occupant.real_name), 2, 6) + R.fields["UE"] = dna.unique_enzymes + R.fields["UI"] = dna.uni_identity + R.fields["SE"] = dna.struc_enzymes + R.fields["blood_type"] = dna.blood_type + R.fields["features"] = dna.features + R.fields["factions"] = mob_occupant.faction + + if (!isnull(mob_occupant.mind)) //Save that mind so traitors can continue traitoring after cloning. + R.fields["mind"] = "\ref[mob_occupant.mind]" + + //Add an implant if needed + var/obj/item/implant/health/imp + for(var/obj/item/implant/health/HI in mob_occupant.implants) + imp = HI + break + if(!imp) + imp = new /obj/item/implant/health(mob_occupant) + imp.implant(mob_occupant) + R.fields["imp"] = "\ref[imp]" + + src.records += R + scantemp = "Subject successfully scanned." + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) ======= playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) From d6ec5791a64a6f494192aa2176e496fe55f2e1bb Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 30 Sep 2017 22:35:57 -0500 Subject: [PATCH 51/60] Update dna.dm --- code/datums/dna.dm | 405 --------------------------------------------- 1 file changed, 405 deletions(-) diff --git a/code/datums/dna.dm b/code/datums/dna.dm index b090a12714..64a1d4ff07 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -1,407 +1,3 @@ -<<<<<<< HEAD - -/////////////////////////// DNA DATUM -/datum/dna - var/unique_enzymes - var/struc_enzymes - var/uni_identity - var/blood_type - var/datum/species/species = new /datum/species/human() //The type of mutant race the player is if applicable (i.e. potato-man) - var/list/features = list("FFF") //first value is mutant color - var/real_name //Stores the real name of the person who originally got this dna datum. Used primarely for changelings, - var/list/mutations = list() //All mutations are from now on here - var/list/temporary_mutations = list() //Timers for temporary mutations - var/list/previous = list() //For temporary name/ui/ue/blood_type modifications - var/mob/living/holder - -/datum/dna/New(mob/living/new_holder) - if(new_holder) - holder = new_holder - -/datum/dna/proc/transfer_identity(mob/living/carbon/destination, transfer_SE = 0) - if(!istype(destination)) - return - destination.dna.unique_enzymes = unique_enzymes - destination.dna.uni_identity = uni_identity - destination.dna.blood_type = blood_type - destination.set_species(species.type, icon_update=0) - destination.dna.features = features.Copy() - destination.dna.real_name = real_name - destination.dna.temporary_mutations = temporary_mutations.Copy() - if(transfer_SE) - destination.dna.struc_enzymes = struc_enzymes - if(ishuman(destination)) - var/mob/living/carbon/human/H = destination - H.give_genitals(TRUE)//This gives the body the genitals of this DNA. Used for any transformations based on DNA - destination.flavor_text = destination.dna.features["flavor_text"] //Update the flavor_text to use new dna text - -/datum/dna/proc/copy_dna(datum/dna/new_dna) - new_dna.unique_enzymes = unique_enzymes - new_dna.struc_enzymes = struc_enzymes - new_dna.uni_identity = uni_identity - new_dna.blood_type = blood_type - new_dna.features = features.Copy() - new_dna.species = new species.type - new_dna.real_name = real_name - new_dna.mutations = mutations.Copy() - -/datum/dna/proc/add_mutation(mutation_name) - var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name] - HM.on_acquiring(holder) - -/datum/dna/proc/remove_mutation(mutation_name) - var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name] - HM.on_losing(holder) - -/datum/dna/proc/check_mutation(mutation_name) - var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name] - return mutations.Find(HM) - -/datum/dna/proc/remove_all_mutations() - remove_mutation_group(mutations) - -/datum/dna/proc/remove_mutation_group(list/group) - if(!group) - return - for(var/datum/mutation/human/HM in group) - HM.force_lose(holder) - -/datum/dna/proc/generate_uni_identity() - . = "" - var/list/L = new /list(DNA_UNI_IDENTITY_BLOCKS) - - L[DNA_GENDER_BLOCK] = construct_block((holder.gender!=MALE)+1, 2) - if(ishuman(holder)) - var/mob/living/carbon/human/H = holder - if(!GLOB.hair_styles_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/hair,GLOB.hair_styles_list, GLOB.hair_styles_male_list, GLOB.hair_styles_female_list) - L[DNA_HAIR_STYLE_BLOCK] = construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len) - L[DNA_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.hair_color) - if(!GLOB.facial_hair_styles_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, GLOB.facial_hair_styles_list, GLOB.facial_hair_styles_male_list, GLOB.facial_hair_styles_female_list) - L[DNA_FACIAL_HAIR_STYLE_BLOCK] = construct_block(GLOB.facial_hair_styles_list.Find(H.facial_hair_style), GLOB.facial_hair_styles_list.len) - L[DNA_FACIAL_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.facial_hair_color) - L[DNA_SKIN_TONE_BLOCK] = construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len) - L[DNA_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.eye_color) - - for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++) - if(L[i]) - . += L[i] - else - . += random_string(DNA_BLOCK_SIZE,GLOB.hex_characters) - return . - -/datum/dna/proc/generate_struc_enzymes() - var/list/sorting = new /list(DNA_STRUC_ENZYMES_BLOCKS) - var/result = "" - for(var/datum/mutation/human/A in GLOB.good_mutations + GLOB.bad_mutations + GLOB.not_good_mutations) - if(A.name == RACEMUT && ismonkey(holder)) - sorting[A.dna_block] = num2hex(A.lowest_value + rand(0, 256 * 6), DNA_BLOCK_SIZE) - mutations |= A - else - sorting[A.dna_block] = random_string(DNA_BLOCK_SIZE, list("0","1","2","3","4","5","6")) - - for(var/B in sorting) - result += B - return result - -/datum/dna/proc/generate_unique_enzymes() - . = "" - if(istype(holder)) - real_name = holder.real_name - . += md5(holder.real_name) - else - . += random_string(DNA_UNIQUE_ENZYMES_LEN, GLOB.hex_characters) - return . - -/datum/dna/proc/update_ui_block(blocknumber) - if(!blocknumber || !ishuman(holder)) - return - var/mob/living/carbon/human/H = holder - switch(blocknumber) - if(DNA_HAIR_COLOR_BLOCK) - setblock(uni_identity, blocknumber, sanitize_hexcolor(H.hair_color)) - if(DNA_FACIAL_HAIR_COLOR_BLOCK) - setblock(uni_identity, blocknumber, sanitize_hexcolor(H.facial_hair_color)) - if(DNA_SKIN_TONE_BLOCK) - setblock(uni_identity, blocknumber, construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len)) - if(DNA_EYE_COLOR_BLOCK) - setblock(uni_identity, blocknumber, sanitize_hexcolor(H.eye_color)) - if(DNA_GENDER_BLOCK) - setblock(uni_identity, blocknumber, construct_block((H.gender!=MALE)+1, 2)) - if(DNA_FACIAL_HAIR_STYLE_BLOCK) - setblock(uni_identity, blocknumber, construct_block(GLOB.facial_hair_styles_list.Find(H.facial_hair_style), GLOB.facial_hair_styles_list.len)) - if(DNA_HAIR_STYLE_BLOCK) - setblock(uni_identity, blocknumber, construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len)) - -/datum/dna/proc/mutations_say_mods(message) - if(message) - for(var/datum/mutation/human/M in mutations) - message = M.say_mod(message) - return message - -/datum/dna/proc/mutations_get_spans() - var/list/spans = list() - for(var/datum/mutation/human/M in mutations) - spans |= M.get_spans() - return spans - -/datum/dna/proc/species_get_spans() - var/list/spans = list() - if(species) - spans |= species.get_spans() - return spans - - -/datum/dna/proc/is_same_as(datum/dna/D) - if(uni_identity == D.uni_identity && struc_enzymes == D.struc_enzymes && real_name == D.real_name) - if(species.type == D.species.type && features == D.features && blood_type == D.blood_type) - return 1 - return 0 - -//used to update dna UI, UE, and dna.real_name. -/datum/dna/proc/update_dna_identity() - uni_identity = generate_uni_identity() - unique_enzymes = generate_unique_enzymes() - -/datum/dna/proc/initialize_dna(newblood_type) - if(newblood_type) - blood_type = newblood_type - unique_enzymes = generate_unique_enzymes() - uni_identity = generate_uni_identity() - struc_enzymes = generate_struc_enzymes() - features = random_features() - - -/datum/dna/stored //subtype used by brain mob's stored_dna - -/datum/dna/stored/add_mutation(mutation_name) //no mutation changes on stored dna. - return - -/datum/dna/stored/remove_mutation(mutation_name) - return - -/datum/dna/stored/check_mutation(mutation_name) - return - -/datum/dna/stored/remove_all_mutations() - return - -/datum/dna/stored/remove_mutation_group(list/group) - return - -/////////////////////////// DNA MOB-PROCS ////////////////////// - -/mob/proc/set_species(datum/species/mrace, icon_update = 1) - return - -/mob/living/brain/set_species(datum/species/mrace, icon_update = 1) - if(mrace) - if(ispath(mrace)) - stored_dna.species = new mrace() - else - stored_dna.species = mrace //not calling any species update procs since we're a brain, not a monkey/human - - -/mob/living/carbon/set_species(datum/species/mrace, icon_update = 1) - if(mrace && has_dna()) - dna.species.on_species_loss(src) - var/old_species = dna.species - if(ispath(mrace)) - dna.species = new mrace() - else - dna.species = mrace - dna.species.on_species_gain(src, old_species) - -/mob/living/carbon/human/set_species(datum/species/mrace, icon_update = 1) - ..() - if(icon_update) - update_body() - update_hair() - update_body_parts() - update_mutations_overlay()// no lizard with human hulk overlay please. - - -/mob/proc/has_dna() - return - -/mob/living/carbon/has_dna() - return dna - - -/mob/living/carbon/human/proc/hardset_dna(ui, se, newreal_name, newblood_type, datum/species/mrace, newfeatures) - - if(newfeatures) - dna.features = newfeatures - flavor_text = dna.features["flavor_text"] //Update the flavor_text to use new dna text - - if(mrace) - var/datum/species/newrace = new mrace.type - newrace.copy_properties_from(mrace) - set_species(newrace, icon_update=0) - - if(newreal_name) - real_name = newreal_name - dna.generate_unique_enzymes() - - if(newblood_type) - dna.blood_type = newblood_type - - if(ui) - dna.uni_identity = ui - updateappearance(icon_update=0) - - if(se) - dna.struc_enzymes = se - domutcheck() - - give_genitals(TRUE)//Give all genitalia that DNA says you should have, remove any pre-existing ones as this is a hardset! - - if(mrace || newfeatures || ui) - update_body() - update_hair() - update_body_parts() - update_mutations_overlay() - - -/mob/living/carbon/proc/create_dna() - dna = new /datum/dna(src) - if(!dna.species) - var/rando_race = pick(config.roundstart_races) - dna.species = new rando_race() - -//proc used to update the mob's appearance after its dna UI has been changed -/mob/living/carbon/proc/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0) - if(!has_dna()) - return - gender = (deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 2)-1) ? FEMALE : MALE - -/mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0) - ..() - var/structure = dna.uni_identity - hair_color = sanitize_hexcolor(getblock(structure, DNA_HAIR_COLOR_BLOCK)) - facial_hair_color = sanitize_hexcolor(getblock(structure, DNA_FACIAL_HAIR_COLOR_BLOCK)) - skin_tone = GLOB.skin_tones[deconstruct_block(getblock(structure, DNA_SKIN_TONE_BLOCK), GLOB.skin_tones.len)] - eye_color = sanitize_hexcolor(getblock(structure, DNA_EYE_COLOR_BLOCK)) - facial_hair_style = GLOB.facial_hair_styles_list[deconstruct_block(getblock(structure, DNA_FACIAL_HAIR_STYLE_BLOCK), GLOB.facial_hair_styles_list.len)] - hair_style = GLOB.hair_styles_list[deconstruct_block(getblock(structure, DNA_HAIR_STYLE_BLOCK), GLOB.hair_styles_list.len)] - if(icon_update) - update_body() - update_hair() - if(mutcolor_update) - update_body_parts() - if(mutations_overlay_update) - update_mutations_overlay() - - -/mob/proc/domutcheck() - return - -/mob/living/carbon/domutcheck(force_powers=0) //Set force_powers to 1 to bypass the power chance - if(!has_dna()) - return - - for(var/datum/mutation/human/A in GLOB.good_mutations | GLOB.bad_mutations | GLOB.not_good_mutations) - if(ismob(A.check_block(src, force_powers))) - return //we got monkeyized/humanized, this mob will be deleted, no need to continue. - - update_mutations_overlay() - - - -/////////////////////////// DNA HELPER-PROCS ////////////////////////////// -/proc/getleftblocks(input,blocknumber,blocksize) - if(blocknumber > 1) - return copytext(input,1,((blocksize*blocknumber)-(blocksize-1))) - -/proc/getrightblocks(input,blocknumber,blocksize) - if(blocknumber < (length(input)/blocksize)) - return copytext(input,blocksize*blocknumber+1,length(input)+1) - -/proc/getblock(input, blocknumber, blocksize=DNA_BLOCK_SIZE) - return copytext(input, blocksize*(blocknumber-1)+1, (blocksize*blocknumber)+1) - -/proc/setblock(istring, blocknumber, replacement, blocksize=DNA_BLOCK_SIZE) - if(!istring || !blocknumber || !replacement || !blocksize) - return 0 - return getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize) - -/mob/living/carbon/proc/randmut(list/candidates, difficulty = 2) - if(!has_dna()) - return - var/datum/mutation/human/num = pick(candidates) - . = num.force_give(src) - -/mob/living/carbon/proc/randmutb() - if(!has_dna()) - return - var/datum/mutation/human/HM = pick((GLOB.bad_mutations | GLOB.not_good_mutations) - GLOB.mutations_list[RACEMUT]) - . = HM.force_give(src) - -/mob/living/carbon/proc/randmutg() - if(!has_dna()) - return - var/datum/mutation/human/HM = pick(GLOB.good_mutations) - . = HM.force_give(src) - -/mob/living/carbon/proc/randmutvg() - if(!has_dna()) - return - var/datum/mutation/human/HM = pick((GLOB.good_mutations) - GLOB.mutations_list[HULK] - GLOB.mutations_list[DWARFISM]) - . = HM.force_give(src) - -/mob/living/carbon/proc/randmuti() - if(!has_dna()) - return - var/num = rand(1, DNA_UNI_IDENTITY_BLOCKS) - var/newdna = setblock(dna.uni_identity, num, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters)) - dna.uni_identity = newdna - updateappearance(mutations_overlay_update=1) - -/mob/living/carbon/proc/clean_dna() - if(!has_dna()) - return - dna.remove_all_mutations() - -/mob/living/carbon/proc/clean_randmut(list/candidates, difficulty = 2) - clean_dna() - randmut(candidates, difficulty) - -/proc/scramble_dna(mob/living/carbon/M, ui=FALSE, se=FALSE, probability) - if(!M.has_dna()) - return 0 - if(se) - for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++) - if(prob(probability)) - M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters)) - M.domutcheck() - if(ui) - for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++) - if(prob(probability)) - M.dna.uni_identity = setblock(M.dna.uni_identity, i, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters)) - M.updateappearance(mutations_overlay_update=1) - return 1 - -//value in range 1 to values. values must be greater than 0 -//all arguments assumed to be positive integers -/proc/construct_block(value, values, blocksize=DNA_BLOCK_SIZE) - var/width = round((16**blocksize)/values) - if(value < 1) - value = 1 - value = (value * width) - rand(1,width) - return num2hex(value, blocksize) - -//value is hex -/proc/deconstruct_block(value, values, blocksize=DNA_BLOCK_SIZE) - var/width = round((16**blocksize)/values) - value = round(hex2num(value) / width) + 1 - if(value > values) - value = values - return value - -/////////////////////////// DNA HELPER-PROCS -======= - /////////////////////////// DNA DATUM /datum/dna var/unique_enzymes @@ -795,4 +391,3 @@ return value /////////////////////////// DNA HELPER-PROCS ->>>>>>> 4178c20... Configuration datum refactor (#30763) From 747312cb6daddc022228ec50915938a2f3bfe0da Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 1 Oct 2017 00:59:59 -0500 Subject: [PATCH 52/60] updates --- code/controllers/configuration.dm | 1018 ++----------- code/game/objects/items/manuals.dm | 967 +------------ code/modules/admin/verbs/randomverbs.dm | 1279 +---------------- code/modules/client/preferences.dm | 4 +- .../modules/mob/living/silicon/robot/robot.dm | 5 - .../living/silicon/robot/robot_movement.dm | 35 +- code/modules/mob/living/silicon/robot/say.dm | 7 +- tgstation.dme | 18 +- 8 files changed, 169 insertions(+), 3164 deletions(-) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 0c0baccc56..1e4a574e13 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -1,296 +1,156 @@ -//Configuraton defines //TODO: Move all yes/no switches into bitflags - -//Used by jobs_have_maint_access -#define ASSISTANTS_HAVE_MAINT_ACCESS 1 -#define SECURITY_HAS_MAINT_ACCESS 2 -#define EVERYONE_HAS_MAINT_ACCESS 4 - GLOBAL_VAR_INIT(config_dir, "config/") GLOBAL_PROTECT(config_dir) +/datum/controller/configuration + name = "Configuration" + + var/hiding_entries_by_type = TRUE //Set for readability, admins can set this to FALSE if they want to debug it + var/list/entries + var/list/entries_by_type + + var/list/maplist + var/datum/map_config/defaultmap + + var/list/modes // allowed modes + var/list/gamemode_cache + var/list/votable_modes // votable modes + var/list/mode_names + var/list/mode_reports + var/list/mode_false_report_weight + +/datum/controller/configuration/New() + config = src + var/list/config_files = InitEntries() + LoadModes() + for(var/I in config_files) + LoadEntries(I) + if(Get(/datum/config_entry/flag/maprotation)) + loadmaplist(CONFIG_MAPS_FILE) + +/datum/controller/configuration/Destroy() + entries_by_type.Cut() + QDEL_LIST_ASSOC_VAL(entries) + QDEL_LIST_ASSOC_VAL(maplist) + QDEL_NULL(defaultmap) + + config = null -/datum/configuration/can_vv_get(var_name) - var/static/list/banned_gets = list("autoadmin", "autoadmin_rank") - if (var_name in banned_gets) - return FALSE return ..() -/datum/configuration/vv_edit_var(var_name, var_value) - var/static/list/banned_edits = list("cross_address", "cross_allowed", "autoadmin", "autoadmin_rank", "invoke_youtubedl") - if(var_name in banned_edits) - return FALSE - return ..() +/datum/controller/configuration/proc/InitEntries() + var/list/_entries = list() + entries = _entries + var/list/_entries_by_type = list() + entries_by_type = _entries_by_type -/datum/configuration - var/name = "Configuration" // datum name + . = list() - var/autoadmin = 0 - var/autoadmin_rank = "Game Admin" + for(var/I in typesof(/datum/config_entry)) //typesof is faster in this case + var/datum/config_entry/E = I + if(initial(E.abstract_type) == I) + continue + E = new I + _entries_by_type[I] = E + var/esname = E.name + var/datum/config_entry/test = _entries[esname] + if(test) + log_config("Error: [test.type] has the same name as [E.type]: [esname]! Not initializing [E.type]!") + qdel(E) + continue + _entries[esname] = E + .[E.resident_file] = TRUE - var/server_name = null // server name (the name of the game window) - var/server_sql_name = null // short form server name used for the DB - var/station_name = null // station name (the name of the station in-game) - var/lobby_countdown = 120 // In between round countdown. - var/round_end_countdown = 25 // Post round murder death kill countdown - var/hub = 0 +/datum/controller/configuration/proc/RemoveEntry(datum/config_entry/CE) + entries -= CE.name + entries_by_type -= CE.type - var/log_ooc = 0 // log OOC channel - var/log_access = 0 // log login/logout - var/log_say = 0 // log client say - var/log_admin = 0 // log admin actions - var/log_game = 0 // log game events - var/log_vote = 0 // log voting - var/log_whisper = 0 // log client whisper - var/log_prayer = 0 // log prayers - var/log_law = 0 // log lawchanges - var/log_emote = 0 // log emotes - var/log_attack = 0 // log attack messages - var/log_adminchat = 0 // log admin chat messages - var/log_pda = 0 // log pda messages - var/log_twitter = 0 // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases. - var/log_world_topic = 0 // log all world.Topic() calls - var/sql_enabled = 0 // for sql switching - var/allow_admin_ooccolor = 0 // Allows admins with relevant permissions to have their own ooc colour - var/allow_vote_restart = 0 // allow votes to restart - var/allow_vote_mode = 0 // allow votes to change mode - var/vote_delay = 6000 // minimum time between voting sessions (deciseconds, 10 minute default) - var/vote_period = 600 // length of voting period (deciseconds, default 1 minute) - var/vote_no_default = 0 // vote does not default to nochange/norestart (tbi) - var/vote_no_dead = 0 // dead people can't vote (tbi) - var/del_new_on_log = 1 // del's new players if they log before they spawn in - var/allow_Metadata = 0 // Metadata is supported. - var/popup_admin_pm = 0 //adminPMs to non-admins show in a pop-up 'reply' window when set to 1. - var/fps = 20 - var/allow_holidays = 0 //toggles whether holiday-specific content should be used - var/tick_limit_mc_init = TICK_LIMIT_MC_INIT_DEFAULT //SSinitialization throttling +/datum/controller/configuration/proc/LoadEntries(filename) + log_config("Loading config file [filename]...") + var/list/lines = world.file2list("[GLOB.config_dir][filename]") + var/list/_entries = entries + for(var/L in lines) + if(!L) + continue - var/hostedby = null - var/respawn = 1 - var/guest_jobban = 1 - var/usewhitelist = 0 - var/inactivity_period = 3000 //time in ds until a player is considered inactive - var/afk_period = 6000 //time in ds until a player is considered afk and kickable - var/kick_inactive = FALSE //force disconnect for inactive players - var/load_jobs_from_txt = 0 - var/automute_on = 0 //enables automuting/spam prevention - var/minimal_access_threshold = 0 //If the number of players is larger than this threshold, minimal access will be turned on. - var/jobs_have_minimal_access = 0 //determines whether jobs use minimal access or expanded access. - var/jobs_have_maint_access = 0 //Who gets maint access? See defines above. - var/sec_start_brig = 0 //makes sec start in brig or dept sec posts + if(copytext(L, 1, 2) == "#") + continue - var/server - var/banappeals - var/wikiurl = "http://www.tgstation13.org/wiki" // Default wiki link. - var/forumurl = "http://tgstation13.org/phpBB/index.php" //default forums - var/rulesurl = "http://www.tgstation13.org/wiki/Rules" // default rules - var/githuburl = "https://www.github.com/tgstation/-tg-station" //default github - var/githubrepoid + var/pos = findtext(L, " ") + var/entry = null + var/value = null - var/forbid_singulo_possession = 0 - var/useircbot = 0 + if(pos) + entry = lowertext(copytext(L, 1, pos)) + value = copytext(L, pos + 1) + else + entry = lowertext(L) - var/check_randomizer = 0 + if(!entry) + continue - var/panic_server_name - var/panic_address //Reconnect a player this linked server if this server isn't accepting new players + var/datum/config_entry/E = _entries[entry] + if(!E) + log_config("Unknown setting in configuration: '[entry]'") + continue - var/invoke_youtubedl + if(filename != E.resident_file) + log_config("Found [entry] in [filename] when it should have been in [E.resident_file]! Ignoring.") + continue - //IP Intel vars - var/ipintel_email - var/ipintel_rating_bad = 1 - var/ipintel_save_good = 12 - var/ipintel_save_bad = 1 - var/ipintel_domain = "check.getipintel.net" + var/validated = E.ValidateAndSet(value) + if(!validated) + log_config("Failed to validate setting \"[value]\" for [entry]") + else if(E.modified && !E.dupes_allowed) + log_config("Duplicate setting for [entry] ([value]) detected! Using latest.") - var/admin_legacy_system = 0 //Defines whether the server uses the legacy admin system with admins.txt or the SQL system. Config option in config.txt - var/ban_legacy_system = 0 //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. Config option in config.txt - var/use_age_restriction_for_jobs = 0 //Do jobs use account age restrictions? --requires database - var/use_account_age_for_jobs = 0 //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected. - var/see_own_notes = 0 //Can players see their own admin notes (read-only)? Config option in config.txt - var/note_fresh_days - var/note_stale_days + if(validated) + E.modified = TRUE - var/use_exp_tracking = FALSE - var/use_exp_restrictions_heads = FALSE - var/use_exp_restrictions_heads_hours = 0 - var/use_exp_restrictions_heads_department = FALSE - var/use_exp_restrictions_other = FALSE - var/use_exp_restrictions_admin_bypass = FALSE +/datum/controller/configuration/can_vv_get(var_name) + return (var_name != "entries_by_type" || !hiding_entries_by_type) && ..() - //Population cap vars - var/soft_popcap = 0 - var/hard_popcap = 0 - var/extreme_popcap = 0 - var/soft_popcap_message = "Be warned that the server is currently serving a high number of users, consider using alternative game servers." - var/hard_popcap_message = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers." - var/extreme_popcap_message = "The server is currently serving a high number of users, find alternative servers." +/datum/controller/configuration/vv_edit_var(var_name, var_value) + return !(var_name in list("entries_by_type", "entries")) && ..() - //game_options.txt configs - var/force_random_names = 0 - var/list/mode_names = list() - var/list/mode_reports = list() - var/list/mode_false_report_weight = list() - var/list/modes = list() // allowed modes - var/list/votable_modes = list() // votable modes - var/list/probabilities = list() // relative probability of each mode - var/list/min_pop = list() // overrides for acceptible player counts in a mode - var/list/max_pop = list() - var/list/repeated_mode_adjust = list() // weight adjustments for recent modes - var/humans_need_surnames = 0 - var/allow_ai = 0 // allow ai job - var/forbid_secborg = 0 // disallow secborg module to be chosen. - var/forbid_peaceborg = 0 - var/panic_bunker = 0 // prevents new people it hasn't seen before from connecting - var/notify_new_player_age = 0 // how long do we notify admins of a new player - var/notify_new_player_account_age = 0 // how long do we notify admins of a new byond account - var/irc_first_connection_alert = 0 // do we notify the irc channel when somebody is connecting for the first time? +/datum/controller/configuration/stat_entry() + if(!statclick) + statclick = new/obj/effect/statclick/debug(null, "Edit", src) + stat("[name]:", statclick) - var/traitor_scaling_coeff = 6 //how much does the amount of players get divided by to determine traitors - var/brother_scaling_coeff = 25 //how many players per brother team - var/changeling_scaling_coeff = 6 //how much does the amount of players get divided by to determine changelings - var/security_scaling_coeff = 8 //how much does the amount of players get divided by to determine open security officer positions - var/abductor_scaling_coeff = 15 //how many players per abductor team +/datum/controller/configuration/proc/Get(entry_type) + if(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "\ref[src]") + log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]") + return + var/datum/config_entry/E = entry_type + var/entry_is_abstract = initial(E.abstract_type) == entry_type + if(entry_is_abstract) + CRASH("Tried to retrieve an abstract config_entry: [entry_type]") + E = entries_by_type[entry_type] + if(!E) + CRASH("Missing config entry for [entry_type]!") + return E.value - var/traitor_objectives_amount = 2 - var/brother_objectives_amount = 2 - var/protect_roles_from_antagonist = 0 //If security and such can be traitor/cult/other - var/protect_assistant_from_antagonist = 0 //If assistants can be traitor/cult/other - var/enforce_human_authority = 0 //If non-human species are barred from joining as a head of staff - var/allow_latejoin_antagonists = 0 // If late-joining players can be traitor/changeling - var/list/continuous = list() // which roundtypes continue if all antagonists die - var/list/midround_antag = list() // which roundtypes use the midround antagonist system - var/midround_antag_time_check = 60 // How late (in minutes) you want the midround antag system to stay on, setting this to 0 will disable the system - var/midround_antag_life_check = 0.7 // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist - var/shuttle_refuel_delay = 12000 - var/show_game_type_odds = 0 //if set this allows players to see the odds of each roundtype on the get revision screen - var/mutant_races = 0 //players can choose their mutant race before joining the game - var/list/roundstart_races = list() //races you can play as from the get go. If left undefined the game's roundstart var for species is used - var/mutant_humans = 0 //players can pick mutant bodyparts for humans before joining the game +/datum/controller/configuration/proc/Set(entry_type, new_val) + if(IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Set" && GLOB.LastAdminCalledTargetRef == "\ref[src]") + log_admin_private("Config rewrite of [entry_type] to [new_val] attempted by [key_name(usr)]") + return + var/datum/config_entry/E = entry_type + var/entry_is_abstract = initial(E.abstract_type) == entry_type + if(entry_is_abstract) + CRASH("Tried to retrieve an abstract config_entry: [entry_type]") + E = entries_by_type[entry_type] + if(!E) + CRASH("Missing config entry for [entry_type]!") + return E.ValidateAndSet(new_val) - var/no_summon_guns //No - var/no_summon_magic //Fun - var/no_summon_events //Allowed - - var/intercept = 1 //Whether or not to send a communications intercept report roundstart. This may be overriden by gamemodes. - var/alert_desc_green = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced." - var/alert_desc_blue_upto = "The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible, random searches are permitted." - var/alert_desc_blue_downto = "The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed." - var/alert_desc_red_upto = "There is an immediate serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised." - var/alert_desc_red_downto = "The station's destruction has been averted. There is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised." - var/alert_desc_delta = "Destruction of the station is imminent. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill." - - var/revival_pod_plants = FALSE - var/revival_cloning = FALSE - var/revival_brain_life = -1 - - var/rename_cyborg = 0 - var/ooc_during_round = 0 - var/emojis = 0 - var/no_credits_round_end = FALSE - - //Used for modifying movement speed for mobs. - //Unversal modifiers - var/run_speed = 0 - var/walk_speed = 0 - - //Mob specific modifiers. NOTE: These will affect different mob types in different ways - var/human_delay = 0 - var/robot_delay = 0 - var/monkey_delay = 0 - var/alien_delay = 0 - var/slime_delay = 0 - var/animal_delay = 0 - - var/gateway_delay = 18000 //How long the gateway takes before it activates. Default is half an hour. - var/ghost_interaction = 0 - - var/silent_ai = 0 - var/silent_borg = 0 - - var/damage_multiplier = 1 //Modifier for damage to all mobs. Impacts healing as well. - - var/allowwebclient = 0 - var/webclientmembersonly = 0 - - var/sandbox_autoclose = FALSE // close the sandbox panel after spawning an item, potentially reducing griff - - var/default_laws = 0 //Controls what laws the AI spawns with. - var/silicon_max_law_amount = 12 - var/list/lawids = list() - - var/list/law_weights = list() - - var/assistant_cap = -1 - - var/starlight = 0 - var/generate_minimaps = 0 - var/grey_assistants = 0 - - var/id_console_jobslot_delay = 30 - - var/lavaland_budget = 60 - var/space_budget = 16 - - var/aggressive_changelog = 0 - - var/reactionary_explosions = 0 //If we use reactionary explosions, explosions that react to walls and doors - - var/autoconvert_notes = 0 //if all connecting player's notes should attempt to be converted to the database - - var/announce_admin_logout = 0 - var/announce_admin_login = 0 - - var/list/datum/map_config/maplist = list() - var/datum/map_config/defaultmap = null - var/maprotation = 1 - var/maprotatechancedelta = 0.75 - var/allow_map_voting = TRUE - - // Enables random events mid-round when set to 1 - var/allow_random_events = 0 - - // Multipliers for random events minimal starting time and minimal players amounts - var/events_min_time_mul = 1 - var/events_min_players_mul = 1 - - // The object used for the clickable stat() button. - var/obj/effect/statclick/statclick - - var/client_warn_version = 0 - var/client_warn_message = "Your version of byond may have issues or be blocked from accessing this server in the future." - var/client_error_version = 0 - var/client_error_message = "Your version of byond is too old, may have issues, and is blocked from accessing this server." - - var/cross_name = "Other server" - var/cross_address = "byond://" - var/cross_allowed = FALSE - var/showircname = 0 - - var/list/gamemode_cache = null - - var/minutetopiclimit - var/secondtopiclimit - - var/error_cooldown = 600 // The "cooldown" time for each occurrence of a unique error - var/error_limit = 50 // How many occurrences before the next will silence them - var/error_silence_time = 6000 // How long a unique error will be silenced for - var/error_msg_delay = 50 // How long to wait between messaging admins about occurrences of a unique error - - var/arrivals_shuttle_dock_window = 55 //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station - var/arrivals_shuttle_require_undocked = FALSE //Require the arrivals shuttle to be undocked before latejoiners can join - var/arrivals_shuttle_require_safe_latejoin = FALSE //Require the arrivals shuttle to be operational in order for latejoiners to join - - var/mice_roundstart = 10 // how many wire chewing rodents spawn at roundstart. - - var/irc_announce_new_game = FALSE - - var/list/policies = list() - - var/debug_admin_hrefs = FALSE //turns off admin href token protection for debugging purposes - -/datum/configuration/New() - gamemode_cache = typecacheof(/datum/game_mode,TRUE) +/datum/controller/configuration/proc/LoadModes() + gamemode_cache = typecacheof(/datum/game_mode, TRUE) + modes = list() + mode_names = list() + mode_reports = list() + mode_false_report_weight = list() + votable_modes = list() + var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability) for(var/T in gamemode_cache) // I wish I didn't have to instance the game modes in order to look up // their information, but it is the only way (at least that I know of). @@ -298,7 +158,6 @@ GLOBAL_PROTECT(config_dir) if(M.config_tag) if(!(M.config_tag in modes)) // ensure each mode is added only once - WRITE_FILE(GLOB.config_error_log, "Adding game mode [M.name] ([M.config_tag]) to configuration.") modes += M.config_tag mode_names[M.config_tag] = M.name probabilities[M.config_tag] = M.probability @@ -309,558 +168,7 @@ GLOBAL_PROTECT(config_dir) qdel(M) votable_modes += "secret" - Reload() - -/datum/configuration/proc/Reload() - load("config.txt") - load("comms.txt", "comms") - load("game_options.txt","game_options") - load("policies.txt", "policies") - loadsql("dbconfig.txt") - reload_custom_roundstart_items_list() - if (maprotation) - loadmaplist("maps.txt") - - // apply some settings from config.. - GLOB.abandon_allowed = respawn - -/datum/configuration/proc/load(filename, type = "config") //the type can also be game_options, in which case it uses a different switch. not making it separate to not copypaste code - Urist - filename = "[GLOB.config_dir][filename]" - var/list/Lines = world.file2list(filename) - - for(var/t in Lines) - if(!t) - continue - - t = trim(t) - if(length(t) == 0) - continue - else if(copytext(t, 1, 2) == "#") - continue - - var/pos = findtext(t, " ") - var/name = null - var/value = null - - if(pos) - name = lowertext(copytext(t, 1, pos)) - value = copytext(t, pos + 1) - else - name = lowertext(t) - - if(!name) - continue - - if(type == "config") - switch(name) - if("hub") - hub = 1 - if("admin_legacy_system") - admin_legacy_system = 1 - if("ban_legacy_system") - ban_legacy_system = 1 - if("use_age_restriction_for_jobs") - use_age_restriction_for_jobs = 1 - if("use_account_age_for_jobs") - use_account_age_for_jobs = 1 - if("use_exp_tracking") - use_exp_tracking = TRUE - if("use_exp_restrictions_heads") - use_exp_restrictions_heads = TRUE - if("use_exp_restrictions_heads_hours") - use_exp_restrictions_heads_hours = text2num(value) - if("use_exp_restrictions_heads_department") - use_exp_restrictions_heads_department = TRUE - if("use_exp_restrictions_other") - use_exp_restrictions_other = TRUE - if("use_exp_restrictions_admin_bypass") - use_exp_restrictions_admin_bypass = TRUE - if("lobby_countdown") - lobby_countdown = text2num(value) - if("round_end_countdown") - round_end_countdown = text2num(value) - if("log_ooc") - log_ooc = 1 - if("log_access") - log_access = 1 - if("log_say") - log_say = 1 - if("log_admin") - log_admin = 1 - if("log_prayer") - log_prayer = 1 - if("log_law") - log_law = 1 - if("log_game") - log_game = 1 - if("log_vote") - log_vote = 1 - if("log_whisper") - log_whisper = 1 - if("log_attack") - log_attack = 1 - if("log_emote") - log_emote = 1 - if("log_adminchat") - log_adminchat = 1 - if("log_pda") - log_pda = 1 - if("log_twitter") - log_twitter = 1 - if("log_world_topic") - log_world_topic = 1 - if("allow_admin_ooccolor") - allow_admin_ooccolor = 1 - if("allow_vote_restart") - allow_vote_restart = 1 - if("allow_vote_mode") - allow_vote_mode = 1 - if("no_dead_vote") - vote_no_dead = 1 - if("default_no_vote") - vote_no_default = 1 - if("vote_delay") - vote_delay = text2num(value) - if("vote_period") - vote_period = text2num(value) - if("norespawn") - respawn = 0 - if("servername") - server_name = value - if("serversqlname") - server_sql_name = value - if("stationname") - station_name = value - if("hostedby") - hostedby = value - if("server") - server = value - if("banappeals") - banappeals = value - if("wikiurl") - wikiurl = value - if("forumurl") - forumurl = value - if("rulesurl") - rulesurl = value - if("githuburl") - githuburl = value - if("githubrepoid") - githubrepoid = value - if("guest_jobban") - guest_jobban = 1 - if("guest_ban") - GLOB.guests_allowed = 0 - if("usewhitelist") - usewhitelist = TRUE - if("allow_metadata") - allow_Metadata = 1 - if("id_console_jobslot_delay") - id_console_jobslot_delay = text2num(value) - if("inactivity_period") - inactivity_period = text2num(value) * 10 //documented as seconds in config.txt - if("afk_period") - afk_period = text2num(value) * 10 // ^^^ - if("kick_inactive") - kick_inactive = TRUE - if("load_jobs_from_txt") - load_jobs_from_txt = 1 - if("forbid_singulo_possession") - forbid_singulo_possession = 1 - if("popup_admin_pm") - popup_admin_pm = 1 - if("allow_holidays") - allow_holidays = 1 - if("useircbot") //tgs2 support - useircbot = 1 - if("ticklag") - var/ticklag = text2num(value) - if(ticklag > 0) - fps = 10 / ticklag - if("tick_limit_mc_init") - tick_limit_mc_init = text2num(value) - if("fps") - fps = text2num(value) - if("automute_on") - automute_on = 1 - if("panic_server_name") - if (value != "\[Put the name here\]") - panic_server_name = value - if("panic_server_address") - if(value != "byond://address:port") - panic_address = value - if("invoke_youtubedl") - invoke_youtubedl = value - if("show_irc_name") - showircname = 1 - if("see_own_notes") - see_own_notes = 1 - if("note_fresh_days") - note_fresh_days = text2num(value) - if("note_stale_days") - note_stale_days = text2num(value) - if("soft_popcap") - soft_popcap = text2num(value) - if("hard_popcap") - hard_popcap = text2num(value) - if("extreme_popcap") - extreme_popcap = text2num(value) - if("soft_popcap_message") - soft_popcap_message = value - if("hard_popcap_message") - hard_popcap_message = value - if("extreme_popcap_message") - extreme_popcap_message = value - if("panic_bunker") - panic_bunker = 1 - if("notify_new_player_age") - notify_new_player_age = text2num(value) - if("notify_new_player_account_age") - notify_new_player_account_age = text2num(value) - if("irc_first_connection_alert") - irc_first_connection_alert = 1 - if("check_randomizer") - check_randomizer = 1 - if("ipintel_email") - if (value != "ch@nge.me") - ipintel_email = value - if("ipintel_rating_bad") - ipintel_rating_bad = text2num(value) - if("ipintel_domain") - ipintel_domain = value - if("ipintel_save_good") - ipintel_save_good = text2num(value) - if("ipintel_save_bad") - ipintel_save_bad = text2num(value) - if("aggressive_changelog") - aggressive_changelog = 1 - if("autoconvert_notes") - autoconvert_notes = 1 - if("allow_webclient") - allowwebclient = 1 - if("webclient_only_byond_members") - webclientmembersonly = 1 - if("announce_admin_logout") - announce_admin_logout = 1 - if("announce_admin_login") - announce_admin_login = 1 - if("maprotation") - maprotation = 1 - if("allow_map_voting") - allow_map_voting = text2num(value) - if("maprotationchancedelta") - maprotatechancedelta = text2num(value) - if("autoadmin") - autoadmin = 1 - if(value) - autoadmin_rank = ckeyEx(value) - if("generate_minimaps") - generate_minimaps = 1 - if("client_warn_version") - client_warn_version = text2num(value) - if("client_warn_message") - client_warn_message = value - if("client_error_version") - client_error_version = text2num(value) - if("client_error_message") - client_error_message = value - if("minute_topic_limit") - minutetopiclimit = text2num(value) - if("second_topic_limit") - secondtopiclimit = text2num(value) - if("error_cooldown") - error_cooldown = text2num(value) - if("error_limit") - error_limit = text2num(value) - if("error_silence_time") - error_silence_time = text2num(value) - if("error_msg_delay") - error_msg_delay = text2num(value) - if("irc_announce_new_game") - irc_announce_new_game = TRUE - if("debug_admin_hrefs") - debug_admin_hrefs = TRUE - else -#if DM_VERSION > 511 -#error Replace the line below with WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'") -#endif - HandleCommsConfig(name, value) //TODO: Deprecate this eventually - else if(type == "comms") - HandleCommsConfig(name, value) - else if(type == "game_options") - switch(name) - if("damage_multiplier") - damage_multiplier = text2num(value) - if("revival_pod_plants") - revival_pod_plants = TRUE - if("revival_cloning") - revival_cloning = TRUE - if("revival_brain_life") - revival_brain_life = text2num(value) - if("rename_cyborg") - rename_cyborg = 1 - if("ooc_during_round") - ooc_during_round = 1 - if("emojis") - emojis = 1 - if("no_credits_round_end") - no_credits_round_end = TRUE - if("run_delay") - run_speed = text2num(value) - if("walk_delay") - walk_speed = text2num(value) - if("human_delay") - human_delay = text2num(value) - if("robot_delay") - robot_delay = text2num(value) - if("monkey_delay") - monkey_delay = text2num(value) - if("alien_delay") - alien_delay = text2num(value) - if("slime_delay") - slime_delay = text2num(value) - if("animal_delay") - animal_delay = text2num(value) - if("alert_red_upto") - alert_desc_red_upto = value - if("alert_red_downto") - alert_desc_red_downto = value - if("alert_blue_downto") - alert_desc_blue_downto = value - if("alert_blue_upto") - alert_desc_blue_upto = value - if("alert_green") - alert_desc_green = value - if("alert_delta") - alert_desc_delta = value - if("no_intercept_report") - intercept = 0 - if("assistants_have_maint_access") - jobs_have_maint_access |= ASSISTANTS_HAVE_MAINT_ACCESS - if("security_has_maint_access") - jobs_have_maint_access |= SECURITY_HAS_MAINT_ACCESS - if("everyone_has_maint_access") - jobs_have_maint_access |= EVERYONE_HAS_MAINT_ACCESS - if("sec_start_brig") - sec_start_brig = 1 - if("gateway_delay") - gateway_delay = text2num(value) - if("continuous") - var/mode_name = lowertext(value) - if(mode_name in modes) - continuous[mode_name] = 1 - else - WRITE_FILE(GLOB.config_error_log, "Unknown continuous configuration definition: [mode_name].") - if("midround_antag") - var/mode_name = lowertext(value) - if(mode_name in modes) - midround_antag[mode_name] = 1 - else - WRITE_FILE(GLOB.config_error_log, "Unknown midround antagonist configuration definition: [mode_name].") - if("midround_antag_time_check") - midround_antag_time_check = text2num(value) - if("midround_antag_life_check") - midround_antag_life_check = text2num(value) - if("min_pop") - var/pop_pos = findtext(value, " ") - var/mode_name = null - var/mode_value = null - - if(pop_pos) - mode_name = lowertext(copytext(value, 1, pop_pos)) - mode_value = copytext(value, pop_pos + 1) - if(mode_name in modes) - min_pop[mode_name] = text2num(mode_value) - else - WRITE_FILE(GLOB.config_error_log, "Unknown minimum population configuration definition: [mode_name].") - else - WRITE_FILE(GLOB.config_error_log, "Incorrect minimum population configuration definition: [mode_name] [mode_value].") - if("max_pop") - var/pop_pos = findtext(value, " ") - var/mode_name = null - var/mode_value = null - - if(pop_pos) - mode_name = lowertext(copytext(value, 1, pop_pos)) - mode_value = copytext(value, pop_pos + 1) - if(mode_name in modes) - max_pop[mode_name] = text2num(mode_value) - else - WRITE_FILE(GLOB.config_error_log, "Unknown maximum population configuration definition: [mode_name].") - else - WRITE_FILE(GLOB.config_error_log, "Incorrect maximum population configuration definition: [mode_name] [mode_value].") - if("shuttle_refuel_delay") - shuttle_refuel_delay = text2num(value) - if("show_game_type_odds") - show_game_type_odds = 1 - if("ghost_interaction") - ghost_interaction = 1 - if("traitor_scaling_coeff") - traitor_scaling_coeff = text2num(value) - if("brother_scaling_coeff") - brother_scaling_coeff = text2num(value) - if("changeling_scaling_coeff") - changeling_scaling_coeff = text2num(value) - if("security_scaling_coeff") - security_scaling_coeff = text2num(value) - if("abductor_scaling_coeff") - abductor_scaling_coeff = text2num(value) - if("traitor_objectives_amount") - traitor_objectives_amount = text2num(value) - if("brother_objectives_amount") - brother_objectives_amount = text2num(value) - if("probability") - var/prob_pos = findtext(value, " ") - var/prob_name = null - var/prob_value = null - - if(prob_pos) - prob_name = lowertext(copytext(value, 1, prob_pos)) - prob_value = copytext(value, prob_pos + 1) - if(prob_name in modes) - probabilities[prob_name] = text2num(prob_value) - else - WRITE_FILE(GLOB.config_error_log, "Unknown game mode probability configuration definition: [prob_name].") - else - WRITE_FILE(GLOB.config_error_log, "Incorrect probability configuration definition: [prob_name] [prob_value].") - if("repeated_mode_adjust") - if(value) - repeated_mode_adjust.Cut() - var/values = splittext(value," ") - for(var/v in values) - repeated_mode_adjust += text2num(v) - else - WRITE_FILE(GLOB.config_error_log, "Incorrect round weight adjustment configuration definition for [value].") - if("protect_roles_from_antagonist") - protect_roles_from_antagonist = 1 - if("protect_assistant_from_antagonist") - protect_assistant_from_antagonist = 1 - if("enforce_human_authority") - enforce_human_authority = 1 - if("allow_latejoin_antagonists") - allow_latejoin_antagonists = 1 - if("allow_random_events") - allow_random_events = 1 - - if("events_min_time_mul") - events_min_time_mul = text2num(value) - if("events_min_players_mul") - events_min_players_mul = text2num(value) - - if("minimal_access_threshold") - minimal_access_threshold = text2num(value) - if("jobs_have_minimal_access") - jobs_have_minimal_access = 1 - if("humans_need_surnames") - humans_need_surnames = 1 - if("force_random_names") - force_random_names = 1 - if("allow_ai") - allow_ai = 1 - if("disable_secborg") - forbid_secborg = 1 - if("disable_peaceborg") - forbid_peaceborg = 1 - if("silent_ai") - silent_ai = 1 - if("silent_borg") - silent_borg = 1 - if("sandbox_autoclose") - sandbox_autoclose = 1 - if("default_laws") - default_laws = text2num(value) - if("random_laws") - var/law_id = lowertext(value) - lawids += law_id - if("law_weight") - // Value is in the form "LAWID,NUMBER" - var/list/L = splittext(value, ",") - if(L.len != 2) - WRITE_FILE(GLOB.config_error_log, "Invalid LAW_WEIGHT: " + t) - continue - var/lawid = L[1] - var/weight = text2num(L[2]) - law_weights[lawid] = weight - - if("silicon_max_law_amount") - silicon_max_law_amount = text2num(value) - if("join_with_mutant_race") - mutant_races = 1 - if("roundstart_races") - var/race_id = lowertext(value) - for(var/species_id in GLOB.species_list) - if(species_id == race_id) - roundstart_races += GLOB.species_list[species_id] - GLOB.roundstart_species[species_id] = GLOB.species_list[species_id] - if("join_with_mutant_humans") - mutant_humans = 1 - if("assistant_cap") - assistant_cap = text2num(value) - if("starlight") - starlight = 1 - if("grey_assistants") - grey_assistants = 1 - if("lavaland_budget") - lavaland_budget = text2num(value) - if("space_budget") - space_budget = text2num(value) - if("no_summon_guns") - no_summon_guns = 1 - if("no_summon_magic") - no_summon_magic = 1 - if("no_summon_events") - no_summon_events = 1 - if("reactionary_explosions") - reactionary_explosions = 1 - if("bombcap") - var/BombCap = text2num(value) - if (!BombCap) - continue - if (BombCap < 4) - BombCap = 4 - - GLOB.MAX_EX_DEVESTATION_RANGE = round(BombCap/4) - GLOB.MAX_EX_HEAVY_RANGE = round(BombCap/2) - GLOB.MAX_EX_LIGHT_RANGE = BombCap - GLOB.MAX_EX_FLASH_RANGE = BombCap - GLOB.MAX_EX_FLAME_RANGE = BombCap - if("arrivals_shuttle_dock_window") - arrivals_shuttle_dock_window = max(PARALLAX_LOOP_TIME, text2num(value)) - if("arrivals_shuttle_require_undocked") - arrivals_shuttle_require_undocked = TRUE - if("arrivals_shuttle_require_safe_latejoin") - arrivals_shuttle_require_safe_latejoin = TRUE - if("mice_roundstart") - mice_roundstart = text2num(value) - else - WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'") - else if(type == "policies") - policies[name] = value - - fps = round(fps) - if(fps <= 0) - fps = initial(fps) - -/datum/configuration/proc/HandleCommsConfig(name, value) - switch(name) - if("comms_key") - global.comms_key = value - if(value != "default_pwd" && length(value) > 6) //It's the default value or less than 6 characters long, warn badmins - global.comms_allowed = TRUE - if("cross_server_address") - cross_address = value - if(value != "byond:\\address:port") - cross_allowed = TRUE - if("cross_comms_name") - cross_name = value - if("medal_hub_address") - global.medal_hub = value - if("medal_hub_password") - global.medal_pass = value - else - WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'") - -/datum/configuration/proc/loadmaplist(filename) +/datum/controller/configuration/proc/loadmaplist(filename) filename = "[GLOB.config_dir][filename]" var/list/Lines = world.file2list(filename) @@ -895,7 +203,7 @@ GLOBAL_PROTECT(config_dir) if ("map") currentmap = new ("_maps/[data].json") if(currentmap.defaulted) - log_world("Failed to load map config for [data]!") + log_config("Failed to load map config for [data]!") if ("minplayers","minplayer") currentmap.config_min_users = text2num(data) if ("maxplayers","maxplayer") @@ -905,6 +213,7 @@ GLOBAL_PROTECT(config_dir) if ("default","defaultmap") defaultmap = currentmap if ("endmap") + LAZYINITLIST(maplist) maplist[currentmap.map_name] = currentmap currentmap = null if ("disabled") @@ -913,51 +222,7 @@ GLOBAL_PROTECT(config_dir) WRITE_FILE(GLOB.config_error_log, "Unknown command in map vote config: '[command]'") -/datum/configuration/proc/loadsql(filename) - filename = "[GLOB.config_dir][filename]" - var/list/Lines = world.file2list(filename) - for(var/t in Lines) - if(!t) - continue - - t = trim(t) - if(length(t) == 0) - continue - else if(copytext(t, 1, 2) == "#") - continue - - var/pos = findtext(t, " ") - var/name = null - var/value = null - - if(pos) - name = lowertext(copytext(t, 1, pos)) - value = copytext(t, pos + 1) - else - name = lowertext(t) - - if(!name) - continue - - switch(name) - if("sql_enabled") - sql_enabled = 1 - if("address") - global.sqladdress = value - if("port") - global.sqlport = value - if("feedback_database") - global.sqlfdbkdb = value - if("feedback_login") - global.sqlfdbklogin = value - if("feedback_password") - global.sqlfdbkpass = value - if("feedback_tableprefix") - global.sqlfdbktableprefix = value - else - WRITE_FILE(GLOB.config_error_log, "Unknown setting in configuration: '[name]'") - -/datum/configuration/proc/pick_mode(mode_name) +/datum/controller/configuration/proc/pick_mode(mode_name) // I wish I didn't have to instance the game modes in order to look up // their information, but it is the only way (at least that I know of). // ^ This guy didn't try hard enough @@ -968,8 +233,12 @@ GLOBAL_PROTECT(config_dir) return new T return new /datum/game_mode/extended() -/datum/configuration/proc/get_runnable_modes() +/datum/controller/configuration/proc/get_runnable_modes() var/list/datum/game_mode/runnable_modes = new + var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability) + var/list/min_pop = Get(/datum/config_entry/keyed_number_list/min_pop) + var/list/max_pop = Get(/datum/config_entry/keyed_number_list/max_pop) + var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust) for(var/T in gamemode_cache) var/datum/game_mode/M = new T() if(!(M.config_tag in modes)) @@ -994,8 +263,11 @@ GLOBAL_PROTECT(config_dir) runnable_modes[M] = final_weight return runnable_modes -/datum/configuration/proc/get_runnable_midround_modes(crew) +/datum/controller/configuration/proc/get_runnable_midround_modes(crew) var/list/datum/game_mode/runnable_modes = new + var/list/probabilities = Get(/datum/config_entry/keyed_number_list/probability) + var/list/min_pop = Get(/datum/config_entry/keyed_number_list/min_pop) + var/list/max_pop = Get(/datum/config_entry/keyed_number_list/max_pop) for(var/T in (gamemode_cache - SSticker.mode.type)) var/datum/game_mode/M = new T() if(!(M.config_tag in modes)) @@ -1013,9 +285,3 @@ GLOBAL_PROTECT(config_dir) continue runnable_modes[M] = probabilities[M.config_tag] return runnable_modes - -/datum/configuration/proc/stat_entry() - if(!statclick) - statclick = new/obj/effect/statclick/debug(null, "Edit", src) - - stat("[name]:", statclick) diff --git a/code/game/objects/items/manuals.dm b/code/game/objects/items/manuals.dm index a8bdce5fe9..c0298d8122 100644 --- a/code/game/objects/items/manuals.dm +++ b/code/game/objects/items/manuals.dm @@ -1,4 +1,3 @@ -<<<<<<< HEAD /*********************MANUALS (BOOKS)***********************/ //Oh god what the fuck I am not good at computer @@ -883,7 +882,8 @@ ..() /obj/item/book/manual/wiki/proc/initialize_wikibook() - if(config.wikiurl) + var/wikiurl = CONFIG_GET(string/wikiurl) + if(wikiurl) dat = {" @@ -901,7 +901,7 @@ }

    You start skimming through the manual...

    - + @@ -957,964 +957,3 @@ author = "Engineering Encyclopedia" title = "Hacking" page_link = "Hacking" -======= -/*********************MANUALS (BOOKS)***********************/ - -//Oh god what the fuck I am not good at computer -/obj/item/book/manual - icon = 'icons/obj/library.dmi' - due_date = 0 // Game time in 1/10th seconds - unique = 1 // 0 - Normal book, 1 - Should not be treated as normal book, unable to be copied, unable to be modified - -/obj/item/book/manual/engineering_particle_accelerator - name = "Particle Accelerator User's Guide" - icon_state ="bookParticleAccelerator" - author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned - title = "Particle Accelerator User's Guide" - dat = {" - - - - - -

    Experienced user's guide

    - -

    Setting up

    - -
      -
    1. Wrench all pieces to the floor
    2. -
    3. Add wires to all the pieces
    4. -
    5. Close all the panels with your screwdriver
    6. -
    - -

    Use

    - -
      -
    1. Open the control panel
    2. -
    3. Set the speed to 2
    4. -
    5. Start firing at the singularity generator
    6. -
    7. When the singularity reaches a large enough size so it starts moving on its own set the speed down to 0, but don't shut it off
    8. -
    9. Remember to wear a radiation suit when working with this machine... we did tell you that at the start, right?
    10. -
    - - - "} - - -/obj/item/book/manual/engineering_singularity_safety - name = "Singularity Safety in Special Circumstances" - icon_state ="bookEngineeringSingularitySafety" - author = "Engineering Encyclopedia" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned - title = "Singularity Safety in Special Circumstances" -//big pile of shit below. - - dat = {" - - - - -

    Singularity Safety in Special Circumstances

    - -

    Power outage

    - - A power problem has made the entire station lose power? Could be station-wide wiring problems or syndicate power sinks. In any case follow these steps: -

    - Step one: PANIC!
    - Step two: Get your ass over to engineering! QUICKLY!!!
    - Step three: Make sure the SMES is still powering the emitters, if not, setup the generator in secure storage and disconnect the emitters from the SMES.
    - Step four: Next, head over to the APC and swipe it with your ID card - if it doesn't unlock, continue with step 15.
    - Step five: Open the console and disengage the cover lock.
    - Step six: Pry open the APC with a Crowbar.
    - Step seven: Take out the empty power cell.
    - Step eight: Put in the new, full power cell - if you don't have one, continue with step 15.
    - Step nine: Quickly put on a Radiation suit.
    - Step ten: Check if the singularity field generators withstood the down-time - if they didn't, continue with step 15.
    - Step eleven: Since disaster was averted you now have to ensure it doesn't repeat. If it was a powersink which caused it and if the engineering apc is wired to the same powernet, which the powersink is on, you have to remove the piece of wire which links the apc to the powernet. If it wasn't a powersink which caused it, then skip to step 14.
    - Step twelve: Grab your crowbar and pry away the tile closest to the APC.
    - Step thirteen: Use the wirecutters to cut the wire which is conecting the grid to the terminal.
    - Step fourteen: Go to the bar and tell the guys how you saved them all. Stop reading this guide here.
    - Step fifteen: GET THE FUCK OUT OF THERE!!!
    -

    - -

    Shields get damaged

    - - Step one: GET THE FUCK OUT OF THERE!!! FORGET THE WOMEN AND CHILDREN, SAVE YOURSELF!!!
    - - - "} - -/obj/item/book/manual/hydroponics_pod_people - name = "The Human Harvest - From seed to market" - icon_state ="bookHydroponicsPodPeople" - author = "Farmer John" - title = "The Human Harvest - From seed to market" - dat = {" - - - - -

    Growing Humans

    - - Why would you want to grow humans? Well I'm expecting most readers to be in the slave trade, but a few might actually - want to revive fallen comrades. Growing pod people is easy, but prone to disaster. -

    -

      -
    1. Find a dead person who is in need of cloning.
    2. -
    3. Take a blood sample with a syringe.
    4. -
    5. Inject a seed pack with the blood sample.
    6. -
    7. Plant the seeds.
    8. -
    9. Tend to the plants water and nutrition levels until it is time to harvest the cloned human.
    10. -
    -

    - It really is that easy! Good luck! - - - - "} - -/obj/item/book/manual/medical_cloning - name = "Cloning techniques of the 26th century" - icon_state ="bookCloning" - author = "Medical Journal, volume 3" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned - title = "Cloning techniques of the 26th century" -//big pile of shit below. - - dat = {" - - - - - -

    How to Clone People

    - So there’s 50 dead people lying on the floor, chairs are spinning like no tomorrow and you haven’t the foggiest idea of what to do? Not to worry! This guide is intended to teach you how to clone people and how to do it right, in a simple step-by-step process! If at any point of the guide you have a mental meltdown, genetics probably isn’t for you and you should get a job-change as soon as possible before you’re sued for malpractice. - -
      -
    1. Acquire body
    2. -
    3. Strip body
    4. -
    5. Put body in cloning machine
    6. -
    7. Scan body
    8. -
    9. Clone body
    10. -
    11. Get clean Structurel Enzymes for the body
    12. -
    13. Put body in morgue
    14. -
    15. Await cloned body
    16. -
    17. Use the clean SW injector
    18. -
    19. Give person clothes back
    20. -
    21. Send person on their way
    22. -
    - -

    Step 1: Acquire body

    - This is pretty much vital for the process because without a body, you cannot clone it. Usually, bodies will be brought to you, so you do not need to worry so much about this step. If you already have a body, great! Move on to the next step. - -

    Step 2: Strip body

    - The cloning machine does not like abiotic items. What this means is you can’t clone anyone if they’re wearing clothes, so take all of it off. If it’s just one person, it’s courteous to put their possessions in the closet. If you have about seven people awaiting cloning, just leave the piles where they are, but don’t mix them around and for God’s sake don’t let the Clown in to steal them. - -

    Step 3: Put body in cloning machine

    - Grab the body and then put it inside the DNA modifier. If you cannot do this, then you messed up at Step 2. Go back and check you took EVERYTHING off - a commonly missed item is their headset. - -

    Step 4: Scan body

    - Go onto the computer and scan the body by pressing ‘Scan - ’. If you’re successful, they will be added to the records (note that this can be done at any time, even with living people, so that they can be cloned without a body in the event that they are lying dead on port solars and didn‘t turn on their suit sensors)! If not, and it says “Error: Mental interface failure.”, then they have left their bodily confines and are one with the spirits. If this happens, just shout at them to get back in their body, click ‘Refresh‘ and try scanning them again. If there’s no success, threaten them with gibbing. Still no success? Skip over to Step 7 and don‘t continue after it, as you have an unresponsive body and it cannot be cloned. If you got “Error: Unable to locate valid genetic data.“, you are trying to clone a monkey - start over. - -

    Step 5: Clone body

    - Now that the body has a record, click ’View Records’, click the subject’s name, and then click ‘Clone’ to start the cloning process. Congratulations! You’re halfway there. Remember not to ‘Eject’ the cloning pod as this will kill the developing clone and you’ll have to start the process again. - -

    Step 6: Get clean SEs for body

    - Cloning is a finicky and unreliable process. Whilst it will most certainly bring someone back from the dead, they can have any number of nasty disabilities given to them during the cloning process! For this reason, you need to prepare a clean, defect-free Structural Enzyme (SE) injection for when they’re done. If you’re a competent Geneticist, you will already have one ready on your working computer. If, for any reason, you do not, then eject the body from the DNA modifier (NOT THE CLONING POD) and take it next door to the Genetics research room. Put the body in one of those DNA modifiers and then go onto the console. Go into View/Edit/Transfer Buffer, find an open slot and click “SE“ to save it. Then click ‘Injector’ to get the SEs in syringe form. Put this in your pocket or something for when the body is done. - -

    Step 7: Put body in morgue

    - Now that the cloning process has been initiated and you have some clean Structural Enzymes, you no longer need the body! Drag it to the morgue and tell the Chef over the radio that they have some fresh meat waiting for them in there. To put a body in a morgue bed, simply open the tray, grab the body, put it on the open tray, then close the tray again. Use one of the nearby pens to label the bed “CHEF MEAT” in order to avoid confusion. - -

    Step 8: Await cloned body

    - Now go back to the lab and wait for your patient to be cloned. It won’t be long now, I promise. - -

    Step 9: Use the clean SE injector on person

    - Has your body been cloned yet? Great! As soon as the guy pops out, grab your injector and jab it in them. Once you’ve injected them, they now have clean Structural Enzymes and their defects, if any, will disappear in a short while. - -

    Step 10: Give person clothes back

    - Obviously the person will be naked after they have been cloned. Provided you weren’t an irresponsible little shit, you should have protected their possessions from thieves and should be able to give them back to the patient. No matter how cruel you are, it’s simply against protocol to force your patients to walk outside naked. - -

    Step 11: Send person on their way

    - Give the patient one last check-over - make sure they don’t still have any defects and that they have all their possessions. Ask them how they died, if they know, so that you can report any foul play over the radio. Once you’re done, your patient is ready to go back to work! Chances are they do not have Medbay access, so you should let them out of Genetics and the Medbay main entrance. - -

    If you’ve gotten this far, congratulations! You have mastered the art of cloning. Now, the real problem is how to resurrect yourself after that traitor had his way with you for cloning his target. - - - - - - "} - - -/obj/item/book/manual/ripley_build_and_repair - name = "APLU \"Ripley\" Construction and Operation Manual" - icon_state ="book" - author = "Weyland-Yutani Corp" // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned - title = "APLU \"Ripley\" Construction and Operation Manual" -//big pile of shit below. - - dat = {" - - - - -

    - Weyland-Yutani - Building Better Worlds -

    Autonomous Power Loader Unit \"Ripley\"

    -
    -

    Specifications:

    -
      -
    • Class: Autonomous Power Loader
    • -
    • Scope: Logistics and Construction
    • -
    • Weight: 820kg (without operator and with empty cargo compartment)
    • -
    • Height: 2.5m
    • -
    • Width: 1.8m
    • -
    • Top speed: 5km/hour
    • -
    • Operation in vacuum/hostile environment: Possible -
    • Airtank Volume: 500liters
    • -
    • Devices: -
        -
      • Hydraulic Clamp
      • -
      • High-speed Drill
      • -
      -
    • -
    • Propulsion Device: Powercell-powered electro-hydraulic system.
    • -
    • Powercell capacity: Varies.
    • -
    - -

    Construction:

    -
      -
    1. Connect all exosuit parts to the chassis frame
    2. -
    3. Connect all hydraulic fittings and tighten them up with a wrench
    4. -
    5. Adjust the servohydraulics with a screwdriver
    6. -
    7. Wire the chassis. (Cable is not included.)
    8. -
    9. Use the wirecutters to remove the excess cable if needed.
    10. -
    11. Install the central control module (Not included. Use supplied datadisk to create one).
    12. -
    13. Secure the mainboard with a screwdriver.
    14. -
    15. Install the peripherals control module (Not included. Use supplied datadisk to create one).
    16. -
    17. Secure the peripherals control module with a screwdriver
    18. -
    19. Install the internal armor plating (Not included due to Nanotrasen regulations. Can be made using 5 metal sheets.)
    20. -
    21. Secure the internal armor plating with a wrench
    22. -
    23. Weld the internal armor plating to the chassis
    24. -
    25. Install the external reinforced armor plating (Not included due to Nanotrasen regulations. Can be made using 5 reinforced metal sheets.)
    26. -
    27. Secure the external reinforced armor plating with a wrench
    28. -
    29. Weld the external reinforced armor plating to the chassis
    30. -
    31. -
    32. Additional Information:
    33. -
    34. The firefighting variation is made in a similar fashion.
    35. -
    36. A firesuit must be connected to the Firefighter chassis for heat shielding.
    37. -
    38. Internal armor is plasteel for additional strength.
    39. -
    40. External armor must be installed in 2 parts, totaling 10 sheets.
    41. -
    42. Completed mech is more resiliant against fire, and is a bit more durable overall
    43. -
    44. Nanotrasen is determined to the safety of its investments employees.
    45. -
    - - - -

    Operation

    - Coming soon... - "} - -/obj/item/book/manual/experimentor - name = "Mentoring your Experiments" - icon_state = "rdbook" - author = "Dr. H.P. Kritz" - title = "Mentoring your Experiments" - dat = {" - - - - -

    THE E.X.P.E.R.I-MENTOR

    - The Enhanced Xenobiological Period Extraction (and) Restoration Instructor is a machine designed to discover the secrets behind every item in existence. - With advanced technology, it can process 99.95% of items, and discover their uses and secrets. - The E.X.P.E.R.I-MENTOR is a Research apparatus that takes items, and through a process of elimination, it allows you to deduce new technological designs from them. - Due to the volatile nature of the E.X.P.E.R.I-MENTOR, there is a slight chance for malfunction, potentially causing irreparable damage to you or your environment. - However, upgrading the apparatus has proven to decrease the chances of undesirable, potentially life-threatening outcomes. - Please note that the E.X.P.E.R.I-MENTOR uses a state-of-the-art random generator, which has a larger entropy than the observable universe, - therefore it can generate wildly different results each day, therefore it is highly suggested to re-scan objects of interests frequently (e.g. each shift). - -

    BASIC PROCESS

    - The usage of the E.X.P.E.R.I-MENTOR is quite simple: -
      -
    1. Find an item with a technological background
    2. -
    3. Insert the item into the E.X.P.E.R.I-MENTOR
    4. -
    5. Cycle through each processing method of the device.
    6. -
    7. Stand back, even in case of a successful experiment, as the machine might produce undesired behaviour.
    8. -
    - -

    ADVANCED USAGE

    - The E.X.P.E.R.I-MENTOR has a variety of uses, beyond menial research work. The different results can be used to combat localised events, or even to get special items. - - The E.X.P.E.R.I-MENTOR's OBLITERATE function has the added use of transferring the destroyed item's material into a linked lathe. - - The IRRADIATE function can be used to transform items into other items, resulting in potential upgrades (or downgrades). - - Users should remember to always wear appropriate protection when using the machine, because malfunction can occur at any moment! - -

    EVENTS

    -

    GLOBAL (happens at any time):

    -
      -
    1. DETECTION MALFUNCTION - The machine's onboard sensors have malfunctioned, causing it to redefine the item's experiment type. - Produces the message: The E.X.P.E.R.I-MENTOR's onboard detection system has malfunctioned!
    2. - -
    3. IANIZATION - The machine's onboard corgi-filter has malfunctioned, causing it to produce a corgi from.. somewhere. - Produces the message: The E.X.P.E.R.I-MENTOR melts the banana, ian-izing the air around it!
    4. - -
    5. RUNTIME ERROR - The machine's onboard C4T-P processor has encountered a critical error, causing it to produce a cat from.. somewhere. - Produces the message: The E.X.P.E.R.I-MENTOR encounters a run-time error!
    6. - -
    7. B100DG0D.EXE - The machine has encountered an unknown subroutine, which has been injected into its runtime. It upgrades the held item! - Produces the message: The E.X.P.E.R.I-MENTOR improves the banana, drawing the life essence of those nearby!
    8. - -
    9. POWERSINK - The machine's PSU has tripped the charging mechanism! It consumes massive amounts of power! - Produces the message: The E.X.P.E.R.I-MENTOR begins to smoke and hiss, shaking violently!
    10. -
    -

    FAIL:

    - This event is produced when the item mismatches the selected experiment. - Produces a random message similar to: "the Banana rumbles, and shakes, the experiment was a failure!" - -

    POKE:

    -
      -
    1. WILD ARMS - The machine's gryoscopic processors malfunction, causing it to lash out at nearby people with its arms. - Produces the message: The E.X.P.E.R.I-MENTOR malfunctions and destroys the banana, lashing its arms out at nearby people!
    2. - -
    3. MISTYPE - The machine's interface has been garbled, and it switches to OBLITERATE. - Produces the message: The E.X.P.E.R.I-MENTOR malfunctions!
    4. - -
    5. THROW - The machine's spatial recognition device has shifted several meters across the room, causing it to try and repostion the item there. - Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, throwing the banana!
    6. -
    -

    IRRADIATE:

    -
      -
    1. RADIATION LEAK - The machine's shield has failed, resulting in a toxic radiation leak. - Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, melting the banana and leaking radiation!
    2. - -
    3. RADIATION DUMP - The machine's recycling and containment functions have failed, resulting in a dump of toxic waste around it - Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, spewing toxic waste!
    4. - -
    5. MUTATION - The machine's radio-isotope level meter has malfunctioned, causing it over-irradiate the item, making it transform. - Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, transforming the banana!
    6. -
    -

    GAS:

    -
      -
    1. TOXIN LEAK - The machine's filtering and vent systems have failed, resulting in a cloud of toxic gas being expelled. - Produces the message: The E.X.P.E.R.I-MENTOR destroys the banana, leaking dangerous gas!
    2. - -
    3. GAS LEAK - The machine's vent systems have failed, resulting in a cloud of harmless, but obscuring gas. - Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, spewing harmless gas!
    4. - -
    5. ELECTROMAGNETIC IONS - The machine's electrolytic scanners have failed, causing a dangerous Electromagnetic reaction. - Produces the message: The E.X.P.E.R.I-MENTOR melts the banana, ionizing the air around it!
    6. -
    -

    HEAT:

    -
      -
    1. TOASTER - The machine's heating coils have come into contact with the machine's gas storage, causing a large, sudden blast of flame. - Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, melting the banana and releasing a burst of flame!
    2. - -
    3. SAUNA - The machine's vent loop has sprung a leak, resulting in a large amount of superheated air being dumped around it. - Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, melting the banana and leaking hot air!
    4. - -
    5. EMERGENCY VENT - The machine's temperature gauge has malfunctioned, resulting in it attempting to cool the area around it, but instead, dumping a cloud of steam. - Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, activating its emergency coolant systems!
    6. -
    -

    COLD:

    -
      -
    1. FREEZER - The machine's cooling loop has sprung a leak, resulting in a cloud of super-cooled liquid being blasted into the air. - Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, shattering the banana and releasing a dangerous cloud of coolant!
    2. - -
    3. FRIDGE - The machine's cooling loop has been exposed to the outside air, resulting in a large decrease in temperature. - Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, shattering the banana and leaking cold air!
    4. - -
    5. SNOWSTORM - The machine's cooling loop has come into contact with the heating coils, resulting in a sudden blast of cool air. - Produces the message: The E.X.P.E.R.I-MENTOR malfunctions, releasing a flurry of chilly air as the banana pops out!
    6. -
    -

    OBLITERATE:

    -
      -
    1. IMPLOSION - The machine's pressure leveller has malfunctioned, causing it to pierce the space-time momentarily, making everything in the area fly towards it. - Produces the message: The E.X.P.E.R.I-MENTOR's crusher goes way too many levels too high, crushing right through space-time!
    2. - -
    3. DISTORTION - The machine's pressure leveller has completely disabled, resulting in a momentary space-time distortion, causing everything to fly around. - Produces the message: The E.X.P.E.R.I-MENTOR's crusher goes one level too high, crushing right into space-time!
    4. -
    - - - "} - -/obj/item/book/manual/research_and_development - name = "Research and Development 101" - icon_state = "rdbook" - author = "Dr. L. Ight" - title = "Research and Development 101" - dat = {" - - - - - -

    Science For Dummies

    - So you want to further SCIENCE? Good man/woman/thing! However, SCIENCE is a complicated process even though it's quite easy. For the most part, it's a three step process: -
      -
    1. 1) Deconstruct items in the Destructive Analyzer to advance technology or improve the design.
    2. -
    3. 2) Build unlocked designs in the Protolathe and Circuit Imprinter
    4. -
    5. 3) Repeat!
    6. -
    - - Those are the basic steps to furthing science. What do you do science with, however? Well, you have four major tools: R&D Console, the Destructive Analyzer, the Protolathe, and the Circuit Imprinter. - -

    The R&D Console

    - The R&D console is the cornerstone of any research lab. It is the central system from which the Destructive Analyzer, Protolathe, and Circuit Imprinter (your R&D systems) are controled. More on those systems in their own sections. On its own, the R&D console acts as a database for all your technological gains and new devices you discover. So long as the R&D console remains intact, you'll retain all that SCIENCE you've discovered. Protect it though, because if it gets damaged, you'll lose your data! In addition to this important purpose, the R&D console has a disk menu that lets you transfer data from the database onto disk or from the disk into the database. It also has a settings menu that lets you re-sync with nearby R&D devices (if they've become disconnected), lock the console from the unworthy, upload the data to all other R&D consoles in the network (all R&D consoles are networked by default), connect/disconnect from the network, and purge all data from the database. - NOTE: The technology list screen, circuit imprinter, and protolathe menus are accessible by non-scientists. This is intended to allow 'public' systems for the plebians to utilize some new devices. - -

    Destructive Analyzer

    - This is the source of all technology. Whenever you put a handheld object in it, it analyzes it and determines what sort of technological advancements you can discover from it. If the technology of the object is equal or higher then your current knowledge, you can destroy the object to further those sciences. Some devices (notably, some devices made from the protolathe and circuit imprinter) aren't 100% reliable when you first discover them. If these devices break down, you can put them into the Destructive Analyzer and improve their reliability rather then futher science. If their reliability is high enough ,it'll also advance their related technologies. - -

    Circuit Imprinter

    - This machine, along with the Protolathe, is used to actually produce new devices. The Circuit Imprinter takes glass and various chemicals (depends on the design) to produce new circuit boards to build new machines or computers. It can even be used to print AI modules. - -

    Protolathe

    - This machine is an advanced form of the Autolathe that produce non-circuit designs. Unlike the Autolathe, it can use processed metal, glass, solid plasma, silver, gold, and diamonds along with a variety of chemicals to produce devices. The downside is that, again, not all devices you make are 100% reliable when you first discover them. - -

    Reliability and You

    - As it has been stated, many devices when they're first discovered do not have a 100% reliablity when you first discover them. Instead, the reliablity of the device is dependent upon a base reliability value, whatever improvements to the design you've discovered through the Destructive Analyzer, and any advancements you've made with the device's source technologies. To be able to improve the reliability of a device, you have to use the device until it breaks beyond repair. Once that happens, you can analyze it in a Destructive Analyzer. Once the device reachs a certain minimum reliability, you'll gain tech advancements from it. - -

    Building a Better Machine

    - Many machines produces from circuit boards and inserted into a machine frame require a variety of parts to construct. These are parts like capacitors, batteries, matter bins, and so forth. As your knowledge of science improves, more advanced versions are unlocked. If you use these parts when constructing something, its attributes may be improved. For example, if you use an advanced matter bin when constructing an autolathe (rather then a regular one), it'll hold more materials. Experiment around with stock parts of various qualities to see how they affect the end results! Be warned, however: Tier 3 and higher stock parts don't have 100% reliability and their low reliability may affect the reliability of the end machine. - - - "} - - -/obj/item/book/manual/robotics_cyborgs - name = "Cyborgs for Dummies" - icon_state = "borgbook" - author = "XISC" - title = "Cyborgs for Dummies" - dat = {" - - - - - -

    Cyborgs for Dummies

    - -

    Chapters

    - -
      -
    1. Cyborg Related Equipment
    2. -
    3. Cyborg Modules
    4. -
    5. Cyborg Construction
    6. -
    7. Cyborg Deconstruction
    8. -
    9. Cyborg Maintenance
    10. -
    11. Cyborg Repairs
    12. -
    13. In Case of Emergency
    14. -
    - - -

    Cyborg Related Equipment

    - -

    Exosuit Fabricator

    - The Exosuit Fabricator is the most important piece of equipment related to cyborgs. It allows the construction of the core cyborg parts. Without these machines, cyborgs can not be built. It seems that they may also benefit from advanced research techniques. - -

    Cyborg Recharging Station

    - This useful piece of equipment will suck power out of the power systems to charge a cyborg's power cell back up to full charge. - -

    Robotics Control Console

    - This useful piece of equipment can be used to immobolize or destroy a cyborg. A word of warning: Cyborgs are expensive pieces of equipment, do not destroy them without good reason, or Nanotrasen may see to it that it never happens again. - - -

    Cyborg Modules

    - When a cyborg is created it picks out of an array of modules to designate its purpose. There are 6 different cyborg modules. - -

    Standard Cyborg

    - The standard cyborg module is a multi-purpose cyborg. It is equipped with various modules, allowing it to do basic tasks.
    - -

    Engineering Cyborg

    - The Engineering cyborg module comes equipped with various engineering-related tools to help with engineering-related tasks.
    - -

    Mining Cyborg

    - The Mining Cyborg module comes equipped with the latest in mining equipment. They are efficient at mining due to no need for oxygen, but their power cells limit their time in the mines. - -

    Security Cyborg

    - The Security Cyborg module is equipped with effective security measures used to apprehend and arrest criminals without harming them a bit. - -

    Janitor Cyborg

    - The Janitor Cyborg module is equipped with various cleaning-facilitating devices. - -

    Service Cyborg

    - The service cyborg module comes ready to serve your human needs. It includes various entertainment and refreshment devices. Occasionally some service cyborgs may have been referred to as "Bros" - -

    Cyborg Construction

    - Cyborg construction is a rather easy process, requiring a decent amount of metal and a few other supplies.
    The required materials to make a cyborg are: -
      -
    • Metal
    • -
    • Two Flashes
    • -
    • One Power Cell (Preferrably rated to 15000w)
    • -
    • Some electrical wires
    • -
    • One Human Brain
    • -
    • One Man-Machine Interface
    • -
    - Once you have acquired the materials, you can start on construction of your cyborg.
    To construct a cyborg, follow the steps below: -
      -
    1. Start the Exosuit Fabricators constructing all of the cyborg parts
    2. -
    3. While the parts are being constructed, take your human brain, and place it inside the Man-Machine Interface
    4. -
    5. Once you have a Robot Head, place your two flashes inside the eye sockets
    6. -
    7. Once you have your Robot Chest, wire the Robot chest, then insert the power cell
    8. -
    9. Attach all of the Robot parts to the Robot frame
    10. -
    11. Insert the Man-Machine Interface (With the Brain inside) Into the Robot Body
    12. -
    13. Congratulations! You have a new cyborg!
    14. -
    - -

    Cyborg Deconstruction

    - If you want to deconstruct a cyborg, say to remove its MMI without blowing the Cyborg to pieces, they come apart very quickly, and very safely, in a few simple steps. -
      -
    • Crowbar
    • -
    • Wrench
    • - Optional: -
    • Screwdriver
    • -
    • Wirecutters
    • -
    -
      -
    1. Begin by unlocking the Cyborg's access panel using your ID
    2. -
    3. Use your crowbar to open the Cyborg's access panel
    4. -
    5. Using your bare hands, remove the power cell from the Cyborg
    6. -
    7. Lockdown the Cyborg to disengage safety protocols
    8. -
        - Option 1: Robotics console -
      1. Use the Robotics console in the RD's office
      2. -
      3. Find the entry for your Cyborg
      4. -
      5. Press the Lockdown button on the Robotics console
      6. -
      -
        - Option 2: Lockdown wire -
      1. Use your screwdriver to expose the Cyborg's wiring
      2. -
      3. Use your wirecutters to start cutting all of the wires until the lockdown light turns off, cutting all of the wires irregardless of the lockdown light works as well
      4. -
      -
    9. Use your wrench to unfasten the Cyborg's bolts, the Cyborg will then fall apart onto the floor, the MMI will be there as well
    10. -
    - -

    Cyborg Maintenance

    - Occasionally Cyborgs may require maintenance of a couple types, this could include replacing a power cell with a charged one, or possibly maintaining the cyborg's internal wiring. - -

    Replacing a Power Cell

    - Replacing a Power cell is a common type of maintenance for cyborgs. It usually involves replacing the cell with a fully charged one, or upgrading the cell with a larger capacity cell.
    The steps to replace a cell are follows: -
      -
    1. Unlock the Cyborg's Interface by swiping your ID on it
    2. -
    3. Open the Cyborg's outer panel using a crowbar
    4. -
    5. Remove the old power cell
    6. -
    7. Insert the new power cell
    8. -
    9. Close the Cyborg's outer panel using a crowbar
    10. -
    11. Lock the Cyborg's Interface by swiping your ID on it, this will prevent non-qualified personnel from attempting to remove the power cell
    12. -
    - -

    Exposing the Internal Wiring

    - Exposing the internal wiring of a cyborg is fairly easy to do, and is mainly used for cyborg repairs.
    You can easily expose the internal wiring by following the steps below: -
      -
    1. Follow Steps 1 - 3 of "Replacing a Cyborg's Power Cell"
    2. -
    3. Open the cyborg's internal wiring panel by using a screwdriver to unsecure the panel
    4. -
    - To re-seal the cyborg's internal wiring: -
      -
    1. Use a screwdriver to secure the cyborg's internal panel
    2. -
    3. Follow steps 4 - 6 of "Replacing a Cyborg's Power Cell" to close up the cyborg
    4. -
    - -

    Cyborg Repairs

    - Occasionally a Cyborg may become damaged. This could be in the form of impact damage from a heavy or fast-travelling object, or it could be heat damage from high temperatures, or even lasers or Electromagnetic Pulses (EMPs). - -

    Dents

    - If a cyborg becomes damaged due to impact from heavy or fast-moving objects, it will become dented. Sure, a dent may not seem like much, but it can compromise the structural integrity of the cyborg, possibly causing a critical failure. - Dents in a cyborg's frame are rather easy to repair, all you need is to apply a welding tool to the dented area, and the high-tech cyborg frame will repair the dent under the heat of the welder. - -

    Excessive Heat Damage

    - If a cyborg becomes damaged due to excessive heat, it is likely that the internal wires will have been damaged. You must replace those wires to ensure that the cyborg remains functioning properly.
    To replace the internal wiring follow the steps below: -
      -
    1. Unlock the Cyborg's Interface by swiping your ID
    2. -
    3. Open the Cyborg's External Panel using a crowbar
    4. -
    5. Remove the Cyborg's Power Cell
    6. -
    7. Using a screwdriver, expose the internal wiring or the Cyborg
    8. -
    9. Replace the damaged wires inside the cyborg
    10. -
    11. Secure the internal wiring cover using a screwdriver
    12. -
    13. Insert the Cyborg's Power Cell
    14. -
    15. Close the Cyborg's External Panel using a crowbar
    16. -
    17. Lock the Cyborg's Interface by swiping your ID
    18. -
    - These repair tasks may seem difficult, but are essential to keep your cyborgs running at peak efficiency. - -

    In Case of Emergency

    - In case of emergency, there are a few steps you can take. - -

    "Rogue" Cyborgs

    - If the cyborgs seem to become "rogue", they may have non-standard laws. In this case, use extreme caution. - To repair the situation, follow these steps: -
      -
    1. Locate the nearest robotics console
    2. -
    3. Determine which cyborgs are "Rogue"
    4. -
    5. Press the lockdown button to immobolize the cyborg
    6. -
    7. Locate the cyborg
    8. -
    9. Expose the cyborg's internal wiring
    10. -
    11. Check to make sure the LawSync and AI Sync lights are lit
    12. -
    13. If they are not lit, pulse the LawSync wire using a multitool to enable the cyborg's Law Sync
    14. -
    15. Proceed to a cyborg upload console. Nanotrasen usually places these in the same location as AI uplaod consoles.
    16. -
    17. Use a "Reset" upload moduleto reset the cyborg's laws
    18. -
    19. Proceed to a Robotics Control console
    20. -
    21. Remove the lockdown on the cyborg
    22. -
    - -

    As a last resort

    - If all else fails in a case of cyborg-related emergency. There may be only one option. Using a Robotics Control console, you may have to remotely detonate the cyborg. -

    WARNING:

    Do not detonate a borg without an explicit reason for doing so. Cyborgs are expensive pieces of Nanotrasen equipment, and you may be punished for detonating them without reason. - - - - "} - - - -/obj/item/book/manual/chef_recipes - name = "Chef Recipes" - icon_state = "cooked_book" - author = "Lord Frenrir Cageth" - title = "Chef Recipes" - dat = {" - - - - - -

    Food for Dummies

    - Here is a guide on basic food recipes and also how to not poison your customers accidentally. - - -

    Basic ingredients preparation:

    - - Dough: 10u water + 15u flour for simple dough.
    - 15u egg yolk + 15u flour + 5u sugar for cake batter.
    - Doughs can be transformed by using a knife and rolling pin.
    - All doughs can be microwaved.
    - Bowl: Add water to it for soup preparation.
    - Meat: Microwave it, process it, slice it into microwavable cutlets with your knife, or use it raw.
    - Cheese: Add 5u universal enzyme (catalyst) to milk and soy milk to prepare cheese (sliceable) and tofu.
    - Rice: Mix 10u rice with 10u water in a bowl then microwave it. - -

    Custom food:

    - Add ingredients to a base item to prepare a custom meal.
    - The bases are:
    - - bun (burger)
    - - breadslices(sandwich)
    - - plain bread
    - - plain pie
    - - vanilla cake
    - - empty bowl (salad)
    - - bowl with 10u water (soup)
    - - boiled spaghetti
    - - pizza bread
    - - metal rod (kebab) - -

    Table Craft:

    - Put ingredients on table, then click and drag the table onto yourself to see what recipes you can prepare. - -

    Microwave:

    - Use it to cook or boil food ingredients (meats, doughs, egg, spaghetti, donkpocket, etc...). - It can cook multiple items at once. - -

    Processor:

    - Use it to process certain ingredients (meat into faggot, doughslice into spaghetti, potato into fries,etc...) - -

    Gibber:

    - Stuff an animal in it to grind it into meat. - -

    Meat spike:

    - Stick an animal on it then begin collecting its meat. - - -

    Example recipes:

    - Vanilla Cake: Microwave cake batter.
    - Burger: 1 bun + 1 meat steak
    - Bread: Microwave dough.
    - Waffles: 2 pastry base
    - Popcorn: Microwave corn.
    - Meat Steak: Microwave meat.
    - Meat Pie: 1 plain pie + 1u black pepper + 1u salt + 2 meat cutlets
    - Boiled Spagetti: Microwave spaghetti.
    - Donuts: 1u sugar + 1 pastry base
    - Fries: Process potato. - -

    Sharing your food:

    - You can put your meals on your kitchen counter or load them in the snack vending machines. - - - "} - - -/obj/item/book/manual/barman_recipes - name = "Barman Recipes" - icon_state = "barbook" - author = "Sir John Rose" - title = "Barman Recipes" - dat = {" - - - - - -

    Drinks for dummies

    - Heres a guide for some basic drinks. - -

    Manly Dorf:

    - Mix ale and beer into a glass. - -

    Grog:

    - Mix rum and water into a glass. - -

    Black Russian:

    - Mix vodka and kahlua into a glass. - -

    Irish Cream:

    - Mix cream and whiskey into a glass. - -

    Screwdriver:

    - Mix vodka and orange juice into a glass. - -

    Cafe Latte:

    - Mix milk and coffee into a glass. - -

    Mead:

    - Mix Enzyme, water and sugar into a glass. - -

    Gin Tonic:

    - Mix gin and tonic into a glass. - -

    Classic Martini:

    - Mix vermouth and gin into a glass. - - - - - "} - - -/obj/item/book/manual/detective - name = "The Film Noir: Proper Procedures for Investigations" - icon_state ="bookDetective" - author = "Nanotrasen" - title = "The Film Noir: Proper Procedures for Investigations" - dat = {" - - - - -

    Detective Work

    - - Between your bouts of self-narration, and drinking whiskey on the rocks, you might get a case or two to solve.
    - To have the best chance to solve your case, follow these directions: -

    -

      -
    1. Go to the crime scene.
    2. -
    3. Take your scanner and scan EVERYTHING (Yes, the doors, the tables, even the dog.)
    4. -
    5. Once you are reasonably certain you have every scrap of evidence you can use, find all possible entry points and scan them, too.
    6. -
    7. Return to your office.
    8. -
    9. Using your forensic scanning computer, scan your Scanner to upload all of your evidence into the database.
    10. -
    11. Browse through the resulting dossiers, looking for the one that either has the most complete set of prints, or the most suspicious items handled.
    12. -
    13. If you have 80% or more of the print (The print is displayed) go to step 10, otherwise continue to step 8.
    14. -
    15. Look for clues from the suit fibres you found on your perp, and go about looking for more evidence with this new information, scanning as you go.
    16. -
    17. Try to get a fingerprint card of your perp, as if used in the computer, the prints will be completed on their dossier.
    18. -
    19. Assuming you have enough of a print to see it, grab the biggest complete piece of the print and search the security records for it.
    20. -
    21. Since you now have both your dossier and the name of the person, print both out as evidence, and get security to nab your baddie.
    22. -
    23. Give yourself a pat on the back and a bottle of the ships finest vodka, you did it!
    24. -
    -

    - It really is that easy! Good luck! - - - "} - -/obj/item/book/manual/nuclear - name = "Fission Mailed: Nuclear Sabotage 101" - icon_state ="bookNuclear" - author = "Syndicate" - title = "Fission Mailed: Nuclear Sabotage 101" - dat = {" - Nuclear Explosives 101:
    - Hello and thank you for choosing the Syndicate for your nuclear information needs.
    - Today's crash course will deal with the operation of a Fusion Class Nanotrasen made Nuclear Device.
    - First and foremost, DO NOT TOUCH ANYTHING UNTIL THE BOMB IS IN PLACE.
    - Pressing any button on the compacted bomb will cause it to extend and bolt itself into place.
    - If this is done to unbolt it one must completely log in which at this time may not be possible.
    - To make the nuclear device functional:
    -

  • Place the nuclear device in the designated detonation zone.
  • -
  • Extend and anchor the nuclear device from its interface.
  • -
  • Insert the nuclear authorisation disk into slot.
  • -
  • Type numeric authorisation code into the keypad. This should have been provided. Note: If you make a mistake press R to reset the device. -
  • Press the E button to log onto the device.
  • - You now have activated the device. To deactivate the buttons at anytime for example when you've already prepped the bomb for detonation remove the auth disk OR press the R on the keypad.
    - Now the bomb CAN ONLY be detonated using the timer. Manual detonation is not an option.
    - Note: Nanotrasen is a pain in the neck.
    - Toggle off the SAFETY.
    - Note: You wouldn't believe how many Syndicate Operatives with doctorates have forgotten this step.
    - So use the - - and + + to set a det time between 5 seconds and 10 minutes.
    - Then press the timer toggle button to start the countdown.
    - Now remove the auth. disk so that the buttons deactivate.
    - Note: THE BOMB IS STILL SET AND WILL DETONATE
    - Now before you remove the disk if you need to move the bomb you can:
    - Toggle off the anchor, move it, and re-anchor.

    - Good luck. Remember the order:
    - Disk, Code, Safety, Timer, Disk, RUN!
    - Intelligence Analysts believe that normal Nanotrasen procedure is for the Captain to secure the nuclear authorisation disk.
    - Good luck! - "} - -// Wiki books that are linked to the configured wiki link. - -// A book that links to the wiki -/obj/item/book/manual/wiki - var/page_link = "" - window_size = "970x710" - -/obj/item/book/manual/wiki/attack_self() - if(!dat) - initialize_wikibook() - ..() - -/obj/item/book/manual/wiki/proc/initialize_wikibook() - var/wikiurl = CONFIG_GET(string/wikiurl) - if(wikiurl) - dat = {" - - - - - - -

    You start skimming through the manual...

    - - - - - - "} - -/obj/item/book/manual/wiki/chemistry - name = "Chemistry Textbook" - icon_state ="chemistrybook" - author = "Nanotrasen" - title = "Chemistry Textbook" - page_link = "Guide_to_chemistry" - -/obj/item/book/manual/wiki/engineering_construction - name = "Station Repairs and Construction" - icon_state ="bookEngineering" - author = "Engineering Encyclopedia" - title = "Station Repairs and Construction" - page_link = "Guide_to_construction" - -/obj/item/book/manual/wiki/engineering_guide - name = "Engineering Textbook" - icon_state ="bookEngineering2" - author = "Engineering Encyclopedia" - title = "Engineering Textbook" - page_link = "Guide_to_engineering" - -/obj/item/book/manual/wiki/security_space_law - name = "Space Law" - desc = "A set of Nanotrasen guidelines for keeping law and order on their space stations." - icon_state = "bookSpaceLaw" - author = "Nanotrasen" - title = "Space Law" - page_link = "Space_Law" - -/obj/item/book/manual/wiki/infections - name = "Infections - Making your own pandemic!" - icon_state = "bookInfections" - author = "Infections Encyclopedia" - title = "Infections - Making your own pandemic!" - page_link = "Infections" - -/obj/item/book/manual/wiki/telescience - name = "Teleportation Science - Bluespace for dummies!" - icon_state = "book7" - author = "University of Bluespace" - title = "Teleportation Science - Bluespace for dummies!" - page_link = "Guide_to_telescience" - -/obj/item/book/manual/wiki/engineering_hacking - name = "Hacking" - icon_state ="bookHacking" - author = "Engineering Encyclopedia" - title = "Hacking" - page_link = "Hacking" ->>>>>>> 4178c20... Configuration datum refactor (#30763) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index c30308223f..cdbdb4a311 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1,4 +1,3 @@ -<<<<<<< HEAD /client/proc/cmd_admin_drop_everything(mob/M in GLOB.mob_list) set category = null set name = "Drop Everything" @@ -175,7 +174,7 @@ return if(automute) - if(!config.automute_on) + if(!CONFIG_GET(flag/automute_on)) return else if(!check_rights()) @@ -708,8 +707,9 @@ Traitors and the like can also be revived with the previous role mostly intact. to_chat(usr, "Nope you can't do this, the game's already started. This only works before rounds!") return - if(config.force_random_names) - config.force_random_names = 0 + var/frn = CONFIG_GET(flag/force_random_names) + if(frn) + CONFIG_SET(flag/force_random_names, FALSE) message_admins("Admin [key_name_admin(usr)] has disabled \"Everyone is Special\" mode.") to_chat(usr, "Disabled.") return @@ -727,7 +727,7 @@ Traitors and the like can also be revived with the previous role mostly intact. to_chat(usr, "Remember: you can always disable the randomness by using the verb again, assuming the round hasn't started yet.") - config.force_random_names = 1 + CONFIG_SET(flag/force_random_names, TRUE) SSblackbox.add_details("admin_verb","Make Everyone Random") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -735,15 +735,15 @@ Traitors and the like can also be revived with the previous role mostly intact. set category = "Server" set name = "Toggle random events on/off" set desc = "Toggles random events such as meteors, black holes, blob (but not space dust) on/off" - if(!config.allow_random_events) - config.allow_random_events = 1 + var/new_are = !CONFIG_GET(flag/allow_random_events) + CONFIG_SET(flag/allow_random_events, new_are) + if(new_are) to_chat(usr, "Random events enabled") message_admins("Admin [key_name_admin(usr)] has enabled random events.") else - config.allow_random_events = 0 to_chat(usr, "Random events disabled") message_admins("Admin [key_name_admin(usr)] has disabled random events.") - SSblackbox.add_details("admin_toggle","Toggle Random Events|[config.allow_random_events]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + SSblackbox.add_details("admin_toggle","Toggle Random Events|[new_are]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/admin_change_sec_level() @@ -1257,1265 +1257,4 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits to_chat(usr, "ERROR: Unable to update player flags. Please check logs.") else message_admins("[key_name_admin(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name_admin(C)]") -======= -/client/proc/cmd_admin_drop_everything(mob/M in GLOB.mob_list) - set category = null - set name = "Drop Everything" - if(!holder) - to_chat(src, "Only administrators may use this command.") - return - - var/confirm = alert(src, "Make [M] drop everything?", "Message", "Yes", "No") - if(confirm != "Yes") - return - - for(var/obj/item/W in M) - if(!M.dropItemToGround(W)) - qdel(W) - M.regenerate_icons() - - log_admin("[key_name(usr)] made [key_name(M)] drop everything!") - var/msg = "[key_name_admin(usr)] made [key_name_admin(M)] drop everything!" - message_admins(msg) - admin_ticket_log(M, msg) - SSblackbox.add_details("admin_verb","Drop Everything") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_admin_subtle_message(mob/M in GLOB.mob_list) - set category = "Special Verbs" - set name = "Subtle Message" - - if(!ismob(M)) - return - if (!holder) - to_chat(src, "Only administrators may use this command.") - return - - message_admins("[key_name_admin(src)] has started answering [key_name(M.key, 0, 0)]'s prayer.") - var/msg = input("Message:", text("Subtle PM to [M.key]")) as text - - if (!msg) - message_admins("[key_name_admin(src)] decided not to answer [key_name(M.key, 0, 0)]'s prayer") - return - if(usr) - if (usr.client) - if(usr.client.holder) - to_chat(M, "You hear a voice in your head... [msg]") - - log_admin("SubtlePM: [key_name(usr)] -> [key_name(M)] : [msg]") - msg = " SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg]" - message_admins(msg) - admin_ticket_log(M, msg) - SSblackbox.add_details("admin_verb","Subtle Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_admin_world_narrate() - set category = "Special Verbs" - set name = "Global Narrate" - - if (!holder) - to_chat(src, "Only administrators may use this command.") - return - - var/msg = input("Message:", text("Enter the text you wish to appear to everyone:")) as text - - if (!msg) - return - to_chat(world, "[msg]") - log_admin("GlobalNarrate: [key_name(usr)] : [msg]") - message_admins("[key_name_admin(usr)] Sent a global narrate") - SSblackbox.add_details("admin_verb","Global Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_admin_direct_narrate(mob/M) - set category = "Special Verbs" - set name = "Direct Narrate" - - if(!holder) - to_chat(src, "Only administrators may use this command.") - return - - if(!M) - M = input("Direct narrate to whom?", "Active Players") as null|anything in GLOB.player_list - - if(!M) - return - - var/msg = input("Message:", text("Enter the text you wish to appear to your target:")) as text - - if( !msg ) - return - - to_chat(M, msg) - log_admin("DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg]") - msg = " DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg]
    " - message_admins(msg) - admin_ticket_log(M, msg) - SSblackbox.add_details("admin_verb","Direct Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_admin_local_narrate(atom/A) - set category = "Special Verbs" - set name = "Local Narrate" - - if (!holder) - to_chat(src, "Only administrators may use this command.") - return - if(!A) - return - var/range = input("Range:", "Narrate to mobs within how many tiles:", 7) as num - if(!range) - return - var/msg = input("Message:", text("Enter the text you wish to appear to everyone within view:")) as text - if (!msg) - return - for(var/mob/M in view(range,A)) - to_chat(M, msg) - - log_admin("LocalNarrate: [key_name(usr)] at [get_area(A)][COORD(A)]: [msg]") - message_admins(" LocalNarrate: [key_name_admin(usr)] at [get_area(A)][ADMIN_JMP(A)]: [msg]
    ") - SSblackbox.add_details("admin_verb","Local Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_admin_godmode(mob/M in GLOB.mob_list) - set category = "Special Verbs" - set name = "Godmode" - if(!holder) - to_chat(src, "Only administrators may use this command.") - return - M.status_flags ^= GODMODE - to_chat(usr, "Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"]") - - log_admin("[key_name(usr)] has toggled [key_name(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]") - var/msg = "[key_name_admin(usr)] has toggled [key_name_admin(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]" - message_admins(msg) - admin_ticket_log(M, msg) - SSblackbox.add_details("admin_toggle","Godmode|[M.status_flags & GODMODE]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - - -/proc/cmd_admin_mute(whom, mute_type, automute = 0) - if(!whom) - return - - var/muteunmute - var/mute_string - var/feedback_string - switch(mute_type) - if(MUTE_IC) - mute_string = "IC (say and emote)" - feedback_string = "IC" - if(MUTE_OOC) - mute_string = "OOC" - feedback_string = "OOC" - if(MUTE_PRAY) - mute_string = "pray" - feedback_string = "Pray" - if(MUTE_ADMINHELP) - mute_string = "adminhelp, admin PM and ASAY" - feedback_string = "Adminhelp" - if(MUTE_DEADCHAT) - mute_string = "deadchat and DSAY" - feedback_string = "Deadchat" - if(MUTE_ALL) - mute_string = "everything" - feedback_string = "Everything" - else - return - - var/client/C - if(istype(whom, /client)) - C = whom - else if(istext(whom)) - C = GLOB.directory[whom] - else - return - - var/datum/preferences/P - if(C) - P = C.prefs - else - P = GLOB.preferences_datums[whom] - if(!P) - return - - if(automute) - if(!CONFIG_GET(flag/automute_on)) - return - else - if(!check_rights()) - return - - if(automute) - muteunmute = "auto-muted" - P.muted |= mute_type - log_admin("SPAM AUTOMUTE: [muteunmute] [key_name(whom)] from [mute_string]") - message_admins("SPAM AUTOMUTE: [muteunmute] [key_name_admin(whom)] from [mute_string].") - if(C) - to_chat(C, "You have been [muteunmute] from [mute_string] by the SPAM AUTOMUTE system. Contact an admin.") - SSblackbox.add_details("admin_toggle","Auto Mute [feedback_string]|1") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return - - if(P.muted & mute_type) - muteunmute = "unmuted" - P.muted &= ~mute_type - else - muteunmute = "muted" - P.muted |= mute_type - - log_admin("[key_name(usr)] has [muteunmute] [key_name(whom)] from [mute_string]") - message_admins("[key_name_admin(usr)] has [muteunmute] [key_name_admin(whom)] from [mute_string].") - if(C) - to_chat(C, "You have been [muteunmute] from [mute_string] by [key_name(usr, include_name = FALSE)].") - SSblackbox.add_details("admin_toggle","Mute [feedback_string]|[P.muted & mute_type]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - - -//I use this proc for respawn character too. /N -/proc/create_xeno(ckey) - if(!ckey) - var/list/candidates = list() - for(var/mob/M in GLOB.player_list) - if(M.stat != DEAD) - continue //we are not dead! - if(!(ROLE_ALIEN in M.client.prefs.be_special)) - continue //we don't want to be an alium - if(M.client.is_afk()) - continue //we are afk - if(M.mind && M.mind.current && M.mind.current.stat != DEAD) - continue //we have a live body we are tied to - candidates += M.ckey - if(candidates.len) - ckey = input("Pick the player you want to respawn as a xeno.", "Suitable Candidates") as null|anything in candidates - else - to_chat(usr, "Error: create_xeno(): no suitable candidates.") - if(!istext(ckey)) - return 0 - - var/alien_caste = input(usr, "Please choose which caste to spawn.","Pick a caste",null) as null|anything in list("Queen","Praetorian","Hunter","Sentinel","Drone","Larva") - var/obj/effect/landmark/spawn_here = GLOB.xeno_spawn.len ? pick(GLOB.xeno_spawn) : null - var/mob/living/carbon/alien/new_xeno - switch(alien_caste) - if("Queen") - new_xeno = new /mob/living/carbon/alien/humanoid/royal/queen(spawn_here) - if("Praetorian") - new_xeno = new /mob/living/carbon/alien/humanoid/royal/praetorian(spawn_here) - if("Hunter") - new_xeno = new /mob/living/carbon/alien/humanoid/hunter(spawn_here) - if("Sentinel") - new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(spawn_here) - if("Drone") - new_xeno = new /mob/living/carbon/alien/humanoid/drone(spawn_here) - if("Larva") - new_xeno = new /mob/living/carbon/alien/larva(spawn_here) - else - return 0 - if(!spawn_here) - SSjob.SendToLateJoin(new_xeno, FALSE) - - new_xeno.ckey = ckey - var/msg = "[key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste]." - message_admins(msg) - admin_ticket_log(new_xeno, msg) - return 1 - -/* -If a guy was gibbed and you want to revive him, this is a good way to do so. -Works kind of like entering the game with a new character. Character receives a new mind if they didn't have one. -Traitors and the like can also be revived with the previous role mostly intact. -/N */ -/client/proc/respawn_character() - set category = "Special Verbs" - set name = "Respawn Character" - set desc = "Respawn a person that has been gibbed/dusted/killed. They must be a ghost for this to work and preferably should not have a body to go back into." - if(!holder) - to_chat(src, "Only administrators may use this command.") - return - var/input = ckey(input(src, "Please specify which key will be respawned.", "Key", "")) - if(!input) - return - - var/mob/dead/observer/G_found - for(var/mob/dead/observer/G in GLOB.player_list) - if(G.ckey == input) - G_found = G - break - - if(!G_found)//If a ghost was not found. - to_chat(usr, "There is no active key like that in the game or the person is not currently a ghost.") - return - - if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something - //Check if they were an alien - if(G_found.mind.assigned_role=="Alien") - if(alert("This character appears to have been an alien. Would you like to respawn them as such?",,"Yes","No")=="Yes") - var/turf/T - if(GLOB.xeno_spawn.len) - T = pick(GLOB.xeno_spawn) - - var/mob/living/carbon/alien/new_xeno - switch(G_found.mind.special_role)//If they have a mind, we can determine which caste they were. - if("Hunter") - new_xeno = new /mob/living/carbon/alien/humanoid/hunter(T) - if("Sentinel") - new_xeno = new /mob/living/carbon/alien/humanoid/sentinel(T) - if("Drone") - new_xeno = new /mob/living/carbon/alien/humanoid/drone(T) - if("Praetorian") - new_xeno = new /mob/living/carbon/alien/humanoid/royal/praetorian(T) - if("Queen") - new_xeno = new /mob/living/carbon/alien/humanoid/royal/queen(T) - else//If we don't know what special role they have, for whatever reason, or they're a larva. - create_xeno(G_found.ckey) - return - - if(!T) - SSjob.SendToLateJoin(new_xeno, FALSE) - - //Now to give them their mind back. - G_found.mind.transfer_to(new_xeno) //be careful when doing stuff like this! I've already checked the mind isn't in use - new_xeno.key = G_found.key - to_chat(new_xeno, "You have been fully respawned. Enjoy the game.") - var/msg = "[key_name_admin(usr)] has respawned [new_xeno.key] as a filthy xeno." - message_admins(msg) - admin_ticket_log(new_xeno, msg) - return //all done. The ghost is auto-deleted - - //check if they were a monkey - else if(findtext(G_found.real_name,"monkey")) - if(alert("This character appears to have been a monkey. Would you like to respawn them as such?",,"Yes","No")=="Yes") - var/mob/living/carbon/monkey/new_monkey = new - SSjob.SendToLateJoin(new_monkey) - G_found.mind.transfer_to(new_monkey) //be careful when doing stuff like this! I've already checked the mind isn't in use - new_monkey.key = G_found.key - to_chat(new_monkey, "You have been fully respawned. Enjoy the game.") - var/msg = "[key_name_admin(usr)] has respawned [new_monkey.key] as a filthy xeno." - message_admins(msg) - admin_ticket_log(new_monkey, msg) - return //all done. The ghost is auto-deleted - - - //Ok, it's not a xeno or a monkey. So, spawn a human. - var/mob/living/carbon/human/new_character = new//The mob being spawned. - SSjob.SendToLateJoin(new_character) - - var/datum/data/record/record_found //Referenced to later to either randomize or not randomize the character. - if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something - /*Try and locate a record for the person being respawned through GLOB.data_core. - This isn't an exact science but it does the trick more often than not.*/ - var/id = md5("[G_found.real_name][G_found.mind.assigned_role]") - - record_found = find_record("id", id, GLOB.data_core.locked) - - if(record_found)//If they have a record we can determine a few things. - new_character.real_name = record_found.fields["name"] - new_character.gender = record_found.fields["sex"] - new_character.age = record_found.fields["age"] - new_character.hardset_dna(record_found.fields["identity"], record_found.fields["enzymes"], record_found.fields["name"], record_found.fields["blood_type"], record_found.fields["species"], record_found.fields["features"]) - else - var/datum/preferences/A = new() - A.copy_to(new_character) - A.real_name = G_found.real_name - new_character.dna.update_dna_identity() - - new_character.name = new_character.real_name - - if(G_found.mind && !G_found.mind.active) - G_found.mind.transfer_to(new_character) //be careful when doing stuff like this! I've already checked the mind isn't in use - else - new_character.mind_initialize() - if(!new_character.mind.assigned_role) - new_character.mind.assigned_role = "Assistant"//If they somehow got a null assigned role. - - new_character.key = G_found.key - - /* - The code below functions with the assumption that the mob is already a traitor if they have a special role. - So all it does is re-equip the mob with powers and/or items. Or not, if they have no special role. - If they don't have a mind, they obviously don't have a special role. - */ - - //Two variables to properly announce later on. - var/admin = key_name_admin(src) - var/player_key = G_found.key - - //Now for special roles and equipment. - var/datum/antagonist/traitor/traitordatum = new_character.mind.has_antag_datum(ANTAG_DATUM_TRAITOR) - if(traitordatum) - SSjob.EquipRank(new_character, new_character.mind.assigned_role, 1) - traitordatum.equip() - - - switch(new_character.mind.special_role) - if("Wizard") - new_character.loc = pick(GLOB.wizardstart) - //SSticker.mode.learn_basic_spells(new_character) - SSticker.mode.equip_wizard(new_character) - if("Syndicate") - var/obj/effect/landmark/synd_spawn = locate("landmark*Syndicate-Spawn") - if(synd_spawn) - new_character.loc = get_turf(synd_spawn) - call(/datum/game_mode/proc/equip_syndicate)(new_character) - if("Space Ninja") - var/list/ninja_spawn = list() - for(var/obj/effect/landmark/L in GLOB.landmarks_list) - if(L.name=="carpspawn") - ninja_spawn += L - var/datum/antagonist/ninja/ninjadatum = new_character.mind.has_antag_datum(ANTAG_DATUM_NINJA) - ninjadatum.equip_space_ninja() - if(ninja_spawn.len) - var/obj/effect/landmark/ninja_spawn_here = pick(ninja_spawn) - new_character.loc = ninja_spawn_here.loc - - else//They may also be a cyborg or AI. - switch(new_character.mind.assigned_role) - if("Cyborg")//More rigging to make em' work and check if they're traitor. - new_character = new_character.Robotize() - if("AI") - new_character = new_character.AIize() - else - SSjob.EquipRank(new_character, new_character.mind.assigned_role, 1)//Or we simply equip them. - - //Announces the character on all the systems, based on the record. - if(!issilicon(new_character))//If they are not a cyborg/AI. - if(!record_found&&new_character.mind.assigned_role!=new_character.mind.special_role)//If there are no records for them. If they have a record, this info is already in there. MODE people are not announced anyway. - //Power to the user! - if(alert(new_character,"Warning: No data core entry detected. Would you like to announce the arrival of this character by adding them to various databases, such as medical records?",,"No","Yes")=="Yes") - GLOB.data_core.manifest_inject(new_character) - - if(alert(new_character,"Would you like an active AI to announce this character?",,"No","Yes")=="Yes") - AnnounceArrival(new_character, new_character.mind.assigned_role) - - var/msg = "[admin] has respawned [player_key] as [new_character.real_name]." - message_admins(msg) - admin_ticket_log(new_character, msg) - - to_chat(new_character, "You have been fully respawned. Enjoy the game.") - - SSblackbox.add_details("admin_verb","Respawn Character") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return new_character - -/client/proc/cmd_admin_add_freeform_ai_law() - set category = "Fun" - set name = "Add Custom AI law" - if(!holder) - to_chat(src, "Only administrators may use this command.") - return - var/input = input(usr, "Please enter anything you want the AI to do. Anything. Serious.", "What?", "") as text|null - if(!input) - return - - log_admin("Admin [key_name(usr)] has added a new AI law - [input]") - message_admins("Admin [key_name_admin(usr)] has added a new AI law - [input]") - - var/show_log = alert(src, "Show ion message?", "Message", "Yes", "No") - var/announce_ion_laws = (show_log == "Yes" ? 1 : -1) - - var/datum/round_event/ion_storm/add_law_only/ion = new() - ion.announceEvent = announce_ion_laws - ion.ionMessage = input - - SSblackbox.add_details("admin_verb","Add Custom AI Law") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_admin_rejuvenate(mob/living/M in GLOB.mob_list) - set category = "Special Verbs" - set name = "Rejuvenate" - if(!holder) - to_chat(src, "Only administrators may use this command.") - return - if(!mob) - return - if(!istype(M)) - alert("Cannot revive a ghost") - return - M.revive(full_heal = 1, admin_revive = 1) - - log_admin("[key_name(usr)] healed / revived [key_name(M)]") - var/msg = "Admin [key_name_admin(usr)] healed / revived [key_name_admin(M)]!" - message_admins(msg) - admin_ticket_log(M, msg) - SSblackbox.add_details("admin_verb","Rejuvinate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_admin_create_centcom_report() - set category = "Special Verbs" - set name = "Create Command Report" - if(!holder) - to_chat(src, "Only administrators may use this command.") - return - var/input = input(usr, "Please enter anything you want. Anything. Serious.", "What?", "") as message|null - if(!input) - return - - var/confirm = alert(src, "Do you want to announce the contents of the report to the crew?", "Announce", "Yes", "No", "Cancel") - var/announce_command_report = TRUE - switch(confirm) - if("Yes") - priority_announce(input, null, 'sound/ai/commandreport.ogg') - announce_command_report = FALSE - if("Cancel") - return - - print_command_report(input, "[announce_command_report ? "Classified " : ""][command_name()] Update", announce_command_report) - - log_admin("[key_name(src)] has created a command report: [input]") - message_admins("[key_name_admin(src)] has created a command report") - SSblackbox.add_details("admin_verb","Create Command Report") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_change_command_name() - set category = "Special Verbs" - set name = "Change Command Name" - if(!holder) - to_chat(src, "Only administrators may use this command.") - return - var/input = input(usr, "Please input a new name for Central Command.", "What?", "") as text|null - if(!input) - return - change_command_name(input) - message_admins("[key_name_admin(src)] has changed Central Command's name to [input]") - log_admin("[key_name(src)] has changed the Central Command name to: [input]") - -/client/proc/cmd_admin_delete(atom/A as obj|mob|turf in world) - set category = "Admin" - set name = "Delete" - - if (!holder) - to_chat(src, "Only administrators may use this command.") - return - - admin_delete(A) - -/client/proc/admin_delete(datum/D) - var/atom/A = D - var/coords = istype(A) ? " at ([A.x], [A.y], [A.z])" : "" - if (alert(src, "Are you sure you want to delete:\n[D]\nat[coords]?", "Confirmation", "Yes", "No") == "Yes") - log_admin("[key_name(usr)] deleted [D][coords]") - message_admins("[key_name_admin(usr)] deleted [D][coords]") - SSblackbox.add_details("admin_verb","Delete") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - if(isturf(D)) - var/turf/T = D - T.ChangeTurf(T.baseturf) - else - qdel(D) - -/client/proc/cmd_admin_list_open_jobs() - set category = "Admin" - set name = "Manage Job Slots" - - if (!holder) - to_chat(src, "Only administrators may use this command.") - return - holder.manage_free_slots() - SSblackbox.add_details("admin_verb","Manage Job Slots") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in world) - set category = "Special Verbs" - set name = "Explosion" - - if (!holder) - to_chat(src, "Only administrators may use this command.") - return - - var/devastation = input("Range of total devastation. -1 to none", text("Input")) as num|null - if(devastation == null) return - var/heavy = input("Range of heavy impact. -1 to none", text("Input")) as num|null - if(heavy == null) return - var/light = input("Range of light impact. -1 to none", text("Input")) as num|null - if(light == null) return - var/flash = input("Range of flash. -1 to none", text("Input")) as num|null - if(flash == null) return - var/flames = input("Range of flames. -1 to none", text("Input")) as num|null - if(flames == null) return - - if ((devastation != -1) || (heavy != -1) || (light != -1) || (flash != -1) || (flames != -1)) - if ((devastation > 20) || (heavy > 20) || (light > 20) || (flames > 20)) - if (alert(src, "Are you sure you want to do this? It will laaag.", "Confirmation", "Yes", "No") == "No") - return - - explosion(O, devastation, heavy, light, flash, null, null,flames) - log_admin("[key_name(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])") - message_admins("[key_name_admin(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])") - SSblackbox.add_details("admin_verb","Explosion") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return - else - return - -/client/proc/cmd_admin_emp(atom/O as obj|mob|turf in world) - set category = "Special Verbs" - set name = "EM Pulse" - - if (!holder) - to_chat(src, "Only administrators may use this command.") - return - - var/heavy = input("Range of heavy pulse.", text("Input")) as num|null - if(heavy == null) return - var/light = input("Range of light pulse.", text("Input")) as num|null - if(light == null) return - - if (heavy || light) - - empulse(O, heavy, light) - log_admin("[key_name(usr)] created an EM Pulse ([heavy],[light]) at ([O.x],[O.y],[O.z])") - message_admins("[key_name_admin(usr)] created an EM Pulse ([heavy],[light]) at ([O.x],[O.y],[O.z])") - SSblackbox.add_details("admin_verb","EM Pulse") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - - return - else - return - -/client/proc/cmd_admin_gib(mob/M in GLOB.mob_list) - set category = "Special Verbs" - set name = "Gib" - - if (!holder) - to_chat(src, "Only administrators may use this command.") - return - - var/confirm = alert(src, "Drop a brain?", "Confirm", "Yes", "No","Cancel") - if(confirm == "Cancel") - return - //Due to the delay here its easy for something to have happened to the mob - if(!M) - return - - log_admin("[key_name(usr)] has gibbed [key_name(M)]") - message_admins("[key_name_admin(usr)] has gibbed [key_name_admin(M)]") - - if(isobserver(M)) - new /obj/effect/gibspawner/generic(get_turf(M)) - return - if(confirm == "Yes") - M.gib() - else - M.gib(1) - SSblackbox.add_details("admin_verb","Gib") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_admin_gib_self() - set name = "Gibself" - set category = "Fun" - - var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No") - if(confirm == "Yes") - log_admin("[key_name(usr)] used gibself.") - message_admins("[key_name_admin(usr)] used gibself.") - SSblackbox.add_details("admin_verb","Gib Self") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - mob.gib(1, 1, 1) - -/client/proc/cmd_admin_check_contents(mob/living/M in GLOB.mob_list) - set category = "Special Verbs" - set name = "Check Contents" - - var/list/L = M.get_contents() - for(var/t in L) - to_chat(usr, "[t]") - SSblackbox.add_details("admin_verb","Check Contents") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/toggle_view_range() - set category = "Special Verbs" - set name = "Change View Range" - set desc = "switches between 1x and custom views" - - if(view == world.view) - change_view(input("Select view range:", "FUCK YE", 7) in list(1,2,3,4,5,6,7,8,9,10,11,12,13,14,128)) - else - change_view(world.view) - - log_admin("[key_name(usr)] changed their view range to [view].") - //message_admins("\blue [key_name_admin(usr)] changed their view range to [view].") //why? removed by order of XSI - - SSblackbox.add_details("admin_toggle","Change View Range|[view]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/admin_call_shuttle() - - set category = "Admin" - set name = "Call Shuttle" - - if(EMERGENCY_AT_LEAST_DOCKED) - return - - if (!holder) - to_chat(src, "Only administrators may use this command.") - return - - var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No") - if(confirm != "Yes") - return - - SSshuttle.emergency.request() - SSblackbox.add_details("admin_verb","Call Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - log_admin("[key_name(usr)] admin-called the emergency shuttle.") - message_admins("[key_name_admin(usr)] admin-called the emergency shuttle.") - return - -/client/proc/admin_cancel_shuttle() - set category = "Admin" - set name = "Cancel Shuttle" - if(!check_rights(0)) - return - if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") - return - - if(EMERGENCY_AT_LEAST_DOCKED) - return - - SSshuttle.emergency.cancel() - SSblackbox.add_details("admin_verb","Cancel Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - log_admin("[key_name(usr)] admin-recalled the emergency shuttle.") - message_admins("[key_name_admin(usr)] admin-recalled the emergency shuttle.") - - return - -/client/proc/everyone_random() - set category = "Fun" - set name = "Make Everyone Random" - set desc = "Make everyone have a random appearance. You can only use this before rounds!" - - if(SSticker.HasRoundStarted()) - to_chat(usr, "Nope you can't do this, the game's already started. This only works before rounds!") - return - - var/frn = CONFIG_GET(flag/force_random_names) - if(frn) - CONFIG_SET(flag/force_random_names, FALSE) - message_admins("Admin [key_name_admin(usr)] has disabled \"Everyone is Special\" mode.") - to_chat(usr, "Disabled.") - return - - - var/notifyplayers = alert(src, "Do you want to notify the players?", "Options", "Yes", "No", "Cancel") - if(notifyplayers == "Cancel") - return - - log_admin("Admin [key_name(src)] has forced the players to have random appearances.") - message_admins("Admin [key_name_admin(usr)] has forced the players to have random appearances.") - - if(notifyplayers == "Yes") - to_chat(world, "Admin [usr.key] has forced the players to have completely random identities!") - - to_chat(usr, "Remember: you can always disable the randomness by using the verb again, assuming the round hasn't started yet.") - - CONFIG_SET(flag/force_random_names, TRUE) - SSblackbox.add_details("admin_verb","Make Everyone Random") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - - -/client/proc/toggle_random_events() - set category = "Server" - set name = "Toggle random events on/off" - set desc = "Toggles random events such as meteors, black holes, blob (but not space dust) on/off" - var/new_are = !CONFIG_GET(flag/allow_random_events) - CONFIG_SET(flag/allow_random_events, new_are) - if(new_are) - to_chat(usr, "Random events enabled") - message_admins("Admin [key_name_admin(usr)] has enabled random events.") - else - to_chat(usr, "Random events disabled") - message_admins("Admin [key_name_admin(usr)] has disabled random events.") - SSblackbox.add_details("admin_toggle","Toggle Random Events|[new_are]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - - -/client/proc/admin_change_sec_level() - set category = "Special Verbs" - set name = "Set Security Level" - set desc = "Changes the security level. Announcement only, i.e. setting to Delta won't activate nuke" - - if (!holder) - to_chat(src, "Only administrators may use this command.") - return - - var/level = input("Select security level to change to","Set Security Level") as null|anything in list("green","blue","red","delta") - if(level) - set_security_level(level) - - log_admin("[key_name(usr)] changed the security level to [level]") - message_admins("[key_name_admin(usr)] changed the security level to [level]") - SSblackbox.add_details("admin_verb","Set Security Level [capitalize(level)]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/toggle_nuke(obj/machinery/nuclearbomb/N in GLOB.nuke_list) - set name = "Toggle Nuke" - set category = "Fun" - set popup_menu = 0 - if(!check_rights(R_DEBUG)) - return - - if(!N.timing) - var/newtime = input(usr, "Set activation timer.", "Activate Nuke", "[N.timer_set]") as num - if(!newtime) - return - N.timer_set = newtime - N.set_safety() - N.set_active() - - log_admin("[key_name(usr)] [N.timing ? "activated" : "deactivated"] a nuke at ([N.x],[N.y],[N.z]).") - message_admins("[ADMIN_LOOKUPFLW(usr)] [N.timing ? "activated" : "deactivated"] a nuke at [ADMIN_COORDJMP(N)].") - SSblackbox.add_details("admin_toggle","Toggle Nuke|[N.timing]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits - -/client/proc/create_outfits() - set category = "Debug" - set name = "Create Custom Outfit" - - if(!check_rights(R_DEBUG)) - return - - holder.create_outfit() - -/datum/admins/proc/create_outfit() - var/list/uniforms = typesof(/obj/item/clothing/under) - var/list/suits = typesof(/obj/item/clothing/suit) - var/list/gloves = typesof(/obj/item/clothing/gloves) - var/list/shoes = typesof(/obj/item/clothing/shoes) - var/list/headwear = typesof(/obj/item/clothing/head) - var/list/glasses = typesof(/obj/item/clothing/glasses) - var/list/masks = typesof(/obj/item/clothing/mask) - var/list/ids = typesof(/obj/item/card/id) - - var/uniform_select = "" - - var/suit_select = "" - - var/gloves_select = "" - - var/shoes_select = "" - - var/head_select = "" - - var/glasses_select = "" - - var/mask_select = "" - - var/id_select = "" - - var/dat = {" - Create Outfit -
    - - [HrefTokenFormField()] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Name: - -
    Uniform: - [uniform_select] -
    Suit: - [suit_select] -
    Back: - -
    Belt: - -
    Gloves: - [gloves_select] -
    Shoes: - [shoes_select] -
    Head: - [head_select] -
    Mask: - [mask_select] -
    Ears: - -
    Glasses: - [glasses_select] -
    ID: - [id_select] -
    Left Pocket: - -
    Right Pocket: - -
    Suit Store: - -
    Right Hand: - -
    Left Hand: - -
    -
    - -
    - "} - usr << browse(dat, "window=dressup;size=550x600") - -/client/proc/toggle_antag_hud() - set category = "Admin" - set name = "Toggle AntagHUD" - set desc = "Toggles the Admin AntagHUD" - - if(!holder) return - - var/adding_hud = !has_antag_hud() - - for(var/datum/atom_hud/H in GLOB.huds) - if(istype(H, /datum/atom_hud/antag)) - (adding_hud) ? H.add_hud_to(usr) : H.remove_hud_from(usr) - - to_chat(usr, "You toggled your admin antag HUD [adding_hud ? "ON" : "OFF"].") - message_admins("[key_name_admin(usr)] toggled their admin antag HUD [adding_hud ? "ON" : "OFF"].") - log_admin("[key_name(usr)] toggled their admin antag HUD [adding_hud ? "ON" : "OFF"].") - SSblackbox.add_details("admin_toggle","Toggle Antag HUD|[adding_hud]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/has_antag_hud() - var/datum/atom_hud/A = GLOB.huds[ANTAG_HUD_TRAITOR] - return A.hudusers[mob] - -/client/proc/open_shuttle_manipulator() - set category = "Admin" - set name = "Shuttle Manipulator" - set desc = "Opens the shuttle manipulator UI." - - for(var/obj/machinery/shuttle_manipulator/M in GLOB.machines) - M.ui_interact(usr) - -/client/proc/mass_zombie_infection() - set category = "Fun" - set name = "Mass Zombie Infection" - set desc = "Infects all humans with a latent organ that will zombify \ - them on death." - - if(!holder) - return - - var/confirm = alert(src, "Please confirm you want to add latent zombie organs in all humans?", "Confirm Zombies", "Yes", "No") - if(confirm != "Yes") - return - - for(var/mob/living/carbon/human/H in GLOB.mob_list) - new /obj/item/organ/zombie_infection(H) - - message_admins("[key_name_admin(usr)] added a latent zombie infection to all humans.") - log_admin("[key_name(usr)] added a latent zombie infection to all humans.") - SSblackbox.add_details("admin_verb","Mass Zombie Infection") - -/client/proc/mass_zombie_cure() - set category = "Fun" - set name = "Mass Zombie Cure" - set desc = "Removes the zombie infection from all humans, returning them to normal." - if(!holder) - return - - var/confirm = alert(src, "Please confirm you want to cure all zombies?", "Confirm Zombie Cure", "Yes", "No") - if(confirm != "Yes") - return - - for(var/obj/item/organ/zombie_infection/I in GLOB.zombie_infection_list) - qdel(I) - - message_admins("[key_name_admin(usr)] cured all zombies.") - log_admin("[key_name(usr)] cured all zombies.") - SSblackbox.add_details("admin_verb","Mass Zombie Cure") - -/client/proc/polymorph_all() - set category = "Fun" - set name = "Polymorph All" - set desc = "Applies the effects of the bolt of change to every single mob." - - if(!holder) - return - - var/confirm = alert(src, "Please confirm you want polymorph all mobs?", "Confirm Polymorph", "Yes", "No") - if(confirm != "Yes") - return - - var/list/mobs = shuffle(GLOB.living_mob_list.Copy()) // might change while iterating - var/who_did_it = key_name_admin(usr) - - message_admins("[key_name_admin(usr)] started polymorphed all living mobs.") - log_admin("[key_name(usr)] polymorphed all living mobs.") - SSblackbox.add_details("admin_verb","Polymorph All") - - for(var/mob/living/M in mobs) - CHECK_TICK - - if(!M) - continue - - M.audible_message("...wabbajack...wabbajack...") - playsound(M.loc, 'sound/magic/staff_change.ogg', 50, 1, -1) - - wabbajack(M) - - message_admins("Mass polymorph started by [who_did_it] is complete.") - - -/client/proc/show_tip() - set category = "Admin" - set name = "Show Tip" - set desc = "Sends a tip (that you specify) to all players. After all \ - you're the experienced player here." - - if(!holder) - return - - var/input = input(usr, "Please specify your tip that you want to send to the players.", "Tip", "") as message|null - if(!input) - return - - if(!SSticker) - return - - SSticker.selected_tip = input - - // If we've already tipped, then send it straight away. - if(SSticker.tipped) - SSticker.send_tip_of_the_round() - - - message_admins("[key_name_admin(usr)] sent a tip of the round.") - log_admin("[key_name(usr)] sent \"[input]\" as the Tip of the Round.") - SSblackbox.add_details("admin_verb","Show Tip") - -#define ON_PURRBATION(H) (!(H.dna.features["tail_human"] == "None" && H.dna.features["ears"] == "None")) - -/proc/mass_purrbation() - for(var/M in GLOB.mob_list) - if(ishumanbasic(M)) - purrbation_apply(M) - CHECK_TICK - -/proc/mass_remove_purrbation() - for(var/M in GLOB.mob_list) - if(ishumanbasic(M)) - purrbation_remove(M) - CHECK_TICK - -/proc/purrbation_toggle(mob/living/carbon/human/H) - if(!ishumanbasic(H)) - return - if(!ON_PURRBATION(H)) - purrbation_apply(H) - . = TRUE - else - purrbation_remove(H) - . = FALSE - -/proc/purrbation_apply(mob/living/carbon/human/H) - if(!ishuman(H)) - return - if(ON_PURRBATION(H)) - return - to_chat(H, "Something is nya~t right.") - H.dna.features["tail_human"] = "Cat" - H.dna.features["ears"] = "Cat" - H.regenerate_icons() - playsound(get_turf(H), 'sound/effects/meow1.ogg', 50, 1, -1) - -/proc/purrbation_remove(mob/living/carbon/human/H) - if(!ishuman(H)) - return - if(!ON_PURRBATION(H)) - return - to_chat(H, "You are no longer a cat.") - H.dna.features["tail_human"] = "None" - H.dna.features["ears"] = "None" - H.regenerate_icons() - -#undef ON_PURRBATION - -/client/proc/modify_goals() - set category = "Debug" - set name = "Modify goals" - - if(!check_rights(R_ADMIN)) - return - - holder.modify_goals() - -/datum/admins/proc/modify_goals() - var/dat = "" - for(var/datum/station_goal/S in SSticker.mode.station_goals) - dat += "[S.name] -
    Announce | Remove
    " - dat += "
    Add New Goal" - usr << browse(dat, "window=goals;size=400x400") - - -/client/proc/toggle_hub() - set category = "Server" - set name = "Toggle Hub" - - world.update_hub_visibility(!GLOB.hub_visibility) - - log_admin("[key_name(usr)] has toggled the server's hub status for the round, it is now [(GLOB.hub_visibility?"on":"off")] the hub.") - message_admins("[key_name_admin(usr)] has toggled the server's hub status for the round, it is now [(GLOB.hub_visibility?"on":"off")] the hub.") - if (GLOB.hub_visibility && !world.reachable) - message_admins("WARNING: The server will not show up on the hub because byond is detecting that a filewall is blocking incoming connections.") - - SSblackbox.add_details("admin_toggle","Toggled Hub Visibility|[GLOB.hub_visibility]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/smite(mob/living/carbon/human/target as mob) - set name = "Smite" - set category = "Fun" - if(!holder) - return - - var/list/punishment_list = list(ADMIN_PUNISHMENT_LIGHTNING, ADMIN_PUNISHMENT_BRAINDAMAGE, ADMIN_PUNISHMENT_GIB, ADMIN_PUNISHMENT_BSA) - - var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list - - if(QDELETED(target) || !punishment) - return - - switch(punishment) - if(ADMIN_PUNISHMENT_LIGHTNING) - var/turf/T = get_step(get_step(target, NORTH), NORTH) - T.Beam(target, icon_state="lightning[rand(1,12)]", time = 5) - target.adjustFireLoss(75) - target.electrocution_animation(40) - to_chat(target, "The gods have punished you for your sins!") - if(ADMIN_PUNISHMENT_BRAINDAMAGE) - target.adjustBrainLoss(75) - if(ADMIN_PUNISHMENT_GIB) - target.gib(FALSE) - if(ADMIN_PUNISHMENT_BSA) - bluespace_artillery(target) - - var/msg = "[key_name_admin(usr)] punished [key_name_admin(target)] with [punishment]." - message_admins(msg) - admin_ticket_log(target, msg) - log_admin("[key_name(usr)] punished [key_name(target)] with [punishment].") - - -/client/proc/trigger_centcom_recall() - if(!holder) - return - var/message = pick(GLOB.admiral_messages) - message = input("Enter message from the on-call admiral to be put in the recall report.", "Admiral Message", message) as text|null - - if(!message) - return - - message_admins("[key_name_admin(usr)] triggered a CentCom recall, with the admiral message of: [message]") - log_game("[key_name(usr)] triggered a CentCom recall, with the message of: [message]") - SSshuttle.centcom_recall(SSshuttle.emergency.timer, message) - -/client/proc/cmd_admin_check_player_exp() //Allows admins to determine who the newer players are. - set category = "Admin" - set name = "Player Playtime" - if(!check_rights(R_ADMIN)) - return - - var/list/msg = list() - msg += "Playtime ReportPlaytime:
    " - src << browse(msg.Join(), "window=Player_playtime_check") - -/datum/admins/proc/cmd_show_exp_panel(client/C) - if(!check_rights(R_ADMIN)) - return - if(!C) - to_chat(usr, "ERROR: Client not found.") - return - - var/list/body = list() - body += "Playtime for [C.key]
    Playtime:" - body += C.get_exp_report() - body += "Toggle Exempt status" - body += "" - usr << browse(body.Join(), "window=playerplaytime[C.ckey];size=550x615") - -/datum/admins/proc/toggle_exempt_status(client/C) - if(!check_rights(R_ADMIN)) - return - if(!C) - to_chat(usr, "ERROR: Client not found.") - return - - if(!C.set_db_player_flags()) - to_chat(usr, "ERROR: Unable read player flags from database. Please check logs.") - var/dbflags = C.prefs.db_flags - var/newstate = FALSE - if(dbflags & DB_FLAG_EXEMPT) - newstate = FALSE - else - newstate = TRUE - - if(C.update_flag_db(DB_FLAG_EXEMPT, newstate)) - to_chat(usr, "ERROR: Unable to update player flags. Please check logs.") - else - message_admins("[key_name_admin(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name_admin(C)]") ->>>>>>> 4178c20... Configuration datum refactor (#30763) log_admin("[key_name(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name(C)]") \ No newline at end of file diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index ad0e9ba50e..38e0b0bd90 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -46,7 +46,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/preferred_map = null var/uses_glasses_colour = 0 - + var/screenshake = 100 var/damagescreenshake = 2 @@ -571,7 +571,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) dat += "[features["flavor_text"]]" else dat += "[TextPreview(features["flavor_text"])]...
    " - if(config.mutant_races)//really don't need this check, but fuck un-tabbing all those lines + if(CONFIG_GET(flag/join_with_mutant_race))//really don't need this check, but fuck un-tabbing all those lines dat += "

    Body

    " dat += "Gender: [gender == MALE ? "Male" : "Female"]
    " dat += "Species:[pref_species.id]
    " diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 0c5489cf59..bd1493452f 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -207,16 +207,11 @@ "Medical" = /obj/item/robot_module/medical, \ "Miner" = /obj/item/robot_module/miner, \ "Janitor" = /obj/item/robot_module/janitor, \ -<<<<<<< HEAD "Service" = /obj/item/robot_module/butler, \ "MediHound" = /obj/item/robot_module/medihound, \ "Security K9" = /obj/item/robot_module/k9, \ "Scrub Puppy" = /obj/item/robot_module/scrubpup) - if(!config.forbid_peaceborg) -======= - "Service" = /obj/item/robot_module/butler) if(!CONFIG_GET(flag/disable_peaceborg)) ->>>>>>> 4178c20... Configuration datum refactor (#30763) modulelist["Peacekeeper"] = /obj/item/robot_module/peacekeeper if(!CONFIG_GET(flag/disable_secborg)) modulelist["Security"] = /obj/item/robot_module/security diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm index d48cd9e301..762d86dee9 100644 --- a/code/modules/mob/living/silicon/robot/robot_movement.dm +++ b/code/modules/mob/living/silicon/robot/robot_movement.dm @@ -1,4 +1,3 @@ -<<<<<<< HEAD /mob/living/silicon/robot/Process_Spacemove(movement_dir = 0) if(ionpulse()) return 1 @@ -6,8 +5,10 @@ /mob/living/silicon/robot/movement_delay() . = ..() - . += speed - . += config.robot_delay + var/static/config_robot_delay + if(isnull(config_robot_delay)) + config_robot_delay = CONFIG_GET(number/robot_delay) + . += speed + config_robot_delay /mob/living/silicon/robot/mob_negates_gravity() return magpulse @@ -23,31 +24,3 @@ . = ..() if(riding_datum) riding_datum.on_vehicle_move() -======= -/mob/living/silicon/robot/Process_Spacemove(movement_dir = 0) - if(ionpulse()) - return 1 - return ..() - -/mob/living/silicon/robot/movement_delay() - . = ..() - var/static/config_robot_delay - if(isnull(config_robot_delay)) - config_robot_delay = CONFIG_GET(number/robot_delay) - . += speed + config_robot_delay - -/mob/living/silicon/robot/mob_negates_gravity() - return magpulse - -/mob/living/silicon/robot/mob_has_gravity() - return ..() || mob_negates_gravity() - -/mob/living/silicon/robot/experience_pressure_difference(pressure_difference, direction) - if(!magpulse) - return ..() - -/mob/living/silicon/robot/Moved() - . = ..() - if(riding_datum) - riding_datum.on_vehicle_move() ->>>>>>> 4178c20... Configuration datum refactor (#30763) diff --git a/code/modules/mob/living/silicon/robot/say.dm b/code/modules/mob/living/silicon/robot/say.dm index ada91337eb..910373e89b 100644 --- a/code/modules/mob/living/silicon/robot/say.dm +++ b/code/modules/mob/living/silicon/robot/say.dm @@ -1,7 +1,2 @@ -<<<<<<< HEAD /mob/living/silicon/robot/IsVocal() - return !config.silent_borg -======= -/mob/living/silicon/robot/IsVocal() - return !CONFIG_GET(flag/silent_borg) ->>>>>>> 4178c20... Configuration datum refactor (#30763) + return !CONFIG_GET(flag/silent_borg) diff --git a/tgstation.dme b/tgstation.dme index 8f3e2e591a..0e31fe6c1a 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -28,8 +28,8 @@ #include "code\__DEFINES\atmospherics.dm" #include "code\__DEFINES\atom_hud.dm" #include "code\__DEFINES\callbacks.dm" -#include "code\__DEFINES\citadel_defines.dm" #include "code\__DEFINES\cinematics.dm" +#include "code\__DEFINES\citadel_defines.dm" #include "code\__DEFINES\clockcult.dm" #include "code\__DEFINES\combat.dm" #include "code\__DEFINES\components.dm" @@ -189,21 +189,19 @@ #include "code\citadel\organs\womb.dm" #include "code\citadel\toys\dildos.dm" #include "code\controllers\admin.dm" -#include "code\controllers\configuration.dm" #include "code\controllers\configuration_citadel.dm" -#include "code\controllers\configuration\entries\comms.dm" -#include "code\controllers\configuration\entries\config.dm" -#include "code\controllers\configuration\entries\dbconfig.dm" -#include "code\controllers\configuration\entries\game_options.dm" -#include "code\controllers\configuration\config_entry.dm" -#include "code\controllers\configuration\configuration.dm" -#include "code\controllers\admin.dm" #include "code\controllers\controller.dm" #include "code\controllers\failsafe.dm" #include "code\controllers\globals.dm" #include "code\controllers\hooks.dm" #include "code\controllers\master.dm" #include "code\controllers\subsystem.dm" +#include "code\controllers\configuration\config_entry.dm" +#include "code\controllers\configuration\configuration.dm" +#include "code\controllers\configuration\entries\comms.dm" +#include "code\controllers\configuration\entries\config.dm" +#include "code\controllers\configuration\entries\dbconfig.dm" +#include "code\controllers\configuration\entries\game_options.dm" #include "code\controllers\subsystem\acid.dm" #include "code\controllers\subsystem\air.dm" #include "code\controllers\subsystem\assets.dm" @@ -2290,9 +2288,9 @@ #include "code\modules\VR\vr_sleeper.dm" #include "code\modules\zombie\items.dm" #include "code\modules\zombie\organs.dm" -#include "modular_citadel\cit_screenshake.dm" #include "interface\interface.dm" #include "interface\menu.dm" #include "interface\stylesheet.dm" #include "interface\skin.dmf" +#include "modular_citadel\cit_screenshake.dm" // END_INCLUDE From 121b7af232475def8bb28d38bddb4cc754c27dc2 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 1 Oct 2017 01:50:34 -0500 Subject: [PATCH 53/60] Automatic changelog generation for PR #2972 [ci skip] --- html/changelogs/AutoChangeLog-pr-2972.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-2972.yml diff --git a/html/changelogs/AutoChangeLog-pr-2972.yml b/html/changelogs/AutoChangeLog-pr-2972.yml new file mode 100644 index 0000000000..9f1e5aa596 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2972.yml @@ -0,0 +1,5 @@ +author: "Xhuis" +delete-after: True +changes: + - rscadd: "Ian has recently communed with unspeakable horrors and may now be warped by their power if Nar-Sie passes near them." + - rscadd: "In order to fight back against their ancient foe Ian, Poly has struck a bargain with Ratvar and will be transformed into a machine by their presence." From 7980a720924c9194cc8bc5269cc3503d0b521809 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 1 Oct 2017 01:51:57 -0500 Subject: [PATCH 54/60] Automatic changelog generation for PR #2985 [ci skip] --- html/changelogs/AutoChangeLog-pr-2985.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-2985.yml diff --git a/html/changelogs/AutoChangeLog-pr-2985.yml b/html/changelogs/AutoChangeLog-pr-2985.yml new file mode 100644 index 0000000000..1a5d0fb559 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2985.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "The syndicate have recently begun sending agents to extract vital research information from Nanotrasen." From 346ec9a0bf0d23b2496cc32e7708d5230c3fc727 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 1 Oct 2017 02:38:14 -0500 Subject: [PATCH 55/60] Update README.md --- README.md | 176 +++++++++--------------------------------------------- 1 file changed, 27 insertions(+), 149 deletions(-) diff --git a/README.md b/README.md index 3bd9c03c61..0ce4d8a094 100644 --- a/README.md +++ b/README.md @@ -1,152 +1,31 @@ - -##Citadel Station 13
    -Based and maintained from /tg/station.
    - -[![Build Status](https://api.travis-ci.org/Citadel-Station-13/Citadel-Station-13.png)](https://travis-ci.org/Citadel-Station-13/Citadel-Station-13) [![Krihelimeter](http://www.krihelinator.xyz/badge/Citadel-Station-13/Citadel-Station-13)](http://www.krihelinator.xyz) - -[![Percentage of issues still open](http://isitmaintained.com/badge/open/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Percentage of issues still open") [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Average time to resolve an issue") - -**Upstream Information**
    -**Website:** http://www.tgstation13.org
    -**Code:** https://github.com/tgstation/tgstation
    -**Wiki** http://tgstation13.org/wiki/Main_Page
    -**IRC:** irc://irc.rizon.net/coderbus or if you dont have an IRC client, you can click [here](https://kiwiirc.com/client/irc.rizon.net:6667/?&theme=cli#coderbus).
    - -**Citadel Station Information**
    -**Forums:** http://citadel-station.net/forum/
    -**Ban Appeals:** http://citadel-station.net/forum/forumdisplay.php?fid=8
    -**Code:** https://github.com/Citadel-Station-13/Citadel-Station-13
    -**Discord:** [Here](https://discord.gg/3gJ9pnM).
    - -## DOWNLOADING - -There are a number of ways to download the source code. Some are described here, an alternative all-inclusive guide is also located at http://www.tgstation13.org/wiki/Downloading_the_source_code - -Option 1: -Follow this: http://www.tgstation13.org/wiki/Setting_up_git - + +##Citadel Station 13
    +Based and maintained from /tg/station.
    + +[![Build Status](https://api.travis-ci.org/Citadel-Station-13/Citadel-Station-13.png)](https://travis-ci.org/Citadel-Station-13/Citadel-Station-13) [![Krihelimeter](http://www.krihelinator.xyz/badge/Citadel-Station-13/Citadel-Station-13)](http://www.krihelinator.xyz) + +[![Percentage of issues still open](http://isitmaintained.com/badge/open/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Percentage of issues still open") [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/Citadel-Station-13/Citadel-Station-13.svg)](http://isitmaintained.com/project/Citadel-Station-13/Citadel-Station-13 "Average time to resolve an issue") + +**Upstream Information**
    +**Website:** http://www.tgstation13.org
    +**Code:** https://github.com/tgstation/tgstation
    +**Wiki** http://tgstation13.org/wiki/Main_Page
    +**IRC:** irc://irc.rizon.net/coderbus or if you dont have an IRC client, you can click [here](https://kiwiirc.com/client/irc.rizon.net:6667/?&theme=cli#coderbus).
    + +**Citadel Station Information**
    +**Forums:** http://citadel-station.net/forum/
    +**Ban Appeals:** http://citadel-station.net/forum/forumdisplay.php?fid=8
    +**Code:** https://github.com/Citadel-Station-13/Citadel-Station-13
    +**Discord:** [Here](https://discord.gg/3gJ9pnM).
    + +## DOWNLOADING + +There are a number of ways to download the source code. Some are described here, an alternative all-inclusive guide is also located at http://www.tgstation13.org/wiki/Downloading_the_source_code + +Option 1: +Follow this: http://www.tgstation13.org/wiki/Setting_up_git + Option 2: Download the source code as a zip by clicking the ZIP button in the -<<<<<<< HEAD -code tab of https://github.com/tgstation/tgstation -(note: this will use a lot of bandwidth if you wish to update and is a lot of -hassle if you want to make any changes at all, so it's not recommended.) - -## INSTALLATION - -First-time installation should be fairly straightforward. First, you'll need -BYOND installed. You can get it from http://www.byond.com/. Once you've done -that, extract the game files to wherever you want to keep them. This is a -sourcecode-only release, so the next step is to compile the server files. -Open tgstation.dme by double-clicking it, open the Build menu, and click -compile. This'll take a little while, and if everything's done right you'll get -a message like this: - -``` -saving tgstation.dmb (DEBUG mode) -tgstation.dmb - 0 errors, 0 warnings -``` - -If you see any errors or warnings, something has gone wrong - possibly a corrupt -download or the files extracted wrong. If problems persist, ask for assistance -in irc://irc.rizon.net/coderbus - -Once that's done, open up the config folder. You'll want to edit config.txt to -set the probabilities for different gamemodes in Secret and to set your server -location so that all your players don't get disconnected at the end of each -round. It's recommended you don't turn on the gamemodes with probability 0, -except Extended, as they have various issues and aren't currently being tested, -so they may have unknown and bizarre bugs. Extended is essentially no mode, and -isn't in the Secret rotation by default as it's just not very fun. - -You'll also want to edit config/admins.txt to remove the default admins and add -your own. "Game Master" is the highest level of access, and probably the one -you'll want to use for now. You can set up your own ranks and find out more in -config/admin_ranks.txt - -The format is - -``` -byondkey = Rank -((i.e. spessmans = Host )) -``` - -where the admin rank must be properly capitalised. - -Finally, to start the server, run Dream Daemon and enter the path to your -compiled tgstation.dmb file. Make sure to set the port to the one you -specified in the config.txt, and set the Security box to 'Safe'. Then press GO -and the server should start up and be ready to join. It is also recommended that -you set up the SQL backend (see below). - -## UPDATING - -To update an existing installation, first back up your /config and /data folders -as these store your server configuration, player preferences and banlist. - -Then, extract the new files (preferably into a clean directory, but updating in -place should work fine), copy your /config and /data folders back into the new -install, overwriting when prompted except if we've specified otherwise, and -recompile the game. Once you start the server up again, you should be running -the new version. - -## MAPS - -Citadel Station maintains their own map, but frequently uses /tg/station's currently maintained maps as well. - -* [tgstation2 (default)](http://tgstation13.org/wiki/Boxstation) -* [MetaStation](https://tgstation13.org/wiki/MetaStation) -* [DeltaStation](https://tgstation13.org/wiki/DeltaStation) -* [OmegaStation](https://tgstation13.org/wiki/OmegaStation) -* [PubbyStation](https://tgstation13.org/wiki/PubbyStation) - - -All maps have their own code file that is in the base of the _maps directory. Maps are loaded dynamically when the game starts. Follow this guideline when adding your own map, to your fork, for easy compatibility. - -The map that will be loaded for the upcoming round is determined by reading data/next_map.json, which is a copy of the json files found in the _maps tree. If this file does not exist, the default map from config/maps.txt will be loaded. Failing that, tgstation2 will be loaded. If you want to set a specific map to load next round you can use the Change Map verb in game before restarting the server or copy a json from _maps to data/next_map.json before starting the server. Also, for debugging purposes, ticking a corresponding map's code file in Dream Maker will force that map to load every round. - -If you are hosting a server, and want randomly picked maps to be played each round, you can enable map rotation in [config.txt](config/config.txt) and then set the maps to be picked in the [maps.txt](config/maps.txt) file. - -Anytime you want to make changes to a map it's imperative you use the [Map Merging tools](http://tgstation13.org/wiki/Map_Merger) - -## AWAY MISSIONS - -/tg/station supports loading away missions however they are disabled by default. - -Map files for away missions are located in the _maps/RandomZLevels directory. Each away mission includes it's own code definitions located in /code/modules/awaymissions/mission_code. These files must be included and compiled with the server beforehand otherwise the server will crash upon trying to load away missions that lack their code. - -To enable an away mission open `config/awaymissionconfig.txt` and uncomment one of the .dmm lines by removing the #. If more than one away mission is uncommented then the away mission loader will randomly select one the enabled ones to load. - -## SQL SETUP - -The SQL backend requires a MySQL server. SQL is required for the library, stats tracking, admin notes, and job-only bans, among other features, mostly related to server administration. Your server details go in /config/dbconfig.txt, and the SQL schema is in /SQL/tgstation_schema.sql and /SQL/tgstation_schema_prefix.sql depending on if you want table prefixes. More detailed setup instructions are located here: http://www.tgstation13.org/wiki/Downloading_the_source_code#Setting_up_the_database - -## IRC BOT SETUP - -Included in the repository is a python3 compatible IRC bot capable of relaying adminhelps to a specified -IRC channel/server, see the /bot folder for more - -## CONTRIBUTING - -Please see [CONTRIBUTING.md](.github/CONTRIBUTING.md) - -## LICENSE - -All code after [commit 333c566b88108de218d882840e61928a9b759d8f on 2014/31/12 at 4:38 PM PST](https://github.com/tgstation/tgstation/commit/333c566b88108de218d882840e61928a9b759d8f) is licensed under [GNU AGPL v3](http://www.gnu.org/licenses/agpl-3.0.html). - -All code before [commit 333c566b88108de218d882840e61928a9b759d8f on 2014/31/12 at 4:38 PM PST](https://github.com/tgstation/tgstation/commit/333c566b88108de218d882840e61928a9b759d8f) is licensed under [GNU GPL v3](https://www.gnu.org/licenses/gpl-3.0.html). -(Including tools unless their readme specifies otherwise.) - -See LICENSE-AGPLv3.txt and LICENSE-GPLv3.txt for more details. - -tgui clientside is licensed as a subproject under the MIT license. -Font Awesome font files, used by tgui, are licensed under the SIL Open Font License v1.1 -tgui assets are licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-sa/4.0/). - -See tgui/LICENSE.md for the MIT license. -See tgui/assets/fonts/SIL-OFL-1.1-LICENSE.md for the SIL Open Font License. - -All assets including icons and sound are under a [Creative Commons 3.0 BY-SA license](http://creativecommons.org/licenses/by-sa/3.0/) unless otherwise indicated. -======= code tab of https://github.com/tgstation/tgstation (note: this will use a lot of bandwidth if you wish to update and is a lot of hassle if you want to make any changes at all, so it's not recommended.) @@ -273,4 +152,3 @@ See tgui/assets/fonts/SIL-OFL-1.1-LICENSE.md for the SIL Open Font License. See the footers of code/\_\_DEFINES/server\_tools.dm, code/modules/server\_tools/st\_commands.dm, and code/modules/server\_tools/st\_inteface.dm for the MIT license. All assets including icons and sound are under a [Creative Commons 3.0 BY-SA license](http://creativecommons.org/licenses/by-sa/3.0/) unless otherwise indicated. ->>>>>>> 62f788f... Server tools API v3.1 (#31000) From ef10ac589aec43a34ad1f09470d687cdcba8c0da Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 1 Oct 2017 02:39:07 -0500 Subject: [PATCH 56/60] Update getrev.dm --- code/datums/helper_datums/getrev.dm | 45 ----------------------------- 1 file changed, 45 deletions(-) diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm index 12935eea76..7b60070fc7 100644 --- a/code/datums/helper_datums/getrev.dm +++ b/code/datums/helper_datums/getrev.dm @@ -5,25 +5,7 @@ var/date /datum/getrev/New() -<<<<<<< HEAD - if(world.RunningService()) - var/file_name - if(ServiceVersion()) //will return null for versions < 3.0.91.0 - file_name = SERVICE_PR_TEST_JSON_OLD - else - file_name = SERVICE_PR_TEST_JSON - if(fexists(file_name)) - testmerge = json_decode(file2text(file_name)) -#ifdef SERVERTOOLS - else if(!world.RunningService() && fexists("../prtestjob.lk")) //tgs2 support - var/list/tmp = world.file2list("..\\prtestjob.lk") - for(var/I in tmp) - if(I) - testmerge |= I -#endif -======= testmerge = SERVER_TOOLS_PR_LIST ->>>>>>> 62f788f... Server tools API v3.1 (#31000) log_world("Running /tg/ revision:") var/list/logs = world.file2list(".git/logs/HEAD") if(logs) @@ -45,34 +27,7 @@ log_world("Based off origin/master commit [originmastercommit]") else log_world(originmastercommit) -<<<<<<< HEAD -/datum/getrev/proc/DownloadPRDetails() - var/repo_id = CONFIG_GET(number/githubrepoid) - if(!repo_id) - if(testmerge.len) - log_world("PR details download failed: No github repo config set") - return - for(var/line in testmerge) - if(!isnum(text2num(line))) - log_world("PR details download failed: Invalid PR number: [line]") - return - var/url = "https://api.github.com/repositories/[repo_id]/pulls/[line].json" - GLOB.valid_HTTPSGet = TRUE - var/json = HTTPSGet(url) - if(!json) - return - - testmerge[line] = json_decode(json) - - if(!testmerge[line]) - log_world("PR details download failed: null details returned") - return - CHECK_TICK - log_world("PR details successfully downloaded") - has_pr_details = TRUE -======= ->>>>>>> 62f788f... Server tools API v3.1 (#31000) /datum/getrev/proc/GetTestMergeInfo(header = TRUE) if(!testmerge.len) From 80a84db9194830468fc7cd7f243143fb36ee3f7d Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 1 Oct 2017 02:39:24 -0500 Subject: [PATCH 57/60] Update adminhelp.dm --- code/modules/admin/verbs/adminhelp.dm | 7 ------- 1 file changed, 7 deletions(-) diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 40a68acaa1..3a343b7f06 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -587,15 +587,8 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) /proc/send2irc(msg,msg2) -<<<<<<< HEAD - if(world.RunningService()) - world.ExportService("[SERVICE_REQUEST_IRC_ADMIN_CHANNEL_MESSAGE] [msg] | [msg2]") - else if(CONFIG_GET(flag/useircbot)) - shell("python nudge.py [msg] [msg2]") -======= if(SERVER_TOOLS_PRESENT) SERVER_TOOLS_RELAY_BROADCAST("[msg] | [msg2]") ->>>>>>> 62f788f... Server tools API v3.1 (#31000) /proc/send2otherserver(source,msg,type = "Ahelp") var/comms_key = CONFIG_GET(string/comms_key) From 926db45b546af38e240243b4f5e3d02f49770f97 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 1 Oct 2017 03:06:11 -0500 Subject: [PATCH 58/60] Update world.dm --- code/game/world.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/game/world.dm b/code/game/world.dm index a58c26f62b..2f54467c95 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -35,8 +35,6 @@ GLOBAL_PROTECT(security_mode) Master.Initialize(10, FALSE) - if(CONFIG_GET(flag/irc_announce_new_game)) - IRCBroadcast("New round starting on [SSmapping.config.map_name]!") /world/proc/SetupExternalRSC() #if (PRELOAD_RSC == 0) @@ -130,7 +128,7 @@ GLOBAL_PROTECT(security_mode) SERVER_TOOLS_ON_TOPIC //redirect to server tools if necessary var/comms_key = CONFIG_GET(string/comms_key) - var/key_valid = (comms_key && input["key"] == comms_key) + var/key_valid = (comms_key && input["key"] == comms_key) if(pinging) var/x = 1 From 69f354718ceb56754811846c3467fef93a4a0669 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 1 Oct 2017 13:02:25 -0500 Subject: [PATCH 59/60] Update tgstation.dme --- tgstation.dme | 1 - 1 file changed, 1 deletion(-) diff --git a/tgstation.dme b/tgstation.dme index c873eb24b1..1d878fc78b 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -2140,7 +2140,6 @@ #include "code\modules\ruins\spaceruin_code\TheDerelict.dm" #include "code\modules\security_levels\keycard_authentication.dm" #include "code\modules\security_levels\security_levels.dm" -#include "code\modules\server_tools\server_tools.dm" #include "code\modules\server_tools\st_commands.dm" #include "code\modules\server_tools\st_interface.dm" #include "code\modules\shuttle\arrivals.dm" From 490885a36fd4cc7fda2ac3fc8ccd6481d3628df2 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 1 Oct 2017 13:02:52 -0500 Subject: [PATCH 60/60] update --- code/game/world.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/world.dm b/code/game/world.dm index 2f54467c95..bd04008ea3 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -30,6 +30,7 @@ GLOBAL_PROTECT(security_mode) if(CONFIG_GET(flag/usewhitelist)) load_whitelist() LoadBans() + reload_custom_roundstart_items_list() GLOB.timezoneOffset = text2num(time2text(0,"hh")) * 36000