From 29a3968f48fce46ab56a81f89f305f423d113299 Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Wed, 10 May 2017 03:41:01 -0700 Subject: [PATCH 001/262] kinda_working --- code/citadel/custom_loadout/custom_items.dm | 2 + code/citadel/custom_loadout/load_to_mob.dm | 49 + code/game/objects/items.dm | 1256 +++++++++---------- code/modules/mob/inventory.dm | 4 +- 4 files changed, 681 insertions(+), 630 deletions(-) create mode 100644 code/citadel/custom_loadout/custom_items.dm create mode 100644 code/citadel/custom_loadout/load_to_mob.dm diff --git a/code/citadel/custom_loadout/custom_items.dm b/code/citadel/custom_loadout/custom_items.dm new file mode 100644 index 0000000000..37e6e478b7 --- /dev/null +++ b/code/citadel/custom_loadout/custom_items.dm @@ -0,0 +1,2 @@ + +//For custom items. diff --git a/code/citadel/custom_loadout/load_to_mob.dm b/code/citadel/custom_loadout/load_to_mob.dm new file mode 100644 index 0000000000..654784bcb2 --- /dev/null +++ b/code/citadel/custom_loadout/load_to_mob.dm @@ -0,0 +1,49 @@ + +//Proc that does the actual loading of items to mob +/*Itemlists are formatted as +"[typepath]" = number_of_it_to_spawn +*/ + +#define DROP_TO_FLOOR 0 +#define LOADING_TO_HUMAN 1 + +//Just incase there's extra mob selections in the future..... +/proc/load_itemlist_to_mob(mob/living/L, list/itemlist, drop_on_floor_if_full = TRUE, load_to_all_slots = TRUE, replace_slots = FALSE) + if(!istype(L) || !islist(itemlist)) + return FALSE + var/loading_mode = DROP_TO_FLOOR + var/turf/current_turf = get_turf(L) + if(ishuman(L)) + loading_mode = LOADING_TO_HUMAN + switch(loading_mode) + if(DROP_TO_FLOOR) + for(var/I in itemlist) + var/typepath = text2path(I) + if(!typepath) + continue + for(var/i = 0, i < itemlist[I], i++) + new typepath(current_turf) + return TRUE + if(LOADING_TO_HUMAN) + return load_itemlist_to_human(L, itemlist, drop_on_floor_if_full, load_to_all_slots, replace_slots) + +/proc/load_itemlist_to_human(mob/living/carbon/human/H, list/itemlist, drop_on_floor_if_full = TRUE, load_to_all_slots = TRUE, replace_slots = FALSE) + if(!istype(H) || !islist(itemlist)) + return FALSE + var/turf/T = get_turf(H) + for(var/item in itemlist) + var/path = text2path(item) + if(!path) + continue + var/atom/movable/loaded_atom = new path + if(!istype(loaded_atom)) + QDEL_NULL(loaded_atom) + continue + if(!istype(loaded_atom, /obj/item)) + loaded_atom.forceMove(T) + continue + var/obj/item/loaded = loaded_atom + if(!loaded.equip_to_best_slot(H, TRUE)) + if(!H.put_in_hands(loaded)) + loaded.forceMove(T) + return TRUE diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 8dc9bd89b2..28388d656d 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -1,629 +1,629 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/effects/fire.dmi', "fire")) - -GLOBAL_VAR_INIT(rpg_loot_items, FALSE) -// if true, everyone item when created will have its name changed to be -// more... RPG-like. - -/obj/item - name = "item" - icon = 'icons/obj/items.dmi' - var/item_state = null - var/lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' - var/righthand_file = 'icons/mob/inhands/items_righthand.dmi' - - //Dimensions of the icon file used when this item is worn, eg: hats.dmi - //eg: 32x32 sprite, 64x64 sprite, etc. - //allows inhands/worn sprites to be of any size, but still centered on a mob properly - var/worn_x_dimension = 32 - var/worn_y_dimension = 32 - //Same as above but for inhands, uses the lefthand_ and righthand_ file vars - var/inhand_x_dimension = 32 - var/inhand_y_dimension = 32 - - //Not on /clothing because for some reason any /obj/item can technically be "worn" with enough fuckery. - var/icon/alternate_worn_icon = null//If this is set, update_icons() will find on mob (WORN, NOT INHANDS) states in this file instead, primary use: badminnery/events - var/alternate_worn_layer = null//If this is set, update_icons() will force the on mob state (WORN, NOT INHANDS) onto this layer, instead of it's default - - obj_integrity = 200 - max_integrity = 200 - - - var/hitsound = null - var/usesound = null - var/throwhitsound = null - var/w_class = WEIGHT_CLASS_NORMAL - var/slot_flags = 0 //This is used to determine on which slots an item can fit. - pass_flags = PASSTABLE - pressure_resistance = 4 - var/obj/item/master = null - - var/heat_protection = 0 //flags which determine which body parts are protected from heat. Use the HEAD, CHEST, GROIN, etc. flags. See setup.dm - var/cold_protection = 0 //flags which determine which body parts are protected from cold. Use the HEAD, CHEST, GROIN, etc. flags. See setup.dm - var/max_heat_protection_temperature //Set this variable to determine up to which temperature (IN KELVIN) the item protects against heat damage. Keep at null to disable protection. Only protects areas set by heat_protection flags - var/min_cold_protection_temperature //Set this variable to determine down to which temperature (IN KELVIN) the item protects against cold damage. 0 is NOT an acceptable number due to if(varname) tests!! Keep at null to disable protection. Only protects areas set by cold_protection flags - - var/list/actions //list of /datum/action's that this item has. - var/list/actions_types //list of paths of action datums to give to the item on New(). - - //Since any item can now be a piece of clothing, this has to be put here so all items share it. - var/flags_inv //This flag is used to determine when items in someone's inventory cover others. IE helmets making it so you can't see glasses, etc. - - var/item_color = null //this needs deprecating, soonish - - var/body_parts_covered = 0 //see setup.dm for appropriate bit flags - //var/heat_transfer_coefficient = 1 //0 prevents all transfers, 1 is invisible - var/gas_transfer_coefficient = 1 // for leaking gas from turf to mask and vice-versa (for masks right now, but at some point, i'd like to include space helmets) - var/permeability_coefficient = 1 // for chemicals/diseases - var/siemens_coefficient = 1 // for electrical admittance/conductance (electrocution checks and shit) - var/slowdown = 0 // How much clothing is slowing you down. Negative values speeds you up - var/armour_penetration = 0 //percentage of armour effectiveness to remove - var/list/allowed = null //suit storage stuff. - var/obj/item/device/uplink/hidden_uplink = null - var/strip_delay = 40 - var/put_on_delay = 20 - var/breakouttime = 0 - var/list/materials - var/origin_tech = null //Used by R&D to determine what research bonuses it grants. - var/needs_permit = 0 //Used by security bots to determine if this item is safe for public use. - - var/list/attack_verb //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]" - var/list/species_exception = null // list() of species types, if a species cannot put items in a certain slot, but species type is in list, it will be able to wear that item - - var/suittoggled = 0 - var/hooded = 0 - - var/mob/thrownby = null - - /obj/item/mouse_drag_pointer = MOUSE_ACTIVE_POINTER //the icon to indicate this object is being dragged - - //So items can have custom embedd values - //Because customisation is king - var/embed_chance = EMBED_CHANCE - var/embedded_fall_chance = EMBEDDED_ITEM_FALLOUT - var/embedded_pain_chance = EMBEDDED_PAIN_CHANCE - var/embedded_pain_multiplier = EMBEDDED_PAIN_MULTIPLIER //The coefficient of multiplication for the damage this item does while embedded (this*w_class) - var/embedded_fall_pain_multiplier = EMBEDDED_FALL_PAIN_MULTIPLIER //The coefficient of multiplication for the damage this item does when falling out of a limb (this*w_class) - var/embedded_impact_pain_multiplier = EMBEDDED_IMPACT_PAIN_MULTIPLIER //The coefficient of multiplication for the damage this item does when first embedded (this*w_class) - var/embedded_unsafe_removal_pain_multiplier = EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER //The coefficient of multiplication for the damage removing this without surgery causes (this*w_class) - var/embedded_unsafe_removal_time = EMBEDDED_UNSAFE_REMOVAL_TIME //A time in ticks, multiplied by the w_class. - - var/flags_cover = 0 //for flags such as GLASSESCOVERSEYES - var/heat = 0 - var/sharpness = IS_BLUNT - var/toolspeed = 1 - - var/block_chance = 0 - var/hit_reaction_chance = 0 //If you want to have something unrelated to blocking/armour piercing etc. Maybe not needed, but trying to think ahead/allow more freedom - var/reach = 1 //In tiles, how far this weapon can reach; 1 for adjacent, which is default - - //The list of slots by priority. equip_to_appropriate_slot() uses this list. Doesn't matter if a mob type doesn't have a slot. - var/list/slot_equipment_priority = null // for default list, see /mob/proc/equip_to_appropriate_slot() - - // Needs to be in /obj/item because corgis can wear a lot of - // non-clothing items - var/datum/dog_fashion/dog_fashion = null - - var/datum/rpg_loot/rpg_loot = null - -/obj/item/Initialize() - if (!materials) - materials = list() - . = ..() - for(var/path in actions_types) - new path(src) - actions_types = null - - if(GLOB.rpg_loot_items) - rpg_loot = new(src) - -/obj/item/Destroy() - flags &= ~DROPDEL //prevent reqdels - if(ismob(loc)) - var/mob/m = loc - m.temporarilyRemoveItemFromInventory(src, TRUE) - for(var/X in actions) - qdel(X) - QDEL_NULL(rpg_loot) - return ..() - -/obj/item/device - icon = 'icons/obj/device.dmi' - -/obj/item/proc/check_allowed_items(atom/target, not_inside, target_self) - if(((src in target) && !target_self) || (!isturf(target.loc) && !isturf(target) && not_inside)) - return 0 - else - return 1 - -/obj/item/blob_act(obj/structure/blob/B) - if(B && B.loc == loc) - qdel(src) - -//user: The mob that is suiciding -//damagetype: The type of damage the item will inflict on the user -//BRUTELOSS = 1 -//FIRELOSS = 2 -//TOXLOSS = 4 -//OXYLOSS = 8 -//Output a creative message and then return the damagetype done -/obj/item/proc/suicide_act(mob/user) - return - -/obj/item/verb/move_to_top() - set name = "Move To Top" - set category = "Object" - set src in oview(1) - - if(!isturf(loc) || usr.stat || usr.restrained() || !usr.canmove) - return - - var/turf/T = src.loc - - src.loc = null - - src.loc = T - -/obj/item/examine(mob/user) //This might be spammy. Remove? - ..() - var/pronoun - if(src.gender == PLURAL) - pronoun = "They are" - else - pronoun = "It is" - var/size = weightclass2text(src.w_class) - to_chat(user, "[pronoun] a [size] item." ) - - if(user.research_scanner) //Mob has a research scanner active. - var/msg = "*--------*
" - - if(origin_tech) - msg += "Testing potentials:
" - var/list/techlvls = params2list(origin_tech) - for(var/T in techlvls) //This needs to use the better names. - msg += "Tech: [CallTechName(T)] | magnitude: [techlvls[T]]
" - else - msg += "No tech origins detected.
" - - - if(materials.len) - msg += "Extractable materials:
" - for(var/mat in materials) - msg += "[CallMaterialName(mat)]
" //Capitize first word, remove the "$" - else - msg += "No extractable materials detected.
" - msg += "*--------*" - to_chat(user, msg) - - -/obj/item/attack_self(mob/user) - interact(user) - -/obj/item/interact(mob/user) - add_fingerprint(user) - if(hidden_uplink && hidden_uplink.active) - hidden_uplink.interact(user) - return 1 - ui_interact(user) - -/obj/item/ui_act(action, params) - add_fingerprint(usr) - return ..() - -/obj/item/attack_hand(mob/user) - if(!user) - return - if(anchored) - return - - if(resistance_flags & ON_FIRE) - var/mob/living/carbon/C = user - if(istype(C)) - if(C.gloves && (C.gloves.max_heat_protection_temperature > 360)) - extinguish() - to_chat(user, "You put out the fire on [src].") - else - to_chat(user, "You burn your hand on [src]!") - var/obj/item/bodypart/affecting = C.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm") - if(affecting && affecting.receive_damage( 0, 5 )) // 5 burn damage - C.update_damage_overlays() - return - else - extinguish() - - if(acid_level > 20 && !ismob(loc))// so we can still remove the clothes on us that have acid. - var/mob/living/carbon/C = user - if(istype(C)) - if(!C.gloves || (!(C.gloves.resistance_flags & (UNACIDABLE|ACID_PROOF)))) - to_chat(user, "The acid on [src] burns your hand!") - var/obj/item/bodypart/affecting = C.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm") - if(affecting && affecting.receive_damage( 0, 5 )) // 5 burn damage - C.update_damage_overlays() - - - if(istype(loc, /obj/item/weapon/storage)) - //If the item is in a storage item, take it out - var/obj/item/weapon/storage/S = loc - S.remove_from_storage(src, user.loc) - - if(throwing) - throwing.finalize(FALSE) - if(loc == user) - if(!user.dropItemToGround(src)) - return - - pickup(user) - add_fingerprint(user) - if(!user.put_in_active_hand(src)) - dropped(user) - - -/obj/item/attack_paw(mob/user) - if(!user) - return - if(anchored) - return - - if(istype(loc, /obj/item/weapon/storage)) - var/obj/item/weapon/storage/S = loc - S.remove_from_storage(src, user.loc) - - if(throwing) - throwing.finalize(FALSE) - if(loc == user) - if(!user.dropItemToGround(src)) - return - - pickup(user) - add_fingerprint(user) - if(!user.put_in_active_hand(src)) - dropped(user) - -/obj/item/attack_alien(mob/user) - var/mob/living/carbon/alien/A = user - - if(!A.has_fine_manipulation) - if(src in A.contents) // To stop Aliens having items stuck in their pockets - A.dropItemToGround(src) - to_chat(user, "Your claws aren't capable of such fine manipulation!") - return - attack_paw(A) - -/obj/item/attack_ai(mob/user) - if(istype(src.loc, /obj/item/weapon/robot_module)) - //If the item is part of a cyborg module, equip it - if(!iscyborg(user)) - return - var/mob/living/silicon/robot/R = user - if(!R.low_power_mode) //can't equip modules with an empty cell. - R.activate_module(src) - R.hud_used.update_robot_modules_display() - -// Due to storage type consolidation this should get used more now. -// I have cleaned it up a little, but it could probably use more. -Sayu -// The lack of ..() is intentional, do not add one -/obj/item/attackby(obj/item/weapon/W, mob/user, params) - if(istype(W,/obj/item/weapon/storage)) - var/obj/item/weapon/storage/S = W - if(S.use_to_pickup) - if(S.collection_mode) //Mode is set to collect multiple items on a tile and we clicked on a valid one. - if(isturf(loc)) - var/list/rejections = list() - - var/list/things = loc.contents.Copy() - if (S.collection_mode == 2) - things = typecache_filter_list(things, typecacheof(type)) - - var/len = things.len - if(!len) - to_chat(user, "You failed to pick up anything with [S].") - return - var/datum/progressbar/progress = new(user, len, loc) - - while (do_after(user, 10, TRUE, S, FALSE, CALLBACK(src, .proc/handle_mass_pickup, S, things, loc, rejections, progress))) - sleep(1) - - qdel(progress) - - to_chat(user, "You put everything you could [S.preposition] [S].") - - else if(S.can_be_inserted(src)) - S.handle_item_insertion(src) - -/obj/item/proc/handle_mass_pickup(obj/item/weapon/storage/S, list/things, atom/thing_loc, list/rejections, datum/progressbar/progress) - for(var/obj/item/I in things) - things -= I - if(I.loc != thing_loc) - continue - if(I.type in rejections) // To limit bag spamming: any given type only complains once - continue - if(!S.can_be_inserted(I, stop_messages = TRUE)) // Note can_be_inserted still makes noise when the answer is no - if(S.contents.len >= S.storage_slots) - break - rejections += I.type // therefore full bags are still a little spammy - continue - - S.handle_item_insertion(I, TRUE) //The 1 stops the "You put the [src] into [S]" insertion message from being displayed. - - if (TICK_CHECK) - progress.update(progress.goal - things.len) - return TRUE - - progress.update(progress.goal - things.len) - return FALSE - -// afterattack() and attack() prototypes moved to _onclick/item_attack.dm for consistency - -/obj/item/proc/hit_reaction(mob/living/carbon/human/owner, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - if(prob(final_block_chance)) - owner.visible_message("[owner] blocks [attack_text] with [src]!") - return 1 - return 0 - -/obj/item/proc/talk_into(mob/M, input, channel, spans, datum/language/language) - return ITALICS | REDUCE_RANGE - -/obj/item/proc/dropped(mob/user) - for(var/X in actions) - var/datum/action/A = X - A.Remove(user) - if(DROPDEL & flags) - qdel(src) - -// called just as an item is picked up (loc is not yet changed) -/obj/item/proc/pickup(mob/user) - return - - -// called when this item is removed from a storage item, which is passed on as S. The loc variable is already set to the new destination before this is called. -/obj/item/proc/on_exit_storage(obj/item/weapon/storage/S) - return - -// called when this item is added into a storage item, which is passed on as S. The loc variable is already set to the storage item. -/obj/item/proc/on_enter_storage(obj/item/weapon/storage/S) - return - -// called when "found" in pockets and storage items. Returns 1 if the search should end. -/obj/item/proc/on_found(mob/finder) - return - -// called after an item is placed in an equipment slot //NOPE, for example, if you put a helmet in slot_head, it is NOT in user's head variable yet, how stupid. -// user is mob that equipped it -// slot uses the slot_X defines found in setup.dm -// for items that can be placed in multiple slots -// note this isn't called during the initial dressing of a player -/obj/item/proc/equipped(mob/user, slot) - for(var/X in actions) - var/datum/action/A = X - if(item_action_slot_check(slot, user)) //some items only give their actions buttons when in a specific slot. - A.Grant(user) - -//sometimes we only want to grant the item's action if it's equipped in a specific slot. -/obj/item/proc/item_action_slot_check(slot, mob/user) - if(slot == slot_in_backpack || slot == slot_legcuffed) //these aren't true slots, so avoid granting actions there - return FALSE - return TRUE - -//the mob M is attempting to equip this item into the slot passed through as 'slot'. Return 1 if it can do this and 0 if it can't. -//if this is being done by a mob other than M, it will include the mob equipper, who is trying to equip the item to mob M. equipper will be null otherwise. -//If you are making custom procs but would like to retain partial or complete functionality of this one, include a 'return ..()' to where you want this to happen. -//Set disable_warning to 1 if you wish it to not give you outputs. -/obj/item/proc/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0) - if(!M) - return 0 - - return M.can_equip(src, slot, disable_warning) - -/obj/item/verb/verb_pickup() - set src in oview(1) - set category = "Object" - set name = "Pick up" - - if(usr.incapacitated() || !Adjacent(usr) || usr.lying) - return - - if(usr.get_active_held_item() == null) // Let me know if this has any problems -Yota - usr.UnarmedAttack(src) - -//This proc is executed when someone clicks the on-screen UI button. -//The default action is attack_self(). -//Checks before we get to here are: mob is alive, mob is not restrained, paralyzed, asleep, resting, laying, item is on the mob. -/obj/item/proc/ui_action_click(mob/user, actiontype) - attack_self(user) - -/obj/item/proc/IsReflect(var/def_zone) //This proc determines if and at what% an object will reflect energy projectiles if it's in l_hand,r_hand or wear_suit - return 0 - -/obj/item/proc/eyestab(mob/living/carbon/M, mob/living/carbon/user) - - var/is_human_victim = 0 - var/obj/item/bodypart/affecting = M.get_bodypart("head") - if(ishuman(M)) - if(!affecting) //no head! - return - is_human_victim = 1 - var/mob/living/carbon/human/H = M - if((H.head && H.head.flags_cover & HEADCOVERSEYES) || \ - (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || \ - (H.glasses && H.glasses.flags_cover & GLASSESCOVERSEYES)) - // you can't stab someone in the eyes wearing a mask! - to_chat(user, "You're going to need to remove that mask/helmet/glasses first!") - return - - if(ismonkey(M)) - var/mob/living/carbon/monkey/Mo = M - if(Mo.wear_mask && Mo.wear_mask.flags_cover & MASKCOVERSEYES) - // you can't stab someone in the eyes wearing a mask! - to_chat(user, "You're going to need to remove that mask/helmet/glasses first!") - return - - if(isalien(M))//Aliens don't have eyes./N slimes also don't have eyes! - to_chat(user, "You cannot locate any eyes on this creature!") - return - - if(isbrain(M)) - to_chat(user, "You cannot locate any organic eyes on this brain!") - return - - src.add_fingerprint(user) - - playsound(loc, src.hitsound, 30, 1, -1) - - user.do_attack_animation(M) - - if(M != user) - M.visible_message("[user] has stabbed [M] in the eye with [src]!", \ - "[user] stabs you in the eye with [src]!") - else - user.visible_message( \ - "[user] has stabbed themself in the eyes with [src]!", \ - "You stab yourself in the eyes with [src]!" \ - ) - if(is_human_victim) - var/mob/living/carbon/human/U = M - U.apply_damage(7, BRUTE, affecting) - - else - M.take_bodypart_damage(7) - - add_logs(user, M, "attacked", "[src.name]", "(INTENT: [uppertext(user.a_intent)])") - - M.adjust_blurriness(3) - M.adjust_eye_damage(rand(2,4)) - if(M.eye_damage >= 10) - M.adjust_blurriness(15) - if(M.stat != DEAD) - to_chat(M, "Your eyes start to bleed profusely!") - if(!(M.disabilities & (NEARSIGHT | BLIND))) - if(M.become_nearsighted()) - to_chat(M, "You become nearsighted!") - if(prob(50)) - if(M.stat != DEAD) - if(M.drop_item()) - to_chat(M, "You drop what you're holding and clutch at your eyes!") - M.adjust_blurriness(10) - M.Paralyse(1) - M.Weaken(2) - if (prob(M.eye_damage - 10 + 1)) - if(M.become_blind()) - to_chat(M, "You go blind!") - -/obj/item/clean_blood() - . = ..() - if(.) - if(initial(icon) && initial(icon_state)) - var/index = blood_splatter_index() - var/icon/blood_splatter_icon = GLOB.blood_splatter_icons[index] - if(blood_splatter_icon) - cut_overlay(blood_splatter_icon) - -/obj/item/clothing/gloves/clean_blood() - . = ..() - if(.) - transfer_blood = 0 - -/obj/item/singularity_pull(S, current_size) - if(current_size >= STAGE_FOUR) - throw_at(S,14,3, spin=0) - else ..() - -/obj/item/throw_impact(atom/A) - if(A && !QDELETED(A)) - var/itempush = 1 - if(w_class < 4) - itempush = 0 //too light to push anything - return A.hitby(src, 0, itempush) - -/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback) - thrownby = thrower - callback = CALLBACK(src, .proc/after_throw, callback) //replace their callback with our own - . = ..(target, range, speed, thrower, spin, diagonals_first, callback) - - -/obj/item/proc/after_throw(datum/callback/callback) - if (callback) //call the original callback - . = callback.Invoke() - throw_speed = initial(throw_speed) //explosions change this. - -/obj/item/proc/remove_item_from_storage(atom/newLoc) //please use this if you're going to snowflake an item out of a obj/item/weapon/storage - if(!newLoc) - return 0 - if(istype(loc,/obj/item/weapon/storage)) - var/obj/item/weapon/storage/S = loc - S.remove_from_storage(src,newLoc) - return 1 - return 0 - -/obj/item/proc/is_hot() - return heat - -/obj/item/proc/is_sharp() - return sharpness - -/obj/item/proc/get_dismemberment_chance(obj/item/bodypart/affecting) - if(affecting.can_dismember(src)) - if((sharpness || damtype == BURN) && w_class >= 3) - . = force*(w_class-1) - -/obj/item/proc/get_dismember_sound() - if(damtype == BURN) - . = 'sound/weapons/sear.ogg' - else - . = pick('sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg') - -/obj/item/proc/open_flame(flame_heat=700) - var/turf/location = loc - if(ismob(location)) - var/mob/M = location - var/success = FALSE - if(src == M.get_item_by_slot(slot_wear_mask)) - success = TRUE - if(success) - location = get_turf(M) - if(isturf(location)) - location.hotspot_expose(flame_heat, 5) - -/obj/item/proc/ignition_effect(atom/A, mob/user) - if(is_hot()) - . = "[user] lights [A] with [src]." - else - . = "" - - -//when an item modify our speech spans when in our active hand. Override this to modify speech spans. -/obj/item/proc/get_held_item_speechspans(mob/living/carbon/user) - return - -/obj/item/hitby(atom/movable/AM) - return - -/obj/item/attack_hulk(mob/living/carbon/human/user) - return 0 - -/obj/item/attack_animal(mob/living/simple_animal/M) - return 0 - -/obj/item/mech_melee_attack(obj/mecha/M) - return 0 - -/obj/item/burn() - if(!QDELETED(src)) - var/turf/T = get_turf(src) - var/ash_type = /obj/effect/decal/cleanable/ash - if(w_class == WEIGHT_CLASS_HUGE || w_class == WEIGHT_CLASS_GIGANTIC) - ash_type = /obj/effect/decal/cleanable/ash/large - var/obj/effect/decal/cleanable/ash/A = new ash_type(T) - A.desc += "\nLooks like this used to be \an [name] some time ago." - ..() - -/obj/item/acid_melt() - if(!QDELETED(src)) - var/turf/T = get_turf(src) - var/obj/effect/decal/cleanable/molten_object/MO = new(T) - MO.pixel_x = rand(-16,16) - MO.pixel_y = rand(-16,16) - MO.desc = "Looks like this was \an [src] some time ago." - ..() - -/obj/item/proc/microwave_act(obj/machinery/microwave/M) - if(M && M.dirty < 100) - M.dirty++ + +GLOBAL_VAR_INIT(rpg_loot_items, FALSE) +// if true, everyone item when created will have its name changed to be +// more... RPG-like. + +/obj/item + name = "item" + icon = 'icons/obj/items.dmi' + var/item_state = null + var/lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' + var/righthand_file = 'icons/mob/inhands/items_righthand.dmi' + + //Dimensions of the icon file used when this item is worn, eg: hats.dmi + //eg: 32x32 sprite, 64x64 sprite, etc. + //allows inhands/worn sprites to be of any size, but still centered on a mob properly + var/worn_x_dimension = 32 + var/worn_y_dimension = 32 + //Same as above but for inhands, uses the lefthand_ and righthand_ file vars + var/inhand_x_dimension = 32 + var/inhand_y_dimension = 32 + + //Not on /clothing because for some reason any /obj/item can technically be "worn" with enough fuckery. + var/icon/alternate_worn_icon = null//If this is set, update_icons() will find on mob (WORN, NOT INHANDS) states in this file instead, primary use: badminnery/events + var/alternate_worn_layer = null//If this is set, update_icons() will force the on mob state (WORN, NOT INHANDS) onto this layer, instead of it's default + + obj_integrity = 200 + max_integrity = 200 + + + var/hitsound = null + var/usesound = null + var/throwhitsound = null + var/w_class = WEIGHT_CLASS_NORMAL + var/slot_flags = 0 //This is used to determine on which slots an item can fit. + pass_flags = PASSTABLE + pressure_resistance = 4 + var/obj/item/master = null + + var/heat_protection = 0 //flags which determine which body parts are protected from heat. Use the HEAD, CHEST, GROIN, etc. flags. See setup.dm + var/cold_protection = 0 //flags which determine which body parts are protected from cold. Use the HEAD, CHEST, GROIN, etc. flags. See setup.dm + var/max_heat_protection_temperature //Set this variable to determine up to which temperature (IN KELVIN) the item protects against heat damage. Keep at null to disable protection. Only protects areas set by heat_protection flags + var/min_cold_protection_temperature //Set this variable to determine down to which temperature (IN KELVIN) the item protects against cold damage. 0 is NOT an acceptable number due to if(varname) tests!! Keep at null to disable protection. Only protects areas set by cold_protection flags + + var/list/actions //list of /datum/action's that this item has. + var/list/actions_types //list of paths of action datums to give to the item on New(). + + //Since any item can now be a piece of clothing, this has to be put here so all items share it. + var/flags_inv //This flag is used to determine when items in someone's inventory cover others. IE helmets making it so you can't see glasses, etc. + + var/item_color = null //this needs deprecating, soonish + + var/body_parts_covered = 0 //see setup.dm for appropriate bit flags + //var/heat_transfer_coefficient = 1 //0 prevents all transfers, 1 is invisible + var/gas_transfer_coefficient = 1 // for leaking gas from turf to mask and vice-versa (for masks right now, but at some point, i'd like to include space helmets) + var/permeability_coefficient = 1 // for chemicals/diseases + var/siemens_coefficient = 1 // for electrical admittance/conductance (electrocution checks and shit) + var/slowdown = 0 // How much clothing is slowing you down. Negative values speeds you up + var/armour_penetration = 0 //percentage of armour effectiveness to remove + var/list/allowed = null //suit storage stuff. + var/obj/item/device/uplink/hidden_uplink = null + var/strip_delay = 40 + var/put_on_delay = 20 + var/breakouttime = 0 + var/list/materials + var/origin_tech = null //Used by R&D to determine what research bonuses it grants. + var/needs_permit = 0 //Used by security bots to determine if this item is safe for public use. + + var/list/attack_verb //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]" + var/list/species_exception = null // list() of species types, if a species cannot put items in a certain slot, but species type is in list, it will be able to wear that item + + var/suittoggled = 0 + var/hooded = 0 + + var/mob/thrownby = null + + /obj/item/mouse_drag_pointer = MOUSE_ACTIVE_POINTER //the icon to indicate this object is being dragged + + //So items can have custom embedd values + //Because customisation is king + var/embed_chance = EMBED_CHANCE + var/embedded_fall_chance = EMBEDDED_ITEM_FALLOUT + var/embedded_pain_chance = EMBEDDED_PAIN_CHANCE + var/embedded_pain_multiplier = EMBEDDED_PAIN_MULTIPLIER //The coefficient of multiplication for the damage this item does while embedded (this*w_class) + var/embedded_fall_pain_multiplier = EMBEDDED_FALL_PAIN_MULTIPLIER //The coefficient of multiplication for the damage this item does when falling out of a limb (this*w_class) + var/embedded_impact_pain_multiplier = EMBEDDED_IMPACT_PAIN_MULTIPLIER //The coefficient of multiplication for the damage this item does when first embedded (this*w_class) + var/embedded_unsafe_removal_pain_multiplier = EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER //The coefficient of multiplication for the damage removing this without surgery causes (this*w_class) + var/embedded_unsafe_removal_time = EMBEDDED_UNSAFE_REMOVAL_TIME //A time in ticks, multiplied by the w_class. + + var/flags_cover = 0 //for flags such as GLASSESCOVERSEYES + var/heat = 0 + var/sharpness = IS_BLUNT + var/toolspeed = 1 + + var/block_chance = 0 + var/hit_reaction_chance = 0 //If you want to have something unrelated to blocking/armour piercing etc. Maybe not needed, but trying to think ahead/allow more freedom + var/reach = 1 //In tiles, how far this weapon can reach; 1 for adjacent, which is default + + //The list of slots by priority. equip_to_appropriate_slot() uses this list. Doesn't matter if a mob type doesn't have a slot. + var/list/slot_equipment_priority = null // for default list, see /mob/proc/equip_to_appropriate_slot() + + // Needs to be in /obj/item because corgis can wear a lot of + // non-clothing items + var/datum/dog_fashion/dog_fashion = null + + var/datum/rpg_loot/rpg_loot = null + +/obj/item/Initialize() + if (!materials) + materials = list() + . = ..() + for(var/path in actions_types) + new path(src) + actions_types = null + + if(GLOB.rpg_loot_items) + rpg_loot = new(src) + +/obj/item/Destroy() + flags &= ~DROPDEL //prevent reqdels + if(ismob(loc)) + var/mob/m = loc + m.temporarilyRemoveItemFromInventory(src, TRUE) + for(var/X in actions) + qdel(X) + QDEL_NULL(rpg_loot) + return ..() + +/obj/item/device + icon = 'icons/obj/device.dmi' + +/obj/item/proc/check_allowed_items(atom/target, not_inside, target_self) + if(((src in target) && !target_self) || (!isturf(target.loc) && !isturf(target) && not_inside)) + return 0 + else + return 1 + +/obj/item/blob_act(obj/structure/blob/B) + if(B && B.loc == loc) + qdel(src) + +//user: The mob that is suiciding +//damagetype: The type of damage the item will inflict on the user +//BRUTELOSS = 1 +//FIRELOSS = 2 +//TOXLOSS = 4 +//OXYLOSS = 8 +//Output a creative message and then return the damagetype done +/obj/item/proc/suicide_act(mob/user) + return + +/obj/item/verb/move_to_top() + set name = "Move To Top" + set category = "Object" + set src in oview(1) + + if(!isturf(loc) || usr.stat || usr.restrained() || !usr.canmove) + return + + var/turf/T = src.loc + + src.loc = null + + src.loc = T + +/obj/item/examine(mob/user) //This might be spammy. Remove? + ..() + var/pronoun + if(src.gender == PLURAL) + pronoun = "They are" + else + pronoun = "It is" + var/size = weightclass2text(src.w_class) + to_chat(user, "[pronoun] a [size] item." ) + + if(user.research_scanner) //Mob has a research scanner active. + var/msg = "*--------*
" + + if(origin_tech) + msg += "Testing potentials:
" + var/list/techlvls = params2list(origin_tech) + for(var/T in techlvls) //This needs to use the better names. + msg += "Tech: [CallTechName(T)] | magnitude: [techlvls[T]]
" + else + msg += "No tech origins detected.
" + + + if(materials.len) + msg += "Extractable materials:
" + for(var/mat in materials) + msg += "[CallMaterialName(mat)]
" //Capitize first word, remove the "$" + else + msg += "No extractable materials detected.
" + msg += "*--------*" + to_chat(user, msg) + + +/obj/item/attack_self(mob/user) + interact(user) + +/obj/item/interact(mob/user) + add_fingerprint(user) + if(hidden_uplink && hidden_uplink.active) + hidden_uplink.interact(user) + return 1 + ui_interact(user) + +/obj/item/ui_act(action, params) + add_fingerprint(usr) + return ..() + +/obj/item/attack_hand(mob/user) + if(!user) + return + if(anchored) + return + + if(resistance_flags & ON_FIRE) + var/mob/living/carbon/C = user + if(istype(C)) + if(C.gloves && (C.gloves.max_heat_protection_temperature > 360)) + extinguish() + to_chat(user, "You put out the fire on [src].") + else + to_chat(user, "You burn your hand on [src]!") + var/obj/item/bodypart/affecting = C.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm") + if(affecting && affecting.receive_damage( 0, 5 )) // 5 burn damage + C.update_damage_overlays() + return + else + extinguish() + + if(acid_level > 20 && !ismob(loc))// so we can still remove the clothes on us that have acid. + var/mob/living/carbon/C = user + if(istype(C)) + if(!C.gloves || (!(C.gloves.resistance_flags & (UNACIDABLE|ACID_PROOF)))) + to_chat(user, "The acid on [src] burns your hand!") + var/obj/item/bodypart/affecting = C.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm") + if(affecting && affecting.receive_damage( 0, 5 )) // 5 burn damage + C.update_damage_overlays() + + + if(istype(loc, /obj/item/weapon/storage)) + //If the item is in a storage item, take it out + var/obj/item/weapon/storage/S = loc + S.remove_from_storage(src, user.loc) + + if(throwing) + throwing.finalize(FALSE) + if(loc == user) + if(!user.dropItemToGround(src)) + return + + pickup(user) + add_fingerprint(user) + if(!user.put_in_active_hand(src)) + dropped(user) + + +/obj/item/attack_paw(mob/user) + if(!user) + return + if(anchored) + return + + if(istype(loc, /obj/item/weapon/storage)) + var/obj/item/weapon/storage/S = loc + S.remove_from_storage(src, user.loc) + + if(throwing) + throwing.finalize(FALSE) + if(loc == user) + if(!user.dropItemToGround(src)) + return + + pickup(user) + add_fingerprint(user) + if(!user.put_in_active_hand(src)) + dropped(user) + +/obj/item/attack_alien(mob/user) + var/mob/living/carbon/alien/A = user + + if(!A.has_fine_manipulation) + if(src in A.contents) // To stop Aliens having items stuck in their pockets + A.dropItemToGround(src) + to_chat(user, "Your claws aren't capable of such fine manipulation!") + return + attack_paw(A) + +/obj/item/attack_ai(mob/user) + if(istype(src.loc, /obj/item/weapon/robot_module)) + //If the item is part of a cyborg module, equip it + if(!iscyborg(user)) + return + var/mob/living/silicon/robot/R = user + if(!R.low_power_mode) //can't equip modules with an empty cell. + R.activate_module(src) + R.hud_used.update_robot_modules_display() + +// Due to storage type consolidation this should get used more now. +// I have cleaned it up a little, but it could probably use more. -Sayu +// The lack of ..() is intentional, do not add one +/obj/item/attackby(obj/item/weapon/W, mob/user, params) + if(istype(W,/obj/item/weapon/storage)) + var/obj/item/weapon/storage/S = W + if(S.use_to_pickup) + if(S.collection_mode) //Mode is set to collect multiple items on a tile and we clicked on a valid one. + if(isturf(loc)) + var/list/rejections = list() + + var/list/things = loc.contents.Copy() + if (S.collection_mode == 2) + things = typecache_filter_list(things, typecacheof(type)) + + var/len = things.len + if(!len) + to_chat(user, "You failed to pick up anything with [S].") + return + var/datum/progressbar/progress = new(user, len, loc) + + while (do_after(user, 10, TRUE, S, FALSE, CALLBACK(src, .proc/handle_mass_pickup, S, things, loc, rejections, progress))) + sleep(1) + + qdel(progress) + + to_chat(user, "You put everything you could [S.preposition] [S].") + + else if(S.can_be_inserted(src)) + S.handle_item_insertion(src) + +/obj/item/proc/handle_mass_pickup(obj/item/weapon/storage/S, list/things, atom/thing_loc, list/rejections, datum/progressbar/progress) + for(var/obj/item/I in things) + things -= I + if(I.loc != thing_loc) + continue + if(I.type in rejections) // To limit bag spamming: any given type only complains once + continue + if(!S.can_be_inserted(I, stop_messages = TRUE)) // Note can_be_inserted still makes noise when the answer is no + if(S.contents.len >= S.storage_slots) + break + rejections += I.type // therefore full bags are still a little spammy + continue + + S.handle_item_insertion(I, TRUE) //The 1 stops the "You put the [src] into [S]" insertion message from being displayed. + + if (TICK_CHECK) + progress.update(progress.goal - things.len) + return TRUE + + progress.update(progress.goal - things.len) + return FALSE + +// afterattack() and attack() prototypes moved to _onclick/item_attack.dm for consistency + +/obj/item/proc/hit_reaction(mob/living/carbon/human/owner, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) + if(prob(final_block_chance)) + owner.visible_message("[owner] blocks [attack_text] with [src]!") + return 1 + return 0 + +/obj/item/proc/talk_into(mob/M, input, channel, spans, datum/language/language) + return ITALICS | REDUCE_RANGE + +/obj/item/proc/dropped(mob/user) + for(var/X in actions) + var/datum/action/A = X + A.Remove(user) + if(DROPDEL & flags) + qdel(src) + +// called just as an item is picked up (loc is not yet changed) +/obj/item/proc/pickup(mob/user) + return + + +// called when this item is removed from a storage item, which is passed on as S. The loc variable is already set to the new destination before this is called. +/obj/item/proc/on_exit_storage(obj/item/weapon/storage/S) + return + +// called when this item is added into a storage item, which is passed on as S. The loc variable is already set to the storage item. +/obj/item/proc/on_enter_storage(obj/item/weapon/storage/S) + return + +// called when "found" in pockets and storage items. Returns 1 if the search should end. +/obj/item/proc/on_found(mob/finder) + return + +// called after an item is placed in an equipment slot //NOPE, for example, if you put a helmet in slot_head, it is NOT in user's head variable yet, how stupid. +// user is mob that equipped it +// slot uses the slot_X defines found in setup.dm +// for items that can be placed in multiple slots +// note this isn't called during the initial dressing of a player +/obj/item/proc/equipped(mob/user, slot) + for(var/X in actions) + var/datum/action/A = X + if(item_action_slot_check(slot, user)) //some items only give their actions buttons when in a specific slot. + A.Grant(user) + +//sometimes we only want to grant the item's action if it's equipped in a specific slot. +/obj/item/proc/item_action_slot_check(slot, mob/user) + if(slot == slot_in_backpack || slot == slot_legcuffed) //these aren't true slots, so avoid granting actions there + return FALSE + return TRUE + +//the mob M is attempting to equip this item into the slot passed through as 'slot'. Return 1 if it can do this and 0 if it can't. +//if this is being done by a mob other than M, it will include the mob equipper, who is trying to equip the item to mob M. equipper will be null otherwise. +//If you are making custom procs but would like to retain partial or complete functionality of this one, include a 'return ..()' to where you want this to happen. +//Set disable_warning to 1 if you wish it to not give you outputs. +/obj/item/proc/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0) + if(!M) + return 0 + + return M.can_equip(src, slot, disable_warning) + +/obj/item/verb/verb_pickup() + set src in oview(1) + set category = "Object" + set name = "Pick up" + + if(usr.incapacitated() || !Adjacent(usr) || usr.lying) + return + + if(usr.get_active_held_item() == null) // Let me know if this has any problems -Yota + usr.UnarmedAttack(src) + +//This proc is executed when someone clicks the on-screen UI button. +//The default action is attack_self(). +//Checks before we get to here are: mob is alive, mob is not restrained, paralyzed, asleep, resting, laying, item is on the mob. +/obj/item/proc/ui_action_click(mob/user, actiontype) + attack_self(user) + +/obj/item/proc/IsReflect(var/def_zone) //This proc determines if and at what% an object will reflect energy projectiles if it's in l_hand,r_hand or wear_suit + return 0 + +/obj/item/proc/eyestab(mob/living/carbon/M, mob/living/carbon/user) + + var/is_human_victim = 0 + var/obj/item/bodypart/affecting = M.get_bodypart("head") + if(ishuman(M)) + if(!affecting) //no head! + return + is_human_victim = 1 + var/mob/living/carbon/human/H = M + if((H.head && H.head.flags_cover & HEADCOVERSEYES) || \ + (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || \ + (H.glasses && H.glasses.flags_cover & GLASSESCOVERSEYES)) + // you can't stab someone in the eyes wearing a mask! + to_chat(user, "You're going to need to remove that mask/helmet/glasses first!") + return + + if(ismonkey(M)) + var/mob/living/carbon/monkey/Mo = M + if(Mo.wear_mask && Mo.wear_mask.flags_cover & MASKCOVERSEYES) + // you can't stab someone in the eyes wearing a mask! + to_chat(user, "You're going to need to remove that mask/helmet/glasses first!") + return + + if(isalien(M))//Aliens don't have eyes./N slimes also don't have eyes! + to_chat(user, "You cannot locate any eyes on this creature!") + return + + if(isbrain(M)) + to_chat(user, "You cannot locate any organic eyes on this brain!") + return + + src.add_fingerprint(user) + + playsound(loc, src.hitsound, 30, 1, -1) + + user.do_attack_animation(M) + + if(M != user) + M.visible_message("[user] has stabbed [M] in the eye with [src]!", \ + "[user] stabs you in the eye with [src]!") + else + user.visible_message( \ + "[user] has stabbed themself in the eyes with [src]!", \ + "You stab yourself in the eyes with [src]!" \ + ) + if(is_human_victim) + var/mob/living/carbon/human/U = M + U.apply_damage(7, BRUTE, affecting) + + else + M.take_bodypart_damage(7) + + add_logs(user, M, "attacked", "[src.name]", "(INTENT: [uppertext(user.a_intent)])") + + M.adjust_blurriness(3) + M.adjust_eye_damage(rand(2,4)) + if(M.eye_damage >= 10) + M.adjust_blurriness(15) + if(M.stat != DEAD) + to_chat(M, "Your eyes start to bleed profusely!") + if(!(M.disabilities & (NEARSIGHT | BLIND))) + if(M.become_nearsighted()) + to_chat(M, "You become nearsighted!") + if(prob(50)) + if(M.stat != DEAD) + if(M.drop_item()) + to_chat(M, "You drop what you're holding and clutch at your eyes!") + M.adjust_blurriness(10) + M.Paralyse(1) + M.Weaken(2) + if (prob(M.eye_damage - 10 + 1)) + if(M.become_blind()) + to_chat(M, "You go blind!") + +/obj/item/clean_blood() + . = ..() + if(.) + if(initial(icon) && initial(icon_state)) + var/index = blood_splatter_index() + var/icon/blood_splatter_icon = GLOB.blood_splatter_icons[index] + if(blood_splatter_icon) + cut_overlay(blood_splatter_icon) + +/obj/item/clothing/gloves/clean_blood() + . = ..() + if(.) + transfer_blood = 0 + +/obj/item/singularity_pull(S, current_size) + if(current_size >= STAGE_FOUR) + throw_at(S,14,3, spin=0) + else ..() + +/obj/item/throw_impact(atom/A) + if(A && !QDELETED(A)) + var/itempush = 1 + if(w_class < 4) + itempush = 0 //too light to push anything + return A.hitby(src, 0, itempush) + +/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback) + thrownby = thrower + callback = CALLBACK(src, .proc/after_throw, callback) //replace their callback with our own + . = ..(target, range, speed, thrower, spin, diagonals_first, callback) + + +/obj/item/proc/after_throw(datum/callback/callback) + if (callback) //call the original callback + . = callback.Invoke() + throw_speed = initial(throw_speed) //explosions change this. + +/obj/item/proc/remove_item_from_storage(atom/newLoc) //please use this if you're going to snowflake an item out of a obj/item/weapon/storage + if(!newLoc) + return 0 + if(istype(loc,/obj/item/weapon/storage)) + var/obj/item/weapon/storage/S = loc + S.remove_from_storage(src,newLoc) + return 1 + return 0 + +/obj/item/proc/is_hot() + return heat + +/obj/item/proc/is_sharp() + return sharpness + +/obj/item/proc/get_dismemberment_chance(obj/item/bodypart/affecting) + if(affecting.can_dismember(src)) + if((sharpness || damtype == BURN) && w_class >= 3) + . = force*(w_class-1) + +/obj/item/proc/get_dismember_sound() + if(damtype == BURN) + . = 'sound/weapons/sear.ogg' + else + . = pick('sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg') + +/obj/item/proc/open_flame(flame_heat=700) + var/turf/location = loc + if(ismob(location)) + var/mob/M = location + var/success = FALSE + if(src == M.get_item_by_slot(slot_wear_mask)) + success = TRUE + if(success) + location = get_turf(M) + if(isturf(location)) + location.hotspot_expose(flame_heat, 5) + +/obj/item/proc/ignition_effect(atom/A, mob/user) + if(is_hot()) + . = "[user] lights [A] with [src]." + else + . = "" + + +//when an item modify our speech spans when in our active hand. Override this to modify speech spans. +/obj/item/proc/get_held_item_speechspans(mob/living/carbon/user) + return + +/obj/item/hitby(atom/movable/AM) + return + +/obj/item/attack_hulk(mob/living/carbon/human/user) + return 0 + +/obj/item/attack_animal(mob/living/simple_animal/M) + return 0 + +/obj/item/mech_melee_attack(obj/mecha/M) + return 0 + +/obj/item/burn() + if(!QDELETED(src)) + var/turf/T = get_turf(src) + var/ash_type = /obj/effect/decal/cleanable/ash + if(w_class == WEIGHT_CLASS_HUGE || w_class == WEIGHT_CLASS_GIGANTIC) + ash_type = /obj/effect/decal/cleanable/ash/large + var/obj/effect/decal/cleanable/ash/A = new ash_type(T) + A.desc += "\nLooks like this used to be \an [name] some time ago." + ..() + +/obj/item/acid_melt() + if(!QDELETED(src)) + var/turf/T = get_turf(src) + var/obj/effect/decal/cleanable/molten_object/MO = new(T) + MO.pixel_x = rand(-16,16) + MO.pixel_y = rand(-16,16) + MO.desc = "Looks like this was \an [src] some time ago." + ..() + +/obj/item/proc/microwave_act(obj/machinery/microwave/M) + if(M && M.dirty < 100) + M.dirty++ diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 2c3b8bdbd4..4a650ae165 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -354,8 +354,8 @@ dropItemToGround(I) drop_all_held_items() -/obj/item/proc/equip_to_best_slot(var/mob/M) - if(src != M.get_active_held_item()) +/obj/item/proc/equip_to_best_slot(var/mob/M, override_held_check = FALSE) + if((src != M.get_active_held_item()) && !override_held_check) to_chat(M, "You are not holding anything to equip!") return FALSE From e9a35b03f605a469b2de884300b4c492e161aa63 Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Wed, 10 May 2017 16:22:19 -0700 Subject: [PATCH 002/262] dme --- tgstation.dme | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tgstation.dme b/tgstation.dme index 543fb04f6c..8f2d06c029 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -167,6 +167,8 @@ #include "code\citadel\cit_uniforms.dm" #include "code\citadel\cit_vendors.dm" #include "code\citadel\dogborgstuff.dm" +#include "code\citadel\custom_loadout\custom_items.dm" +#include "code\citadel\custom_loadout\load_to_mob.dm" #include "code\citadel\organs\breasts.dm" #include "code\citadel\organs\eggsack.dm" #include "code\citadel\organs\genitals.dm" From 9e0866871ed3baa943dca981a5a27cb10e330df3 Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Sat, 13 May 2017 11:26:07 -0700 Subject: [PATCH 003/262] lists and stuff --- code/citadel/custom_loadout/load_to_mob.dm | 8 +++ code/citadel/custom_loadout/read_from_file.dm | 50 +++++++++++++++++++ config/custom_items.txt | 0 tgstation.dme | 1 + 4 files changed, 59 insertions(+) create mode 100644 code/citadel/custom_loadout/read_from_file.dm create mode 100644 config/custom_items.txt diff --git a/code/citadel/custom_loadout/load_to_mob.dm b/code/citadel/custom_loadout/load_to_mob.dm index 654784bcb2..e8cde02cd0 100644 --- a/code/citadel/custom_loadout/load_to_mob.dm +++ b/code/citadel/custom_loadout/load_to_mob.dm @@ -7,6 +7,14 @@ #define DROP_TO_FLOOR 0 #define LOADING_TO_HUMAN 1 +/proc/handle_roundstart_items(mob/living/M) + if(!M.ckey || !istype(M)) + return FALSE + var/list/items = parse_custom_items_by_key(M.ckey) + if(isnull(items)) + return FALSE + load_itemlist_to_mob(M, items, TRUE, TRUE, FALSE) + //Just incase there's extra mob selections in the future..... /proc/load_itemlist_to_mob(mob/living/L, list/itemlist, drop_on_floor_if_full = TRUE, load_to_all_slots = TRUE, replace_slots = FALSE) if(!istype(L) || !islist(itemlist)) diff --git a/code/citadel/custom_loadout/read_from_file.dm b/code/citadel/custom_loadout/read_from_file.dm new file mode 100644 index 0000000000..97b621902e --- /dev/null +++ b/code/citadel/custom_loadout/read_from_file.dm @@ -0,0 +1,50 @@ + +#define CUSTOM_ITEM_LIST_FILE 'config/custom_items.txt' +GLOBAL_LIST(custom_item_list) //Assoc list in form of ckey = delimited paramlist. + +//File should be in the format of Ckey|things, where things is in the form of itempath1=amount;itempath2=amount;itempath3=amount +//Each ckey should be on a different line!! + +/proc/reload_custom_item_list(custom_filelist) + if(!custom_filelist) + custom_filelist = CUSTOM_ITEM_LIST_FILE + GLOB.custom_item_list = list() + var/list/file_lines = world.file2list(custom_filelist) + for(var/line in file_lines) + var/list/key_separation = splittext(line, "|") + var/key = key_separation[1] + var/items = key_separation[2] + if(!key) + continue + if(!items) + GLOB.custom_item_list[key] = "ERROR" + continue + GLOB.custom_item_list[key] = list() + var/list/item_separation = splittext(items, ";") + for(var/item_string in item_separation) + var/list/amount_separation = splittext(item_string, "=") + var/path_to_item = amount_separation[1] + if(!ispath(path_to_item)) + GLOB.custom_item_list[key] += "ERROR" + var/amount_of_item = amount_separation[2] + if(!amount_of_item) + GLOB.custom_item_list[key][path_to_item] = "ERROR" + var/amount_of_item_num = 0 + if(isnum(amount_of_item)) + amount_of_item_num = amount_of_item + else + amount_of_item_num = text2num(amount_of_item) + if(!isnum(amount_of_item) || (amount_of_item < 1)) + GLOB.custom_item_list[key][path_to_item] = "ERROR" + GLOB.custom_item_list[key][path_to_item] = amount_of_item_num + return GLOB.custom_item_list + +/proc/parse_custom_items_by_key(ckey) + if(!ckey || !GLOB.custom_item_list[ckey]) + return null + var/list/items = GLOB.custom_item_list[ckey] + for(var/I in items) + if(items[I] == "ERROR") + items -= I + continue + return items diff --git a/config/custom_items.txt b/config/custom_items.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tgstation.dme b/tgstation.dme index 8f2d06c029..3a36f5cede 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -169,6 +169,7 @@ #include "code\citadel\dogborgstuff.dm" #include "code\citadel\custom_loadout\custom_items.dm" #include "code\citadel\custom_loadout\load_to_mob.dm" +#include "code\citadel\custom_loadout\read_from_file.dm" #include "code\citadel\organs\breasts.dm" #include "code\citadel\organs\eggsack.dm" #include "code\citadel\organs\genitals.dm" From 25024432fe71766af20fcfba0a586c9d56e4cbf3 Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Sat, 13 May 2017 16:23:43 -0700 Subject: [PATCH 004/262] more procs and roundstart loading files --- code/citadel/custom_loadout/load_to_mob.dm | 9 ++++++-- code/citadel/custom_loadout/read_from_file.dm | 5 ++-- code/controllers/configuration.dm | 23 ++++++++++--------- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/code/citadel/custom_loadout/load_to_mob.dm b/code/citadel/custom_loadout/load_to_mob.dm index e8cde02cd0..336f2a4630 100644 --- a/code/citadel/custom_loadout/load_to_mob.dm +++ b/code/citadel/custom_loadout/load_to_mob.dm @@ -8,21 +8,26 @@ #define LOADING_TO_HUMAN 1 /proc/handle_roundstart_items(mob/living/M) - if(!M.ckey || !istype(M)) + world << "handle_roundstart_items([M])" + if(!istype(M) || !M.ckey) + world << "handle_roundstart_items: [M] has no ckey." return FALSE var/list/items = parse_custom_items_by_key(M.ckey) if(isnull(items)) + world << "handle_roundstart_items: itemlist null." return FALSE - load_itemlist_to_mob(M, items, TRUE, TRUE, FALSE) + return load_itemlist_to_mob(M, items, TRUE, TRUE, FALSE) //Just incase there's extra mob selections in the future..... /proc/load_itemlist_to_mob(mob/living/L, list/itemlist, drop_on_floor_if_full = TRUE, load_to_all_slots = TRUE, replace_slots = FALSE) + world << "load_itemlist_to_mob([L], [itemlist], [drop_on_floor_if_full], [load_to_all_slots], [replace_slots])" if(!istype(L) || !islist(itemlist)) return FALSE var/loading_mode = DROP_TO_FLOOR var/turf/current_turf = get_turf(L) if(ishuman(L)) loading_mode = LOADING_TO_HUMAN + world << "load_itemlist_to_mob:loading_mode [loading_mode] current_turf [current_turf]" switch(loading_mode) if(DROP_TO_FLOOR) for(var/I in itemlist) diff --git a/code/citadel/custom_loadout/read_from_file.dm b/code/citadel/custom_loadout/read_from_file.dm index 97b621902e..fc37f6e7e8 100644 --- a/code/citadel/custom_loadout/read_from_file.dm +++ b/code/citadel/custom_loadout/read_from_file.dm @@ -1,5 +1,4 @@ -#define CUSTOM_ITEM_LIST_FILE 'config/custom_items.txt' GLOBAL_LIST(custom_item_list) //Assoc list in form of ckey = delimited paramlist. //File should be in the format of Ckey|things, where things is in the form of itempath1=amount;itempath2=amount;itempath3=amount @@ -7,7 +6,7 @@ GLOBAL_LIST(custom_item_list) //Assoc list in form of ckey = delimited paramlist /proc/reload_custom_item_list(custom_filelist) if(!custom_filelist) - custom_filelist = CUSTOM_ITEM_LIST_FILE + custom_filelist = "config/custom_items.txt" GLOB.custom_item_list = list() var/list/file_lines = world.file2list(custom_filelist) for(var/line in file_lines) @@ -40,7 +39,9 @@ GLOBAL_LIST(custom_item_list) //Assoc list in form of ckey = delimited paramlist return GLOB.custom_item_list /proc/parse_custom_items_by_key(ckey) + world << "parse_custom_items_by_key([ckey])" if(!ckey || !GLOB.custom_item_list[ckey]) + world << "parse_custom_items_by_key: no ckey match" return null var/list/items = GLOB.custom_item_list[ckey] for(var/I in items) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index fd3fe6d685..5236cdbb03 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -66,9 +66,9 @@ 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/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. @@ -284,6 +284,7 @@ load("config/config.txt") load("config/game_options.txt","game_options") loadsql("config/dbconfig.txt") + reload_custom_item_list() if (maprotation) loadmaplist("config/maps.txt") @@ -291,7 +292,7 @@ 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 - var/list/Lines = world.file2list(filename) + var/list/Lines = world.file2list(filename) for(var/t in Lines) if(!t) @@ -410,12 +411,12 @@ usewhitelist = TRUE if("allow_metadata") allow_Metadata = 1 - if("inactivity_period") - inactivity_period = text2num(value) * 10 //documented as seconds in config.txt - if("afk_period") - afk_period = text2num(value) * 10 // ^^^ + 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 + kick_inactive = TRUE if("load_jobs_from_txt") load_jobs_from_txt = 1 if("forbid_singulo_possession") @@ -785,7 +786,7 @@ /datum/configuration/proc/loadmaplist(filename) - var/list/Lines = world.file2list(filename) + var/list/Lines = world.file2list(filename) var/datum/map_config/currentmap = null for(var/t in Lines) @@ -835,7 +836,7 @@ /datum/configuration/proc/loadsql(filename) - var/list/Lines = world.file2list(filename) + var/list/Lines = world.file2list(filename) for(var/t in Lines) if(!t) continue From d15b0b96060dcb58ed12da836d013aedbb77a8fa Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Sun, 14 May 2017 14:00:51 -0700 Subject: [PATCH 005/262] stuff --- code/citadel/custom_loadout/load_to_mob.dm | 27 +++++++++++-------- code/citadel/custom_loadout/read_from_file.dm | 4 ++- code/modules/jobs/job_types/job.dm | 2 ++ .../modules/mob/dead/new_player/new_player.dm | 10 +++---- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/code/citadel/custom_loadout/load_to_mob.dm b/code/citadel/custom_loadout/load_to_mob.dm index 336f2a4630..830c1a4171 100644 --- a/code/citadel/custom_loadout/load_to_mob.dm +++ b/code/citadel/custom_loadout/load_to_mob.dm @@ -48,15 +48,20 @@ var/path = text2path(item) if(!path) continue - var/atom/movable/loaded_atom = new path - if(!istype(loaded_atom)) - QDEL_NULL(loaded_atom) - continue - if(!istype(loaded_atom, /obj/item)) - loaded_atom.forceMove(T) - continue - var/obj/item/loaded = loaded_atom - if(!loaded.equip_to_best_slot(H, TRUE)) - if(!H.put_in_hands(loaded)) - loaded.forceMove(T) + var/amount = itemlist[item] + for(var/i in 1 to amount) + var/atom/movable/loaded_atom = new path + if(!istype(loaded_atom)) + QDEL_NULL(loaded_atom) + continue + if(!istype(loaded_atom, /obj/item)) + loaded_atom.forceMove(T) + continue + var/obj/item/loaded = loaded_atom + var/obj/item/weapon/storage/S = H.get_item_by_slot(slot_back) + if(istype(S)) + S.handle_item_insertion(loaded, TRUE, H) //Force it into their backpack + continue + if(!H.put_in_hands(loaded)) //They don't have one/somehow that failed, put it in their hands + loaded.forceMove(T) //Guess we're just dumping it on the floor! return TRUE diff --git a/code/citadel/custom_loadout/read_from_file.dm b/code/citadel/custom_loadout/read_from_file.dm index fc37f6e7e8..8dc7eb29f2 100644 --- a/code/citadel/custom_loadout/read_from_file.dm +++ b/code/citadel/custom_loadout/read_from_file.dm @@ -21,9 +21,11 @@ GLOBAL_LIST(custom_item_list) //Assoc list in form of ckey = delimited paramlist GLOB.custom_item_list[key] = list() var/list/item_separation = splittext(items, ";") for(var/item_string in item_separation) + world << "itemstring [item_string]" var/list/amount_separation = splittext(item_string, "=") + world << "separated [item_string] == [english_list(amount_separation)]" var/path_to_item = amount_separation[1] - if(!ispath(path_to_item)) + if(!ispath(text2path(path_to_item))) GLOB.custom_item_list[key] += "ERROR" var/amount_of_item = amount_separation[2] if(!amount_of_item) diff --git a/code/modules/jobs/job_types/job.dm b/code/modules/jobs/job_types/job.dm index 4d5d4eb80c..9b5876c239 100644 --- a/code/modules/jobs/job_types/job.dm +++ b/code/modules/jobs/job_types/job.dm @@ -75,6 +75,8 @@ H.dna.features["ears"] = "None" H.regenerate_icons() + handle_roundstart_items(H) + /datum/job/proc/get_access() if(!config) //Needed for robots. return src.minimal_access.Copy() diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index e3943d07e6..4effac371d 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -24,10 +24,10 @@ loc = pick(GLOB.newplayer_start) else loc = locate(1,1,1) - . = ..() - -/mob/dead/new_player/prepare_huds() - return + . = ..() + +/mob/dead/new_player/prepare_huds() + return /mob/dead/new_player/proc/new_player_panel() @@ -146,7 +146,7 @@ return 1 if(href_list["late_join"]) - if(!SSticker || !SSticker.IsRoundInProgress()) + if(!SSticker || !SSticker.IsRoundInProgress()) to_chat(usr, "The round is either not ready, or has already finished...") return From 2c6cc491da4b3070cca974a35aa5a8256370ddd7 Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Sun, 14 May 2017 14:15:38 -0700 Subject: [PATCH 006/262] right --- code/citadel/custom_loadout/read_from_file.dm | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/code/citadel/custom_loadout/read_from_file.dm b/code/citadel/custom_loadout/read_from_file.dm index 8dc7eb29f2..5c3f670762 100644 --- a/code/citadel/custom_loadout/read_from_file.dm +++ b/code/citadel/custom_loadout/read_from_file.dm @@ -11,6 +11,9 @@ GLOBAL_LIST(custom_item_list) //Assoc list in form of ckey = delimited paramlist var/list/file_lines = world.file2list(custom_filelist) for(var/line in file_lines) var/list/key_separation = splittext(line, "|") + if((!istype(key_separation))||(key_separation.len > 2)||(key_separation.len < 1)) + stack_trace("Warning: Roundstart items configuration file improperly formatted!") + continue var/key = key_separation[1] var/items = key_separation[2] if(!key) @@ -20,10 +23,16 @@ GLOBAL_LIST(custom_item_list) //Assoc list in form of ckey = delimited paramlist continue GLOB.custom_item_list[key] = list() var/list/item_separation = splittext(items, ";") + if((!istype(item_separation))||(item_separation.len < 1)) + stack_trace("Warning: Roundstart items configuration file improperly formatted!") + continue for(var/item_string in item_separation) world << "itemstring [item_string]" var/list/amount_separation = splittext(item_string, "=") world << "separated [item_string] == [english_list(amount_separation)]" + if((!istype(amount_separation))||(amount_separation.len > 2)||(amount_separation.len < 1)) + stack_trace("Warning: Roundstart items configuration file improperly formatted!") + continue var/path_to_item = amount_separation[1] if(!ispath(text2path(path_to_item))) GLOB.custom_item_list[key] += "ERROR" @@ -51,3 +60,8 @@ GLOBAL_LIST(custom_item_list) //Assoc list in form of ckey = delimited paramlist items -= I continue return items + +/proc/debug_roundstart_items() + reload_custom_item_list() + for(var/mob/M in world) + handle_roundstart_items(M) From e7c41603f0c543fd196b6704f7eaed348419fbbc Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Sun, 14 May 2017 19:22:52 -0700 Subject: [PATCH 007/262] new and improved --- code/citadel/custom_loadout/load_to_mob.dm | 16 ++- code/citadel/custom_loadout/read_from_file.dm | 117 ++++++++++-------- code/controllers/configuration.dm | 1 - config/custom_items.txt | 0 config/custom_roundstart_items.txt | 8 ++ 5 files changed, 84 insertions(+), 58 deletions(-) delete mode 100644 config/custom_items.txt create mode 100644 config/custom_roundstart_items.txt diff --git a/code/citadel/custom_loadout/load_to_mob.dm b/code/citadel/custom_loadout/load_to_mob.dm index 830c1a4171..e0913cd383 100644 --- a/code/citadel/custom_loadout/load_to_mob.dm +++ b/code/citadel/custom_loadout/load_to_mob.dm @@ -9,10 +9,17 @@ /proc/handle_roundstart_items(mob/living/M) world << "handle_roundstart_items([M])" - if(!istype(M) || !M.ckey) - world << "handle_roundstart_items: [M] has no ckey." + if(!istype(M) || !M.ckey || !M.mind) + world << "handle_roundstart_items: [M] has either no ckey or no mind!" return FALSE - var/list/items = parse_custom_items_by_key(M.ckey) + var/list/items = parse_custom_items_by_key_and_job(M.ckey, M.mind.assigned_role) + if(M.mind.special_role) + var/list/items_special = parse_custom_items_by_key_and_job(M.ckey, M.mind.special_role) //And this way you can have snowflake antags! + for(var/thing in items_special) + if(!items[thing]) + items[thing] = items_special[thing] //don't have it, make it have it! + else + items[thing] += items_special[thing] //More~ if(isnull(items)) world << "handle_roundstart_items: itemlist null." return FALSE @@ -45,7 +52,8 @@ return FALSE var/turf/T = get_turf(H) for(var/item in itemlist) - var/path = text2path(item) + if(!ispath(item)) + item = text2path(item) if(!path) continue var/amount = itemlist[item] diff --git a/code/citadel/custom_loadout/read_from_file.dm b/code/citadel/custom_loadout/read_from_file.dm index 5c3f670762..dbca069cb7 100644 --- a/code/citadel/custom_loadout/read_from_file.dm +++ b/code/citadel/custom_loadout/read_from_file.dm @@ -1,67 +1,78 @@ -GLOBAL_LIST(custom_item_list) //Assoc list in form of ckey = delimited paramlist. +GLOBAL_LIST(custom_item_list) +//Layered list in form of custom_item_list[ckey][job][items][amounts] +//ckey is key, job is specific jobs, or "ALL" for all jobs, items for items, amounts for amount of item. -//File should be in the format of Ckey|things, where things is in the form of itempath1=amount;itempath2=amount;itempath3=amount -//Each ckey should be on a different line!! +//File should be in the format of ckey|exact job name/exact job name/or put ALL instead of any job names|/path/to/item=amount;/path/to/item=amount +//Each ckey should be in a different line +//if there's multiple entries of a single ckey the later ones will add to the earlier definitions. -/proc/reload_custom_item_list(custom_filelist) +/proc/reload_custom_roundstart_items_list(custom_filelist) if(!custom_filelist) - custom_filelist = "config/custom_items.txt" + custom_filelist = "config/custom_roundstart_items.txt" GLOB.custom_item_list = list() var/list/file_lines = world.file2list(custom_filelist) for(var/line in file_lines) - var/list/key_separation = splittext(line, "|") - if((!istype(key_separation))||(key_separation.len > 2)||(key_separation.len < 1)) - stack_trace("Warning: Roundstart items configuration file improperly formatted!") - continue - var/key = key_separation[1] - var/items = key_separation[2] - if(!key) - continue - if(!items) - GLOB.custom_item_list[key] = "ERROR" - continue - GLOB.custom_item_list[key] = list() - var/list/item_separation = splittext(items, ";") - if((!istype(item_separation))||(item_separation.len < 1)) - stack_trace("Warning: Roundstart items configuration file improperly formatted!") - continue - for(var/item_string in item_separation) - world << "itemstring [item_string]" - var/list/amount_separation = splittext(item_string, "=") - world << "separated [item_string] == [english_list(amount_separation)]" - if((!istype(amount_separation))||(amount_separation.len > 2)||(amount_separation.len < 1)) - stack_trace("Warning: Roundstart items configuration file improperly formatted!") + try //Lazy as fuck. + if(length(line) == 0) //Emptyline, no one cares. continue - var/path_to_item = amount_separation[1] - if(!ispath(text2path(path_to_item))) - GLOB.custom_item_list[key] += "ERROR" - var/amount_of_item = amount_separation[2] - if(!amount_of_item) - GLOB.custom_item_list[key][path_to_item] = "ERROR" - var/amount_of_item_num = 0 - if(isnum(amount_of_item)) - amount_of_item_num = amount_of_item - else - amount_of_item_num = text2num(amount_of_item) - if(!isnum(amount_of_item) || (amount_of_item < 1)) - GLOB.custom_item_list[key][path_to_item] = "ERROR" - GLOB.custom_item_list[key][path_to_item] = amount_of_item_num + if(copytext(line,1,3) == "//") //Commented line, ignore. + continue + var/ckey_str_sep = findtext(line, "|") //Process our stuff.. + var/job_str_sep = findtext(line, "|", ckey_str_sep+1) + var/item_str_sep = findtext(line, "|", job_str_sep+1) + var/ckey_str = ckey(copytext(line, 1, ckey_str_sep)) + var/job_str = copytext(line, ckey_str_sep+1, job_str_sep) + var/item_str = copytext(line, job_str_sep+1, item_str_sep) + world << "DEBUG: Line process: [line]" + world << "DEBUG: [ckey_str_sep], [job_str_sep], [item_str_sep], [ckey_str], [job_str], [item_str]." + if(!islist(GLOB.custom_item_list[ckey_str])) + GLOB.custom_item_list[ckey_str] = list() //Initialize list for this ckey if it isn't initialized.. + var/list/jobs = splittext(job_str, "/") + world << "DEBUG: Job string processed." + world << "DEBUG: JOBS: [english_list(jobs)]" + for(var/job in jobs) + if(!islist(GLOB.custom_item_list[ckey_str][job])) + GLOB.custom_item_list[ckey_str][job] = list() //Initialize item list for this job of this ckey if not already initialized. + var/list/item_strings = splittext(item_str, ";") //Get item strings in format of /path/to/item=amount + for(var/item_string in item_strings) + var/path_str_sep = findtext(item_string, "=") + var/path = copytext(item_string, 1, path_str_sep) //Path to spawn + var/amount = copytext(item_string, path_str_sep+1) //Amount to spawn + world << "DEBUG: Item string [item_string] processed" + path = text2path(path) + world << "DEBUG: [path_str_sep], [path], [amount]" + for(var/job in jobs) + if(GLOB.custom_item_list[ckey_str][job][path]) //Doesn't exist, make it exist! + GLOB.custom_item_list[ckey_str][job][path] = amount + else + GLOB.custom_item_list[ckey_str][job][path] += amount //Exists, we want more~ + catch //Uh oh. + var/msg = "Error processing line in [custom_filelist]. Line : [line]" + message_admins(msg) + log_game(msg) + stack_trace(msg) + continue return GLOB.custom_item_list -/proc/parse_custom_items_by_key(ckey) - world << "parse_custom_items_by_key([ckey])" +/proc/parse_custom_item_list_key_to_joblist(ckey) //First stage if(!ckey || !GLOB.custom_item_list[ckey]) - world << "parse_custom_items_by_key: no ckey match" return null - var/list/items = GLOB.custom_item_list[ckey] - for(var/I in items) - if(items[I] == "ERROR") - items -= I - continue - return items + return GLOB.custom_item_list[ckey] + +/proc/parse_custom_item_list_joblist_to_items(list, job) //Second stage + var/list/ret = list() + for(var/j in list) //for job in ckey-job-item list + if((j == job) || (j == "ALL") || (job == "ALL")) //job matches or is all jobs or we want everything. + for(var/i in list[j]) //for item in job-item list + if(!ret[i]) + ret[i] = list[j][i] //add to return with return value if not there + else + ret[i] += list[j][i] //else, add to that item in return value! + return ret //If done properly, you'll have a list of item typepaths with how many to spawn. + +/proc/parse_custom_items_by_key_and_job(ckey, job) + return parse_custom_item_list_joblist_to_items(parse_custom_item_list_key_to_joblist(ckey), job) /proc/debug_roundstart_items() - reload_custom_item_list() - for(var/mob/M in world) - handle_roundstart_items(M) + reload_custom_roundstart_items_list() diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 5236cdbb03..6fd3969cd3 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -284,7 +284,6 @@ load("config/config.txt") load("config/game_options.txt","game_options") loadsql("config/dbconfig.txt") - reload_custom_item_list() if (maprotation) loadmaplist("config/maps.txt") diff --git a/config/custom_items.txt b/config/custom_items.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/config/custom_roundstart_items.txt b/config/custom_roundstart_items.txt new file mode 100644 index 0000000000..227015e9e1 --- /dev/null +++ b/config/custom_roundstart_items.txt @@ -0,0 +1,8 @@ +//File should be in the format of ckey|exact job name/exact job name/or put ALL instead of any job names|/path/to/item=amount;/path/to/item=amount +//Each ckey should be in a different line +//if there's multiple entries of a single ckey the later ones will add to the earlier definitions. +//is obviously a comment. +//Recommend defining one job per line, but do what you want. +test1|testjob1/test job 2/ALL|/obj/item/weapon/gun/energy/laser=3;/obj/item/weapon/gun/energy/laser/retro=1;/obj/item/weapon/gun/energy=2 +test1|testjob1|/obj/item/device/aicard=3;/obj/item/device/flightpack=1;/obj/item/weapon/gun/energy=3 + From da615b14402a7bd172d8fa56cb2c72ce6b5c384f Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Sun, 14 May 2017 20:19:26 -0700 Subject: [PATCH 008/262] h --- code/citadel/custom_loadout/load_to_mob.dm | 9 ++++++--- code/citadel/custom_loadout/read_from_file.dm | 7 ++++++- code/controllers/subsystem/server_maint.dm | 1 + config/custom_roundstart_items.txt | 2 ++ 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/code/citadel/custom_loadout/load_to_mob.dm b/code/citadel/custom_loadout/load_to_mob.dm index e0913cd383..9e8bddd677 100644 --- a/code/citadel/custom_loadout/load_to_mob.dm +++ b/code/citadel/custom_loadout/load_to_mob.dm @@ -10,7 +10,9 @@ /proc/handle_roundstart_items(mob/living/M) world << "handle_roundstart_items([M])" if(!istype(M) || !M.ckey || !M.mind) - world << "handle_roundstart_items: [M] has either no ckey or no mind!" + world << "handle_roundstart_items: [M] has either no ckey or no mind!" + if(!M.mind) + world << "[M] has no mind!" return FALSE var/list/items = parse_custom_items_by_key_and_job(M.ckey, M.mind.assigned_role) if(M.mind.special_role) @@ -52,8 +54,9 @@ return FALSE var/turf/T = get_turf(H) for(var/item in itemlist) - if(!ispath(item)) - item = text2path(item) + var/path = item + if(!ispath(path)) + path = text2path(path) if(!path) continue var/amount = itemlist[item] diff --git a/code/citadel/custom_loadout/read_from_file.dm b/code/citadel/custom_loadout/read_from_file.dm index dbca069cb7..642c56f8c0 100644 --- a/code/citadel/custom_loadout/read_from_file.dm +++ b/code/citadel/custom_loadout/read_from_file.dm @@ -24,6 +24,8 @@ GLOBAL_LIST(custom_item_list) var/ckey_str = ckey(copytext(line, 1, ckey_str_sep)) var/job_str = copytext(line, ckey_str_sep+1, job_str_sep) var/item_str = copytext(line, job_str_sep+1, item_str_sep) + if(!ckey_str || !job_str || !item_str || !length(ckey_str) || length(job_str) || length(item_str)) + throw EXCEPTION("Errored Line") world << "DEBUG: Line process: [line]" world << "DEBUG: [ckey_str_sep], [job_str_sep], [item_str_sep], [ckey_str], [job_str], [item_str]." if(!islist(GLOB.custom_item_list[ckey_str])) @@ -40,10 +42,13 @@ GLOBAL_LIST(custom_item_list) var/path = copytext(item_string, 1, path_str_sep) //Path to spawn var/amount = copytext(item_string, path_str_sep+1) //Amount to spawn world << "DEBUG: Item string [item_string] processed" + amount = text2num(amount) path = text2path(path) + if(!ispath(path) || !isnum(amount)) + throw EXCEPTION("Errored line") world << "DEBUG: [path_str_sep], [path], [amount]" for(var/job in jobs) - if(GLOB.custom_item_list[ckey_str][job][path]) //Doesn't exist, make it exist! + if(!GLOB.custom_item_list[ckey_str][job][path]) //Doesn't exist, make it exist! GLOB.custom_item_list[ckey_str][job][path] = amount else GLOB.custom_item_list[ckey_str][job][path] += amount //Exists, we want more~ diff --git a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm index 08f60d23e6..4d32ce719c 100644 --- a/code/controllers/subsystem/server_maint.dm +++ b/code/controllers/subsystem/server_maint.dm @@ -8,6 +8,7 @@ SUBSYSTEM_DEF(server_maint) var/list/currentrun /datum/controller/subsystem/server_maint/Initialize(timeofday) + reload_custom_roundstart_items_list() if (config.hub) world.visibility = 1 ..() diff --git a/config/custom_roundstart_items.txt b/config/custom_roundstart_items.txt index 227015e9e1..7d206d8d09 100644 --- a/config/custom_roundstart_items.txt +++ b/config/custom_roundstart_items.txt @@ -5,4 +5,6 @@ //Recommend defining one job per line, but do what you want. test1|testjob1/test job 2/ALL|/obj/item/weapon/gun/energy/laser=3;/obj/item/weapon/gun/energy/laser/retro=1;/obj/item/weapon/gun/energy=2 test1|testjob1|/obj/item/device/aicard=3;/obj/item/device/flightpack=1;/obj/item/weapon/gun/energy=3 +kevinz000|ALL|/obj/item/weapon/bikehorn/airhorn=1 +kevinz000|Clown|/obj/item/weapon/bikehorn=1 From d557c03ca2136eb2cc21084d0d21f789482547ae Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Tue, 16 May 2017 17:09:39 -0700 Subject: [PATCH 009/262] fix --- code/citadel/custom_loadout/read_from_file.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/citadel/custom_loadout/read_from_file.dm b/code/citadel/custom_loadout/read_from_file.dm index 642c56f8c0..a65fd04252 100644 --- a/code/citadel/custom_loadout/read_from_file.dm +++ b/code/citadel/custom_loadout/read_from_file.dm @@ -24,7 +24,7 @@ GLOBAL_LIST(custom_item_list) var/ckey_str = ckey(copytext(line, 1, ckey_str_sep)) var/job_str = copytext(line, ckey_str_sep+1, job_str_sep) var/item_str = copytext(line, job_str_sep+1, item_str_sep) - if(!ckey_str || !job_str || !item_str || !length(ckey_str) || length(job_str) || length(item_str)) + if(!ckey_str || !job_str || !item_str || !length(ckey_str) || !length(job_str) || !length(item_str)) throw EXCEPTION("Errored Line") world << "DEBUG: Line process: [line]" world << "DEBUG: [ckey_str_sep], [job_str_sep], [item_str_sep], [ckey_str], [job_str], [item_str]." From c58c6ffdd89241c032349b4f9652418a32b9c469 Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Thu, 18 May 2017 21:24:02 -0700 Subject: [PATCH 010/262] autoloading --- code/citadel/custom_loadout/read_from_file.dm | 2 ++ code/controllers/configuration.dm | 7 ++++--- code/modules/mob/dead/new_player/new_player.dm | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/code/citadel/custom_loadout/read_from_file.dm b/code/citadel/custom_loadout/read_from_file.dm index a65fd04252..a4d363bd06 100644 --- a/code/citadel/custom_loadout/read_from_file.dm +++ b/code/citadel/custom_loadout/read_from_file.dm @@ -71,8 +71,10 @@ GLOBAL_LIST(custom_item_list) if((j == job) || (j == "ALL") || (job == "ALL")) //job matches or is all jobs or we want everything. for(var/i in list[j]) //for item in job-item list if(!ret[i]) + world << "DEBUG: [i] initialized to return list" ret[i] = list[j][i] //add to return with return value if not there else + world << "DEBUG: [i] added to return list" ret[i] += list[j][i] //else, add to that item in return value! return ret //If done properly, you'll have a list of item typepaths with how many to spawn. diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 4d9c819ef9..4c95463247 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -127,7 +127,7 @@ 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/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? var/traitor_scaling_coeff = 6 //how much does the amount of players get divided by to determine traitors @@ -278,6 +278,7 @@ votable_modes += "secret" Reload() + reload_custom_roundstart_items_list() /datum/configuration/proc/Reload() load("config/config.txt") @@ -473,8 +474,8 @@ 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("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") diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 4effac371d..c22418cbd6 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -371,6 +371,7 @@ if(SHUTTLE_CALL) if(SSshuttle.emergency.timeLeft(1) > initial(SSshuttle.emergencyCallTime)*0.5) SSticker.mode.make_antag_chance(humanc) + handle_roundstart_items(character) qdel(src) /mob/dead/new_player/proc/AddEmploymentContract(mob/living/carbon/human/employee) From 0bf9f163f3e096fbb1b1bd4ff55a71d3f4f0c6d2 Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Sun, 21 May 2017 21:54:31 -0700 Subject: [PATCH 011/262] missed a spot --- code/game/objects/items.dm | 1259 ++++++++++++++++++------------------ 1 file changed, 631 insertions(+), 628 deletions(-) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 28388d656d..4a69fdff87 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -1,629 +1,632 @@ GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/effects/fire.dmi', "fire")) - -GLOBAL_VAR_INIT(rpg_loot_items, FALSE) -// if true, everyone item when created will have its name changed to be -// more... RPG-like. - -/obj/item - name = "item" - icon = 'icons/obj/items.dmi' - var/item_state = null - var/lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' - var/righthand_file = 'icons/mob/inhands/items_righthand.dmi' - - //Dimensions of the icon file used when this item is worn, eg: hats.dmi - //eg: 32x32 sprite, 64x64 sprite, etc. - //allows inhands/worn sprites to be of any size, but still centered on a mob properly - var/worn_x_dimension = 32 - var/worn_y_dimension = 32 - //Same as above but for inhands, uses the lefthand_ and righthand_ file vars - var/inhand_x_dimension = 32 - var/inhand_y_dimension = 32 - - //Not on /clothing because for some reason any /obj/item can technically be "worn" with enough fuckery. - var/icon/alternate_worn_icon = null//If this is set, update_icons() will find on mob (WORN, NOT INHANDS) states in this file instead, primary use: badminnery/events - var/alternate_worn_layer = null//If this is set, update_icons() will force the on mob state (WORN, NOT INHANDS) onto this layer, instead of it's default - - obj_integrity = 200 - max_integrity = 200 - - - var/hitsound = null - var/usesound = null - var/throwhitsound = null - var/w_class = WEIGHT_CLASS_NORMAL - var/slot_flags = 0 //This is used to determine on which slots an item can fit. - pass_flags = PASSTABLE - pressure_resistance = 4 - var/obj/item/master = null - - var/heat_protection = 0 //flags which determine which body parts are protected from heat. Use the HEAD, CHEST, GROIN, etc. flags. See setup.dm - var/cold_protection = 0 //flags which determine which body parts are protected from cold. Use the HEAD, CHEST, GROIN, etc. flags. See setup.dm - var/max_heat_protection_temperature //Set this variable to determine up to which temperature (IN KELVIN) the item protects against heat damage. Keep at null to disable protection. Only protects areas set by heat_protection flags - var/min_cold_protection_temperature //Set this variable to determine down to which temperature (IN KELVIN) the item protects against cold damage. 0 is NOT an acceptable number due to if(varname) tests!! Keep at null to disable protection. Only protects areas set by cold_protection flags - - var/list/actions //list of /datum/action's that this item has. - var/list/actions_types //list of paths of action datums to give to the item on New(). - - //Since any item can now be a piece of clothing, this has to be put here so all items share it. - var/flags_inv //This flag is used to determine when items in someone's inventory cover others. IE helmets making it so you can't see glasses, etc. - - var/item_color = null //this needs deprecating, soonish - - var/body_parts_covered = 0 //see setup.dm for appropriate bit flags - //var/heat_transfer_coefficient = 1 //0 prevents all transfers, 1 is invisible - var/gas_transfer_coefficient = 1 // for leaking gas from turf to mask and vice-versa (for masks right now, but at some point, i'd like to include space helmets) - var/permeability_coefficient = 1 // for chemicals/diseases - var/siemens_coefficient = 1 // for electrical admittance/conductance (electrocution checks and shit) - var/slowdown = 0 // How much clothing is slowing you down. Negative values speeds you up - var/armour_penetration = 0 //percentage of armour effectiveness to remove - var/list/allowed = null //suit storage stuff. - var/obj/item/device/uplink/hidden_uplink = null - var/strip_delay = 40 - var/put_on_delay = 20 - var/breakouttime = 0 - var/list/materials - var/origin_tech = null //Used by R&D to determine what research bonuses it grants. - var/needs_permit = 0 //Used by security bots to determine if this item is safe for public use. - - var/list/attack_verb //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]" - var/list/species_exception = null // list() of species types, if a species cannot put items in a certain slot, but species type is in list, it will be able to wear that item - - var/suittoggled = 0 - var/hooded = 0 - - var/mob/thrownby = null - - /obj/item/mouse_drag_pointer = MOUSE_ACTIVE_POINTER //the icon to indicate this object is being dragged - - //So items can have custom embedd values - //Because customisation is king - var/embed_chance = EMBED_CHANCE - var/embedded_fall_chance = EMBEDDED_ITEM_FALLOUT - var/embedded_pain_chance = EMBEDDED_PAIN_CHANCE - var/embedded_pain_multiplier = EMBEDDED_PAIN_MULTIPLIER //The coefficient of multiplication for the damage this item does while embedded (this*w_class) - var/embedded_fall_pain_multiplier = EMBEDDED_FALL_PAIN_MULTIPLIER //The coefficient of multiplication for the damage this item does when falling out of a limb (this*w_class) - var/embedded_impact_pain_multiplier = EMBEDDED_IMPACT_PAIN_MULTIPLIER //The coefficient of multiplication for the damage this item does when first embedded (this*w_class) - var/embedded_unsafe_removal_pain_multiplier = EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER //The coefficient of multiplication for the damage removing this without surgery causes (this*w_class) - var/embedded_unsafe_removal_time = EMBEDDED_UNSAFE_REMOVAL_TIME //A time in ticks, multiplied by the w_class. - - var/flags_cover = 0 //for flags such as GLASSESCOVERSEYES - var/heat = 0 - var/sharpness = IS_BLUNT - var/toolspeed = 1 - - var/block_chance = 0 - var/hit_reaction_chance = 0 //If you want to have something unrelated to blocking/armour piercing etc. Maybe not needed, but trying to think ahead/allow more freedom - var/reach = 1 //In tiles, how far this weapon can reach; 1 for adjacent, which is default - - //The list of slots by priority. equip_to_appropriate_slot() uses this list. Doesn't matter if a mob type doesn't have a slot. - var/list/slot_equipment_priority = null // for default list, see /mob/proc/equip_to_appropriate_slot() - - // Needs to be in /obj/item because corgis can wear a lot of - // non-clothing items - var/datum/dog_fashion/dog_fashion = null - - var/datum/rpg_loot/rpg_loot = null - -/obj/item/Initialize() - if (!materials) - materials = list() - . = ..() - for(var/path in actions_types) - new path(src) - actions_types = null - - if(GLOB.rpg_loot_items) - rpg_loot = new(src) - -/obj/item/Destroy() - flags &= ~DROPDEL //prevent reqdels - if(ismob(loc)) - var/mob/m = loc - m.temporarilyRemoveItemFromInventory(src, TRUE) - for(var/X in actions) - qdel(X) - QDEL_NULL(rpg_loot) - return ..() - -/obj/item/device - icon = 'icons/obj/device.dmi' - -/obj/item/proc/check_allowed_items(atom/target, not_inside, target_self) - if(((src in target) && !target_self) || (!isturf(target.loc) && !isturf(target) && not_inside)) - return 0 - else - return 1 - -/obj/item/blob_act(obj/structure/blob/B) - if(B && B.loc == loc) - qdel(src) - -//user: The mob that is suiciding -//damagetype: The type of damage the item will inflict on the user -//BRUTELOSS = 1 -//FIRELOSS = 2 -//TOXLOSS = 4 -//OXYLOSS = 8 -//Output a creative message and then return the damagetype done -/obj/item/proc/suicide_act(mob/user) - return - -/obj/item/verb/move_to_top() - set name = "Move To Top" - set category = "Object" - set src in oview(1) - - if(!isturf(loc) || usr.stat || usr.restrained() || !usr.canmove) - return - - var/turf/T = src.loc - - src.loc = null - - src.loc = T - -/obj/item/examine(mob/user) //This might be spammy. Remove? - ..() - var/pronoun - if(src.gender == PLURAL) - pronoun = "They are" - else - pronoun = "It is" - var/size = weightclass2text(src.w_class) - to_chat(user, "[pronoun] a [size] item." ) - - if(user.research_scanner) //Mob has a research scanner active. - var/msg = "*--------*
" - - if(origin_tech) - msg += "Testing potentials:
" - var/list/techlvls = params2list(origin_tech) - for(var/T in techlvls) //This needs to use the better names. - msg += "Tech: [CallTechName(T)] | magnitude: [techlvls[T]]
" - else - msg += "No tech origins detected.
" - - - if(materials.len) - msg += "Extractable materials:
" - for(var/mat in materials) - msg += "[CallMaterialName(mat)]
" //Capitize first word, remove the "$" - else - msg += "No extractable materials detected.
" - msg += "*--------*" - to_chat(user, msg) - - -/obj/item/attack_self(mob/user) - interact(user) - -/obj/item/interact(mob/user) - add_fingerprint(user) - if(hidden_uplink && hidden_uplink.active) - hidden_uplink.interact(user) - return 1 - ui_interact(user) - -/obj/item/ui_act(action, params) - add_fingerprint(usr) - return ..() - -/obj/item/attack_hand(mob/user) - if(!user) - return - if(anchored) - return - - if(resistance_flags & ON_FIRE) - var/mob/living/carbon/C = user - if(istype(C)) - if(C.gloves && (C.gloves.max_heat_protection_temperature > 360)) - extinguish() - to_chat(user, "You put out the fire on [src].") - else - to_chat(user, "You burn your hand on [src]!") - var/obj/item/bodypart/affecting = C.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm") - if(affecting && affecting.receive_damage( 0, 5 )) // 5 burn damage - C.update_damage_overlays() - return - else - extinguish() - - if(acid_level > 20 && !ismob(loc))// so we can still remove the clothes on us that have acid. - var/mob/living/carbon/C = user - if(istype(C)) - if(!C.gloves || (!(C.gloves.resistance_flags & (UNACIDABLE|ACID_PROOF)))) - to_chat(user, "The acid on [src] burns your hand!") - var/obj/item/bodypart/affecting = C.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm") - if(affecting && affecting.receive_damage( 0, 5 )) // 5 burn damage - C.update_damage_overlays() - - - if(istype(loc, /obj/item/weapon/storage)) - //If the item is in a storage item, take it out - var/obj/item/weapon/storage/S = loc - S.remove_from_storage(src, user.loc) - - if(throwing) - throwing.finalize(FALSE) - if(loc == user) - if(!user.dropItemToGround(src)) - return - - pickup(user) - add_fingerprint(user) - if(!user.put_in_active_hand(src)) - dropped(user) - - -/obj/item/attack_paw(mob/user) - if(!user) - return - if(anchored) - return - - if(istype(loc, /obj/item/weapon/storage)) - var/obj/item/weapon/storage/S = loc - S.remove_from_storage(src, user.loc) - - if(throwing) - throwing.finalize(FALSE) - if(loc == user) - if(!user.dropItemToGround(src)) - return - - pickup(user) - add_fingerprint(user) - if(!user.put_in_active_hand(src)) - dropped(user) - -/obj/item/attack_alien(mob/user) - var/mob/living/carbon/alien/A = user - - if(!A.has_fine_manipulation) - if(src in A.contents) // To stop Aliens having items stuck in their pockets - A.dropItemToGround(src) - to_chat(user, "Your claws aren't capable of such fine manipulation!") - return - attack_paw(A) - -/obj/item/attack_ai(mob/user) - if(istype(src.loc, /obj/item/weapon/robot_module)) - //If the item is part of a cyborg module, equip it - if(!iscyborg(user)) - return - var/mob/living/silicon/robot/R = user - if(!R.low_power_mode) //can't equip modules with an empty cell. - R.activate_module(src) - R.hud_used.update_robot_modules_display() - -// Due to storage type consolidation this should get used more now. -// I have cleaned it up a little, but it could probably use more. -Sayu -// The lack of ..() is intentional, do not add one -/obj/item/attackby(obj/item/weapon/W, mob/user, params) - if(istype(W,/obj/item/weapon/storage)) - var/obj/item/weapon/storage/S = W - if(S.use_to_pickup) - if(S.collection_mode) //Mode is set to collect multiple items on a tile and we clicked on a valid one. - if(isturf(loc)) - var/list/rejections = list() - - var/list/things = loc.contents.Copy() - if (S.collection_mode == 2) - things = typecache_filter_list(things, typecacheof(type)) - - var/len = things.len - if(!len) - to_chat(user, "You failed to pick up anything with [S].") - return - var/datum/progressbar/progress = new(user, len, loc) - - while (do_after(user, 10, TRUE, S, FALSE, CALLBACK(src, .proc/handle_mass_pickup, S, things, loc, rejections, progress))) - sleep(1) - - qdel(progress) - - to_chat(user, "You put everything you could [S.preposition] [S].") - - else if(S.can_be_inserted(src)) - S.handle_item_insertion(src) - -/obj/item/proc/handle_mass_pickup(obj/item/weapon/storage/S, list/things, atom/thing_loc, list/rejections, datum/progressbar/progress) - for(var/obj/item/I in things) - things -= I - if(I.loc != thing_loc) - continue - if(I.type in rejections) // To limit bag spamming: any given type only complains once - continue - if(!S.can_be_inserted(I, stop_messages = TRUE)) // Note can_be_inserted still makes noise when the answer is no - if(S.contents.len >= S.storage_slots) - break - rejections += I.type // therefore full bags are still a little spammy - continue - - S.handle_item_insertion(I, TRUE) //The 1 stops the "You put the [src] into [S]" insertion message from being displayed. - - if (TICK_CHECK) - progress.update(progress.goal - things.len) - return TRUE - - progress.update(progress.goal - things.len) - return FALSE - -// afterattack() and attack() prototypes moved to _onclick/item_attack.dm for consistency - -/obj/item/proc/hit_reaction(mob/living/carbon/human/owner, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) - if(prob(final_block_chance)) - owner.visible_message("[owner] blocks [attack_text] with [src]!") - return 1 - return 0 - -/obj/item/proc/talk_into(mob/M, input, channel, spans, datum/language/language) - return ITALICS | REDUCE_RANGE - -/obj/item/proc/dropped(mob/user) - for(var/X in actions) - var/datum/action/A = X - A.Remove(user) - if(DROPDEL & flags) - qdel(src) - -// called just as an item is picked up (loc is not yet changed) -/obj/item/proc/pickup(mob/user) - return - - -// called when this item is removed from a storage item, which is passed on as S. The loc variable is already set to the new destination before this is called. -/obj/item/proc/on_exit_storage(obj/item/weapon/storage/S) - return - -// called when this item is added into a storage item, which is passed on as S. The loc variable is already set to the storage item. -/obj/item/proc/on_enter_storage(obj/item/weapon/storage/S) - return - -// called when "found" in pockets and storage items. Returns 1 if the search should end. -/obj/item/proc/on_found(mob/finder) - return - -// called after an item is placed in an equipment slot //NOPE, for example, if you put a helmet in slot_head, it is NOT in user's head variable yet, how stupid. -// user is mob that equipped it -// slot uses the slot_X defines found in setup.dm -// for items that can be placed in multiple slots -// note this isn't called during the initial dressing of a player -/obj/item/proc/equipped(mob/user, slot) - for(var/X in actions) - var/datum/action/A = X - if(item_action_slot_check(slot, user)) //some items only give their actions buttons when in a specific slot. - A.Grant(user) - -//sometimes we only want to grant the item's action if it's equipped in a specific slot. -/obj/item/proc/item_action_slot_check(slot, mob/user) - if(slot == slot_in_backpack || slot == slot_legcuffed) //these aren't true slots, so avoid granting actions there - return FALSE - return TRUE - -//the mob M is attempting to equip this item into the slot passed through as 'slot'. Return 1 if it can do this and 0 if it can't. -//if this is being done by a mob other than M, it will include the mob equipper, who is trying to equip the item to mob M. equipper will be null otherwise. -//If you are making custom procs but would like to retain partial or complete functionality of this one, include a 'return ..()' to where you want this to happen. -//Set disable_warning to 1 if you wish it to not give you outputs. -/obj/item/proc/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0) - if(!M) - return 0 - - return M.can_equip(src, slot, disable_warning) - -/obj/item/verb/verb_pickup() - set src in oview(1) - set category = "Object" - set name = "Pick up" - - if(usr.incapacitated() || !Adjacent(usr) || usr.lying) - return - - if(usr.get_active_held_item() == null) // Let me know if this has any problems -Yota - usr.UnarmedAttack(src) - -//This proc is executed when someone clicks the on-screen UI button. -//The default action is attack_self(). -//Checks before we get to here are: mob is alive, mob is not restrained, paralyzed, asleep, resting, laying, item is on the mob. -/obj/item/proc/ui_action_click(mob/user, actiontype) - attack_self(user) - -/obj/item/proc/IsReflect(var/def_zone) //This proc determines if and at what% an object will reflect energy projectiles if it's in l_hand,r_hand or wear_suit - return 0 - -/obj/item/proc/eyestab(mob/living/carbon/M, mob/living/carbon/user) - - var/is_human_victim = 0 - var/obj/item/bodypart/affecting = M.get_bodypart("head") - if(ishuman(M)) - if(!affecting) //no head! - return - is_human_victim = 1 - var/mob/living/carbon/human/H = M - if((H.head && H.head.flags_cover & HEADCOVERSEYES) || \ - (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || \ - (H.glasses && H.glasses.flags_cover & GLASSESCOVERSEYES)) - // you can't stab someone in the eyes wearing a mask! - to_chat(user, "You're going to need to remove that mask/helmet/glasses first!") - return - - if(ismonkey(M)) - var/mob/living/carbon/monkey/Mo = M - if(Mo.wear_mask && Mo.wear_mask.flags_cover & MASKCOVERSEYES) - // you can't stab someone in the eyes wearing a mask! - to_chat(user, "You're going to need to remove that mask/helmet/glasses first!") - return - - if(isalien(M))//Aliens don't have eyes./N slimes also don't have eyes! - to_chat(user, "You cannot locate any eyes on this creature!") - return - - if(isbrain(M)) - to_chat(user, "You cannot locate any organic eyes on this brain!") - return - - src.add_fingerprint(user) - - playsound(loc, src.hitsound, 30, 1, -1) - - user.do_attack_animation(M) - - if(M != user) - M.visible_message("[user] has stabbed [M] in the eye with [src]!", \ - "[user] stabs you in the eye with [src]!") - else - user.visible_message( \ - "[user] has stabbed themself in the eyes with [src]!", \ - "You stab yourself in the eyes with [src]!" \ - ) - if(is_human_victim) - var/mob/living/carbon/human/U = M - U.apply_damage(7, BRUTE, affecting) - - else - M.take_bodypart_damage(7) - - add_logs(user, M, "attacked", "[src.name]", "(INTENT: [uppertext(user.a_intent)])") - - M.adjust_blurriness(3) - M.adjust_eye_damage(rand(2,4)) - if(M.eye_damage >= 10) - M.adjust_blurriness(15) - if(M.stat != DEAD) - to_chat(M, "Your eyes start to bleed profusely!") - if(!(M.disabilities & (NEARSIGHT | BLIND))) - if(M.become_nearsighted()) - to_chat(M, "You become nearsighted!") - if(prob(50)) - if(M.stat != DEAD) - if(M.drop_item()) - to_chat(M, "You drop what you're holding and clutch at your eyes!") - M.adjust_blurriness(10) - M.Paralyse(1) - M.Weaken(2) - if (prob(M.eye_damage - 10 + 1)) - if(M.become_blind()) - to_chat(M, "You go blind!") - -/obj/item/clean_blood() - . = ..() - if(.) - if(initial(icon) && initial(icon_state)) - var/index = blood_splatter_index() - var/icon/blood_splatter_icon = GLOB.blood_splatter_icons[index] - if(blood_splatter_icon) - cut_overlay(blood_splatter_icon) - -/obj/item/clothing/gloves/clean_blood() - . = ..() - if(.) - transfer_blood = 0 - -/obj/item/singularity_pull(S, current_size) - if(current_size >= STAGE_FOUR) - throw_at(S,14,3, spin=0) - else ..() - -/obj/item/throw_impact(atom/A) - if(A && !QDELETED(A)) - var/itempush = 1 - if(w_class < 4) - itempush = 0 //too light to push anything - return A.hitby(src, 0, itempush) - -/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback) - thrownby = thrower - callback = CALLBACK(src, .proc/after_throw, callback) //replace their callback with our own - . = ..(target, range, speed, thrower, spin, diagonals_first, callback) - - -/obj/item/proc/after_throw(datum/callback/callback) - if (callback) //call the original callback - . = callback.Invoke() - throw_speed = initial(throw_speed) //explosions change this. - -/obj/item/proc/remove_item_from_storage(atom/newLoc) //please use this if you're going to snowflake an item out of a obj/item/weapon/storage - if(!newLoc) - return 0 - if(istype(loc,/obj/item/weapon/storage)) - var/obj/item/weapon/storage/S = loc - S.remove_from_storage(src,newLoc) - return 1 - return 0 - -/obj/item/proc/is_hot() - return heat - -/obj/item/proc/is_sharp() - return sharpness - -/obj/item/proc/get_dismemberment_chance(obj/item/bodypart/affecting) - if(affecting.can_dismember(src)) - if((sharpness || damtype == BURN) && w_class >= 3) - . = force*(w_class-1) - -/obj/item/proc/get_dismember_sound() - if(damtype == BURN) - . = 'sound/weapons/sear.ogg' - else - . = pick('sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg') - -/obj/item/proc/open_flame(flame_heat=700) - var/turf/location = loc - if(ismob(location)) - var/mob/M = location - var/success = FALSE - if(src == M.get_item_by_slot(slot_wear_mask)) - success = TRUE - if(success) - location = get_turf(M) - if(isturf(location)) - location.hotspot_expose(flame_heat, 5) - -/obj/item/proc/ignition_effect(atom/A, mob/user) - if(is_hot()) - . = "[user] lights [A] with [src]." - else - . = "" - - -//when an item modify our speech spans when in our active hand. Override this to modify speech spans. -/obj/item/proc/get_held_item_speechspans(mob/living/carbon/user) - return - -/obj/item/hitby(atom/movable/AM) - return - -/obj/item/attack_hulk(mob/living/carbon/human/user) - return 0 - -/obj/item/attack_animal(mob/living/simple_animal/M) - return 0 - -/obj/item/mech_melee_attack(obj/mecha/M) - return 0 - -/obj/item/burn() - if(!QDELETED(src)) - var/turf/T = get_turf(src) - var/ash_type = /obj/effect/decal/cleanable/ash - if(w_class == WEIGHT_CLASS_HUGE || w_class == WEIGHT_CLASS_GIGANTIC) - ash_type = /obj/effect/decal/cleanable/ash/large - var/obj/effect/decal/cleanable/ash/A = new ash_type(T) - A.desc += "\nLooks like this used to be \an [name] some time ago." - ..() - -/obj/item/acid_melt() - if(!QDELETED(src)) - var/turf/T = get_turf(src) - var/obj/effect/decal/cleanable/molten_object/MO = new(T) - MO.pixel_x = rand(-16,16) - MO.pixel_y = rand(-16,16) - MO.desc = "Looks like this was \an [src] some time ago." - ..() - -/obj/item/proc/microwave_act(obj/machinery/microwave/M) - if(M && M.dirty < 100) - M.dirty++ + +GLOBAL_VAR_INIT(rpg_loot_items, FALSE) +// if true, everyone item when created will have its name changed to be +// more... RPG-like. + +/obj/item + name = "item" + icon = 'icons/obj/items.dmi' + var/item_state = null + var/lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' + var/righthand_file = 'icons/mob/inhands/items_righthand.dmi' + + //Dimensions of the icon file used when this item is worn, eg: hats.dmi + //eg: 32x32 sprite, 64x64 sprite, etc. + //allows inhands/worn sprites to be of any size, but still centered on a mob properly + var/worn_x_dimension = 32 + var/worn_y_dimension = 32 + //Same as above but for inhands, uses the lefthand_ and righthand_ file vars + var/inhand_x_dimension = 32 + var/inhand_y_dimension = 32 + + //Not on /clothing because for some reason any /obj/item can technically be "worn" with enough fuckery. + var/icon/alternate_worn_icon = null//If this is set, update_icons() will find on mob (WORN, NOT INHANDS) states in this file instead, primary use: badminnery/events + var/alternate_worn_layer = null//If this is set, update_icons() will force the on mob state (WORN, NOT INHANDS) onto this layer, instead of it's default + + obj_integrity = 200 + max_integrity = 200 + + + var/hitsound = null + var/usesound = null + var/throwhitsound = null + var/w_class = WEIGHT_CLASS_NORMAL + var/slot_flags = 0 //This is used to determine on which slots an item can fit. + pass_flags = PASSTABLE + pressure_resistance = 4 + var/obj/item/master = null + + var/heat_protection = 0 //flags which determine which body parts are protected from heat. Use the HEAD, CHEST, GROIN, etc. flags. See setup.dm + var/cold_protection = 0 //flags which determine which body parts are protected from cold. Use the HEAD, CHEST, GROIN, etc. flags. See setup.dm + var/max_heat_protection_temperature //Set this variable to determine up to which temperature (IN KELVIN) the item protects against heat damage. Keep at null to disable protection. Only protects areas set by heat_protection flags + var/min_cold_protection_temperature //Set this variable to determine down to which temperature (IN KELVIN) the item protects against cold damage. 0 is NOT an acceptable number due to if(varname) tests!! Keep at null to disable protection. Only protects areas set by cold_protection flags + + var/list/actions //list of /datum/action's that this item has. + var/list/actions_types //list of paths of action datums to give to the item on New(). + + //Since any item can now be a piece of clothing, this has to be put here so all items share it. + var/flags_inv //This flag is used to determine when items in someone's inventory cover others. IE helmets making it so you can't see glasses, etc. + + var/item_color = null //this needs deprecating, soonish + + var/body_parts_covered = 0 //see setup.dm for appropriate bit flags + //var/heat_transfer_coefficient = 1 //0 prevents all transfers, 1 is invisible + var/gas_transfer_coefficient = 1 // for leaking gas from turf to mask and vice-versa (for masks right now, but at some point, i'd like to include space helmets) + var/permeability_coefficient = 1 // for chemicals/diseases + var/siemens_coefficient = 1 // for electrical admittance/conductance (electrocution checks and shit) + var/slowdown = 0 // How much clothing is slowing you down. Negative values speeds you up + var/armour_penetration = 0 //percentage of armour effectiveness to remove + var/list/allowed = null //suit storage stuff. + var/obj/item/device/uplink/hidden_uplink = null + var/strip_delay = 40 + var/put_on_delay = 20 + var/breakouttime = 0 + var/list/materials + var/origin_tech = null //Used by R&D to determine what research bonuses it grants. + var/needs_permit = 0 //Used by security bots to determine if this item is safe for public use. + + var/list/attack_verb //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]" + var/list/species_exception = null // list() of species types, if a species cannot put items in a certain slot, but species type is in list, it will be able to wear that item + + var/suittoggled = 0 + var/hooded = 0 + + var/mob/thrownby = null + + /obj/item/mouse_drag_pointer = MOUSE_ACTIVE_POINTER //the icon to indicate this object is being dragged + + //So items can have custom embedd values + //Because customisation is king + var/embed_chance = EMBED_CHANCE + var/embedded_fall_chance = EMBEDDED_ITEM_FALLOUT + var/embedded_pain_chance = EMBEDDED_PAIN_CHANCE + var/embedded_pain_multiplier = EMBEDDED_PAIN_MULTIPLIER //The coefficient of multiplication for the damage this item does while embedded (this*w_class) + var/embedded_fall_pain_multiplier = EMBEDDED_FALL_PAIN_MULTIPLIER //The coefficient of multiplication for the damage this item does when falling out of a limb (this*w_class) + var/embedded_impact_pain_multiplier = EMBEDDED_IMPACT_PAIN_MULTIPLIER //The coefficient of multiplication for the damage this item does when first embedded (this*w_class) + var/embedded_unsafe_removal_pain_multiplier = EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER //The coefficient of multiplication for the damage removing this without surgery causes (this*w_class) + var/embedded_unsafe_removal_time = EMBEDDED_UNSAFE_REMOVAL_TIME //A time in ticks, multiplied by the w_class. + + var/flags_cover = 0 //for flags such as GLASSESCOVERSEYES + var/heat = 0 + var/sharpness = IS_BLUNT + var/toolspeed = 1 + + var/block_chance = 0 + var/hit_reaction_chance = 0 //If you want to have something unrelated to blocking/armour piercing etc. Maybe not needed, but trying to think ahead/allow more freedom + var/reach = 1 //In tiles, how far this weapon can reach; 1 for adjacent, which is default + + //The list of slots by priority. equip_to_appropriate_slot() uses this list. Doesn't matter if a mob type doesn't have a slot. + var/list/slot_equipment_priority = null // for default list, see /mob/proc/equip_to_appropriate_slot() + + // Needs to be in /obj/item because corgis can wear a lot of + // non-clothing items + var/datum/dog_fashion/dog_fashion = null + + var/datum/rpg_loot/rpg_loot = null + +/obj/item/Initialize() + if (!materials) + materials = list() + . = ..() + for(var/path in actions_types) + new path(src) + actions_types = null + + if(GLOB.rpg_loot_items) + rpg_loot = new(src) + +/obj/item/Destroy() + flags &= ~DROPDEL //prevent reqdels + if(ismob(loc)) + var/mob/m = loc + m.temporarilyRemoveItemFromInventory(src, TRUE) + for(var/X in actions) + qdel(X) + QDEL_NULL(rpg_loot) + return ..() + +/obj/item/device + icon = 'icons/obj/device.dmi' + +/obj/item/proc/check_allowed_items(atom/target, not_inside, target_self) + if(((src in target) && !target_self) || (!isturf(target.loc) && !isturf(target) && not_inside)) + return 0 + else + return 1 + +/obj/item/blob_act(obj/structure/blob/B) + if(B && B.loc == loc) + qdel(src) + +//user: The mob that is suiciding +//damagetype: The type of damage the item will inflict on the user +//BRUTELOSS = 1 +//FIRELOSS = 2 +//TOXLOSS = 4 +//OXYLOSS = 8 +//Output a creative message and then return the damagetype done +/obj/item/proc/suicide_act(mob/user) + return + +/obj/item/verb/move_to_top() + set name = "Move To Top" + set category = "Object" + set src in oview(1) + + if(!isturf(loc) || usr.stat || usr.restrained() || !usr.canmove) + return + + var/turf/T = src.loc + + src.loc = null + + src.loc = T + +/obj/item/examine(mob/user) //This might be spammy. Remove? + ..() + var/pronoun + if(src.gender == PLURAL) + pronoun = "They are" + else + pronoun = "It is" + var/size = weightclass2text(src.w_class) + to_chat(user, "[pronoun] a [size] item." ) + + if(user.research_scanner) //Mob has a research scanner active. + var/msg = "*--------*
" + + if(origin_tech) + msg += "Testing potentials:
" + var/list/techlvls = params2list(origin_tech) + for(var/T in techlvls) //This needs to use the better names. + msg += "Tech: [CallTechName(T)] | magnitude: [techlvls[T]]
" + else + msg += "No tech origins detected.
" + + + if(materials.len) + msg += "Extractable materials:
" + for(var/mat in materials) + msg += "[CallMaterialName(mat)]
" //Capitize first word, remove the "$" + else + msg += "No extractable materials detected.
" + msg += "*--------*" + to_chat(user, msg) + + +/obj/item/attack_self(mob/user) + interact(user) + +/obj/item/interact(mob/user) + add_fingerprint(user) + if(hidden_uplink && hidden_uplink.active) + hidden_uplink.interact(user) + return 1 + ui_interact(user) + +/obj/item/ui_act(action, params) + add_fingerprint(usr) + return ..() + +/obj/item/attack_hand(mob/user) + if(!user) + return + if(anchored) + return + + if(resistance_flags & ON_FIRE) + var/mob/living/carbon/C = user + if(istype(C)) + if(C.gloves && (C.gloves.max_heat_protection_temperature > 360)) + extinguish() + to_chat(user, "You put out the fire on [src].") + else + to_chat(user, "You burn your hand on [src]!") + var/obj/item/bodypart/affecting = C.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm") + if(affecting && affecting.receive_damage( 0, 5 )) // 5 burn damage + C.update_damage_overlays() + return + else + extinguish() + + if(acid_level > 20 && !ismob(loc))// so we can still remove the clothes on us that have acid. + var/mob/living/carbon/C = user + if(istype(C)) + if(!C.gloves || (!(C.gloves.resistance_flags & (UNACIDABLE|ACID_PROOF)))) + to_chat(user, "The acid on [src] burns your hand!") + var/obj/item/bodypart/affecting = C.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm") + if(affecting && affecting.receive_damage( 0, 5 )) // 5 burn damage + C.update_damage_overlays() + + + if(istype(loc, /obj/item/weapon/storage)) + //If the item is in a storage item, take it out + var/obj/item/weapon/storage/S = loc + S.remove_from_storage(src, user.loc) + + if(throwing) + throwing.finalize(FALSE) + if(loc == user) + if(!user.dropItemToGround(src)) + return + + pickup(user) + add_fingerprint(user) + if(!user.put_in_active_hand(src)) + dropped(user) + + +/obj/item/attack_paw(mob/user) + if(!user) + return + if(anchored) + return + + if(istype(loc, /obj/item/weapon/storage)) + var/obj/item/weapon/storage/S = loc + S.remove_from_storage(src, user.loc) + + if(throwing) + throwing.finalize(FALSE) + if(loc == user) + if(!user.dropItemToGround(src)) + return + + pickup(user) + add_fingerprint(user) + if(!user.put_in_active_hand(src)) + dropped(user) + +/obj/item/attack_alien(mob/user) + var/mob/living/carbon/alien/A = user + + if(!A.has_fine_manipulation) + if(src in A.contents) // To stop Aliens having items stuck in their pockets + A.dropItemToGround(src) + to_chat(user, "Your claws aren't capable of such fine manipulation!") + return + attack_paw(A) + +/obj/item/attack_ai(mob/user) + if(istype(src.loc, /obj/item/weapon/robot_module)) + //If the item is part of a cyborg module, equip it + if(!iscyborg(user)) + return + var/mob/living/silicon/robot/R = user + if(!R.low_power_mode) //can't equip modules with an empty cell. + R.activate_module(src) + R.hud_used.update_robot_modules_display() + +// Due to storage type consolidation this should get used more now. +// I have cleaned it up a little, but it could probably use more. -Sayu +// The lack of ..() is intentional, do not add one +/obj/item/attackby(obj/item/weapon/W, mob/user, params) + if(istype(W,/obj/item/weapon/storage)) + var/obj/item/weapon/storage/S = W + if(S.use_to_pickup) + if(S.collection_mode) //Mode is set to collect multiple items on a tile and we clicked on a valid one. + if(isturf(loc)) + var/list/rejections = list() + + var/list/things = loc.contents.Copy() + if (S.collection_mode == 2) + things = typecache_filter_list(things, typecacheof(type)) + + var/len = things.len + if(!len) + to_chat(user, "You failed to pick up anything with [S].") + return + var/datum/progressbar/progress = new(user, len, loc) + + while (do_after(user, 10, TRUE, S, FALSE, CALLBACK(src, .proc/handle_mass_pickup, S, things, loc, rejections, progress))) + sleep(1) + + qdel(progress) + + to_chat(user, "You put everything you could [S.preposition] [S].") + + else if(S.can_be_inserted(src)) + S.handle_item_insertion(src) + +/obj/item/proc/handle_mass_pickup(obj/item/weapon/storage/S, list/things, atom/thing_loc, list/rejections, datum/progressbar/progress) + for(var/obj/item/I in things) + things -= I + if(I.loc != thing_loc) + continue + if(I.type in rejections) // To limit bag spamming: any given type only complains once + continue + if(!S.can_be_inserted(I, stop_messages = TRUE)) // Note can_be_inserted still makes noise when the answer is no + if(S.contents.len >= S.storage_slots) + break + rejections += I.type // therefore full bags are still a little spammy + continue + + S.handle_item_insertion(I, TRUE) //The 1 stops the "You put the [src] into [S]" insertion message from being displayed. + + if (TICK_CHECK) + progress.update(progress.goal - things.len) + return TRUE + + progress.update(progress.goal - things.len) + return FALSE + +// afterattack() and attack() prototypes moved to _onclick/item_attack.dm for consistency + +/obj/item/proc/hit_reaction(mob/living/carbon/human/owner, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK) + if(prob(final_block_chance)) + owner.visible_message("[owner] blocks [attack_text] with [src]!") + return 1 + return 0 + +/obj/item/proc/talk_into(mob/M, input, channel, spans, datum/language/language) + return ITALICS | REDUCE_RANGE + +/obj/item/proc/dropped(mob/user) + for(var/X in actions) + var/datum/action/A = X + A.Remove(user) + if(DROPDEL & flags) + qdel(src) + +// called just as an item is picked up (loc is not yet changed) +/obj/item/proc/pickup(mob/user) + return + + +// called when this item is removed from a storage item, which is passed on as S. The loc variable is already set to the new destination before this is called. +/obj/item/proc/on_exit_storage(obj/item/weapon/storage/S) + return + +// called when this item is added into a storage item, which is passed on as S. The loc variable is already set to the storage item. +/obj/item/proc/on_enter_storage(obj/item/weapon/storage/S) + return + +// called when "found" in pockets and storage items. Returns 1 if the search should end. +/obj/item/proc/on_found(mob/finder) + return + +// called after an item is placed in an equipment slot //NOPE, for example, if you put a helmet in slot_head, it is NOT in user's head variable yet, how stupid. +// user is mob that equipped it +// slot uses the slot_X defines found in setup.dm +// for items that can be placed in multiple slots +// note this isn't called during the initial dressing of a player +/obj/item/proc/equipped(mob/user, slot) + for(var/X in actions) + var/datum/action/A = X + if(item_action_slot_check(slot, user)) //some items only give their actions buttons when in a specific slot. + A.Grant(user) + +//sometimes we only want to grant the item's action if it's equipped in a specific slot. +/obj/item/proc/item_action_slot_check(slot, mob/user) + if(slot == slot_in_backpack || slot == slot_legcuffed) //these aren't true slots, so avoid granting actions there + return FALSE + return TRUE + +//the mob M is attempting to equip this item into the slot passed through as 'slot'. Return 1 if it can do this and 0 if it can't. +//if this is being done by a mob other than M, it will include the mob equipper, who is trying to equip the item to mob M. equipper will be null otherwise. +//If you are making custom procs but would like to retain partial or complete functionality of this one, include a 'return ..()' to where you want this to happen. +//Set disable_warning to 1 if you wish it to not give you outputs. +/obj/item/proc/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0) + if(!M) + return 0 + + return M.can_equip(src, slot, disable_warning) + +/obj/item/verb/verb_pickup() + set src in oview(1) + set category = "Object" + set name = "Pick up" + + if(usr.incapacitated() || !Adjacent(usr) || usr.lying) + return + + if(usr.get_active_held_item() == null) // Let me know if this has any problems -Yota + usr.UnarmedAttack(src) + +//This proc is executed when someone clicks the on-screen UI button. +//The default action is attack_self(). +//Checks before we get to here are: mob is alive, mob is not restrained, paralyzed, asleep, resting, laying, item is on the mob. +/obj/item/proc/ui_action_click(mob/user, actiontype) + attack_self(user) + +/obj/item/proc/IsReflect(var/def_zone) //This proc determines if and at what% an object will reflect energy projectiles if it's in l_hand,r_hand or wear_suit + return 0 + +/obj/item/proc/eyestab(mob/living/carbon/M, mob/living/carbon/user) + + var/is_human_victim = 0 + var/obj/item/bodypart/affecting = M.get_bodypart("head") + if(ishuman(M)) + if(!affecting) //no head! + return + is_human_victim = 1 + var/mob/living/carbon/human/H = M + if((H.head && H.head.flags_cover & HEADCOVERSEYES) || \ + (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || \ + (H.glasses && H.glasses.flags_cover & GLASSESCOVERSEYES)) + // you can't stab someone in the eyes wearing a mask! + to_chat(user, "You're going to need to remove that mask/helmet/glasses first!") + return + + if(ismonkey(M)) + var/mob/living/carbon/monkey/Mo = M + if(Mo.wear_mask && Mo.wear_mask.flags_cover & MASKCOVERSEYES) + // you can't stab someone in the eyes wearing a mask! + to_chat(user, "You're going to need to remove that mask/helmet/glasses first!") + return + + if(isalien(M))//Aliens don't have eyes./N slimes also don't have eyes! + to_chat(user, "You cannot locate any eyes on this creature!") + return + + if(isbrain(M)) + to_chat(user, "You cannot locate any organic eyes on this brain!") + return + + src.add_fingerprint(user) + + playsound(loc, src.hitsound, 30, 1, -1) + + user.do_attack_animation(M) + + if(M != user) + M.visible_message("[user] has stabbed [M] in the eye with [src]!", \ + "[user] stabs you in the eye with [src]!") + else + user.visible_message( \ + "[user] has stabbed themself in the eyes with [src]!", \ + "You stab yourself in the eyes with [src]!" \ + ) + if(is_human_victim) + var/mob/living/carbon/human/U = M + U.apply_damage(7, BRUTE, affecting) + + else + M.take_bodypart_damage(7) + + add_logs(user, M, "attacked", "[src.name]", "(INTENT: [uppertext(user.a_intent)])") + + M.adjust_blurriness(3) + M.adjust_eye_damage(rand(2,4)) + if(M.eye_damage >= 10) + M.adjust_blurriness(15) + if(M.stat != DEAD) + to_chat(M, "Your eyes start to bleed profusely!") + if(!(M.disabilities & (NEARSIGHT | BLIND))) + if(M.become_nearsighted()) + to_chat(M, "You become nearsighted!") + if(prob(50)) + if(M.stat != DEAD) + if(M.drop_item()) + to_chat(M, "You drop what you're holding and clutch at your eyes!") + M.adjust_blurriness(10) + M.Paralyse(1) + M.Weaken(2) + if (prob(M.eye_damage - 10 + 1)) + if(M.become_blind()) + to_chat(M, "You go blind!") + +/obj/item/clean_blood() + . = ..() + if(.) + if(initial(icon) && initial(icon_state)) + var/index = blood_splatter_index() + var/icon/blood_splatter_icon = GLOB.blood_splatter_icons[index] + if(blood_splatter_icon) + cut_overlay(blood_splatter_icon) + +/obj/item/clothing/gloves/clean_blood() + . = ..() + if(.) + transfer_blood = 0 + +/obj/item/singularity_pull(S, current_size) + if(current_size >= STAGE_FOUR) + throw_at(S,14,3, spin=0) + else ..() + +/obj/item/throw_impact(atom/A) + if(A && !QDELETED(A)) + if(is_hot() && isliving(A)) + var/mob/living/L = A + L.IgniteMob() + var/itempush = 1 + if(w_class < 4) + itempush = 0 //too light to push anything + return A.hitby(src, 0, itempush) + +/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback) + thrownby = thrower + callback = CALLBACK(src, .proc/after_throw, callback) //replace their callback with our own + . = ..(target, range, speed, thrower, spin, diagonals_first, callback) + + +/obj/item/proc/after_throw(datum/callback/callback) + if (callback) //call the original callback + . = callback.Invoke() + throw_speed = initial(throw_speed) //explosions change this. + +/obj/item/proc/remove_item_from_storage(atom/newLoc) //please use this if you're going to snowflake an item out of a obj/item/weapon/storage + if(!newLoc) + return 0 + if(istype(loc,/obj/item/weapon/storage)) + var/obj/item/weapon/storage/S = loc + S.remove_from_storage(src,newLoc) + return 1 + return 0 + +/obj/item/proc/is_hot() + return heat + +/obj/item/proc/is_sharp() + return sharpness + +/obj/item/proc/get_dismemberment_chance(obj/item/bodypart/affecting) + if(affecting.can_dismember(src)) + if((sharpness || damtype == BURN) && w_class >= 3) + . = force*(w_class-1) + +/obj/item/proc/get_dismember_sound() + if(damtype == BURN) + . = 'sound/weapons/sear.ogg' + else + . = pick('sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg') + +/obj/item/proc/open_flame(flame_heat=700) + var/turf/location = loc + if(ismob(location)) + var/mob/M = location + var/success = FALSE + if(src == M.get_item_by_slot(slot_wear_mask)) + success = TRUE + if(success) + location = get_turf(M) + if(isturf(location)) + location.hotspot_expose(flame_heat, 5) + +/obj/item/proc/ignition_effect(atom/A, mob/user) + if(is_hot()) + . = "[user] lights [A] with [src]." + else + . = "" + + +//when an item modify our speech spans when in our active hand. Override this to modify speech spans. +/obj/item/proc/get_held_item_speechspans(mob/living/carbon/user) + return + +/obj/item/hitby(atom/movable/AM) + return + +/obj/item/attack_hulk(mob/living/carbon/human/user) + return 0 + +/obj/item/attack_animal(mob/living/simple_animal/M) + return 0 + +/obj/item/mech_melee_attack(obj/mecha/M) + return 0 + +/obj/item/burn() + if(!QDELETED(src)) + var/turf/T = get_turf(src) + var/ash_type = /obj/effect/decal/cleanable/ash + if(w_class == WEIGHT_CLASS_HUGE || w_class == WEIGHT_CLASS_GIGANTIC) + ash_type = /obj/effect/decal/cleanable/ash/large + var/obj/effect/decal/cleanable/ash/A = new ash_type(T) + A.desc += "\nLooks like this used to be \an [name] some time ago." + ..() + +/obj/item/acid_melt() + if(!QDELETED(src)) + var/turf/T = get_turf(src) + var/obj/effect/decal/cleanable/molten_object/MO = new(T) + MO.pixel_x = rand(-16,16) + MO.pixel_y = rand(-16,16) + MO.desc = "Looks like this was \an [src] some time ago." + ..() + +/obj/item/proc/microwave_act(obj/machinery/microwave/M) + if(M && M.dirty < 100) + M.dirty++ From ff4ef6a1f565b7dfc01be8d1c23e3e49635bb1ec Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Sun, 21 May 2017 21:58:11 -0700 Subject: [PATCH 012/262] reset --- code/__HELPERS/mobs.dm | 28 +- code/_onclick/item_attack.dm | 2 +- code/controllers/configuration.dm | 1862 ++++++++--------- code/controllers/subsystem/server_maint.dm | 1 - code/controllers/subsystem/spacedrift.dm | 2 +- code/game/gamemodes/antag_spawner.dm | 12 +- code/game/machinery/computer/cloning.dm | 1004 ++++----- code/game/machinery/computer/robot.dm | 344 +-- code/game/machinery/recycler.dm | 420 ++-- code/game/machinery/suit_storage_unit.dm | 776 +++---- code/game/objects/effects/portals.dm | 138 +- code/game/objects/items/devices/PDA/radio.dm | 4 +- code/game/objects/items/devices/powersink.dm | 290 +-- .../objects/items/devices/radio/beacon.dm | 4 +- .../objects/items/devices/radio/headset.dm | 22 +- .../objects/items/devices/radio/intercom.dm | 4 +- .../objects/items/devices/transfer_valve.dm | 422 ++-- .../objects/items/weapons/dna_injector.dm | 8 +- .../objects/items/weapons/grenades/grenade.dm | 36 +- .../items/weapons/implants/implantchair.dm | 378 ++-- .../items/weapons/storage/uplink_kits.dm | 608 +++--- .../objects/items/weapons/tanks/tank_types.dm | 4 +- code/game/objects/items/weapons/weaponry.dm | 1106 +++++----- code/game/objects/structures/bedsheet_bin.dm | 632 +++--- .../crates_lockers/closets/secure/security.dm | 566 ++--- code/game/objects/structures/mineral_doors.dm | 442 ++-- code/modules/admin/verbs/randomverbs.dm | 6 +- code/modules/assembly/timer.dm | 230 +- .../atmospherics/machinery/portable/pump.dm | 282 +-- code/modules/jobs/job_types/job.dm | 2 - code/modules/mapping/ruins.dm | 186 +- .../modules/mob/dead/new_player/new_player.dm | 11 +- code/modules/mob/inventory.dm | 4 +- .../mob/living/carbon/human/inventory.dm | 490 ++--- .../carbon/human/species_types/golems.dm | 1396 ++++++------ .../carbon/human/species_types/zombies.dm | 100 +- .../mob/living/simple_animal/friendly/cat.dm | 548 ++--- code/modules/paperwork/clipboard.dm | 244 +-- code/modules/paperwork/folders.dm | 18 +- code/modules/power/gravitygenerator.dm | 24 +- code/modules/power/singularity/emitter.dm | 986 ++++----- .../particle_accelerator/particle_control.dm | 656 +++--- code/modules/projectiles/ammunition/energy.dm | 1 + .../modules/projectiles/projectile/bullets.dm | 54 +- code/modules/projectiles/projectile/energy.dm | 2 + .../chemistry/reagents/food_reagents.dm | 0 .../reagents/reagent_containers/glass.dm | 0 .../reagents/reagent_containers/spray.dm | 478 ++--- code/modules/shuttle/ferry.dm | 66 +- icons/emoji.dmi | Bin tgstation.dme | 25 +- tools/tgstation-server/Start Server.bat | 44 +- 52 files changed, 7490 insertions(+), 7478 deletions(-) mode change 100644 => 100755 code/game/objects/items/weapons/tanks/tank_types.dm mode change 100755 => 100644 code/modules/reagents/chemistry/reagents/food_reagents.dm mode change 100755 => 100644 code/modules/reagents/reagent_containers/glass.dm mode change 100755 => 100644 icons/emoji.dmi diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 6a4ec3456e..43b657dd9c 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -340,20 +340,20 @@ Proc for attack log creation, because really why not qdel(progbar) -//some additional checks as a callback for for do_afters that want to break on losing health or on the mob taking action -/mob/proc/break_do_after_checks(list/checked_health, check_clicks) - if(check_clicks && next_move > world.time) - return FALSE - return TRUE - -//pass a list in the format list("health" = mob's health var) to check health during this -/mob/living/break_do_after_checks(list/checked_health, check_clicks) - if(islist(checked_health)) - if(health < checked_health["health"]) - return FALSE - checked_health["health"] = health - return ..() - +//some additional checks as a callback for for do_afters that want to break on losing health or on the mob taking action +/mob/proc/break_do_after_checks(list/checked_health, check_clicks) + if(check_clicks && next_move > world.time) + return FALSE + return TRUE + +//pass a list in the format list("health" = mob's health var) to check health during this +/mob/living/break_do_after_checks(list/checked_health, check_clicks) + if(islist(checked_health)) + if(health < checked_health["health"]) + return FALSE + checked_health["health"] = health + return ..() + /proc/do_after(mob/user, delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null) if(!user) return 0 diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 09bdd44e6a..24f6559dd6 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -28,7 +28,7 @@ if(sharpness) to_chat(user, "You begin to butcher [src]...") playsound(loc, 'sound/weapons/slice.ogg', 50, 1, -1) - if(do_mob(user, src, 80/sharpness) && Adjacent(I)) + if(do_mob(user, src, 80/sharpness) && Adjacent(I)) harvest(user) return 1 return I.attack(src, user) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index e808b03ac7..e9bdeca880 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -1,931 +1,931 @@ -//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 - -/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") - if(var_name in banned_edits) - return FALSE - return ..() - -/datum/configuration - var/name = "Configuration" // datum name - - var/autoadmin = 0 - var/autoadmin_rank = "Game Admin" - - 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 - - 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 - - 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 - - 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/forbid_singulo_possession = 0 - var/useircbot = 0 - - var/check_randomizer = 0 - - var/allow_panic_bunker_bounce = 0 //Send new players somewhere else - var/panic_server_name = "somewhere else" - var/panic_address = "byond://" //Reconnect a player this linked server if this server isn't accepting new players - - //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/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 - - //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." - - //game_options.txt configs - var/force_random_names = 0 - var/list/mode_names = 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/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? - - var/traitor_scaling_coeff = 6 //how much does the amount of players get divided by to determine traitors - 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 - - var/traitor_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 - - 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 - - //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 = 0 // 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/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_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. - -/datum/configuration/New() - gamemode_cache = typecacheof(/datum/game_mode,TRUE) - 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 - 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 - if(M.votable) - votable_modes += M.config_tag - qdel(M) - votable_modes += "secret" - - Reload() - -/datum/configuration/proc/Reload() - load("config/config.txt") - load("config/game_options.txt","game_options") - loadsql("config/dbconfig.txt") - if (maprotation) - loadmaplist("config/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 - 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("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("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") - 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("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 = 1 - if("cross_server_address") - cross_address = value - if(value != "byond:\\address:port") - cross_allowed = 1 - if("cross_comms_name") - cross_name = value - if("panic_server_name") - panic_server_name = value - if("panic_server_address") - panic_address = value - if(value != "byond:\\address:port") - allow_panic_bunker_bounce = 1 - if("medal_hub_address") - global.medal_hub = value - if("medal_hub_password") - global.medal_pass = value - if("show_irc_name") - showircname = 1 - if("see_own_notes") - see_own_notes = 1 - 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) - else - GLOB.config_error_log << "Unknown setting in configuration: '[name]'" - - 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("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 - 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 - 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 - GLOB.config_error_log << "Unknown minimum population configuration definition: [mode_name]." - else - 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 - GLOB.config_error_log << "Unknown maximum population configuration definition: [mode_name]." - else - 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("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("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 - GLOB.config_error_log << "Unknown game mode probability configuration definition: [prob_name]." - else - GLOB.config_error_log << "Incorrect probability configuration definition: [prob_name] [prob_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) - 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_safe_latejoin") - arrivals_shuttle_require_safe_latejoin = TRUE - if("mice_roundstart") - mice_roundstart = text2num(value) - if ("mentor_mobname_only") - mentors_mobname_only = 1 - if ("mentor_legacy_system") - mentor_legacy_system = 1 - else - GLOB.config_error_log << "Unknown setting in configuration: '[name]'" - - fps = round(fps) - if(fps <= 0) - fps = initial(fps) - - -/datum/configuration/proc/loadmaplist(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_world("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") - maplist[currentmap.map_name] = currentmap - currentmap = null - else - GLOB.config_error_log << "Unknown command in map vote config: '[command]'" - - -/datum/configuration/proc/loadsql(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 - GLOB.config_error_log << "Unknown setting in configuration: '[name]'" - -/datum/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). - for(var/T in gamemode_cache) - var/datum/game_mode/M = new T() - if(M.config_tag && M.config_tag == mode_name) - return M - qdel(M) - return new /datum/game_mode/extended() - -/datum/configuration/proc/get_runnable_modes() - var/list/datum/game_mode/runnable_modes = new - for(var/T in gamemode_cache) - var/datum/game_mode/M = new T() - //to_chat(world, "DEBUG: [T], tag=[M.config_tag], prob=[probabilities[M.config_tag]]") - 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()) - runnable_modes[M] = probabilities[M.config_tag] - //to_chat(world, "DEBUG: runnable_mode\[[runnable_modes.len]\] = [M.config_tag]") - return runnable_modes - -/datum/configuration/proc/get_runnable_midround_modes(crew) - var/list/datum/game_mode/runnable_modes = new - 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 - -/datum/configuration/proc/stat_entry() - if(!statclick) - statclick = new/obj/effect/statclick/debug(null, "Edit", src) - - stat("[name]:", statclick) +//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 + +/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") + if(var_name in banned_edits) + return FALSE + return ..() + +/datum/configuration + var/name = "Configuration" // datum name + + var/autoadmin = 0 + var/autoadmin_rank = "Game Admin" + + 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 + + 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 + + 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 + + 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/forbid_singulo_possession = 0 + var/useircbot = 0 + + var/check_randomizer = 0 + + var/allow_panic_bunker_bounce = 0 //Send new players somewhere else + var/panic_server_name = "somewhere else" + var/panic_address = "byond://" //Reconnect a player this linked server if this server isn't accepting new players + + //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/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 + + //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." + + //game_options.txt configs + var/force_random_names = 0 + var/list/mode_names = 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/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? + + var/traitor_scaling_coeff = 6 //how much does the amount of players get divided by to determine traitors + 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 + + var/traitor_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 + + 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 + + //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 = 0 // 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/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_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. + +/datum/configuration/New() + gamemode_cache = typecacheof(/datum/game_mode,TRUE) + 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 + 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 + if(M.votable) + votable_modes += M.config_tag + qdel(M) + votable_modes += "secret" + + Reload() + +/datum/configuration/proc/Reload() + load("config/config.txt") + load("config/game_options.txt","game_options") + loadsql("config/dbconfig.txt") + if (maprotation) + loadmaplist("config/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 + 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("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("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") + 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("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 = 1 + if("cross_server_address") + cross_address = value + if(value != "byond:\\address:port") + cross_allowed = 1 + if("cross_comms_name") + cross_name = value + if("panic_server_name") + panic_server_name = value + if("panic_server_address") + panic_address = value + if(value != "byond:\\address:port") + allow_panic_bunker_bounce = 1 + if("medal_hub_address") + global.medal_hub = value + if("medal_hub_password") + global.medal_pass = value + if("show_irc_name") + showircname = 1 + if("see_own_notes") + see_own_notes = 1 + 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) + else + GLOB.config_error_log << "Unknown setting in configuration: '[name]'" + + 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("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 + 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 + 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 + GLOB.config_error_log << "Unknown minimum population configuration definition: [mode_name]." + else + 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 + GLOB.config_error_log << "Unknown maximum population configuration definition: [mode_name]." + else + 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("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("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 + GLOB.config_error_log << "Unknown game mode probability configuration definition: [prob_name]." + else + GLOB.config_error_log << "Incorrect probability configuration definition: [prob_name] [prob_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) + 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_safe_latejoin") + arrivals_shuttle_require_safe_latejoin = TRUE + if("mice_roundstart") + mice_roundstart = text2num(value) + if ("mentor_mobname_only") + mentors_mobname_only = 1 + if ("mentor_legacy_system") + mentor_legacy_system = 1 + else + GLOB.config_error_log << "Unknown setting in configuration: '[name]'" + + fps = round(fps) + if(fps <= 0) + fps = initial(fps) + + +/datum/configuration/proc/loadmaplist(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_world("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") + maplist[currentmap.map_name] = currentmap + currentmap = null + else + GLOB.config_error_log << "Unknown command in map vote config: '[command]'" + + +/datum/configuration/proc/loadsql(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 + GLOB.config_error_log << "Unknown setting in configuration: '[name]'" + +/datum/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). + for(var/T in gamemode_cache) + var/datum/game_mode/M = new T() + if(M.config_tag && M.config_tag == mode_name) + return M + qdel(M) + return new /datum/game_mode/extended() + +/datum/configuration/proc/get_runnable_modes() + var/list/datum/game_mode/runnable_modes = new + for(var/T in gamemode_cache) + var/datum/game_mode/M = new T() + //to_chat(world, "DEBUG: [T], tag=[M.config_tag], prob=[probabilities[M.config_tag]]") + 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()) + runnable_modes[M] = probabilities[M.config_tag] + //to_chat(world, "DEBUG: runnable_mode\[[runnable_modes.len]\] = [M.config_tag]") + return runnable_modes + +/datum/configuration/proc/get_runnable_midround_modes(crew) + var/list/datum/game_mode/runnable_modes = new + 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 + +/datum/configuration/proc/stat_entry() + if(!statclick) + statclick = new/obj/effect/statclick/debug(null, "Edit", src) + + stat("[name]:", statclick) diff --git a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm index bed923ffe2..a0ca6a7b67 100644 --- a/code/controllers/subsystem/server_maint.dm +++ b/code/controllers/subsystem/server_maint.dm @@ -9,7 +9,6 @@ SUBSYSTEM_DEF(server_maint) var/list/currentrun /datum/controller/subsystem/server_maint/Initialize(timeofday) - reload_custom_roundstart_items_list() if (config.hub) world.visibility = 1 ..() diff --git a/code/controllers/subsystem/spacedrift.dm b/code/controllers/subsystem/spacedrift.dm index 3012abec3e..53e6c0cee1 100644 --- a/code/controllers/subsystem/spacedrift.dm +++ b/code/controllers/subsystem/spacedrift.dm @@ -3,7 +3,7 @@ SUBSYSTEM_DEF(spacedrift) priority = 30 wait = 5 flags = SS_NO_INIT|SS_KEEP_TIMING - runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME var/list/currentrun = list() var/list/processing = list() diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index da749b603a..fd2c58fc80 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -142,25 +142,25 @@ /obj/item/weapon/antag_spawner/nuke_ops/proc/check_usability(mob/user) if(used) to_chat(user, "[src] is out of power!") - return 0 + return FALSE if(!(user.mind in SSticker.mode.syndicates)) to_chat(user, "AUTHENTICATION FAILURE. ACCESS DENIED.") - return 0 + return FALSE if(user.z != ZLEVEL_CENTCOM) to_chat(user, "[src] is out of range! It can only be used at your base!") - return 0 - return 1 + return FALSE + return TRUE /obj/item/weapon/antag_spawner/nuke_ops/attack_self(mob/user) if(!(check_usability(user))) return to_chat(user, "You activate [src] and wait for confirmation.") - var/list/nuke_candidates = pollCandidatesForMob("Do you want to play as a syndicate [borg_to_spawn ? "[lowertext(borg_to_spawn)] cyborg":"operative"]?", ROLE_OPERATIVE, null, ROLE_OPERATIVE, 150, POLL_IGNORE_SYNDICATE, src) + var/list/nuke_candidates = pollGhostCandidates("Do you want to play as a syndicate [borg_to_spawn ? "[lowertext(borg_to_spawn)] cyborg":"operative"]?", ROLE_OPERATIVE, null, ROLE_OPERATIVE, 150, POLL_IGNORE_SYNDICATE) if(nuke_candidates.len) if(!(check_usability(user))) return - used = 1 + used = TRUE var/mob/dead/observer/theghost = pick(nuke_candidates) spawn_antag(theghost.client, get_turf(src), "syndieborg") do_sparks(4, TRUE, src) diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 2d21b1aaf5..9e367d43b1 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -1,502 +1,502 @@ -/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/weapon/circuitboard/computer/cloning - req_access = list(GLOB.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/weapon/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/weapon/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/weapon/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 = 1 - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else - scanner.locked = 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/weapon/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(istype(mob_occupant, /mob/living/brain)) - 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/weapon/implant/health/imp - for(var/obj/item/weapon/implant/health/HI in mob_occupant.implants) - imp = HI - break - if(!imp) - imp = new /obj/item/weapon/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) +/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/weapon/circuitboard/computer/cloning + req_access = list(GLOB.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/weapon/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/weapon/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/weapon/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 = 1 + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else + scanner.locked = 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/weapon/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(istype(mob_occupant, /mob/living/brain)) + 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/weapon/implant/health/imp + for(var/obj/item/weapon/implant/health/HI in mob_occupant.implants) + imp = HI + break + if(!imp) + imp = new /obj/item/weapon/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) diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index 214163c739..79d6aa0b52 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -1,172 +1,172 @@ - - - -/obj/machinery/computer/robotics - name = "robotics control console" - desc = "Used to remotely lockdown or detonate linked Cyborgs." - icon_screen = "robot" - icon_keyboard = "rd_key" - req_access = list(GLOB.access_robotics) - circuit = /obj/item/weapon/circuitboard/computer/robotics - var/temp = null - - light_color = LIGHT_COLOR_PINK - -/obj/machinery/computer/robotics/proc/can_control(mob/user, mob/living/silicon/robot/R) - if(!istype(R)) - return 0 - if(isAI(user)) - if (R.connected_ai != user) - return 0 - if(iscyborg(user)) - if (R != user) - return 0 - if(R.scrambledcodes) - return 0 - return 1 - -/obj/machinery/computer/robotics/attack_hand(mob/user) - if(..()) - return - interact(user) - -/obj/machinery/computer/robotics/interact(mob/user) - if (src.z > 6) - to_chat(user, "Unable to establish a connection: \black You're too far away from the station!") - return - user.set_machine(src) - var/dat - var/robots = 0 - for(var/mob/living/silicon/robot/R in GLOB.mob_list) - if(!can_control(user, R)) - continue - robots++ - dat += "[R.name] |" - if(R.stat) - dat += " Not Responding |" - else if (!R.canmove) - dat += " Locked Down |" - else - dat += " Operating Normally |" - if (!R.canmove) - else if(R.cell) - dat += " Battery Installed ([R.cell.charge]/[R.cell.maxcharge]) |" - else - dat += " No Cell Installed |" - if(R.module) - dat += " Module Installed ([R.module.name]) |" - else - dat += " No Module Installed |" - if(R.connected_ai) - dat += " Slaved to [R.connected_ai.name] |" - else - dat += " Independent from AI |" - if(issilicon(user) || IsAdminGhost(user)) - if(is_servant_of_ratvar(user) && user != R) - dat += "(Convert) " - else if(((issilicon(user) && is_special_character(user)) || IsAdminGhost(user)) && !R.emagged && (user != R || R.syndicate)) - dat += "(Hack) " - dat += "([R.canmove ? "Lockdown" : "Release"]) " - dat += "(Destroy)" - dat += "
" - - if(!robots) - dat += "No Cyborg Units detected within access parameters." - dat += "
" - - var/drones = 0 - for(var/mob/living/simple_animal/drone/D in GLOB.mob_list) - if(D.hacked) - continue - drones++ - dat += "[D.name] |" - if(D.stat) - dat += " Not Responding |" - dat += "(Destroy)" - dat += "
" - - if(!drones) - dat += "No Drone Units detected within access parameters." - - var/datum/browser/popup = new(user, "computer", "Cyborg Control Console", 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/robotics/Topic(href, href_list) - if(..()) - return - - if (href_list["temp"]) - src.temp = null - - else if (href_list["killbot"]) - if(src.allowed(usr)) - var/mob/living/silicon/robot/R = locate(href_list["killbot"]) in GLOB.silicon_mobs - if(can_control(usr, R)) - var/choice = input("Are you certain you wish to detonate [R.name]?") in list("Confirm", "Abort") - if(choice == "Confirm" && can_control(usr, R) && !..()) - if(R.syndicate && R.emagged) - to_chat(R, "Extreme danger. Termination codes detected. Scrambling security codes and automatic AI unlink triggered.") - if(R.connected_ai) - to_chat(R.connected_ai, "

ALERT - Cyborg detonation detected: [R.name]
") - R.ResetSecurityCodes() - else - var/turf/T = get_turf(R) - message_admins("[ADMIN_LOOKUPFLW(usr)] detonated [key_name(R, R.client)][ADMIN_JMP(T)]!") - log_game("\[key_name(usr)] detonated [key_name(R)]!") - if(R.connected_ai) - to_chat(R.connected_ai, "

ALERT - Cyborg detonation detected: [R.name]
") - R.self_destruct() - else - to_chat(usr, "Access Denied.") - - else if (href_list["stopbot"]) - if(src.allowed(usr)) - var/mob/living/silicon/robot/R = locate(href_list["stopbot"]) in GLOB.silicon_mobs - if(can_control(usr, R)) - var/choice = input("Are you certain you wish to [R.canmove ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort") - if(choice == "Confirm" && can_control(usr, R) && !..()) - message_admins("[ADMIN_LOOKUPFLW(usr)] [R.canmove ? "locked down" : "released"] [key_name(R, R.client)][ADMIN_LOOKUPFLW(R)]!") - log_game("[key_name(usr)] [R.canmove ? "locked down" : "released"] [key_name(R)]!") - R.SetLockdown(!R.lockcharge) - to_chat(R, "[!R.lockcharge ? "Your lockdown has been lifted!" : "You have been locked down!"]") - if(R.connected_ai) - to_chat(R.connected_ai, "[!R.lockcharge ? "NOTICE - Cyborg lockdown lifted" : "ALERT - Cyborg lockdown detected"]: [R.name]
") - - else - to_chat(usr, "Access Denied.") - - else if (href_list["magbot"]) - if((issilicon(usr) && is_special_character(usr)) || IsAdminGhost(usr)) - var/mob/living/silicon/robot/R = locate(href_list["magbot"]) in GLOB.silicon_mobs - if(istype(R) && !R.emagged && ((R.syndicate && R == usr) || R.connected_ai == usr || IsAdminGhost(usr)) && !R.scrambledcodes && can_control(usr, R)) - log_game("[key_name(usr)] emagged [R.name] using robotic console!") - message_admins("[key_name_admin(usr)] emagged cyborg [key_name_admin(R)] using robotic console!") - R.SetEmagged(1) - if(is_special_character(R)) - R.verbs += /mob/living/silicon/robot/proc/ResetSecurityCodes - - else if(href_list["convert"]) - if(issilicon(usr) && is_special_character(usr)) - var/mob/living/silicon/robot/R = locate(href_list["convert"]) in GLOB.silicon_mobs - if(istype(R) && !is_servant_of_ratvar(R) && is_servant_of_ratvar(usr) && R.connected_ai == usr) - log_game("[key_name(usr)] converted [R.name] using robotic console!") - message_admins("[key_name_admin(usr)] converted cyborg [key_name_admin(R)] using robotic console!") - add_servant_of_ratvar(R) - - else if (href_list["killdrone"]) - if(src.allowed(usr)) - var/mob/living/simple_animal/drone/D = locate(href_list["killdrone"]) - if(D.hacked) - to_chat(usr, "ERROR: [D] is not responding to external commands.") - else - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(3, 1, D) - s.start() - D.visible_message("\the [D] self destructs!") - D.gib() - - src.updateUsrDialog() - return + + + +/obj/machinery/computer/robotics + name = "robotics control console" + desc = "Used to remotely lockdown or detonate linked Cyborgs." + icon_screen = "robot" + icon_keyboard = "rd_key" + req_access = list(GLOB.access_robotics) + circuit = /obj/item/weapon/circuitboard/computer/robotics + var/temp = null + + light_color = LIGHT_COLOR_PINK + +/obj/machinery/computer/robotics/proc/can_control(mob/user, mob/living/silicon/robot/R) + if(!istype(R)) + return 0 + if(isAI(user)) + if (R.connected_ai != user) + return 0 + if(iscyborg(user)) + if (R != user) + return 0 + if(R.scrambledcodes) + return 0 + return 1 + +/obj/machinery/computer/robotics/attack_hand(mob/user) + if(..()) + return + interact(user) + +/obj/machinery/computer/robotics/interact(mob/user) + if (src.z > 6) + to_chat(user, "Unable to establish a connection: \black You're too far away from the station!") + return + user.set_machine(src) + var/dat + var/robots = 0 + for(var/mob/living/silicon/robot/R in GLOB.mob_list) + if(!can_control(user, R)) + continue + robots++ + dat += "[R.name] |" + if(R.stat) + dat += " Not Responding |" + else if (!R.canmove) + dat += " Locked Down |" + else + dat += " Operating Normally |" + if (!R.canmove) + else if(R.cell) + dat += " Battery Installed ([R.cell.charge]/[R.cell.maxcharge]) |" + else + dat += " No Cell Installed |" + if(R.module) + dat += " Module Installed ([R.module.name]) |" + else + dat += " No Module Installed |" + if(R.connected_ai) + dat += " Slaved to [R.connected_ai.name] |" + else + dat += " Independent from AI |" + if(issilicon(user) || IsAdminGhost(user)) + if(is_servant_of_ratvar(user) && user != R) + dat += "(Convert) " + else if(((issilicon(user) && is_special_character(user)) || IsAdminGhost(user)) && !R.emagged && (user != R || R.syndicate)) + dat += "(Hack) " + dat += "([R.canmove ? "Lockdown" : "Release"]) " + dat += "(Destroy)" + dat += "
" + + if(!robots) + dat += "No Cyborg Units detected within access parameters." + dat += "
" + + var/drones = 0 + for(var/mob/living/simple_animal/drone/D in GLOB.mob_list) + if(D.hacked) + continue + drones++ + dat += "[D.name] |" + if(D.stat) + dat += " Not Responding |" + dat += "(Destroy)" + dat += "
" + + if(!drones) + dat += "No Drone Units detected within access parameters." + + var/datum/browser/popup = new(user, "computer", "Cyborg Control Console", 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/robotics/Topic(href, href_list) + if(..()) + return + + if (href_list["temp"]) + src.temp = null + + else if (href_list["killbot"]) + if(src.allowed(usr)) + var/mob/living/silicon/robot/R = locate(href_list["killbot"]) in GLOB.silicon_mobs + if(can_control(usr, R)) + var/choice = input("Are you certain you wish to detonate [R.name]?") in list("Confirm", "Abort") + if(choice == "Confirm" && can_control(usr, R) && !..()) + if(R.syndicate && R.emagged) + to_chat(R, "Extreme danger. Termination codes detected. Scrambling security codes and automatic AI unlink triggered.") + if(R.connected_ai) + to_chat(R.connected_ai, "

ALERT - Cyborg detonation detected: [R.name]
") + R.ResetSecurityCodes() + else + var/turf/T = get_turf(R) + message_admins("[ADMIN_LOOKUPFLW(usr)] detonated [key_name(R, R.client)][ADMIN_JMP(T)]!") + log_game("\[key_name(usr)] detonated [key_name(R)]!") + if(R.connected_ai) + to_chat(R.connected_ai, "

ALERT - Cyborg detonation detected: [R.name]
") + R.self_destruct() + else + to_chat(usr, "Access Denied.") + + else if (href_list["stopbot"]) + if(src.allowed(usr)) + var/mob/living/silicon/robot/R = locate(href_list["stopbot"]) in GLOB.silicon_mobs + if(can_control(usr, R)) + var/choice = input("Are you certain you wish to [R.canmove ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort") + if(choice == "Confirm" && can_control(usr, R) && !..()) + message_admins("[ADMIN_LOOKUPFLW(usr)] [R.canmove ? "locked down" : "released"] [key_name(R, R.client)][ADMIN_LOOKUPFLW(R)]!") + log_game("[key_name(usr)] [R.canmove ? "locked down" : "released"] [key_name(R)]!") + R.SetLockdown(!R.lockcharge) + to_chat(R, "[!R.lockcharge ? "Your lockdown has been lifted!" : "You have been locked down!"]") + if(R.connected_ai) + to_chat(R.connected_ai, "[!R.lockcharge ? "NOTICE - Cyborg lockdown lifted" : "ALERT - Cyborg lockdown detected"]: [R.name]
") + + else + to_chat(usr, "Access Denied.") + + else if (href_list["magbot"]) + if((issilicon(usr) && is_special_character(usr)) || IsAdminGhost(usr)) + var/mob/living/silicon/robot/R = locate(href_list["magbot"]) in GLOB.silicon_mobs + if(istype(R) && !R.emagged && ((R.syndicate && R == usr) || R.connected_ai == usr || IsAdminGhost(usr)) && !R.scrambledcodes && can_control(usr, R)) + log_game("[key_name(usr)] emagged [R.name] using robotic console!") + message_admins("[key_name_admin(usr)] emagged cyborg [key_name_admin(R)] using robotic console!") + R.SetEmagged(1) + if(is_special_character(R)) + R.verbs += /mob/living/silicon/robot/proc/ResetSecurityCodes + + else if(href_list["convert"]) + if(issilicon(usr) && is_special_character(usr)) + var/mob/living/silicon/robot/R = locate(href_list["convert"]) in GLOB.silicon_mobs + if(istype(R) && !is_servant_of_ratvar(R) && is_servant_of_ratvar(usr) && R.connected_ai == usr) + log_game("[key_name(usr)] converted [R.name] using robotic console!") + message_admins("[key_name_admin(usr)] converted cyborg [key_name_admin(R)] using robotic console!") + add_servant_of_ratvar(R) + + else if (href_list["killdrone"]) + if(src.allowed(usr)) + var/mob/living/simple_animal/drone/D = locate(href_list["killdrone"]) + if(D.hacked) + to_chat(usr, "ERROR: [D] is not responding to external commands.") + else + var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread + s.set_up(3, 1, D) + s.start() + D.visible_message("\the [D] self destructs!") + D.gib() + + src.updateUsrDialog() + return diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index e683b77097..fdeb6598e5 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -1,211 +1,211 @@ -#define SAFETY_COOLDOWN 100 - -/obj/machinery/recycler - name = "recycler" - desc = "A large crushing machine used to recycle small items inefficiently. There are lights on the side." - icon = 'icons/obj/recycling.dmi' - icon_state = "grinder-o0" - layer = ABOVE_ALL_MOB_LAYER // Overhead - anchored = 1 - density = 1 - var/safety_mode = FALSE // Temporarily stops machine if it detects a mob - var/icon_name = "grinder-o" - var/blood = 0 - var/eat_dir = WEST - var/amount_produced = 50 - var/datum/material_container/materials - var/crush_damage = 1000 - var/eat_victim_items = TRUE - var/item_recycle_sound = 'sound/items/Welder.ogg' - -/obj/machinery/recycler/New() - ..() - materials = new /datum/material_container(src, list(MAT_METAL, MAT_GLASS, MAT_PLASMA, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM)) - var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/recycler(null) - B.apply_default_parts(src) - update_icon() - -/obj/item/weapon/circuitboard/machine/recycler - name = "Recycler (Machine Board)" - build_path = /obj/machinery/recycler - origin_tech = "programming=2;engineering=2" - req_components = list( - /obj/item/weapon/stock_parts/matter_bin = 1, - /obj/item/weapon/stock_parts/manipulator = 1) - -/obj/machinery/recycler/RefreshParts() - var/amt_made = 0 - var/mat_mod = 0 - for(var/obj/item/weapon/stock_parts/matter_bin/B in component_parts) - mat_mod = 2 * B.rating - mat_mod *= 50000 - for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) - amt_made = 12.5 * M.rating //% of materials salvaged - materials.max_amount = mat_mod - amount_produced = min(50, amt_made) + 50 - -/obj/machinery/recycler/examine(mob/user) - ..() - to_chat(user, "The power light is [(stat & NOPOWER) ? "off" : "on"].") - to_chat(user, "The safety-mode light is [safety_mode ? "on" : "off"].") - to_chat(user, "The safety-sensors status light is [emagged ? "off" : "on"].") - -/obj/machinery/recycler/power_change() - ..() - update_icon() - - -/obj/machinery/recycler/attackby(obj/item/I, mob/user, params) - if(default_deconstruction_screwdriver(user, "grinder-oOpen", "grinder-o0", I)) - return - - if(exchange_parts(user, I)) - return - - if(default_pry_open(I)) - return - - if(default_unfasten_wrench(user, I)) - return - - if(default_deconstruction_crowbar(I)) - return - return ..() - -/obj/machinery/recycler/emag_act(mob/user) - if(!emagged) - emagged = TRUE - if(safety_mode) - safety_mode = FALSE - update_icon() - playsound(src.loc, "sparks", 75, 1, -1) - to_chat(user, "You use the cryptographic sequencer on the [src.name].") - -/obj/machinery/recycler/update_icon() - ..() - var/is_powered = !(stat & (BROKEN|NOPOWER)) - if(safety_mode) - is_powered = FALSE - icon_state = icon_name + "[is_powered]" + "[(blood ? "bld" : "")]" // add the blood tag at the end - -// This is purely for admin possession !FUN!. -/obj/machinery/recycler/Bump(atom/movable/AM) - ..() - if(AM) - Bumped(AM) - - -/obj/machinery/recycler/Bumped(atom/movable/AM) - - if(stat & (BROKEN|NOPOWER)) - return - if(!anchored) - return - if(safety_mode) - return - - var/move_dir = get_dir(loc, AM.loc) - if(move_dir == eat_dir) - eat(AM) - -/obj/machinery/recycler/proc/eat(atom/AM0, sound=TRUE) - var/list/to_eat - if(istype(AM0, /obj/item)) - to_eat = AM0.GetAllContents() - else - to_eat = list(AM0) - - var/items_recycled = 0 - - for(var/i in to_eat) - var/atom/movable/AM = i - var/obj/item/bodypart/head/as_head = AM - var/obj/item/device/mmi/as_mmi = AM - var/brain_holder = istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /mob/living/brain) - if(isliving(AM) || brain_holder) - if(emagged) - if(!brain_holder) - crush_living(AM) - else - emergency_stop(AM) - else if(istype(AM, /obj/item)) - recycle_item(AM) - items_recycled++ - else - playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) - AM.loc = src.loc - - if(items_recycled && sound) - playsound(src.loc, item_recycle_sound, 50, 1) - -/obj/machinery/recycler/proc/recycle_item(obj/item/I) - I.loc = src.loc - - var/material_amount = materials.get_item_material_amount(I) - if(!material_amount) - qdel(I) - return - materials.insert_item(I, multiplier = (amount_produced / 100)) - qdel(I) - materials.retrieve_all() - - -/obj/machinery/recycler/proc/emergency_stop(mob/living/L) - playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) - safety_mode = TRUE - update_icon() - L.loc = src.loc - addtimer(CALLBACK(src, .proc/reboot), SAFETY_COOLDOWN) - -/obj/machinery/recycler/proc/reboot() - playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) - safety_mode = FALSE - update_icon() - -/obj/machinery/recycler/proc/crush_living(mob/living/L) - - L.loc = src.loc - - if(issilicon(L)) - playsound(src.loc, 'sound/items/Welder.ogg', 50, 1) - else - playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) - - var/gib = TRUE - // By default, the emagged recycler will gib all non-carbons. (human simple animal mobs don't count) - if(iscarbon(L)) - gib = FALSE - if(L.stat == CONSCIOUS) - L.say("ARRRRRRRRRRRGH!!!") - add_mob_blood(L) - - if(!blood && !issilicon(L)) - blood = TRUE - update_icon() - - // Remove and recycle the equipped items - if(eat_victim_items) - for(var/obj/item/I in L.get_equipped_items()) - if(L.dropItemToGround(I)) - eat(I, sound=FALSE) - - // Instantly lie down, also go unconscious from the pain, before you die. - L.Paralyse(5) - - // For admin fun, var edit emagged to 2. - if(gib || emagged == 2) - L.gib() - else if(emagged == 1) - L.adjustBruteLoss(crush_damage) - -/obj/machinery/recycler/deathtrap - name = "dangerous old crusher" - emagged = TRUE - crush_damage = 120 - flags = NODECONSTRUCT - -/obj/item/weapon/paper/recycler - name = "paper - 'garbage duty instructions'" - info = "

New Assignment

You have been assigned to collect garbage from trash bins, located around the station. The crewmembers will put their trash into it and you will collect the said trash.

There is a recycling machine near your closet, inside maintenance; use it to recycle the trash for a small chance to get useful minerals. Then deliver these minerals to cargo or engineering. You are our last hope for a clean station, do not screw this up!" - +#define SAFETY_COOLDOWN 100 + +/obj/machinery/recycler + name = "recycler" + desc = "A large crushing machine used to recycle small items inefficiently. There are lights on the side." + icon = 'icons/obj/recycling.dmi' + icon_state = "grinder-o0" + layer = ABOVE_ALL_MOB_LAYER // Overhead + anchored = 1 + density = 1 + var/safety_mode = FALSE // Temporarily stops machine if it detects a mob + var/icon_name = "grinder-o" + var/blood = 0 + var/eat_dir = WEST + var/amount_produced = 50 + var/datum/material_container/materials + var/crush_damage = 1000 + var/eat_victim_items = TRUE + var/item_recycle_sound = 'sound/items/Welder.ogg' + +/obj/machinery/recycler/New() + ..() + materials = new /datum/material_container(src, list(MAT_METAL, MAT_GLASS, MAT_PLASMA, MAT_SILVER, MAT_GOLD, MAT_DIAMOND, MAT_URANIUM, MAT_BANANIUM, MAT_TITANIUM)) + var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/recycler(null) + B.apply_default_parts(src) + update_icon() + +/obj/item/weapon/circuitboard/machine/recycler + name = "Recycler (Machine Board)" + build_path = /obj/machinery/recycler + origin_tech = "programming=2;engineering=2" + req_components = list( + /obj/item/weapon/stock_parts/matter_bin = 1, + /obj/item/weapon/stock_parts/manipulator = 1) + +/obj/machinery/recycler/RefreshParts() + var/amt_made = 0 + var/mat_mod = 0 + for(var/obj/item/weapon/stock_parts/matter_bin/B in component_parts) + mat_mod = 2 * B.rating + mat_mod *= 50000 + for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) + amt_made = 12.5 * M.rating //% of materials salvaged + materials.max_amount = mat_mod + amount_produced = min(50, amt_made) + 50 + +/obj/machinery/recycler/examine(mob/user) + ..() + to_chat(user, "The power light is [(stat & NOPOWER) ? "off" : "on"].") + to_chat(user, "The safety-mode light is [safety_mode ? "on" : "off"].") + to_chat(user, "The safety-sensors status light is [emagged ? "off" : "on"].") + +/obj/machinery/recycler/power_change() + ..() + update_icon() + + +/obj/machinery/recycler/attackby(obj/item/I, mob/user, params) + if(default_deconstruction_screwdriver(user, "grinder-oOpen", "grinder-o0", I)) + return + + if(exchange_parts(user, I)) + return + + if(default_pry_open(I)) + return + + if(default_unfasten_wrench(user, I)) + return + + if(default_deconstruction_crowbar(I)) + return + return ..() + +/obj/machinery/recycler/emag_act(mob/user) + if(!emagged) + emagged = TRUE + if(safety_mode) + safety_mode = FALSE + update_icon() + playsound(src.loc, "sparks", 75, 1, -1) + to_chat(user, "You use the cryptographic sequencer on the [src.name].") + +/obj/machinery/recycler/update_icon() + ..() + var/is_powered = !(stat & (BROKEN|NOPOWER)) + if(safety_mode) + is_powered = FALSE + icon_state = icon_name + "[is_powered]" + "[(blood ? "bld" : "")]" // add the blood tag at the end + +// This is purely for admin possession !FUN!. +/obj/machinery/recycler/Bump(atom/movable/AM) + ..() + if(AM) + Bumped(AM) + + +/obj/machinery/recycler/Bumped(atom/movable/AM) + + if(stat & (BROKEN|NOPOWER)) + return + if(!anchored) + return + if(safety_mode) + return + + var/move_dir = get_dir(loc, AM.loc) + if(move_dir == eat_dir) + eat(AM) + +/obj/machinery/recycler/proc/eat(atom/AM0, sound=TRUE) + var/list/to_eat + if(istype(AM0, /obj/item)) + to_eat = AM0.GetAllContents() + else + to_eat = list(AM0) + + var/items_recycled = 0 + + for(var/i in to_eat) + var/atom/movable/AM = i + var/obj/item/bodypart/head/as_head = AM + var/obj/item/device/mmi/as_mmi = AM + var/brain_holder = istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /mob/living/brain) + if(isliving(AM) || brain_holder) + if(emagged) + if(!brain_holder) + crush_living(AM) + else + emergency_stop(AM) + else if(istype(AM, /obj/item)) + recycle_item(AM) + items_recycled++ + else + playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) + AM.loc = src.loc + + if(items_recycled && sound) + playsound(src.loc, item_recycle_sound, 50, 1) + +/obj/machinery/recycler/proc/recycle_item(obj/item/I) + I.loc = src.loc + + var/material_amount = materials.get_item_material_amount(I) + if(!material_amount) + qdel(I) + return + materials.insert_item(I, multiplier = (amount_produced / 100)) + qdel(I) + materials.retrieve_all() + + +/obj/machinery/recycler/proc/emergency_stop(mob/living/L) + playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 0) + safety_mode = TRUE + update_icon() + L.loc = src.loc + addtimer(CALLBACK(src, .proc/reboot), SAFETY_COOLDOWN) + +/obj/machinery/recycler/proc/reboot() + playsound(src.loc, 'sound/machines/ping.ogg', 50, 0) + safety_mode = FALSE + update_icon() + +/obj/machinery/recycler/proc/crush_living(mob/living/L) + + L.loc = src.loc + + if(issilicon(L)) + playsound(src.loc, 'sound/items/Welder.ogg', 50, 1) + else + playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) + + var/gib = TRUE + // By default, the emagged recycler will gib all non-carbons. (human simple animal mobs don't count) + if(iscarbon(L)) + gib = FALSE + if(L.stat == CONSCIOUS) + L.say("ARRRRRRRRRRRGH!!!") + add_mob_blood(L) + + if(!blood && !issilicon(L)) + blood = TRUE + update_icon() + + // Remove and recycle the equipped items + if(eat_victim_items) + for(var/obj/item/I in L.get_equipped_items()) + if(L.dropItemToGround(I)) + eat(I, sound=FALSE) + + // Instantly lie down, also go unconscious from the pain, before you die. + L.Paralyse(5) + + // For admin fun, var edit emagged to 2. + if(gib || emagged == 2) + L.gib() + else if(emagged == 1) + L.adjustBruteLoss(crush_damage) + +/obj/machinery/recycler/deathtrap + name = "dangerous old crusher" + emagged = TRUE + crush_damage = 120 + flags = NODECONSTRUCT + +/obj/item/weapon/paper/recycler + name = "paper - 'garbage duty instructions'" + info = "

New Assignment

You have been assigned to collect garbage from trash bins, located around the station. The crewmembers will put their trash into it and you will collect the said trash.

There is a recycling machine near your closet, inside maintenance; use it to recycle the trash for a small chance to get useful minerals. Then deliver these minerals to cargo or engineering. You are our last hope for a clean station, do not screw this up!" + #undef SAFETY_COOLDOWN \ No newline at end of file diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index f64f761736..18d2a1b5bd 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -1,388 +1,388 @@ -// SUIT STORAGE UNIT ///////////////// -/obj/machinery/suit_storage_unit - name = "suit storage unit" - desc = "An industrial unit made to hold space suits. It comes with a built-in UV cauterization mechanism. A small warning label advises that organic matter should not be placed into the unit." - icon = 'icons/obj/suitstorage.dmi' - icon_state = "close" - anchored = 1 - density = 1 - obj_integrity = 250 - max_integrity = 250 - - var/obj/item/clothing/suit/space/suit = null - var/obj/item/clothing/head/helmet/space/helmet = null - var/obj/item/clothing/mask/mask = null - var/obj/item/storage = null - - var/suit_type = null - var/helmet_type = null - var/mask_type = null - var/storage_type = null - - state_open = FALSE - var/locked = FALSE - panel_open = FALSE - var/safeties = TRUE - - var/uv = FALSE - var/uv_super = FALSE - var/uv_cycles = 6 - -/obj/machinery/suit_storage_unit/standard_unit - suit_type = /obj/item/clothing/suit/space/eva - helmet_type = /obj/item/clothing/head/helmet/space/eva - mask_type = /obj/item/clothing/mask/breath - -/obj/machinery/suit_storage_unit/captain - suit_type = /obj/item/clothing/suit/space/hardsuit/captain - mask_type = /obj/item/clothing/mask/gas/sechailer - storage_type = /obj/item/weapon/tank/jetpack/oxygen/captain - -/obj/machinery/suit_storage_unit/engine - suit_type = /obj/item/clothing/suit/space/hardsuit/engine - mask_type = /obj/item/clothing/mask/breath - -/obj/machinery/suit_storage_unit/ce - suit_type = /obj/item/clothing/suit/space/hardsuit/engine/elite - mask_type = /obj/item/clothing/mask/breath - storage_type= /obj/item/clothing/shoes/magboots/advance - -/obj/machinery/suit_storage_unit/security - suit_type = /obj/item/clothing/suit/space/hardsuit/security - mask_type = /obj/item/clothing/mask/gas/sechailer - -/obj/machinery/suit_storage_unit/hos - suit_type = /obj/item/clothing/suit/space/hardsuit/security/hos - mask_type = /obj/item/clothing/mask/gas/sechailer - storage_type = /obj/item/weapon/tank/internals/oxygen - -/obj/machinery/suit_storage_unit/atmos - suit_type = /obj/item/clothing/suit/space/hardsuit/engine/atmos - mask_type = /obj/item/clothing/mask/gas - storage_type = /obj/item/weapon/watertank/atmos - -/obj/machinery/suit_storage_unit/mining - suit_type = /obj/item/clothing/suit/hooded/explorer - mask_type = /obj/item/clothing/mask/gas/explorer - -/obj/machinery/suit_storage_unit/mining/eva - suit_type = /obj/item/clothing/suit/space/hardsuit/mining - mask_type = /obj/item/clothing/mask/breath - -/obj/machinery/suit_storage_unit/cmo - suit_type = /obj/item/clothing/suit/space/hardsuit/medical - mask_type = /obj/item/clothing/mask/breath - -/obj/machinery/suit_storage_unit/rd - suit_type = /obj/item/clothing/suit/space/hardsuit/rd - mask_type = /obj/item/clothing/mask/breath - -/obj/machinery/suit_storage_unit/syndicate - suit_type = /obj/item/clothing/suit/space/hardsuit/syndi - mask_type = /obj/item/clothing/mask/gas/syndicate - storage_type = /obj/item/weapon/tank/jetpack/oxygen/harness - -/obj/machinery/suit_storage_unit/ert/command - suit_type = /obj/item/clothing/suit/space/hardsuit/ert - mask_type = /obj/item/clothing/mask/breath - storage_type = /obj/item/weapon/tank/internals/emergency_oxygen/double - -/obj/machinery/suit_storage_unit/ert/security - suit_type = /obj/item/clothing/suit/space/hardsuit/ert/sec - mask_type = /obj/item/clothing/mask/breath - storage_type = /obj/item/weapon/tank/internals/emergency_oxygen/double - -/obj/machinery/suit_storage_unit/ert/engineer - suit_type = /obj/item/clothing/suit/space/hardsuit/ert/engi - mask_type = /obj/item/clothing/mask/breath - storage_type = /obj/item/weapon/tank/internals/emergency_oxygen/double - -/obj/machinery/suit_storage_unit/ert/medical - suit_type = /obj/item/clothing/suit/space/hardsuit/ert/med - mask_type = /obj/item/clothing/mask/breath - storage_type = /obj/item/weapon/tank/internals/emergency_oxygen/double - -/obj/machinery/suit_storage_unit/New() - ..() - wires = new /datum/wires/suit_storage_unit(src) - if(suit_type) - suit = new suit_type(src) - if(helmet_type) - helmet = new helmet_type(src) - if(mask_type) - mask = new mask_type(src) - if(storage_type) - storage = new storage_type(src) - update_icon() - -/obj/machinery/suit_storage_unit/Destroy() - if(suit) - qdel(suit) - suit = null - if(helmet) - qdel(helmet) - helmet = null - if(mask) - qdel(mask) - mask = null - if(storage) - qdel(storage) - storage = null - return ..() - -/obj/machinery/suit_storage_unit/update_icon() - cut_overlays() - - if(uv) - if(uv_super) - add_overlay("super") - else if(occupant) - add_overlay("uvhuman") - else - add_overlay("uv") - else if(state_open) - if(stat & BROKEN) - add_overlay("broken") - else - add_overlay("open") - if(suit) - add_overlay("suit") - if(helmet) - add_overlay("helm") - if(storage) - add_overlay("storage") - else if(occupant) - add_overlay("human") - -/obj/machinery/suit_storage_unit/power_change() - ..() - if(!is_operational() && state_open) - open_machine() - dump_contents() - update_icon() - -/obj/machinery/suit_storage_unit/proc/dump_contents() - dropContents() - helmet = null - suit = null - mask = null - storage = null - occupant = null - -/obj/machinery/suit_storage_unit/deconstruct(disassembled = TRUE) - if(!(flags & NODECONSTRUCT)) - open_machine() - dump_contents() - new /obj/item/stack/sheet/metal (loc, 2) - qdel(src) - -/obj/machinery/suit_storage_unit/MouseDrop_T(atom/A, mob/user) - if(user.stat || user.lying || !Adjacent(user) || !Adjacent(A) || !isliving(A)) - return - var/mob/living/target = A - if(!state_open) - to_chat(user, "The unit's doors are shut!") - return - if(!is_operational()) - to_chat(user, "The unit is not operational!") - return - if(occupant || helmet || suit || storage) - to_chat(user, "It's too cluttered inside to fit in!") - return - - if(target == user) - user.visible_message("[user] starts squeezing into [src]!", "You start working your way into [src]...") - else - target.visible_message("[user] starts shoving [target] into [src]!", "[user] starts shoving you into [src]!") - - if(do_mob(user, target, 30)) - if(occupant || helmet || suit || storage) - return - if(target == user) - user.visible_message("[user] slips into [src] and closes the door behind them!", "You slip into [src]'s cramped space and shut its door.") - else - target.visible_message("[user] pushes [target] into [src] and shuts its door!", "[user] shoves you into [src] and shuts the door!") - close_machine(target) - add_fingerprint(user) - -/obj/machinery/suit_storage_unit/proc/cook() - if(uv_cycles) - uv_cycles-- - uv = TRUE - locked = TRUE - update_icon() - if(occupant) - var/mob/living/mob_occupant = occupant - if(uv_super) - mob_occupant.adjustFireLoss(rand(20, 36)) - else - mob_occupant.adjustFireLoss(rand(10, 16)) - mob_occupant.emote("scream") - addtimer(CALLBACK(src, .proc/cook), 50) - else - uv_cycles = initial(uv_cycles) - uv = FALSE - locked = FALSE - if(uv_super) - visible_message("[src]'s door creaks open with a loud whining noise. A cloud of foul black smoke escapes from its chamber.") - playsound(src, 'sound/machines/airlock_alien_prying.ogg', 50, 1) - helmet = null - qdel(helmet) - suit = null - qdel(suit) // Delete everything but the occupant. - mask = null - qdel(mask) - storage = null - qdel(storage) - // The wires get damaged too. - wires.cut_all() - else - if(!occupant) - visible_message("[src]'s door slides open. The glowing yellow lights dim to a gentle green.") - else - visible_message("[src]'s door slides open, barraging you with the nauseating smell of charred flesh.") - playsound(src, 'sound/machines/AirlockClose.ogg', 25, 1) - for(var/obj/item/I in src) //Scorches away blood and forensic evidence, although the SSU itself is unaffected - I.clean_blood() - I.fingerprints = list() - open_machine(FALSE) - if(occupant) - dump_contents() - -/obj/machinery/suit_storage_unit/proc/shock(mob/user, prb) - if(!prob(prb)) - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(5, 1, src) - s.start() - if(electrocute_mob(user, src, src, 1, TRUE)) - return 1 - -/obj/machinery/suit_storage_unit/relaymove(mob/user) - container_resist(user) - -/obj/machinery/suit_storage_unit/container_resist(mob/living/user) - add_fingerprint(user) - if(locked) - visible_message("You see [user] kicking against the doors of [src]!", "You start kicking against the doors...") - addtimer(CALLBACK(src, .proc/resist_open, user), 300) - else - open_machine() - dump_contents() - -/obj/machinery/suit_storage_unit/proc/resist_open(mob/user) - if(!state_open && occupant && (user in src) && user.stat == 0) // Check they're still here. - visible_message("You see [user] bursts out of [src]!", "You escape the cramped confines of [src]!") - open_machine() - -/obj/machinery/suit_storage_unit/attackby(obj/item/I, mob/user, params) - if(state_open && is_operational()) - if(istype(I, /obj/item/clothing/suit/space)) - if(suit) - to_chat(user, "The unit already contains a suit!.") - return - if(!user.drop_item()) - return - suit = I - else if(istype(I, /obj/item/clothing/head/helmet)) - if(helmet) - to_chat(user, "The unit already contains a helmet!") - return - if(!user.drop_item()) - return - helmet = I - else if(istype(I, /obj/item/clothing/mask)) - if(mask) - to_chat(user, "The unit already contains a mask!") - return - if(!user.drop_item()) - return - mask = I - else - if(storage) - to_chat(user, "The auxiliary storage compartment is full!") - return - if(!user.drop_item()) - return - storage = I - - I.loc = src - visible_message("[user] inserts [I] into [src]", "You load [I] into [src].") - update_icon() - return - - if(panel_open && is_wire_tool(I)) - wires.interact(user) - if(!state_open) - if(default_deconstruction_screwdriver(user, "panel", "close", I)) - return - if(default_pry_open(I)) - dump_contents() - return - - return ..() - -/obj/machinery/suit_storage_unit/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "suit_storage_unit", name, 400, 305, master_ui, state) - ui.open() - -/obj/machinery/suit_storage_unit/ui_data() - var/list/data = list() - data["locked"] = locked - data["open"] = state_open - data["safeties"] = safeties - data["uv_active"] = uv - data["uv_super"] = uv_super - if(helmet) - data["helmet"] = helmet.name - if(suit) - data["suit"] = suit.name - if(mask) - data["mask"] = mask.name - if(storage) - data["storage"] = storage.name - if(occupant) - data["occupied"] = 1 - return data - -/obj/machinery/suit_storage_unit/ui_act(action, params) - if(..() || uv) - return - switch(action) - if("door") - if(state_open) - close_machine() - else - open_machine(0) - if(occupant) - dump_contents() // Dump out contents if someone is in there. - . = TRUE - if("lock") - locked = !locked - . = TRUE - if("uv") - if(occupant && safeties) - return - else if(!helmet && !mask && !suit && !storage && !occupant) - return - else - if(occupant) - var/mob/living/mob_occupant = occupant - to_chat(mob_occupant, "[src]'s confines grow warm, then hot, then scorching. You're being burned [!mob_occupant.stat ? "alive" : "away"]!") - cook() - . = TRUE - if("dispense") - if(!state_open) - return - - var/static/list/valid_items = list("helmet", "suit", "mask", "storage") - var/item_name = params["item"] - if(item_name in valid_items) - var/obj/item/I = vars[item_name] - vars[item_name] = null - if(I) - I.forceMove(loc) - . = TRUE - update_icon() +// SUIT STORAGE UNIT ///////////////// +/obj/machinery/suit_storage_unit + name = "suit storage unit" + desc = "An industrial unit made to hold space suits. It comes with a built-in UV cauterization mechanism. A small warning label advises that organic matter should not be placed into the unit." + icon = 'icons/obj/suitstorage.dmi' + icon_state = "close" + anchored = 1 + density = 1 + obj_integrity = 250 + max_integrity = 250 + + var/obj/item/clothing/suit/space/suit = null + var/obj/item/clothing/head/helmet/space/helmet = null + var/obj/item/clothing/mask/mask = null + var/obj/item/storage = null + + var/suit_type = null + var/helmet_type = null + var/mask_type = null + var/storage_type = null + + state_open = FALSE + var/locked = FALSE + panel_open = FALSE + var/safeties = TRUE + + var/uv = FALSE + var/uv_super = FALSE + var/uv_cycles = 6 + +/obj/machinery/suit_storage_unit/standard_unit + suit_type = /obj/item/clothing/suit/space/eva + helmet_type = /obj/item/clothing/head/helmet/space/eva + mask_type = /obj/item/clothing/mask/breath + +/obj/machinery/suit_storage_unit/captain + suit_type = /obj/item/clothing/suit/space/hardsuit/captain + mask_type = /obj/item/clothing/mask/gas/sechailer + storage_type = /obj/item/weapon/tank/jetpack/oxygen/captain + +/obj/machinery/suit_storage_unit/engine + suit_type = /obj/item/clothing/suit/space/hardsuit/engine + mask_type = /obj/item/clothing/mask/breath + +/obj/machinery/suit_storage_unit/ce + suit_type = /obj/item/clothing/suit/space/hardsuit/engine/elite + mask_type = /obj/item/clothing/mask/breath + storage_type= /obj/item/clothing/shoes/magboots/advance + +/obj/machinery/suit_storage_unit/security + suit_type = /obj/item/clothing/suit/space/hardsuit/security + mask_type = /obj/item/clothing/mask/gas/sechailer + +/obj/machinery/suit_storage_unit/hos + suit_type = /obj/item/clothing/suit/space/hardsuit/security/hos + mask_type = /obj/item/clothing/mask/gas/sechailer + storage_type = /obj/item/weapon/tank/internals/oxygen + +/obj/machinery/suit_storage_unit/atmos + suit_type = /obj/item/clothing/suit/space/hardsuit/engine/atmos + mask_type = /obj/item/clothing/mask/gas + storage_type = /obj/item/weapon/watertank/atmos + +/obj/machinery/suit_storage_unit/mining + suit_type = /obj/item/clothing/suit/hooded/explorer + mask_type = /obj/item/clothing/mask/gas/explorer + +/obj/machinery/suit_storage_unit/mining/eva + suit_type = /obj/item/clothing/suit/space/hardsuit/mining + mask_type = /obj/item/clothing/mask/breath + +/obj/machinery/suit_storage_unit/cmo + suit_type = /obj/item/clothing/suit/space/hardsuit/medical + mask_type = /obj/item/clothing/mask/breath + +/obj/machinery/suit_storage_unit/rd + suit_type = /obj/item/clothing/suit/space/hardsuit/rd + mask_type = /obj/item/clothing/mask/breath + +/obj/machinery/suit_storage_unit/syndicate + suit_type = /obj/item/clothing/suit/space/hardsuit/syndi + mask_type = /obj/item/clothing/mask/gas/syndicate + storage_type = /obj/item/weapon/tank/jetpack/oxygen/harness + +/obj/machinery/suit_storage_unit/ert/command + suit_type = /obj/item/clothing/suit/space/hardsuit/ert + mask_type = /obj/item/clothing/mask/breath + storage_type = /obj/item/weapon/tank/internals/emergency_oxygen/double + +/obj/machinery/suit_storage_unit/ert/security + suit_type = /obj/item/clothing/suit/space/hardsuit/ert/sec + mask_type = /obj/item/clothing/mask/breath + storage_type = /obj/item/weapon/tank/internals/emergency_oxygen/double + +/obj/machinery/suit_storage_unit/ert/engineer + suit_type = /obj/item/clothing/suit/space/hardsuit/ert/engi + mask_type = /obj/item/clothing/mask/breath + storage_type = /obj/item/weapon/tank/internals/emergency_oxygen/double + +/obj/machinery/suit_storage_unit/ert/medical + suit_type = /obj/item/clothing/suit/space/hardsuit/ert/med + mask_type = /obj/item/clothing/mask/breath + storage_type = /obj/item/weapon/tank/internals/emergency_oxygen/double + +/obj/machinery/suit_storage_unit/New() + ..() + wires = new /datum/wires/suit_storage_unit(src) + if(suit_type) + suit = new suit_type(src) + if(helmet_type) + helmet = new helmet_type(src) + if(mask_type) + mask = new mask_type(src) + if(storage_type) + storage = new storage_type(src) + update_icon() + +/obj/machinery/suit_storage_unit/Destroy() + if(suit) + qdel(suit) + suit = null + if(helmet) + qdel(helmet) + helmet = null + if(mask) + qdel(mask) + mask = null + if(storage) + qdel(storage) + storage = null + return ..() + +/obj/machinery/suit_storage_unit/update_icon() + cut_overlays() + + if(uv) + if(uv_super) + add_overlay("super") + else if(occupant) + add_overlay("uvhuman") + else + add_overlay("uv") + else if(state_open) + if(stat & BROKEN) + add_overlay("broken") + else + add_overlay("open") + if(suit) + add_overlay("suit") + if(helmet) + add_overlay("helm") + if(storage) + add_overlay("storage") + else if(occupant) + add_overlay("human") + +/obj/machinery/suit_storage_unit/power_change() + ..() + if(!is_operational() && state_open) + open_machine() + dump_contents() + update_icon() + +/obj/machinery/suit_storage_unit/proc/dump_contents() + dropContents() + helmet = null + suit = null + mask = null + storage = null + occupant = null + +/obj/machinery/suit_storage_unit/deconstruct(disassembled = TRUE) + if(!(flags & NODECONSTRUCT)) + open_machine() + dump_contents() + new /obj/item/stack/sheet/metal (loc, 2) + qdel(src) + +/obj/machinery/suit_storage_unit/MouseDrop_T(atom/A, mob/user) + if(user.stat || user.lying || !Adjacent(user) || !Adjacent(A) || !isliving(A)) + return + var/mob/living/target = A + if(!state_open) + to_chat(user, "The unit's doors are shut!") + return + if(!is_operational()) + to_chat(user, "The unit is not operational!") + return + if(occupant || helmet || suit || storage) + to_chat(user, "It's too cluttered inside to fit in!") + return + + if(target == user) + user.visible_message("[user] starts squeezing into [src]!", "You start working your way into [src]...") + else + target.visible_message("[user] starts shoving [target] into [src]!", "[user] starts shoving you into [src]!") + + if(do_mob(user, target, 30)) + if(occupant || helmet || suit || storage) + return + if(target == user) + user.visible_message("[user] slips into [src] and closes the door behind them!", "You slip into [src]'s cramped space and shut its door.") + else + target.visible_message("[user] pushes [target] into [src] and shuts its door!", "[user] shoves you into [src] and shuts the door!") + close_machine(target) + add_fingerprint(user) + +/obj/machinery/suit_storage_unit/proc/cook() + if(uv_cycles) + uv_cycles-- + uv = TRUE + locked = TRUE + update_icon() + if(occupant) + var/mob/living/mob_occupant = occupant + if(uv_super) + mob_occupant.adjustFireLoss(rand(20, 36)) + else + mob_occupant.adjustFireLoss(rand(10, 16)) + mob_occupant.emote("scream") + addtimer(CALLBACK(src, .proc/cook), 50) + else + uv_cycles = initial(uv_cycles) + uv = FALSE + locked = FALSE + if(uv_super) + visible_message("[src]'s door creaks open with a loud whining noise. A cloud of foul black smoke escapes from its chamber.") + playsound(src, 'sound/machines/airlock_alien_prying.ogg', 50, 1) + helmet = null + qdel(helmet) + suit = null + qdel(suit) // Delete everything but the occupant. + mask = null + qdel(mask) + storage = null + qdel(storage) + // The wires get damaged too. + wires.cut_all() + else + if(!occupant) + visible_message("[src]'s door slides open. The glowing yellow lights dim to a gentle green.") + else + visible_message("[src]'s door slides open, barraging you with the nauseating smell of charred flesh.") + playsound(src, 'sound/machines/AirlockClose.ogg', 25, 1) + for(var/obj/item/I in src) //Scorches away blood and forensic evidence, although the SSU itself is unaffected + I.clean_blood() + I.fingerprints = list() + open_machine(FALSE) + if(occupant) + dump_contents() + +/obj/machinery/suit_storage_unit/proc/shock(mob/user, prb) + if(!prob(prb)) + var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread + s.set_up(5, 1, src) + s.start() + if(electrocute_mob(user, src, src, 1, TRUE)) + return 1 + +/obj/machinery/suit_storage_unit/relaymove(mob/user) + container_resist(user) + +/obj/machinery/suit_storage_unit/container_resist(mob/living/user) + add_fingerprint(user) + if(locked) + visible_message("You see [user] kicking against the doors of [src]!", "You start kicking against the doors...") + addtimer(CALLBACK(src, .proc/resist_open, user), 300) + else + open_machine() + dump_contents() + +/obj/machinery/suit_storage_unit/proc/resist_open(mob/user) + if(!state_open && occupant && (user in src) && user.stat == 0) // Check they're still here. + visible_message("You see [user] bursts out of [src]!", "You escape the cramped confines of [src]!") + open_machine() + +/obj/machinery/suit_storage_unit/attackby(obj/item/I, mob/user, params) + if(state_open && is_operational()) + if(istype(I, /obj/item/clothing/suit/space)) + if(suit) + to_chat(user, "The unit already contains a suit!.") + return + if(!user.drop_item()) + return + suit = I + else if(istype(I, /obj/item/clothing/head/helmet)) + if(helmet) + to_chat(user, "The unit already contains a helmet!") + return + if(!user.drop_item()) + return + helmet = I + else if(istype(I, /obj/item/clothing/mask)) + if(mask) + to_chat(user, "The unit already contains a mask!") + return + if(!user.drop_item()) + return + mask = I + else + if(storage) + to_chat(user, "The auxiliary storage compartment is full!") + return + if(!user.drop_item()) + return + storage = I + + I.loc = src + visible_message("[user] inserts [I] into [src]", "You load [I] into [src].") + update_icon() + return + + if(panel_open && is_wire_tool(I)) + wires.interact(user) + if(!state_open) + if(default_deconstruction_screwdriver(user, "panel", "close", I)) + return + if(default_pry_open(I)) + dump_contents() + return + + return ..() + +/obj/machinery/suit_storage_unit/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \ + datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "suit_storage_unit", name, 400, 305, master_ui, state) + ui.open() + +/obj/machinery/suit_storage_unit/ui_data() + var/list/data = list() + data["locked"] = locked + data["open"] = state_open + data["safeties"] = safeties + data["uv_active"] = uv + data["uv_super"] = uv_super + if(helmet) + data["helmet"] = helmet.name + if(suit) + data["suit"] = suit.name + if(mask) + data["mask"] = mask.name + if(storage) + data["storage"] = storage.name + if(occupant) + data["occupied"] = 1 + return data + +/obj/machinery/suit_storage_unit/ui_act(action, params) + if(..() || uv) + return + switch(action) + if("door") + if(state_open) + close_machine() + else + open_machine(0) + if(occupant) + dump_contents() // Dump out contents if someone is in there. + . = TRUE + if("lock") + locked = !locked + . = TRUE + if("uv") + if(occupant && safeties) + return + else if(!helmet && !mask && !suit && !storage && !occupant) + return + else + if(occupant) + var/mob/living/mob_occupant = occupant + to_chat(mob_occupant, "[src]'s confines grow warm, then hot, then scorching. You're being burned [!mob_occupant.stat ? "alive" : "away"]!") + cook() + . = TRUE + if("dispense") + if(!state_open) + return + + var/static/list/valid_items = list("helmet", "suit", "mask", "storage") + var/item_name = params["item"] + if(item_name in valid_items) + var/obj/item/I = vars[item_name] + vars[item_name] = null + if(I) + I.forceMove(loc) + . = TRUE + update_icon() diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index 9e7dbe7fa9..7f66b0ab1a 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -1,69 +1,69 @@ - -/obj/effect/portal - name = "portal" - desc = "Looks unstable. Best to test it with the clown." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "portal" - density = 1 - var/obj/item/target = null - var/creator = null - anchored = 1 - var/precision = 1 // how close to the portal you will teleport. 0 = on the portal, 1 = adjacent - var/mech_sized = FALSE - -/obj/effect/portal/Bumped(mob/M as mob|obj) - teleport(M) - -/obj/effect/portal/attack_tk(mob/user) - return - -/obj/effect/portal/attack_hand(mob/user) - if(Adjacent(user)) - teleport(user) - -/obj/effect/portal/attackby(obj/item/weapon/W, mob/user, params) - if(user && Adjacent(user)) - teleport(user) - -/obj/effect/portal/make_frozen_visual() - return - -/obj/effect/portal/New(loc, turf/target, creator=null, lifespan=300) - ..() - GLOB.portals += src - src.target = target - src.creator = creator - - var/area/A = get_area(target) - if(A && A.noteleport) // No point in persisting if the target is unreachable. - qdel(src) - return - if(lifespan > 0) - QDEL_IN(src, lifespan) - -/obj/effect/portal/Destroy() - GLOB.portals -= src - if(istype(creator, /obj/item/weapon/hand_tele)) - var/obj/item/weapon/hand_tele/O = creator - O.active_portals-- - else if(istype(creator, /obj/item/weapon/gun/energy/wormhole_projector)) - var/obj/item/weapon/gun/energy/wormhole_projector/P = creator - P.portal_destroyed(src) - creator = null - return ..() - -/obj/effect/portal/proc/teleport(atom/movable/M as mob|obj) - if(istype(M, /obj/effect)) //sparks don't teleport - return - if(M.anchored) - if(!(istype(M, /obj/mecha) && mech_sized)) - return - if (!( target )) - qdel(src) - return - if (istype(M, /atom/movable)) - if(ismegafauna(M)) - message_admins("[M] [ADMIN_FLW(M)] has teleported through [src].") - do_teleport(M, target, precision) ///You will appear adjacent to the beacon - - + +/obj/effect/portal + name = "portal" + desc = "Looks unstable. Best to test it with the clown." + icon = 'icons/obj/stationobjs.dmi' + icon_state = "portal" + density = 1 + var/obj/item/target = null + var/creator = null + anchored = 1 + var/precision = 1 // how close to the portal you will teleport. 0 = on the portal, 1 = adjacent + var/mech_sized = FALSE + +/obj/effect/portal/Bumped(mob/M as mob|obj) + teleport(M) + +/obj/effect/portal/attack_tk(mob/user) + return + +/obj/effect/portal/attack_hand(mob/user) + if(Adjacent(user)) + teleport(user) + +/obj/effect/portal/attackby(obj/item/weapon/W, mob/user, params) + if(user && Adjacent(user)) + teleport(user) + +/obj/effect/portal/make_frozen_visual() + return + +/obj/effect/portal/New(loc, turf/target, creator=null, lifespan=300) + ..() + GLOB.portals += src + src.target = target + src.creator = creator + + var/area/A = get_area(target) + if(A && A.noteleport) // No point in persisting if the target is unreachable. + qdel(src) + return + if(lifespan > 0) + QDEL_IN(src, lifespan) + +/obj/effect/portal/Destroy() + GLOB.portals -= src + if(istype(creator, /obj/item/weapon/hand_tele)) + var/obj/item/weapon/hand_tele/O = creator + O.active_portals-- + else if(istype(creator, /obj/item/weapon/gun/energy/wormhole_projector)) + var/obj/item/weapon/gun/energy/wormhole_projector/P = creator + P.portal_destroyed(src) + creator = null + return ..() + +/obj/effect/portal/proc/teleport(atom/movable/M as mob|obj) + if(istype(M, /obj/effect)) //sparks don't teleport + return + if(M.anchored) + if(!(istype(M, /obj/mecha) && mech_sized)) + return + if (!( target )) + qdel(src) + return + if (istype(M, /atom/movable)) + if(ismegafauna(M)) + message_admins("[M] [ADMIN_FLW(M)] has teleported through [src].") + do_teleport(M, target, precision) ///You will appear adjacent to the beacon + + diff --git a/code/game/objects/items/devices/PDA/radio.dm b/code/game/objects/items/devices/PDA/radio.dm index bfe86bc8ff..a83c6247f8 100644 --- a/code/game/objects/items/devices/PDA/radio.dm +++ b/code/game/objects/items/devices/PDA/radio.dm @@ -8,8 +8,8 @@ var/on = 0 //Are we currently active?? var/menu_message = "" -/obj/item/radio/integrated/Initialize() - . = ..() +/obj/item/radio/integrated/Initialize() + . = ..() if (istype(loc.loc, /obj/item/device/pda)) hostpda = loc.loc diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index fb70d77ff3..e03c85c09a 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -1,145 +1,145 @@ -// Powersink - used to drain station power - -/obj/item/device/powersink - desc = "A nulling power sink which drains energy from electrical systems." - name = "power sink" - icon_state = "powersink0" - item_state = "electronic" - w_class = WEIGHT_CLASS_BULKY - flags = CONDUCT - throwforce = 5 - throw_speed = 1 - throw_range = 2 - materials = list(MAT_METAL=750) - origin_tech = "powerstorage=5;syndicate=5" - var/drain_rate = 1600000 // amount of power to drain per tick - var/power_drained = 0 // has drained this much power - var/max_power = 1e10 // maximum power that can be drained before exploding - var/mode = 0 // 0 = off, 1=clamped (off), 2=operating - var/admins_warned = 0 // stop spam, only warn the admins once that we are about to boom - - var/const/DISCONNECTED = 0 - var/const/CLAMPED_OFF = 1 - var/const/OPERATING = 2 - - var/obj/structure/cable/attached // the attached cable - -/obj/item/device/powersink/update_icon() - icon_state = "powersink[mode == OPERATING]" - -/obj/item/device/powersink/proc/set_mode(value) - if(value == mode) - return - switch(value) - if(DISCONNECTED) - attached = null - if(mode == OPERATING) - STOP_PROCESSING(SSobj, src) - anchored = 0 - - if(CLAMPED_OFF) - if(!attached) - return - if(mode == OPERATING) - STOP_PROCESSING(SSobj, src) - anchored = 1 - - if(OPERATING) - if(!attached) - return - START_PROCESSING(SSobj, src) - anchored = 1 - - mode = value - update_icon() - set_light(0) - -/obj/item/device/powersink/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/weapon/screwdriver)) - if(mode == DISCONNECTED) - var/turf/T = loc - if(isturf(T) && !T.intact) - attached = locate() in T - if(!attached) - to_chat(user, "This device must be placed over an exposed, powered cable node!") - else - set_mode(CLAMPED_OFF) - user.visible_message( \ - "[user] attaches \the [src] to the cable.", \ - "You attach \the [src] to the cable.", - "You hear some wires being connected to something.") - else - to_chat(user, "This device must be placed over an exposed, powered cable node!") - else - set_mode(DISCONNECTED) - user.visible_message( \ - "[user] detaches \the [src] from the cable.", \ - "You detach \the [src] from the cable.", - "You hear some wires being disconnected from something.") - else - return ..() - -/obj/item/device/powersink/attack_paw() - return - -/obj/item/device/powersink/attack_ai() - return - -/obj/item/device/powersink/attack_hand(mob/user) - switch(mode) - if(DISCONNECTED) - ..() - - if(CLAMPED_OFF) - user.visible_message( \ - "[user] activates \the [src]!", \ - "You activate \the [src].", - "You hear a click.") - message_admins("Power sink activated by [ADMIN_LOOKUPFLW(user)] at [ADMIN_COORDJMP(src)]") - log_game("Power sink activated by [key_name(user)] at [COORD(src)]") - set_mode(OPERATING) - - if(OPERATING) - user.visible_message( \ - "[user] deactivates \the [src]!", \ - "You deactivate \the [src].", - "You hear a click.") - set_mode(CLAMPED_OFF) - -/obj/item/device/powersink/process() - if(!attached) - set_mode(DISCONNECTED) - return - - var/datum/powernet/PN = attached.powernet - if(PN) - set_light(5) - - // found a powernet, so drain up to max power from it - - var/drained = min ( drain_rate, PN.avail ) - PN.load += drained - power_drained += drained - - // if tried to drain more than available on powernet - // now look for APCs and drain their cells - if(drained < drain_rate) - for(var/obj/machinery/power/terminal/T in PN.nodes) - if(istype(T.master, /obj/machinery/power/apc)) - var/obj/machinery/power/apc/A = T.master - if(A.operating && A.cell) - A.cell.charge = max(0, A.cell.charge - 50) - power_drained += 50 - if(A.charging == 2) // If the cell was full - A.charging = 1 // It's no longer full - - if(power_drained > max_power * 0.98) - if (!admins_warned) - admins_warned = 1 - message_admins("Power sink at ([x],[y],[z] - JMP) is 95% full. Explosion imminent.") - playsound(src, 'sound/effects/screech.ogg', 100, 1, 1) - - if(power_drained >= max_power) - STOP_PROCESSING(SSobj, src) - explosion(src.loc, 4,8,16,32) - qdel(src) +// Powersink - used to drain station power + +/obj/item/device/powersink + desc = "A nulling power sink which drains energy from electrical systems." + name = "power sink" + icon_state = "powersink0" + item_state = "electronic" + w_class = WEIGHT_CLASS_BULKY + flags = CONDUCT + throwforce = 5 + throw_speed = 1 + throw_range = 2 + materials = list(MAT_METAL=750) + origin_tech = "powerstorage=5;syndicate=5" + var/drain_rate = 1600000 // amount of power to drain per tick + var/power_drained = 0 // has drained this much power + var/max_power = 1e10 // maximum power that can be drained before exploding + var/mode = 0 // 0 = off, 1=clamped (off), 2=operating + var/admins_warned = 0 // stop spam, only warn the admins once that we are about to boom + + var/const/DISCONNECTED = 0 + var/const/CLAMPED_OFF = 1 + var/const/OPERATING = 2 + + var/obj/structure/cable/attached // the attached cable + +/obj/item/device/powersink/update_icon() + icon_state = "powersink[mode == OPERATING]" + +/obj/item/device/powersink/proc/set_mode(value) + if(value == mode) + return + switch(value) + if(DISCONNECTED) + attached = null + if(mode == OPERATING) + STOP_PROCESSING(SSobj, src) + anchored = 0 + + if(CLAMPED_OFF) + if(!attached) + return + if(mode == OPERATING) + STOP_PROCESSING(SSobj, src) + anchored = 1 + + if(OPERATING) + if(!attached) + return + START_PROCESSING(SSobj, src) + anchored = 1 + + mode = value + update_icon() + set_light(0) + +/obj/item/device/powersink/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/weapon/screwdriver)) + if(mode == DISCONNECTED) + var/turf/T = loc + if(isturf(T) && !T.intact) + attached = locate() in T + if(!attached) + to_chat(user, "This device must be placed over an exposed, powered cable node!") + else + set_mode(CLAMPED_OFF) + user.visible_message( \ + "[user] attaches \the [src] to the cable.", \ + "You attach \the [src] to the cable.", + "You hear some wires being connected to something.") + else + to_chat(user, "This device must be placed over an exposed, powered cable node!") + else + set_mode(DISCONNECTED) + user.visible_message( \ + "[user] detaches \the [src] from the cable.", \ + "You detach \the [src] from the cable.", + "You hear some wires being disconnected from something.") + else + return ..() + +/obj/item/device/powersink/attack_paw() + return + +/obj/item/device/powersink/attack_ai() + return + +/obj/item/device/powersink/attack_hand(mob/user) + switch(mode) + if(DISCONNECTED) + ..() + + if(CLAMPED_OFF) + user.visible_message( \ + "[user] activates \the [src]!", \ + "You activate \the [src].", + "You hear a click.") + message_admins("Power sink activated by [ADMIN_LOOKUPFLW(user)] at [ADMIN_COORDJMP(src)]") + log_game("Power sink activated by [key_name(user)] at [COORD(src)]") + set_mode(OPERATING) + + if(OPERATING) + user.visible_message( \ + "[user] deactivates \the [src]!", \ + "You deactivate \the [src].", + "You hear a click.") + set_mode(CLAMPED_OFF) + +/obj/item/device/powersink/process() + if(!attached) + set_mode(DISCONNECTED) + return + + var/datum/powernet/PN = attached.powernet + if(PN) + set_light(5) + + // found a powernet, so drain up to max power from it + + var/drained = min ( drain_rate, PN.avail ) + PN.load += drained + power_drained += drained + + // if tried to drain more than available on powernet + // now look for APCs and drain their cells + if(drained < drain_rate) + for(var/obj/machinery/power/terminal/T in PN.nodes) + if(istype(T.master, /obj/machinery/power/apc)) + var/obj/machinery/power/apc/A = T.master + if(A.operating && A.cell) + A.cell.charge = max(0, A.cell.charge - 50) + power_drained += 50 + if(A.charging == 2) // If the cell was full + A.charging = 1 // It's no longer full + + if(power_drained > max_power * 0.98) + if (!admins_warned) + admins_warned = 1 + message_admins("Power sink at ([x],[y],[z] - JMP) is 95% full. Explosion imminent.") + playsound(src, 'sound/effects/screech.ogg', 100, 1, 1) + + if(power_drained >= max_power) + STOP_PROCESSING(SSobj, src) + explosion(src.loc, 4,8,16,32) + qdel(src) diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm index 78cacb7281..5343e04f78 100644 --- a/code/game/objects/items/devices/radio/beacon.dm +++ b/code/game/objects/items/devices/radio/beacon.dm @@ -7,8 +7,8 @@ origin_tech = "bluespace=1" dog_fashion = null -/obj/item/device/radio/beacon/Initialize() - . = ..() +/obj/item/device/radio/beacon/Initialize() + . = ..() GLOB.teleportbeacons += src /obj/item/device/radio/beacon/Destroy() diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 2a1397d519..e1be1ca01b 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -11,8 +11,8 @@ var/obj/item/device/encryptionkey/keyslot2 = null dog_fashion = null -/obj/item/device/radio/headset/Initialize() - . = ..() +/obj/item/device/radio/headset/Initialize() + . = ..() recalculateChannels() /obj/item/device/radio/headset/Destroy() @@ -47,21 +47,21 @@ item_state = "syndie_headset" /obj/item/device/radio/headset/syndicate/alt/Initialize(mapload) - . = ..() + . = ..() SET_SECONDARY_FLAG(src, BANG_PROTECT) /obj/item/device/radio/headset/syndicate/alt/leader name = "team leader headset" command = TRUE -/obj/item/device/radio/headset/syndicate/Initialize() - . = ..() +/obj/item/device/radio/headset/syndicate/Initialize() + . = ..() make_syndie() /obj/item/device/radio/headset/binary origin_tech = "syndicate=3" -/obj/item/device/radio/headset/binary/Initialize() - . = ..() +/obj/item/device/radio/headset/binary/Initialize() + . = ..() qdel(keyslot) keyslot = new /obj/item/device/encryptionkey/binary recalculateChannels() @@ -79,7 +79,7 @@ item_state = "sec_headset_alt" /obj/item/device/radio/headset/headset_sec/alt/Initialize(mapload) - . = ..() + . = ..() SET_SECONDARY_FLAG(src, BANG_PROTECT) /obj/item/device/radio/headset/headset_eng @@ -134,7 +134,7 @@ item_state = "com_headset_alt" /obj/item/device/radio/headset/heads/captain/alt/Initialize(mapload) - . = ..() + . = ..() SET_SECONDARY_FLAG(src, BANG_PROTECT) /obj/item/device/radio/headset/heads/rd @@ -156,7 +156,7 @@ item_state = "com_headset_alt" /obj/item/device/radio/headset/heads/hos/alt/Initialize(mapload) - . = ..() + . = ..() SET_SECONDARY_FLAG(src, BANG_PROTECT) /obj/item/device/radio/headset/heads/ce @@ -213,7 +213,7 @@ keyslot = null /obj/item/device/radio/headset/headset_cent/alt/Initialize(mapload) - . = ..() + . = ..() SET_SECONDARY_FLAG(src, BANG_PROTECT) /obj/item/device/radio/headset/ai diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index c975dbff20..a7dceaccf1 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -11,8 +11,8 @@ var/last_tick //used to delay the powercheck dog_fashion = null -/obj/item/device/radio/intercom/Initialize() - . = ..() +/obj/item/device/radio/intercom/Initialize() + . = ..() START_PROCESSING(SSobj, src) /obj/item/device/radio/intercom/Destroy() diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 9296dd9e09..635338fe96 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -1,211 +1,211 @@ -/obj/item/device/transfer_valve - icon = 'icons/obj/assemblies.dmi' - name = "tank transfer valve" - icon_state = "valve_1" - item_state = "ttv" - desc = "Regulates the transfer of air between two tanks" - var/obj/item/weapon/tank/tank_one - var/obj/item/weapon/tank/tank_two - var/obj/item/device/attached_device - var/mob/attacher = null - var/valve_open = 0 - var/toggle = 1 - origin_tech = "materials=1;engineering=1" - -/obj/item/device/transfer_valve/IsAssemblyHolder() - return 1 - -/obj/item/device/transfer_valve/attackby(obj/item/item, mob/user, params) - if(istype(item, /obj/item/weapon/tank)) - if(tank_one && tank_two) - to_chat(user, "There are already two tanks attached, remove one first!") - return - - if(!tank_one) - if(!user.transferItemToLoc(item, src)) - return - tank_one = item - to_chat(user, "You attach the tank to the transfer valve.") - if(item.w_class > w_class) - w_class = item.w_class - else if(!tank_two) - if(!user.transferItemToLoc(item, src)) - return - tank_two = item - to_chat(user, "You attach the tank to the transfer valve.") - if(item.w_class > w_class) - w_class = item.w_class - - update_icon() -//TODO: Have this take an assemblyholder - else if(isassembly(item)) - var/obj/item/device/assembly/A = item - if(A.secured) - to_chat(user, "The device is secured.") - return - if(attached_device) - to_chat(user, "There is already a device attached to the valve, remove it first!") - return - if(!user.transferItemToLoc(item, src)) - return - attached_device = A - to_chat(user, "You attach the [item] to the valve controls and secure it.") - A.holder = src - A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb). - - GLOB.bombers += "[key_name(user)] attached a [item] to a transfer valve." - message_admins("[key_name_admin(user)] attached a [item] to a transfer valve.") - log_game("[key_name_admin(user)] attached a [item] to a transfer valve.") - attacher = user - return - -/obj/item/device/transfer_valve/attack_self(mob/user) - user.set_machine(src) - var/dat = {" Valve properties: -
Attachment one: [tank_one] [tank_one ? "Remove" : ""] -
Attachment two: [tank_two] [tank_two ? "Remove" : ""] -
Valve attachment: [attached_device ? "[attached_device]" : "None"] [attached_device ? "Remove" : ""] -
Valve status: [ valve_open ? "Closed Open" : "Closed Open"]"} - - var/datum/browser/popup = new(user, "trans_valve", name) - popup.set_content(dat) - popup.open() - return - -/obj/item/device/transfer_valve/Topic(href, href_list) - ..() - if ( usr.stat || usr.restrained() ) - return - if (src.loc == usr) - if(tank_one && href_list["tankone"]) - split_gases() - valve_open = 0 - tank_one.loc = get_turf(src) - tank_one = null - update_icon() - if((!tank_two || tank_two.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL)) - w_class = WEIGHT_CLASS_NORMAL - else if(tank_two && href_list["tanktwo"]) - split_gases() - valve_open = 0 - tank_two.loc = get_turf(src) - tank_two = null - update_icon() - if((!tank_one || tank_one.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL)) - w_class = WEIGHT_CLASS_NORMAL - else if(href_list["open"]) - toggle_valve() - else if(attached_device) - if(href_list["rem_device"]) - attached_device.loc = get_turf(src) - attached_device:holder = null - attached_device = null - update_icon() - if(href_list["device"]) - attached_device.attack_self(usr) - - src.attack_self(usr) - src.add_fingerprint(usr) - return - return - -/obj/item/device/transfer_valve/proc/process_activation(obj/item/device/D) - if(toggle) - toggle = 0 - toggle_valve() - spawn(50) // To stop a signal being spammed from a proxy sensor constantly going off or whatever - toggle = 1 - -/obj/item/device/transfer_valve/update_icon() - cut_overlays() - underlays = null - - if(!tank_one && !tank_two && !attached_device) - icon_state = "valve_1" - return - icon_state = "valve" - - if(tank_one) - add_overlay("[tank_one.icon_state]") - if(tank_two) - var/icon/J = new(icon, icon_state = "[tank_two.icon_state]") - J.Shift(WEST, 13) - underlays += J - if(attached_device) - add_overlay("device") - -/obj/item/device/transfer_valve/proc/merge_gases() - tank_two.air_contents.volume += tank_one.air_contents.volume - var/datum/gas_mixture/temp - temp = tank_one.air_contents.remove_ratio(1) - tank_two.air_contents.merge(temp) - -/obj/item/device/transfer_valve/proc/split_gases() - if (!valve_open || !tank_one || !tank_two) - return - var/ratio1 = tank_one.air_contents.volume/tank_two.air_contents.volume - var/datum/gas_mixture/temp - temp = tank_two.air_contents.remove_ratio(ratio1) - tank_one.air_contents.merge(temp) - tank_two.air_contents.volume -= tank_one.air_contents.volume - - /* - Exadv1: I know this isn't how it's going to work, but this was just to check - it explodes properly when it gets a signal (and it does). - */ - -/obj/item/device/transfer_valve/proc/toggle_valve() - if(!valve_open && tank_one && tank_two) - valve_open = 1 - var/turf/bombturf = get_turf(src) - var/area/A = get_area(bombturf) - - var/attachment = "no device" - if(attached_device) - if(istype(attached_device, /obj/item/device/assembly/signaler)) - attachment = "[attached_device]" - else - attachment = attached_device - - var/attacher_name = "" - if(!attacher) - attacher_name = "Unknown" - else - attacher_name = "[key_name_admin(attacher)]" - - var/log_str1 = "Bomb valve opened in " - var/log_str2 = "with [attachment] attacher: [attacher_name]" - - var/log_attacher = "" - if(attacher) - log_attacher = "[ADMIN_QUE(attacher)] [ADMIN_FLW(attacher)]" - - var/mob/mob = get_mob_by_key(src.fingerprintslast) - var/last_touch_info = "" - if(mob) - last_touch_info = "[ADMIN_QUE(mob)] [ADMIN_FLW(mob)]" - - var/log_str3 = " Last touched by: [key_name_admin(mob)]" - - var/bomb_message = "[log_str1] [A.name][ADMIN_JMP(bombturf)] [log_str2][log_attacher] [log_str3][last_touch_info]" - - GLOB.bombers += bomb_message - - message_admins(bomb_message, 0, 1) - log_game("[log_str1] [A.name][COORD(bombturf)] [log_str2] [log_str3]") - merge_gases() - spawn(20) // In case one tank bursts - for (var/i=0,i<5,i++) - src.update_icon() - sleep(10) - src.update_icon() - - else if(valve_open && tank_one && tank_two) - split_gases() - valve_open = 0 - src.update_icon() - -// this doesn't do anything but the timer etc. expects it to be here -// eventually maybe have it update icon to show state (timer, prox etc.) like old bombs -/obj/item/device/transfer_valve/proc/c_state() - return +/obj/item/device/transfer_valve + icon = 'icons/obj/assemblies.dmi' + name = "tank transfer valve" + icon_state = "valve_1" + item_state = "ttv" + desc = "Regulates the transfer of air between two tanks" + var/obj/item/weapon/tank/tank_one + var/obj/item/weapon/tank/tank_two + var/obj/item/device/attached_device + var/mob/attacher = null + var/valve_open = 0 + var/toggle = 1 + origin_tech = "materials=1;engineering=1" + +/obj/item/device/transfer_valve/IsAssemblyHolder() + return 1 + +/obj/item/device/transfer_valve/attackby(obj/item/item, mob/user, params) + if(istype(item, /obj/item/weapon/tank)) + if(tank_one && tank_two) + to_chat(user, "There are already two tanks attached, remove one first!") + return + + if(!tank_one) + if(!user.transferItemToLoc(item, src)) + return + tank_one = item + to_chat(user, "You attach the tank to the transfer valve.") + if(item.w_class > w_class) + w_class = item.w_class + else if(!tank_two) + if(!user.transferItemToLoc(item, src)) + return + tank_two = item + to_chat(user, "You attach the tank to the transfer valve.") + if(item.w_class > w_class) + w_class = item.w_class + + update_icon() +//TODO: Have this take an assemblyholder + else if(isassembly(item)) + var/obj/item/device/assembly/A = item + if(A.secured) + to_chat(user, "The device is secured.") + return + if(attached_device) + to_chat(user, "There is already a device attached to the valve, remove it first!") + return + if(!user.transferItemToLoc(item, src)) + return + attached_device = A + to_chat(user, "You attach the [item] to the valve controls and secure it.") + A.holder = src + A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb). + + GLOB.bombers += "[key_name(user)] attached a [item] to a transfer valve." + message_admins("[key_name_admin(user)] attached a [item] to a transfer valve.") + log_game("[key_name_admin(user)] attached a [item] to a transfer valve.") + attacher = user + return + +/obj/item/device/transfer_valve/attack_self(mob/user) + user.set_machine(src) + var/dat = {" Valve properties: +
Attachment one: [tank_one] [tank_one ? "Remove" : ""] +
Attachment two: [tank_two] [tank_two ? "Remove" : ""] +
Valve attachment: [attached_device ? "[attached_device]" : "None"] [attached_device ? "Remove" : ""] +
Valve status: [ valve_open ? "Closed Open" : "Closed Open"]"} + + var/datum/browser/popup = new(user, "trans_valve", name) + popup.set_content(dat) + popup.open() + return + +/obj/item/device/transfer_valve/Topic(href, href_list) + ..() + if ( usr.stat || usr.restrained() ) + return + if (src.loc == usr) + if(tank_one && href_list["tankone"]) + split_gases() + valve_open = 0 + tank_one.loc = get_turf(src) + tank_one = null + update_icon() + if((!tank_two || tank_two.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL)) + w_class = WEIGHT_CLASS_NORMAL + else if(tank_two && href_list["tanktwo"]) + split_gases() + valve_open = 0 + tank_two.loc = get_turf(src) + tank_two = null + update_icon() + if((!tank_one || tank_one.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL)) + w_class = WEIGHT_CLASS_NORMAL + else if(href_list["open"]) + toggle_valve() + else if(attached_device) + if(href_list["rem_device"]) + attached_device.loc = get_turf(src) + attached_device:holder = null + attached_device = null + update_icon() + if(href_list["device"]) + attached_device.attack_self(usr) + + src.attack_self(usr) + src.add_fingerprint(usr) + return + return + +/obj/item/device/transfer_valve/proc/process_activation(obj/item/device/D) + if(toggle) + toggle = 0 + toggle_valve() + spawn(50) // To stop a signal being spammed from a proxy sensor constantly going off or whatever + toggle = 1 + +/obj/item/device/transfer_valve/update_icon() + cut_overlays() + underlays = null + + if(!tank_one && !tank_two && !attached_device) + icon_state = "valve_1" + return + icon_state = "valve" + + if(tank_one) + add_overlay("[tank_one.icon_state]") + if(tank_two) + var/icon/J = new(icon, icon_state = "[tank_two.icon_state]") + J.Shift(WEST, 13) + underlays += J + if(attached_device) + add_overlay("device") + +/obj/item/device/transfer_valve/proc/merge_gases() + tank_two.air_contents.volume += tank_one.air_contents.volume + var/datum/gas_mixture/temp + temp = tank_one.air_contents.remove_ratio(1) + tank_two.air_contents.merge(temp) + +/obj/item/device/transfer_valve/proc/split_gases() + if (!valve_open || !tank_one || !tank_two) + return + var/ratio1 = tank_one.air_contents.volume/tank_two.air_contents.volume + var/datum/gas_mixture/temp + temp = tank_two.air_contents.remove_ratio(ratio1) + tank_one.air_contents.merge(temp) + tank_two.air_contents.volume -= tank_one.air_contents.volume + + /* + Exadv1: I know this isn't how it's going to work, but this was just to check + it explodes properly when it gets a signal (and it does). + */ + +/obj/item/device/transfer_valve/proc/toggle_valve() + if(!valve_open && tank_one && tank_two) + valve_open = 1 + var/turf/bombturf = get_turf(src) + var/area/A = get_area(bombturf) + + var/attachment = "no device" + if(attached_device) + if(istype(attached_device, /obj/item/device/assembly/signaler)) + attachment = "[attached_device]" + else + attachment = attached_device + + var/attacher_name = "" + if(!attacher) + attacher_name = "Unknown" + else + attacher_name = "[key_name_admin(attacher)]" + + var/log_str1 = "Bomb valve opened in " + var/log_str2 = "with [attachment] attacher: [attacher_name]" + + var/log_attacher = "" + if(attacher) + log_attacher = "[ADMIN_QUE(attacher)] [ADMIN_FLW(attacher)]" + + var/mob/mob = get_mob_by_key(src.fingerprintslast) + var/last_touch_info = "" + if(mob) + last_touch_info = "[ADMIN_QUE(mob)] [ADMIN_FLW(mob)]" + + var/log_str3 = " Last touched by: [key_name_admin(mob)]" + + var/bomb_message = "[log_str1] [A.name][ADMIN_JMP(bombturf)] [log_str2][log_attacher] [log_str3][last_touch_info]" + + GLOB.bombers += bomb_message + + message_admins(bomb_message, 0, 1) + log_game("[log_str1] [A.name][COORD(bombturf)] [log_str2] [log_str3]") + merge_gases() + spawn(20) // In case one tank bursts + for (var/i=0,i<5,i++) + src.update_icon() + sleep(10) + src.update_icon() + + else if(valve_open && tank_one && tank_two) + split_gases() + valve_open = 0 + src.update_icon() + +// this doesn't do anything but the timer etc. expects it to be here +// eventually maybe have it update icon to show state (timer, prox etc.) like old bombs +/obj/item/device/transfer_valve/proc/c_state() + return diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index f0fd4947f2..c50ef26b81 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -50,7 +50,7 @@ M.dna.uni_identity = merge_text(M.dna.uni_identity, fields["UI"]) M.updateappearance(mutations_overlay_update=1) log_attack(log_msg) - return TRUE + return TRUE /obj/item/weapon/dnainjector/attack(mob/target, mob/user) if(!user.IsAdvancedToolUser()) @@ -77,9 +77,9 @@ add_logs(user, target, "injected", src) - if(!inject(target, user)) //Now we actually do the heavy lifting. - to_chat(user, "It appears that [target] does not have compatible DNA.") - + if(!inject(target, user)) //Now we actually do the heavy lifting. + to_chat(user, "It appears that [target] does not have compatible DNA.") + used = 1 icon_state = "dnainjector0" desc += " This one is used up." diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm index 81ccd127c8..a5f5eb6133 100644 --- a/code/game/objects/items/weapons/grenades/grenade.dm +++ b/code/game/objects/items/weapons/grenades/grenade.dm @@ -48,27 +48,27 @@ /obj/item/weapon/grenade/attack_self(mob/user) if(!active) if(clown_check(user)) - preprime(user) + preprime(user) if(iscarbon(user)) var/mob/living/carbon/C = user C.throw_mode_on() -/obj/item/weapon/grenade/proc/preprime(mob/user) - if(user) - to_chat(user, "You prime the [name]! [det_time/10] seconds!") - playsound(loc, 'sound/weapons/armbomb.ogg', 60, 1) - active = TRUE - icon_state = initial(icon_state) + "_active" - add_fingerprint(user) - var/turf/bombturf = get_turf(src) - var/area/A = get_area(bombturf) - if(user) - var/message = "[ADMIN_LOOKUPFLW(user)]) has primed a [name] for detonation at [ADMIN_COORDJMP(bombturf)]" - GLOB.bombers += message - message_admins(message) - log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].") - - addtimer(CALLBACK(src, .proc/prime), det_time) +/obj/item/weapon/grenade/proc/preprime(mob/user) + if(user) + to_chat(user, "You prime the [name]! [det_time/10] seconds!") + playsound(loc, 'sound/weapons/armbomb.ogg', 60, 1) + active = TRUE + icon_state = initial(icon_state) + "_active" + add_fingerprint(user) + var/turf/bombturf = get_turf(src) + var/area/A = get_area(bombturf) + if(user) + var/message = "[ADMIN_LOOKUPFLW(user)]) has primed a [name] for detonation at [ADMIN_COORDJMP(bombturf)]" + GLOB.bombers += message + message_admins(message) + log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].") + + addtimer(CALLBACK(src, .proc/prime), det_time) /obj/item/weapon/grenade/proc/prime() @@ -108,4 +108,4 @@ if(damage && attack_type == PROJECTILE_ATTACK && prob(15)) owner.visible_message("[attack_text] hits [owner]'s [src], setting it off! What a shot!") prime() - return 1 //It hit the grenade, not them + return 1 //It hit the grenade, not them diff --git a/code/game/objects/items/weapons/implants/implantchair.dm b/code/game/objects/items/weapons/implants/implantchair.dm index 2cc1e7824f..9d7516faac 100644 --- a/code/game/objects/items/weapons/implants/implantchair.dm +++ b/code/game/objects/items/weapons/implants/implantchair.dm @@ -1,189 +1,189 @@ -/obj/machinery/implantchair - name = "mindshield implanter" - desc = "Used to implant occupants with mindshield implants." - icon = 'icons/obj/machines/implantchair.dmi' - icon_state = "implantchair" - density = 1 - opacity = 0 - anchored = TRUE - - var/ready = TRUE - var/replenishing = FALSE - - var/ready_implants = 5 - var/max_implants = 5 - var/injection_cooldown = 600 - var/replenish_cooldown = 6000 - var/implant_type = /obj/item/weapon/implant/mindshield - var/auto_inject = FALSE - var/auto_replenish = TRUE - var/special = FALSE - var/special_name = "special function" - -/obj/machinery/implantchair/New() - ..() - open_machine() - update_icon() - - -/obj/machinery/implantchair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \ - datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state) - - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "implantchair", name, 375, 280, master_ui, state) - ui.open() - - -/obj/machinery/implantchair/ui_data() - var/list/data = list() - data["occupied"] = occupant ? 1 : 0 - data["open"] = state_open - - data["occupant"] = list() - if(occupant) - var/mob/living/mob_occupant = occupant - data["occupant"]["name"] = mob_occupant.name - data["occupant"]["stat"] = mob_occupant.stat - - data["special_name"] = special ? special_name : null - data["ready_implants"] = ready_implants - data["ready"] = ready - data["replenishing"] = replenishing - - return data - -/obj/machinery/implantchair/ui_act(action, params) - if(..()) - return - switch(action) - if("door") - if(state_open) - close_machine() - else - open_machine() - . = TRUE - if("implant") - implant(occupant,usr) - . = TRUE - -/obj/machinery/implantchair/proc/implant(mob/living/M,mob/user) - if (!istype(M)) - return - if(!ready_implants || !ready) - return - if(implant_action(M,user)) - ready_implants-- - if(!replenishing && auto_replenish) - replenishing = TRUE - addtimer(CALLBACK(src,"replenish"),replenish_cooldown) - if(injection_cooldown > 0) - ready = FALSE - addtimer(CALLBACK(src,"set_ready"),injection_cooldown) - else - playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, 1) - update_icon() - -/obj/machinery/implantchair/proc/implant_action(mob/living/M) - var/obj/item/weapon/implant/I = new implant_type - if(I.implant(M)) - visible_message("[M] has been implanted by the [name].") - return 1 - -/obj/machinery/implantchair/update_icon() - icon_state = initial(icon_state) - if(state_open) - icon_state += "_open" - if(occupant) - icon_state += "_occupied" - if(ready) - add_overlay("ready") - else - cut_overlays() - -/obj/machinery/implantchair/proc/replenish() - if(ready_implants < max_implants) - ready_implants++ - if(ready_implants < max_implants) - addtimer(CALLBACK(src,"replenish"),replenish_cooldown) - else - replenishing = FALSE - -/obj/machinery/implantchair/proc/set_ready() - ready = TRUE - update_icon() - -/obj/machinery/implantchair/container_resist(mob/living/user) - if(state_open) - return - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT - to_chat(user, "You lean on the back of [src] and start pushing the door open... (this will take about about a minute.)") - audible_message("You hear a metallic creaking from [src]!",hearing_distance = 2) - - if(do_after(user, 600, target = src)) - if(!user || user.stat != CONSCIOUS || user.loc != src || state_open) - return - visible_message("[user] successfully broke out of [src]!") - to_chat(user, "You successfully break out of [src]!") - open_machine() - -/obj/machinery/implantchair/relaymove(mob/user) - container_resist(user) - -/obj/machinery/implantchair/MouseDrop_T(mob/target, mob/user) - if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !isliving(target) || !user.IsAdvancedToolUser()) - return - close_machine(target) - -/obj/machinery/implantchair/close_machine(mob/living/user) - if((isnull(user) || istype(user)) && state_open) - ..(user) - if(auto_inject && ready && ready_implants > 0) - implant(user,null) - -/obj/machinery/implantchair/genepurge - name = "Genetic purifier" - desc = "Used to purge human genome of foreign influences" - special = TRUE - special_name = "Purge genome" - injection_cooldown = 0 - replenish_cooldown = 300 - -/obj/machinery/implantchair/genepurge/implant_action(mob/living/carbon/human/H,mob/user) - if(!istype(H)) - return 0 - H.set_species(/datum/species/human, 1)//lizards go home - purrbation_remove(H)//remove cats - H.dna.remove_all_mutations()//hulks out - return 1 - - -/obj/machinery/implantchair/brainwash - name = "Neural Imprinter" - desc = "Used to indoctrinate rehabilitate hardened recidivists." - special_name = "Imprint" - injection_cooldown = 3000 - auto_inject = FALSE - auto_replenish = FALSE - special = TRUE - var/objective = "Obey the law. Praise Nanotrasen." - var/custom = FALSE - -/obj/machinery/implantchair/brainwash/implant_action(mob/living/C,mob/user) - if(!istype(C) || !C.mind) // I don't know how this makes any sense for silicons but laws trump objectives anyway. - return 0 - if(custom) - if(!user || !user.Adjacent(src)) - return 0 - objective = stripped_input(usr,"What order do you want to imprint on [C]?","Enter the order","",120) - message_admins("[key_name_admin(user)] set brainwash machine objective to '[objective]'.") - log_game("[key_name_admin(user)] set brainwash machine objective to '[objective]'.") - var/datum/objective/custom_objective = new/datum/objective(objective) - custom_objective.owner = C.mind - C.mind.objectives += custom_objective - C.mind.announce_objectives() - message_admins("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.") - log_game("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.") - return 1 - +/obj/machinery/implantchair + name = "mindshield implanter" + desc = "Used to implant occupants with mindshield implants." + icon = 'icons/obj/machines/implantchair.dmi' + icon_state = "implantchair" + density = 1 + opacity = 0 + anchored = TRUE + + var/ready = TRUE + var/replenishing = FALSE + + var/ready_implants = 5 + var/max_implants = 5 + var/injection_cooldown = 600 + var/replenish_cooldown = 6000 + var/implant_type = /obj/item/weapon/implant/mindshield + var/auto_inject = FALSE + var/auto_replenish = TRUE + var/special = FALSE + var/special_name = "special function" + +/obj/machinery/implantchair/New() + ..() + open_machine() + update_icon() + + +/obj/machinery/implantchair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \ + datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state) + + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "implantchair", name, 375, 280, master_ui, state) + ui.open() + + +/obj/machinery/implantchair/ui_data() + var/list/data = list() + data["occupied"] = occupant ? 1 : 0 + data["open"] = state_open + + data["occupant"] = list() + if(occupant) + var/mob/living/mob_occupant = occupant + data["occupant"]["name"] = mob_occupant.name + data["occupant"]["stat"] = mob_occupant.stat + + data["special_name"] = special ? special_name : null + data["ready_implants"] = ready_implants + data["ready"] = ready + data["replenishing"] = replenishing + + return data + +/obj/machinery/implantchair/ui_act(action, params) + if(..()) + return + switch(action) + if("door") + if(state_open) + close_machine() + else + open_machine() + . = TRUE + if("implant") + implant(occupant,usr) + . = TRUE + +/obj/machinery/implantchair/proc/implant(mob/living/M,mob/user) + if (!istype(M)) + return + if(!ready_implants || !ready) + return + if(implant_action(M,user)) + ready_implants-- + if(!replenishing && auto_replenish) + replenishing = TRUE + addtimer(CALLBACK(src,"replenish"),replenish_cooldown) + if(injection_cooldown > 0) + ready = FALSE + addtimer(CALLBACK(src,"set_ready"),injection_cooldown) + else + playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, 1) + update_icon() + +/obj/machinery/implantchair/proc/implant_action(mob/living/M) + var/obj/item/weapon/implant/I = new implant_type + if(I.implant(M)) + visible_message("[M] has been implanted by the [name].") + return 1 + +/obj/machinery/implantchair/update_icon() + icon_state = initial(icon_state) + if(state_open) + icon_state += "_open" + if(occupant) + icon_state += "_occupied" + if(ready) + add_overlay("ready") + else + cut_overlays() + +/obj/machinery/implantchair/proc/replenish() + if(ready_implants < max_implants) + ready_implants++ + if(ready_implants < max_implants) + addtimer(CALLBACK(src,"replenish"),replenish_cooldown) + else + replenishing = FALSE + +/obj/machinery/implantchair/proc/set_ready() + ready = TRUE + update_icon() + +/obj/machinery/implantchair/container_resist(mob/living/user) + if(state_open) + return + user.changeNext_move(CLICK_CD_BREAKOUT) + user.last_special = world.time + CLICK_CD_BREAKOUT + to_chat(user, "You lean on the back of [src] and start pushing the door open... (this will take about about a minute.)") + audible_message("You hear a metallic creaking from [src]!",hearing_distance = 2) + + if(do_after(user, 600, target = src)) + if(!user || user.stat != CONSCIOUS || user.loc != src || state_open) + return + visible_message("[user] successfully broke out of [src]!") + to_chat(user, "You successfully break out of [src]!") + open_machine() + +/obj/machinery/implantchair/relaymove(mob/user) + container_resist(user) + +/obj/machinery/implantchair/MouseDrop_T(mob/target, mob/user) + if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !isliving(target) || !user.IsAdvancedToolUser()) + return + close_machine(target) + +/obj/machinery/implantchair/close_machine(mob/living/user) + if((isnull(user) || istype(user)) && state_open) + ..(user) + if(auto_inject && ready && ready_implants > 0) + implant(user,null) + +/obj/machinery/implantchair/genepurge + name = "Genetic purifier" + desc = "Used to purge human genome of foreign influences" + special = TRUE + special_name = "Purge genome" + injection_cooldown = 0 + replenish_cooldown = 300 + +/obj/machinery/implantchair/genepurge/implant_action(mob/living/carbon/human/H,mob/user) + if(!istype(H)) + return 0 + H.set_species(/datum/species/human, 1)//lizards go home + purrbation_remove(H)//remove cats + H.dna.remove_all_mutations()//hulks out + return 1 + + +/obj/machinery/implantchair/brainwash + name = "Neural Imprinter" + desc = "Used to indoctrinate rehabilitate hardened recidivists." + special_name = "Imprint" + injection_cooldown = 3000 + auto_inject = FALSE + auto_replenish = FALSE + special = TRUE + var/objective = "Obey the law. Praise Nanotrasen." + var/custom = FALSE + +/obj/machinery/implantchair/brainwash/implant_action(mob/living/C,mob/user) + if(!istype(C) || !C.mind) // I don't know how this makes any sense for silicons but laws trump objectives anyway. + return 0 + if(custom) + if(!user || !user.Adjacent(src)) + return 0 + objective = stripped_input(usr,"What order do you want to imprint on [C]?","Enter the order","",120) + message_admins("[key_name_admin(user)] set brainwash machine objective to '[objective]'.") + log_game("[key_name_admin(user)] set brainwash machine objective to '[objective]'.") + var/datum/objective/custom_objective = new/datum/objective(objective) + custom_objective.owner = C.mind + C.mind.objectives += custom_objective + C.mind.announce_objectives() + message_admins("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.") + log_game("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.") + return 1 + diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index 1962fbd818..90e7d1be1a 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -1,305 +1,305 @@ -/obj/item/weapon/storage/box/syndicate - -/obj/item/weapon/storage/box/syndicate/PopulateContents() - switch (pickweight(list("bloodyspai" = 3, "stealth" = 2, "bond" = 2, "screwed" = 2, "sabotage" = 3, "guns" = 2, "murder" = 2, "implant" = 1, "hacker" = 3, "darklord" = 1, "sniper" = 1, "metaops" = 1, "ninja" = 1))) - if("bloodyspai") // 27 tc now this is more right - new /obj/item/clothing/under/chameleon(src) // 2 tc since it's not the full set - new /obj/item/clothing/mask/chameleon(src) // Goes with above - new /obj/item/weapon/card/id/syndicate(src) // 2 tc - new /obj/item/clothing/shoes/chameleon(src) // 2 tc - new /obj/item/device/camera_bug(src) // 1 tc - new /obj/item/device/multitool/ai_detect(src) // 1 tc - new /obj/item/device/encryptionkey/syndicate(src) // 2 tc - new /obj/item/weapon/reagent_containers/syringe/mulligan(src) // 4 tc - new /obj/item/weapon/switchblade(src) //I'll count this as 2 tc - new /obj/item/weapon/storage/fancy/cigarettes/cigpack_syndicate (src) // 2 tc this shit heals - new /obj/item/device/flashlight/emp(src) // 2 tc - new /obj/item/device/chameleon(src) // 7 tc - - if("stealth") // 31 tc - new /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow(src) - new /obj/item/weapon/pen/sleepy(src) - new /obj/item/device/healthanalyzer/rad_laser(src) - new /obj/item/device/chameleon(src) - new /obj/item/weapon/soap/syndie(src) - new /obj/item/clothing/glasses/thermal/syndi(src) - - if("bond") // 29 tc - new /obj/item/weapon/gun/ballistic/automatic/pistol(src) - new /obj/item/weapon/suppressor(src) - new /obj/item/ammo_box/magazine/m10mm(src) - new /obj/item/ammo_box/magazine/m10mm(src) - new /obj/item/clothing/under/chameleon(src) - new /obj/item/weapon/card/id/syndicate(src) - new /obj/item/weapon/reagent_containers/syringe/stimulants(src) - - if("screwed") // 29 tc - new /obj/item/device/sbeacondrop/bomb(src) - new /obj/item/weapon/grenade/syndieminibomb(src) - new /obj/item/device/sbeacondrop/powersink(src) - new /obj/item/clothing/suit/space/syndicate/black/red(src) - new /obj/item/clothing/head/helmet/space/syndicate/black/red(src) - new /obj/item/device/encryptionkey/syndicate(src) - - if("guns") // 28 tc now - new /obj/item/weapon/gun/ballistic/revolver(src) - new /obj/item/ammo_box/a357(src) - new /obj/item/ammo_box/a357(src) - new /obj/item/weapon/card/emag(src) - new /obj/item/weapon/grenade/plastic/c4(src) - new /obj/item/clothing/gloves/color/latex/nitrile(src) - new /obj/item/clothing/mask/gas/clown_hat(src) - new /obj/item/clothing/under/suit_jacket/really_black(src) - - if("murder") // 28 tc now - new /obj/item/weapon/melee/energy/sword/saber(src) - new /obj/item/clothing/glasses/thermal/syndi(src) - new /obj/item/weapon/card/emag(src) - new /obj/item/clothing/shoes/chameleon(src) - new /obj/item/device/encryptionkey/syndicate(src) - new /obj/item/weapon/grenade/syndieminibomb(src) - - if("implant") // 55+ tc holy shit what the fuck this is a lottery disguised as fun boxes isn't it? - new /obj/item/weapon/implanter/freedom(src) - new /obj/item/weapon/implanter/uplink/precharged(src) - new /obj/item/weapon/implanter/emp(src) - new /obj/item/weapon/implanter/adrenalin(src) - new /obj/item/weapon/implanter/explosive(src) - new /obj/item/weapon/implanter/storage(src) - - if("hacker") // 26 tc - new /obj/item/weapon/aiModule/syndicate(src) - new /obj/item/weapon/card/emag(src) - new /obj/item/device/encryptionkey/binary(src) - new /obj/item/weapon/aiModule/toyAI(src) - new /obj/item/device/multitool/ai_detect(src) - - if("lordsingulo") // 24 tc - new /obj/item/device/sbeacondrop(src) - new /obj/item/clothing/suit/space/syndicate/black/red(src) - new /obj/item/clothing/head/helmet/space/syndicate/black/red(src) - new /obj/item/weapon/card/emag(src) - - if("sabotage") // 26 tc now - new /obj/item/weapon/grenade/plastic/c4 (src) - new /obj/item/weapon/grenade/plastic/c4 (src) - new /obj/item/device/doorCharge(src) - new /obj/item/device/doorCharge(src) - new /obj/item/device/camera_bug(src) - new /obj/item/device/sbeacondrop/powersink(src) - new /obj/item/weapon/cartridge/syndicate(src) - new /obj/item/weapon/storage/toolbox/syndicate(src) //To actually get to those places - new /obj/item/pizzabox/bomb - - if("darklord") //20 tc + tk + summon item close enough for now - new /obj/item/weapon/twohanded/dualsaber(src) - new /obj/item/weapon/dnainjector/telemut/darkbundle(src) - new /obj/item/clothing/suit/hooded/chaplain_hoodie(src) - new /obj/item/weapon/card/id/syndicate(src) - new /obj/item/clothing/shoes/chameleon(src) //because slipping while being a dark lord sucks - new /obj/item/weapon/spellbook/oneuse/summonitem(src) - - if("sniper") //This shit is unique so can't really balance it around tc, also no silencer because getting killed without ANY indicator on what killed you sucks - new /obj/item/weapon/gun/ballistic/automatic/sniper_rifle(src) // 12 tc - new /obj/item/ammo_box/magazine/sniper_rounds/penetrator(src) - new /obj/item/clothing/glasses/thermal/syndi(src) - new /obj/item/clothing/gloves/color/latex/nitrile(src) - new /obj/item/clothing/mask/gas/clown_hat(src) - new /obj/item/clothing/under/suit_jacket/really_black(src) - - if("metaops") // 30 tc - new /obj/item/clothing/suit/space/hardsuit/syndi(src) // 8 tc - new /obj/item/weapon/gun/ballistic/automatic/shotgun/bulldog/unrestricted(src) // 8 tc - new /obj/item/weapon/implanter/explosive(src) // 2 tc - new /obj/item/ammo_box/magazine/m12g/buckshot(src) // 2 tc - new /obj/item/ammo_box/magazine/m12g/buckshot(src) // 2 tc - new /obj/item/weapon/grenade/plastic/c4 (src) // 1 tc - new /obj/item/weapon/grenade/plastic/c4 (src) // 1 tc - new /obj/item/weapon/card/emag(src) // 6 tc - - if("ninja") // 33 tc worth - new /obj/item/weapon/katana(src) // Unique , hard to tell how much tc this is worth. 8 tc? - new /obj/item/weapon/implanter/adrenalin(src) // 8 tc - new /obj/item/weapon/throwing_star(src) // ~5 tc for all 6 - new /obj/item/weapon/throwing_star(src) - new /obj/item/weapon/throwing_star(src) - new /obj/item/weapon/throwing_star(src) - new /obj/item/weapon/throwing_star(src) - new /obj/item/weapon/throwing_star(src) - new /obj/item/weapon/storage/belt/chameleon(src) // Unique but worth at least 2 tc - new /obj/item/weapon/card/id/syndicate(src) // 2 tc - new /obj/item/device/chameleon(src) // 7 tc - -/obj/item/weapon/storage/box/syndie_kit - name = "box" - desc = "A sleek, sturdy box." - icon_state = "syndiebox" - illustration = "writing_syndie" - -/obj/item/weapon/storage/box/syndie_kit/imp_freedom - name = "boxed freedom implant (with injector)" - -/obj/item/weapon/storage/box/syndie_kit/imp_freedom/PopulateContents() - var/obj/item/weapon/implanter/O = new(src) - O.imp = new /obj/item/weapon/implant/freedom(O) - O.update_icon() - -/obj/item/weapon/storage/box/syndie_kit/imp_microbomb - name = "Microbomb Implant (with injector)" - -/obj/item/weapon/storage/box/syndie_kit/imp_microbomb/PopulateContents() - var/obj/item/weapon/implanter/O = new(src) - O.imp = new /obj/item/weapon/implant/explosive(O) - O.update_icon() - -/obj/item/weapon/storage/box/syndie_kit/imp_macrobomb - name = "Macrobomb Implant (with injector)" - -/obj/item/weapon/storage/box/syndie_kit/imp_macrobomb/PopulateContents() - var/obj/item/weapon/implanter/O = new(src) - O.imp = new /obj/item/weapon/implant/explosive/macro(O) - O.update_icon() - -/obj/item/weapon/storage/box/syndie_kit/imp_uplink - name = "boxed uplink implant (with injector)" - -/obj/item/weapon/storage/box/syndie_kit/imp_uplink/PopulateContents() - ..() - var/obj/item/weapon/implanter/O = new(src) - O.imp = new /obj/item/weapon/implant/uplink(O) - O.update_icon() - -/obj/item/weapon/storage/box/syndie_kit/bioterror - name = "bioterror syringe box" - -/obj/item/weapon/storage/box/syndie_kit/bioterror/PopulateContents() - for(var/i in 1 to 7) - new /obj/item/weapon/reagent_containers/syringe/bioterror(src) - -/obj/item/weapon/storage/box/syndie_kit/imp_adrenal - name = "boxed adrenal implant (with injector)" - -/obj/item/weapon/storage/box/syndie_kit/imp_adrenal/PopulateContents() - var/obj/item/weapon/implanter/O = new(src) - O.imp = new /obj/item/weapon/implant/adrenalin(O) - O.update_icon() - -/obj/item/weapon/storage/box/syndie_kit/imp_storage - name = "boxed storage implant (with injector)" - -/obj/item/weapon/storage/box/syndie_kit/imp_storage/PopulateContents() - new /obj/item/weapon/implanter/storage(src) - -/obj/item/weapon/storage/box/syndie_kit/space - name = "boxed space suit and helmet" - can_hold = list(/obj/item/clothing/suit/space/syndicate, /obj/item/clothing/head/helmet/space/syndicate) - max_w_class = WEIGHT_CLASS_NORMAL - -/obj/item/weapon/storage/box/syndie_kit/space/PopulateContents() - new /obj/item/clothing/suit/space/syndicate/black/red(src) // Black and red is so in right now - new /obj/item/clothing/head/helmet/space/syndicate/black/red(src) - -/obj/item/weapon/storage/box/syndie_kit/emp - name = "boxed EMP kit" - -/obj/item/weapon/storage/box/syndie_kit/emp/PopulateContents() - new /obj/item/weapon/grenade/empgrenade(src) - new /obj/item/weapon/grenade/empgrenade(src) - new /obj/item/weapon/grenade/empgrenade(src) - new /obj/item/weapon/grenade/empgrenade(src) - new /obj/item/weapon/grenade/empgrenade(src) - new /obj/item/weapon/implanter/emp(src) - -/obj/item/weapon/storage/box/syndie_kit/chemical - name = "boxed chemical kit" - storage_slots = 14 - -/obj/item/weapon/storage/box/syndie_kit/chemical/PopulateContents() - new /obj/item/weapon/reagent_containers/glass/bottle/polonium(src) - new /obj/item/weapon/reagent_containers/glass/bottle/venom(src) - new /obj/item/weapon/reagent_containers/glass/bottle/neurotoxin2(src) - new /obj/item/weapon/reagent_containers/glass/bottle/formaldehyde(src) - new /obj/item/weapon/reagent_containers/glass/bottle/spewium(src) - new /obj/item/weapon/reagent_containers/glass/bottle/cyanide(src) - new /obj/item/weapon/reagent_containers/glass/bottle/histamine(src) - new /obj/item/weapon/reagent_containers/glass/bottle/initropidril(src) - new /obj/item/weapon/reagent_containers/glass/bottle/pancuronium(src) - new /obj/item/weapon/reagent_containers/glass/bottle/sodium_thiopental(src) - new /obj/item/weapon/reagent_containers/glass/bottle/coniine(src) - new /obj/item/weapon/reagent_containers/glass/bottle/curare(src) - new /obj/item/weapon/reagent_containers/glass/bottle/amanitin(src) - new /obj/item/weapon/reagent_containers/syringe(src) - -/obj/item/weapon/storage/box/syndie_kit/nuke - name = "box" - -/obj/item/weapon/storage/box/syndie_kit/nuke/PopulateContents() - new /obj/item/weapon/screwdriver/nuke(src) - new /obj/item/nuke_core_container(src) - new /obj/item/weapon/paper/nuke_instructions(src) - -/obj/item/weapon/storage/box/syndie_kit/tuberculosisgrenade - name = "boxed virus grenade kit" - -/obj/item/weapon/storage/box/syndie_kit/tuberculosisgrenade/PopulateContents() - new /obj/item/weapon/grenade/chem_grenade/tuberculosis(src) - for(var/i in 1 to 5) - new /obj/item/weapon/reagent_containers/hypospray/medipen/tuberculosiscure(src) - new /obj/item/weapon/reagent_containers/syringe(src) - new /obj/item/weapon/reagent_containers/glass/bottle/tuberculosiscure(src) - -/obj/item/weapon/storage/box/syndie_kit/chameleon - name = "chameleon kit" - -/obj/item/weapon/storage/box/syndie_kit/chameleon/PopulateContents() - new /obj/item/clothing/under/chameleon(src) - new /obj/item/clothing/suit/chameleon(src) - new /obj/item/clothing/gloves/chameleon(src) - new /obj/item/clothing/shoes/chameleon(src) - new /obj/item/clothing/glasses/chameleon(src) - new /obj/item/clothing/head/chameleon(src) - new /obj/item/clothing/mask/chameleon(src) - new /obj/item/weapon/storage/backpack/chameleon(src) - new /obj/item/device/radio/headset/chameleon(src) - new /obj/item/weapon/stamp/chameleon(src) - new /obj/item/device/pda/chameleon(src) - new /obj/item/weapon/gun/energy/laser/chameleon(src) - -//5*(2*4) = 5*8 = 45, 45 damage if you hit one person with all 5 stars. -//Not counting the damage it will do while embedded (2*4 = 8, at 15% chance) -/obj/item/weapon/storage/box/syndie_kit/throwing_weapons/PopulateContents() - new /obj/item/weapon/throwing_star(src) - new /obj/item/weapon/throwing_star(src) - new /obj/item/weapon/throwing_star(src) - new /obj/item/weapon/throwing_star(src) - new /obj/item/weapon/throwing_star(src) - new /obj/item/weapon/restraints/legcuffs/bola/tactical(src) - new /obj/item/weapon/restraints/legcuffs/bola/tactical(src) - -/obj/item/weapon/storage/box/syndie_kit/cutouts/PopulateContents() - for(var/i in 1 to 3) - new/obj/item/cardboard_cutout/adaptive(src) - new/obj/item/toy/crayon/rainbow(src) - -/obj/item/weapon/storage/box/syndie_kit/romerol/PopulateContents() - new /obj/item/weapon/reagent_containers/glass/bottle/romerol(src) - new /obj/item/weapon/reagent_containers/syringe(src) - new /obj/item/weapon/reagent_containers/dropper(src) - -/obj/item/weapon/storage/box/syndie_kit/ez_clean/PopulateContents() - for(var/i in 1 to 3) - new/obj/item/weapon/grenade/chem_grenade/ez_clean(src) - -/obj/item/weapon/storage/box/hug/reverse_revolver/PopulateContents() - new /obj/item/weapon/gun/ballistic/revolver/reverse(src) - -/obj/item/weapon/storage/box/syndie_kit/mimery/PopulateContents() - new /obj/item/weapon/spellbook/oneuse/mimery_blockade(src) - new /obj/item/weapon/spellbook/oneuse/mimery_guns(src) - -/obj/item/weapon/storage/box/syndie_kit/holoparasite - name = "box" - -/obj/item/weapon/storage/box/syndie_kit/holoparasite/PopulateContents() - new /obj/item/weapon/guardiancreator/tech/choose/traitor(src) +/obj/item/weapon/storage/box/syndicate + +/obj/item/weapon/storage/box/syndicate/PopulateContents() + switch (pickweight(list("bloodyspai" = 3, "stealth" = 2, "bond" = 2, "screwed" = 2, "sabotage" = 3, "guns" = 2, "murder" = 2, "implant" = 1, "hacker" = 3, "darklord" = 1, "sniper" = 1, "metaops" = 1, "ninja" = 1))) + if("bloodyspai") // 27 tc now this is more right + new /obj/item/clothing/under/chameleon(src) // 2 tc since it's not the full set + new /obj/item/clothing/mask/chameleon(src) // Goes with above + new /obj/item/weapon/card/id/syndicate(src) // 2 tc + new /obj/item/clothing/shoes/chameleon(src) // 2 tc + new /obj/item/device/camera_bug(src) // 1 tc + new /obj/item/device/multitool/ai_detect(src) // 1 tc + new /obj/item/device/encryptionkey/syndicate(src) // 2 tc + new /obj/item/weapon/reagent_containers/syringe/mulligan(src) // 4 tc + new /obj/item/weapon/switchblade(src) //I'll count this as 2 tc + new /obj/item/weapon/storage/fancy/cigarettes/cigpack_syndicate (src) // 2 tc this shit heals + new /obj/item/device/flashlight/emp(src) // 2 tc + new /obj/item/device/chameleon(src) // 7 tc + + if("stealth") // 31 tc + new /obj/item/weapon/gun/energy/kinetic_accelerator/crossbow(src) + new /obj/item/weapon/pen/sleepy(src) + new /obj/item/device/healthanalyzer/rad_laser(src) + new /obj/item/device/chameleon(src) + new /obj/item/weapon/soap/syndie(src) + new /obj/item/clothing/glasses/thermal/syndi(src) + + if("bond") // 29 tc + new /obj/item/weapon/gun/ballistic/automatic/pistol(src) + new /obj/item/weapon/suppressor(src) + new /obj/item/ammo_box/magazine/m10mm(src) + new /obj/item/ammo_box/magazine/m10mm(src) + new /obj/item/clothing/under/chameleon(src) + new /obj/item/weapon/card/id/syndicate(src) + new /obj/item/weapon/reagent_containers/syringe/stimulants(src) + + if("screwed") // 29 tc + new /obj/item/device/sbeacondrop/bomb(src) + new /obj/item/weapon/grenade/syndieminibomb(src) + new /obj/item/device/sbeacondrop/powersink(src) + new /obj/item/clothing/suit/space/syndicate/black/red(src) + new /obj/item/clothing/head/helmet/space/syndicate/black/red(src) + new /obj/item/device/encryptionkey/syndicate(src) + + if("guns") // 28 tc now + new /obj/item/weapon/gun/ballistic/revolver(src) + new /obj/item/ammo_box/a357(src) + new /obj/item/ammo_box/a357(src) + new /obj/item/weapon/card/emag(src) + new /obj/item/weapon/grenade/plastic/c4(src) + new /obj/item/clothing/gloves/color/latex/nitrile(src) + new /obj/item/clothing/mask/gas/clown_hat(src) + new /obj/item/clothing/under/suit_jacket/really_black(src) + + if("murder") // 28 tc now + new /obj/item/weapon/melee/energy/sword/saber(src) + new /obj/item/clothing/glasses/thermal/syndi(src) + new /obj/item/weapon/card/emag(src) + new /obj/item/clothing/shoes/chameleon(src) + new /obj/item/device/encryptionkey/syndicate(src) + new /obj/item/weapon/grenade/syndieminibomb(src) + + if("implant") // 55+ tc holy shit what the fuck this is a lottery disguised as fun boxes isn't it? + new /obj/item/weapon/implanter/freedom(src) + new /obj/item/weapon/implanter/uplink/precharged(src) + new /obj/item/weapon/implanter/emp(src) + new /obj/item/weapon/implanter/adrenalin(src) + new /obj/item/weapon/implanter/explosive(src) + new /obj/item/weapon/implanter/storage(src) + + if("hacker") // 26 tc + new /obj/item/weapon/aiModule/syndicate(src) + new /obj/item/weapon/card/emag(src) + new /obj/item/device/encryptionkey/binary(src) + new /obj/item/weapon/aiModule/toyAI(src) + new /obj/item/device/multitool/ai_detect(src) + + if("lordsingulo") // 24 tc + new /obj/item/device/sbeacondrop(src) + new /obj/item/clothing/suit/space/syndicate/black/red(src) + new /obj/item/clothing/head/helmet/space/syndicate/black/red(src) + new /obj/item/weapon/card/emag(src) + + if("sabotage") // 26 tc now + new /obj/item/weapon/grenade/plastic/c4 (src) + new /obj/item/weapon/grenade/plastic/c4 (src) + new /obj/item/device/doorCharge(src) + new /obj/item/device/doorCharge(src) + new /obj/item/device/camera_bug(src) + new /obj/item/device/sbeacondrop/powersink(src) + new /obj/item/weapon/cartridge/syndicate(src) + new /obj/item/weapon/storage/toolbox/syndicate(src) //To actually get to those places + new /obj/item/pizzabox/bomb + + if("darklord") //20 tc + tk + summon item close enough for now + new /obj/item/weapon/twohanded/dualsaber(src) + new /obj/item/weapon/dnainjector/telemut/darkbundle(src) + new /obj/item/clothing/suit/hooded/chaplain_hoodie(src) + new /obj/item/weapon/card/id/syndicate(src) + new /obj/item/clothing/shoes/chameleon(src) //because slipping while being a dark lord sucks + new /obj/item/weapon/spellbook/oneuse/summonitem(src) + + if("sniper") //This shit is unique so can't really balance it around tc, also no silencer because getting killed without ANY indicator on what killed you sucks + new /obj/item/weapon/gun/ballistic/automatic/sniper_rifle(src) // 12 tc + new /obj/item/ammo_box/magazine/sniper_rounds/penetrator(src) + new /obj/item/clothing/glasses/thermal/syndi(src) + new /obj/item/clothing/gloves/color/latex/nitrile(src) + new /obj/item/clothing/mask/gas/clown_hat(src) + new /obj/item/clothing/under/suit_jacket/really_black(src) + + if("metaops") // 30 tc + new /obj/item/clothing/suit/space/hardsuit/syndi(src) // 8 tc + new /obj/item/weapon/gun/ballistic/automatic/shotgun/bulldog/unrestricted(src) // 8 tc + new /obj/item/weapon/implanter/explosive(src) // 2 tc + new /obj/item/ammo_box/magazine/m12g/buckshot(src) // 2 tc + new /obj/item/ammo_box/magazine/m12g/buckshot(src) // 2 tc + new /obj/item/weapon/grenade/plastic/c4 (src) // 1 tc + new /obj/item/weapon/grenade/plastic/c4 (src) // 1 tc + new /obj/item/weapon/card/emag(src) // 6 tc + + if("ninja") // 33 tc worth + new /obj/item/weapon/katana(src) // Unique , hard to tell how much tc this is worth. 8 tc? + new /obj/item/weapon/implanter/adrenalin(src) // 8 tc + new /obj/item/weapon/throwing_star(src) // ~5 tc for all 6 + new /obj/item/weapon/throwing_star(src) + new /obj/item/weapon/throwing_star(src) + new /obj/item/weapon/throwing_star(src) + new /obj/item/weapon/throwing_star(src) + new /obj/item/weapon/throwing_star(src) + new /obj/item/weapon/storage/belt/chameleon(src) // Unique but worth at least 2 tc + new /obj/item/weapon/card/id/syndicate(src) // 2 tc + new /obj/item/device/chameleon(src) // 7 tc + +/obj/item/weapon/storage/box/syndie_kit + name = "box" + desc = "A sleek, sturdy box." + icon_state = "syndiebox" + illustration = "writing_syndie" + +/obj/item/weapon/storage/box/syndie_kit/imp_freedom + name = "boxed freedom implant (with injector)" + +/obj/item/weapon/storage/box/syndie_kit/imp_freedom/PopulateContents() + var/obj/item/weapon/implanter/O = new(src) + O.imp = new /obj/item/weapon/implant/freedom(O) + O.update_icon() + +/obj/item/weapon/storage/box/syndie_kit/imp_microbomb + name = "Microbomb Implant (with injector)" + +/obj/item/weapon/storage/box/syndie_kit/imp_microbomb/PopulateContents() + var/obj/item/weapon/implanter/O = new(src) + O.imp = new /obj/item/weapon/implant/explosive(O) + O.update_icon() + +/obj/item/weapon/storage/box/syndie_kit/imp_macrobomb + name = "Macrobomb Implant (with injector)" + +/obj/item/weapon/storage/box/syndie_kit/imp_macrobomb/PopulateContents() + var/obj/item/weapon/implanter/O = new(src) + O.imp = new /obj/item/weapon/implant/explosive/macro(O) + O.update_icon() + +/obj/item/weapon/storage/box/syndie_kit/imp_uplink + name = "boxed uplink implant (with injector)" + +/obj/item/weapon/storage/box/syndie_kit/imp_uplink/PopulateContents() + ..() + var/obj/item/weapon/implanter/O = new(src) + O.imp = new /obj/item/weapon/implant/uplink(O) + O.update_icon() + +/obj/item/weapon/storage/box/syndie_kit/bioterror + name = "bioterror syringe box" + +/obj/item/weapon/storage/box/syndie_kit/bioterror/PopulateContents() + for(var/i in 1 to 7) + new /obj/item/weapon/reagent_containers/syringe/bioterror(src) + +/obj/item/weapon/storage/box/syndie_kit/imp_adrenal + name = "boxed adrenal implant (with injector)" + +/obj/item/weapon/storage/box/syndie_kit/imp_adrenal/PopulateContents() + var/obj/item/weapon/implanter/O = new(src) + O.imp = new /obj/item/weapon/implant/adrenalin(O) + O.update_icon() + +/obj/item/weapon/storage/box/syndie_kit/imp_storage + name = "boxed storage implant (with injector)" + +/obj/item/weapon/storage/box/syndie_kit/imp_storage/PopulateContents() + new /obj/item/weapon/implanter/storage(src) + +/obj/item/weapon/storage/box/syndie_kit/space + name = "boxed space suit and helmet" + can_hold = list(/obj/item/clothing/suit/space/syndicate, /obj/item/clothing/head/helmet/space/syndicate) + max_w_class = WEIGHT_CLASS_NORMAL + +/obj/item/weapon/storage/box/syndie_kit/space/PopulateContents() + new /obj/item/clothing/suit/space/syndicate/black/red(src) // Black and red is so in right now + new /obj/item/clothing/head/helmet/space/syndicate/black/red(src) + +/obj/item/weapon/storage/box/syndie_kit/emp + name = "boxed EMP kit" + +/obj/item/weapon/storage/box/syndie_kit/emp/PopulateContents() + new /obj/item/weapon/grenade/empgrenade(src) + new /obj/item/weapon/grenade/empgrenade(src) + new /obj/item/weapon/grenade/empgrenade(src) + new /obj/item/weapon/grenade/empgrenade(src) + new /obj/item/weapon/grenade/empgrenade(src) + new /obj/item/weapon/implanter/emp(src) + +/obj/item/weapon/storage/box/syndie_kit/chemical + name = "boxed chemical kit" + storage_slots = 14 + +/obj/item/weapon/storage/box/syndie_kit/chemical/PopulateContents() + new /obj/item/weapon/reagent_containers/glass/bottle/polonium(src) + new /obj/item/weapon/reagent_containers/glass/bottle/venom(src) + new /obj/item/weapon/reagent_containers/glass/bottle/neurotoxin2(src) + new /obj/item/weapon/reagent_containers/glass/bottle/formaldehyde(src) + new /obj/item/weapon/reagent_containers/glass/bottle/spewium(src) + new /obj/item/weapon/reagent_containers/glass/bottle/cyanide(src) + new /obj/item/weapon/reagent_containers/glass/bottle/histamine(src) + new /obj/item/weapon/reagent_containers/glass/bottle/initropidril(src) + new /obj/item/weapon/reagent_containers/glass/bottle/pancuronium(src) + new /obj/item/weapon/reagent_containers/glass/bottle/sodium_thiopental(src) + new /obj/item/weapon/reagent_containers/glass/bottle/coniine(src) + new /obj/item/weapon/reagent_containers/glass/bottle/curare(src) + new /obj/item/weapon/reagent_containers/glass/bottle/amanitin(src) + new /obj/item/weapon/reagent_containers/syringe(src) + +/obj/item/weapon/storage/box/syndie_kit/nuke + name = "box" + +/obj/item/weapon/storage/box/syndie_kit/nuke/PopulateContents() + new /obj/item/weapon/screwdriver/nuke(src) + new /obj/item/nuke_core_container(src) + new /obj/item/weapon/paper/nuke_instructions(src) + +/obj/item/weapon/storage/box/syndie_kit/tuberculosisgrenade + name = "boxed virus grenade kit" + +/obj/item/weapon/storage/box/syndie_kit/tuberculosisgrenade/PopulateContents() + new /obj/item/weapon/grenade/chem_grenade/tuberculosis(src) + for(var/i in 1 to 5) + new /obj/item/weapon/reagent_containers/hypospray/medipen/tuberculosiscure(src) + new /obj/item/weapon/reagent_containers/syringe(src) + new /obj/item/weapon/reagent_containers/glass/bottle/tuberculosiscure(src) + +/obj/item/weapon/storage/box/syndie_kit/chameleon + name = "chameleon kit" + +/obj/item/weapon/storage/box/syndie_kit/chameleon/PopulateContents() + new /obj/item/clothing/under/chameleon(src) + new /obj/item/clothing/suit/chameleon(src) + new /obj/item/clothing/gloves/chameleon(src) + new /obj/item/clothing/shoes/chameleon(src) + new /obj/item/clothing/glasses/chameleon(src) + new /obj/item/clothing/head/chameleon(src) + new /obj/item/clothing/mask/chameleon(src) + new /obj/item/weapon/storage/backpack/chameleon(src) + new /obj/item/device/radio/headset/chameleon(src) + new /obj/item/weapon/stamp/chameleon(src) + new /obj/item/device/pda/chameleon(src) + new /obj/item/weapon/gun/energy/laser/chameleon(src) + +//5*(2*4) = 5*8 = 45, 45 damage if you hit one person with all 5 stars. +//Not counting the damage it will do while embedded (2*4 = 8, at 15% chance) +/obj/item/weapon/storage/box/syndie_kit/throwing_weapons/PopulateContents() + new /obj/item/weapon/throwing_star(src) + new /obj/item/weapon/throwing_star(src) + new /obj/item/weapon/throwing_star(src) + new /obj/item/weapon/throwing_star(src) + new /obj/item/weapon/throwing_star(src) + new /obj/item/weapon/restraints/legcuffs/bola/tactical(src) + new /obj/item/weapon/restraints/legcuffs/bola/tactical(src) + +/obj/item/weapon/storage/box/syndie_kit/cutouts/PopulateContents() + for(var/i in 1 to 3) + new/obj/item/cardboard_cutout/adaptive(src) + new/obj/item/toy/crayon/rainbow(src) + +/obj/item/weapon/storage/box/syndie_kit/romerol/PopulateContents() + new /obj/item/weapon/reagent_containers/glass/bottle/romerol(src) + new /obj/item/weapon/reagent_containers/syringe(src) + new /obj/item/weapon/reagent_containers/dropper(src) + +/obj/item/weapon/storage/box/syndie_kit/ez_clean/PopulateContents() + for(var/i in 1 to 3) + new/obj/item/weapon/grenade/chem_grenade/ez_clean(src) + +/obj/item/weapon/storage/box/hug/reverse_revolver/PopulateContents() + new /obj/item/weapon/gun/ballistic/revolver/reverse(src) + +/obj/item/weapon/storage/box/syndie_kit/mimery/PopulateContents() + new /obj/item/weapon/spellbook/oneuse/mimery_blockade(src) + new /obj/item/weapon/spellbook/oneuse/mimery_guns(src) + +/obj/item/weapon/storage/box/syndie_kit/holoparasite + name = "box" + +/obj/item/weapon/storage/box/syndie_kit/holoparasite/PopulateContents() + new /obj/item/weapon/guardiancreator/tech/choose/traitor(src) new /obj/item/weapon/paper/guardian(src) \ No newline at end of file diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm old mode 100644 new mode 100755 index 97548b97d6..4ffa4a9b89 --- a/code/game/objects/items/weapons/tanks/tank_types.dm +++ b/code/game/objects/items/weapons/tanks/tank_types.dm @@ -140,8 +140,8 @@ item_state = "plasmaman_tank_belt" slot_flags = SLOT_BELT force = 5 - volume = 3 - w_class = WEIGHT_CLASS_SMALL //thanks i forgot this + volume = 3 + w_class = WEIGHT_CLASS_SMALL //thanks i forgot this /obj/item/weapon/tank/internals/plasmaman/belt/full/New() ..() diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index 71e7c0e566..084ac19f63 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -1,553 +1,553 @@ -/obj/item/weapon - -/obj/item/weapon/banhammer - desc = "A banhammer" - name = "banhammer" - icon = 'icons/obj/items.dmi' - icon_state = "toyhammer" - slot_flags = SLOT_BELT - throwforce = 0 - w_class = WEIGHT_CLASS_TINY - throw_speed = 3 - throw_range = 7 - attack_verb = list("banned") - obj_integrity = 200 - max_integrity = 200 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 70) - resistance_flags = FIRE_PROOF - -/obj/item/weapon/banhammer/suicide_act(mob/user) - user.visible_message("[user] is hitting [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to ban [user.p_them()]self from life.") - return (BRUTELOSS|FIRELOSS|TOXLOSS|OXYLOSS) - -/obj/item/weapon/banhammer/attack(mob/M, mob/user) - to_chat(M, " You have been banned FOR NO REISIN by [user]") - to_chat(user, "You have BANNED [M]") - playsound(loc, 'sound/effects/adminhelp.ogg', 15) //keep it at 15% volume so people don't jump out of their skin too much - -/obj/item/weapon/sord - name = "\improper SORD" - desc = "This thing is so unspeakably shitty you are having a hard time even holding it." - icon_state = "sord" - item_state = "sord" - slot_flags = SLOT_BELT - force = 2 - throwforce = 1 - w_class = WEIGHT_CLASS_NORMAL - hitsound = 'sound/weapons/bladeslice.ogg' - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - -/obj/item/weapon/sord/suicide_act(mob/user) - user.visible_message("[user] is trying to impale [user.p_them()]self with [src]! It might be a suicide attempt if it weren't so shitty.", \ - "You try to impale yourself with [src], but it's USELESS...") - return SHAME - -/obj/item/weapon/claymore - name = "claymore" - desc = "What are you standing around staring at this for? Get to killing!" - icon_state = "claymore" - item_state = "claymore" - hitsound = 'sound/weapons/bladeslice.ogg' - flags = CONDUCT - slot_flags = SLOT_BELT | SLOT_BACK - force = 40 - throwforce = 10 - w_class = WEIGHT_CLASS_NORMAL - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - block_chance = 50 - sharpness = IS_SHARP - obj_integrity = 200 - max_integrity = 200 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50) - resistance_flags = FIRE_PROOF - -/obj/item/weapon/claymore/suicide_act(mob/user) - user.visible_message("[user] is falling on [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return(BRUTELOSS) - -/obj/item/weapon/claymore/highlander //ALL COMMENTS MADE REGARDING THIS SWORD MUST BE MADE IN ALL CAPS - desc = "THERE CAN BE ONLY ONE, AND IT WILL BE YOU!!!\nActivate it in your hand to point to the nearest victim." - flags = CONDUCT | NODROP | DROPDEL - slot_flags = null - block_chance = 0 //RNG WON'T HELP YOU NOW, PANSY - luminosity = 3 - attack_verb = list("brutalized", "eviscerated", "disemboweled", "hacked", "carved", "cleaved") //ONLY THE MOST VISCERAL ATTACK VERBS - var/notches = 0 //HOW MANY PEOPLE HAVE BEEN SLAIN WITH THIS BLADE - var/obj/item/weapon/disk/nuclear/nuke_disk //OUR STORED NUKE DISK - -/obj/item/weapon/claymore/highlander/New() - ..() - START_PROCESSING(SSobj, src) - -/obj/item/weapon/claymore/highlander/Destroy() - if(nuke_disk) - nuke_disk.forceMove(get_turf(src)) - nuke_disk.visible_message("The nuke disk is vulnerable!") - nuke_disk = null - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/weapon/claymore/highlander/process() - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - loc.layer = LARGE_MOB_LAYER //NO HIDING BEHIND PLANTS FOR YOU, DICKWEED (HA GET IT, BECAUSE WEEDS ARE PLANTS) - H.bleedsuppress = TRUE //AND WE WON'T BLEED OUT LIKE COWARDS - else - if(!admin_spawned) - qdel(src) - - -/obj/item/weapon/claymore/highlander/pickup(mob/living/user) - to_chat(user, "The power of Scotland protects you! You are shielded from all stuns and knockdowns.") - user.add_stun_absorption("highlander", INFINITY, 1, " is protected by the power of Scotland!", "The power of Scotland absorbs the stun!", " is protected by the power of Scotland!") - user.status_flags += IGNORESLOWDOWN - -/obj/item/weapon/claymore/highlander/dropped(mob/living/user) - user.status_flags -= IGNORESLOWDOWN - qdel(src) //If this ever happens, it's because you lost an arm - -/obj/item/weapon/claymore/highlander/examine(mob/user) - ..() - to_chat(user, "It has [!notches ? "nothing" : "[notches] notches"] scratched into the blade.") - if(nuke_disk) - to_chat(user, "It's holding the nuke disk!") - -/obj/item/weapon/claymore/highlander/attack(mob/living/target, mob/living/user) - . = ..() - if(target && target.stat == DEAD && target.mind && target.mind.special_role == "highlander") - user.fully_heal() //STEAL THE LIFE OF OUR FALLEN FOES - add_notch(user) - target.visible_message("[target] crumbles to dust beneath [user]'s blows!", "As you fall, your body crumbles to dust!") - target.dust() - -/obj/item/weapon/claymore/highlander/attack_self(mob/living/user) - var/closest_victim - var/closest_distance = 255 - for(var/mob/living/carbon/human/H in GLOB.player_list - user) - if(H.client && H.mind.special_role == "highlander" && (!closest_victim || get_dist(user, closest_victim) < closest_distance)) - closest_victim = H - if(!closest_victim) - to_chat(user, "[src] thrums for a moment and falls dark. Perhaps there's nobody nearby.") - return - to_chat(user, "[src] thrums and points to the [dir2text(get_dir(user, closest_victim))].") - -/obj/item/weapon/claymore/highlander/IsReflect() - return 1 //YOU THINK YOUR PUNY LASERS CAN STOP ME? - -/obj/item/weapon/claymore/highlander/proc/add_notch(mob/living/user) //DYNAMIC CLAYMORE PROGRESSION SYSTEM - THIS IS THE FUTURE - notches++ - force++ - var/new_name = name - switch(notches) - if(1) - to_chat(user, "Your first kill - hopefully one of many. You scratch a notch into [src]'s blade.") - to_chat(user, "You feel your fallen foe's soul entering your blade, restoring your wounds!") - new_name = "notched claymore" - if(2) - to_chat(user, "Another falls before you. Another soul fuses with your own. Another notch in the blade.") - new_name = "double-notched claymore" - add_atom_colour(rgb(255, 235, 235), ADMIN_COLOUR_PRIORITY) - if(3) - to_chat(user, "You're beginning to relish the thrill of battle.") - new_name = "triple-notched claymore" - add_atom_colour(rgb(255, 215, 215), ADMIN_COLOUR_PRIORITY) - if(4) - to_chat(user, "You've lost count of how many you've killed.") - new_name = "many-notched claymore" - add_atom_colour(rgb(255, 195, 195), ADMIN_COLOUR_PRIORITY) - if(5) - to_chat(user, "Five voices now echo in your mind, cheering the slaughter.") - new_name = "battle-tested claymore" - add_atom_colour(rgb(255, 175, 175), ADMIN_COLOUR_PRIORITY) - if(6) - to_chat(user, "Is this what the vikings felt like? Visions of glory fill your head as you slay your sixth foe.") - new_name = "battle-scarred claymore" - add_atom_colour(rgb(255, 155, 155), ADMIN_COLOUR_PRIORITY) - if(7) - to_chat(user, "Kill. Butcher. Conquer.") - new_name = "vicious claymore" - add_atom_colour(rgb(255, 135, 135), ADMIN_COLOUR_PRIORITY) - if(8) - to_chat(user, "IT NEVER GETS OLD. THE SCREAMING. THE BLOOD AS IT SPRAYS ACROSS YOUR FACE.") - new_name = "bloodthirsty claymore" - add_atom_colour(rgb(255, 115, 115), ADMIN_COLOUR_PRIORITY) - if(9) - to_chat(user, "ANOTHER ONE FALLS TO YOUR BLOWS. ANOTHER WEAKLING UNFIT TO LIVE.") - new_name = "gore-stained claymore" - add_atom_colour(rgb(255, 95, 95), ADMIN_COLOUR_PRIORITY) - if(10) - user.visible_message("[user]'s eyes light up with a vengeful fire!", \ - "YOU FEEL THE POWER OF VALHALLA FLOWING THROUGH YOU! THERE CAN BE ONLY ONE!!!") - user.update_icons() - new_name = "GORE-DRENCHED CLAYMORE OF [pick("THE WHIMSICAL SLAUGHTER", "A THOUSAND SLAUGHTERED CATTLE", "GLORY AND VALHALLA", "ANNIHILATION", "OBLITERATION")]" - icon_state = "claymore_valhalla" - item_state = "cultblade" - remove_atom_colour(ADMIN_COLOUR_PRIORITY) - - name = new_name - playsound(user, 'sound/items/Screwdriver2.ogg', 50, 1) - -/obj/item/weapon/katana - name = "katana" - desc = "Woefully underpowered in D20" - icon_state = "katana" - item_state = "katana" - flags = CONDUCT - slot_flags = SLOT_BELT | SLOT_BACK - force = 40 - throwforce = 10 - w_class = WEIGHT_CLASS_NORMAL - hitsound = 'sound/weapons/bladeslice.ogg' - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - block_chance = 50 - sharpness = IS_SHARP - obj_integrity = 200 - max_integrity = 200 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50) - resistance_flags = FIRE_PROOF - -/obj/item/weapon/katana/cursed - slot_flags = null - -/obj/item/weapon/katana/suicide_act(mob/user) - user.visible_message("[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!") - return(BRUTELOSS) - -/obj/item/weapon/wirerod - name = "wired rod" - desc = "A rod with some wire wrapped around the top. It'd be easy to attach something to the top bit." - icon_state = "wiredrod" - item_state = "rods" - flags = CONDUCT - force = 9 - throwforce = 10 - w_class = WEIGHT_CLASS_NORMAL - materials = list(MAT_METAL=1150, MAT_GLASS=75) - attack_verb = list("hit", "bludgeoned", "whacked", "bonked") - -/obj/item/weapon/wirerod/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/weapon/shard)) - var/obj/item/weapon/twohanded/spear/S = new /obj/item/weapon/twohanded/spear - - remove_item_from_storage(user) - qdel(I) - qdel(src) - - user.put_in_hands(S) - to_chat(user, "You fasten the glass shard to the top of the rod with the cable.") - - else if(istype(I, /obj/item/device/assembly/igniter) && !(I.flags & NODROP)) - var/obj/item/weapon/melee/baton/cattleprod/P = new /obj/item/weapon/melee/baton/cattleprod - - remove_item_from_storage(user) - - to_chat(user, "You fasten [I] to the top of the rod with the cable.") - - qdel(I) - qdel(src) - - user.put_in_hands(P) - else - return ..() - - -/obj/item/weapon/throwing_star - name = "throwing star" - desc = "An ancient weapon still used to this day due to it's ease of lodging itself into victim's body parts" - icon_state = "throwingstar" - item_state = "eshield0" - force = 2 - throwforce = 20 //This is never used on mobs since this has a 100% embed chance. - throw_speed = 4 - embedded_pain_multiplier = 4 - w_class = WEIGHT_CLASS_SMALL - embed_chance = 100 - embedded_fall_chance = 0 //Hahaha! - sharpness = IS_SHARP - materials = list(MAT_METAL=500, MAT_GLASS=500) - resistance_flags = FIRE_PROOF - - -/obj/item/weapon/switchblade - name = "switchblade" - icon_state = "switchblade" - desc = "A sharp, concealable, spring-loaded knife." - flags = CONDUCT - force = 3 - w_class = WEIGHT_CLASS_SMALL - throwforce = 5 - throw_speed = 3 - throw_range = 6 - materials = list(MAT_METAL=12000) - origin_tech = "engineering=3;combat=2" - hitsound = 'sound/weapons/Genhit.ogg' - attack_verb = list("stubbed", "poked") - resistance_flags = FIRE_PROOF - var/extended = 0 - -/obj/item/weapon/switchblade/attack_self(mob/user) - extended = !extended - playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1) - if(extended) - force = 20 - w_class = WEIGHT_CLASS_NORMAL - throwforce = 23 - icon_state = "switchblade_ext" - attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - hitsound = 'sound/weapons/bladeslice.ogg' - sharpness = IS_SHARP - else - force = 3 - w_class = WEIGHT_CLASS_SMALL - throwforce = 5 - icon_state = "switchblade" - attack_verb = list("stubbed", "poked") - hitsound = 'sound/weapons/Genhit.ogg' - sharpness = IS_BLUNT - -/obj/item/weapon/switchblade/suicide_act(mob/user) - user.visible_message("[user] is slitting [user.p_their()] own throat with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) - -/obj/item/weapon/phone - name = "red phone" - desc = "Should anything ever go wrong..." - icon = 'icons/obj/items.dmi' - icon_state = "red_phone" - force = 3 - throwforce = 2 - throw_speed = 3 - throw_range = 4 - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("called", "rang") - hitsound = 'sound/weapons/ring.ogg' - -/obj/item/weapon/phone/suicide_act(mob/user) - if(locate(/obj/structure/chair/stool) in user.loc) - user.visible_message("[user] begins to tie a noose with [src]'s cord! It looks like [user.p_theyre()] trying to commit suicide!") - else - user.visible_message("[user] is strangling [user.p_them()]self with [src]'s cord! It looks like [user.p_theyre()] trying to commit suicide!") - return(OXYLOSS) - -/obj/item/weapon/cane - name = "cane" - desc = "A cane used by a true gentleman. Or a clown." - icon = 'icons/obj/weapons.dmi' - icon_state = "cane" - item_state = "stick" - force = 5 - throwforce = 5 - w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL=50) - attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed") - -/obj/item/weapon/staff - name = "wizard staff" - desc = "Apparently a staff used by the wizard." - icon = 'icons/obj/wizard.dmi' - icon_state = "staff" - force = 3 - throwforce = 5 - throw_speed = 2 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - armour_penetration = 100 - attack_verb = list("bludgeoned", "whacked", "disciplined") - resistance_flags = FLAMMABLE - -/obj/item/weapon/staff/broom - name = "broom" - desc = "Used for sweeping, and flying into the night while cackling. Black cat not included." - icon = 'icons/obj/wizard.dmi' - icon_state = "broom" - resistance_flags = FLAMMABLE - -/obj/item/weapon/staff/stick - name = "stick" - desc = "A great tool to drag someone else's drinks across the bar." - icon = 'icons/obj/weapons.dmi' - icon_state = "stick" - item_state = "stick" - force = 3 - throwforce = 5 - throw_speed = 2 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - -/obj/item/weapon/ectoplasm - name = "ectoplasm" - desc = "spooky" - gender = PLURAL - icon = 'icons/obj/wizard.dmi' - icon_state = "ectoplasm" - -/obj/item/weapon/ectoplasm/suicide_act(mob/user) - user.visible_message("[user] is inhaling [src]! It looks like [user.p_theyre()] trying to visit the astral plane.") - return (OXYLOSS) - -/obj/item/weapon/mounted_chainsaw - name = "mounted chainsaw" - desc = "A chainsaw that has replaced your arm." - icon_state = "chainsaw_on" - item_state = "mounted_chainsaw" - flags = NODROP | ABSTRACT | DROPDEL - w_class = WEIGHT_CLASS_HUGE - force = 21 - throwforce = 0 - throw_range = 0 - throw_speed = 0 - sharpness = IS_SHARP - attack_verb = list("sawed", "torn", "cut", "chopped", "diced") - hitsound = 'sound/weapons/chainsawhit.ogg' - -/obj/item/weapon/mounted_chainsaw/Destroy() - var/obj/item/bodypart/part - new /obj/item/weapon/twohanded/required/chainsaw(get_turf(src)) - if(iscarbon(loc)) - var/mob/living/carbon/holder = loc - var/index = holder.get_held_index_of_item(src) - if(index) - part = holder.hand_bodyparts[index] - . = ..() - if(part) - part.drop_limb() - -/obj/item/weapon/statuebust - name = "bust" - desc = "A priceless ancient marble bust, the kind that belongs in a museum." //or you can hit people with it - icon = 'icons/obj/statue.dmi' - icon_state = "bust" - force = 15 - throwforce = 10 - throw_speed = 5 - throw_range = 2 - attack_verb = list("busted") - -/obj/item/weapon/tailclub - name = "tail club" - desc = "For the beating to death of lizards with their own tails." - icon_state = "tailclub" - force = 14 - throwforce = 1 // why are you throwing a club do you even weapon - throw_speed = 1 - throw_range = 1 - attack_verb = list("clubbed", "bludgeoned") - -/obj/item/weapon/melee/chainofcommand/tailwhip - name = "liz o' nine tails" - desc = "A whip fashioned from the severed tails of lizards." - icon_state = "tailwhip" - origin_tech = "engineering=3;combat=3;biotech=3" - needs_permit = 0 - -/obj/item/weapon/melee/skateboard - name = "skateboard" - desc = "A skateboard. It can be placed on its wheels and ridden, or used as a strong weapon." - icon_state = "skateboard" - item_state = "skateboard" - force = 12 - throwforce = 4 - w_class = WEIGHT_CLASS_HUGE - attack_verb = list("smacked", "whacked", "slammed", "smashed") - -/obj/item/weapon/melee/skateboard/attack_self(mob/user) - new /obj/vehicle/scooter/skateboard(get_turf(user)) - qdel(src) - -/obj/item/weapon/melee/baseball_bat - name = "baseball bat" - desc = "There ain't a skull in the league that can withstand a swatter." - icon = 'icons/obj/items.dmi' - icon_state = "baseball_bat" - item_state = "baseball_bat" - force = 10 - throwforce = 12 - attack_verb = list("beat", "smacked") - w_class = WEIGHT_CLASS_HUGE - var/homerun_ready = 0 - var/homerun_able = 0 - -/obj/item/weapon/melee/baseball_bat/homerun - name = "home run bat" - desc = "This thing looks dangerous... Dangerously good at baseball, that is." - homerun_able = 1 - -/obj/item/weapon/melee/baseball_bat/attack_self(mob/user) - if(!homerun_able) - ..() - return - if(homerun_ready) - to_chat(user, "You're already ready to do a home run!") - ..() - return - to_chat(user, "You begin gathering strength...") - playsound(get_turf(src), 'sound/magic/lightning_chargeup.ogg', 65, 1) - if(do_after(user, 90, target = src)) - to_chat(user, "You gather power! Time for a home run!") - homerun_ready = 1 - ..() - -/obj/item/weapon/melee/baseball_bat/attack(mob/living/target, mob/living/user) - . = ..() - var/atom/throw_target = get_edge_target_turf(target, user.dir) - if(homerun_ready) - user.visible_message("It's a home run!") - target.throw_at(throw_target, rand(8,10), 14, user) - target.ex_act(2) - playsound(get_turf(src), 'sound/weapons/HOMERUN.ogg', 100, 1) - homerun_ready = 0 - return - else if(!target.anchored) - target.throw_at(throw_target, rand(1,2), 7, user) - -/obj/item/weapon/melee/baseball_bat/ablative - name = "metal baseball bat" - desc = "This bat is made of highly reflective, highly armored material." - icon_state = "baseball_bat_metal" - item_state = "baseball_bat_metal" - force = 12 - throwforce = 15 - -/obj/item/weapon/melee/baseball_bat/ablative/IsReflect()//some day this will reflect thrown items instead of lasers - var/picksound = rand(1,2) - var/turf = get_turf(src) - if(picksound == 1) - playsound(turf, 'sound/weapons/effects/batreflect1.ogg', 50, 1) - if(picksound == 2) - playsound(turf, 'sound/weapons/effects/batreflect2.ogg', 50, 1) - return 1 - -/obj/item/weapon/melee/flyswatter - name = "Flyswatter" - desc = "Useful for killing insects of all sizes." - icon = 'icons/obj/weapons.dmi' - icon_state = "flyswatter" - item_state = "flyswatter" - force = 1 - throwforce = 1 - attack_verb = list("swatted", "smacked") - hitsound = 'sound/effects/snap.ogg' - w_class = WEIGHT_CLASS_SMALL - //Things in this list will be instantly splatted. Flyman weakness is handled in the flyman species weakness proc. - var/list/strong_against - -/obj/item/weapon/melee/flyswatter/New() - ..() - strong_against = typecacheof(list( - /mob/living/simple_animal/hostile/poison/bees/, - /mob/living/simple_animal/butterfly, - /mob/living/simple_animal/cockroach, - /obj/item/queen_bee - )) - - -/obj/item/weapon/melee/flyswatter/afterattack(atom/target, mob/user, proximity_flag) - if(proximity_flag) - if(is_type_in_typecache(target, strong_against)) - new /obj/effect/decal/cleanable/deadcockroach(get_turf(target)) - to_chat(user, "You easily splat the [target].") - if(istype(target, /mob/living/)) - var/mob/living/bug = target - bug.death(1) - else - qdel(target) +/obj/item/weapon + +/obj/item/weapon/banhammer + desc = "A banhammer" + name = "banhammer" + icon = 'icons/obj/items.dmi' + icon_state = "toyhammer" + slot_flags = SLOT_BELT + throwforce = 0 + w_class = WEIGHT_CLASS_TINY + throw_speed = 3 + throw_range = 7 + attack_verb = list("banned") + obj_integrity = 200 + max_integrity = 200 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 70) + resistance_flags = FIRE_PROOF + +/obj/item/weapon/banhammer/suicide_act(mob/user) + user.visible_message("[user] is hitting [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to ban [user.p_them()]self from life.") + return (BRUTELOSS|FIRELOSS|TOXLOSS|OXYLOSS) + +/obj/item/weapon/banhammer/attack(mob/M, mob/user) + to_chat(M, " You have been banned FOR NO REISIN by [user]") + to_chat(user, "You have BANNED [M]") + playsound(loc, 'sound/effects/adminhelp.ogg', 15) //keep it at 15% volume so people don't jump out of their skin too much + +/obj/item/weapon/sord + name = "\improper SORD" + desc = "This thing is so unspeakably shitty you are having a hard time even holding it." + icon_state = "sord" + item_state = "sord" + slot_flags = SLOT_BELT + force = 2 + throwforce = 1 + w_class = WEIGHT_CLASS_NORMAL + hitsound = 'sound/weapons/bladeslice.ogg' + attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + +/obj/item/weapon/sord/suicide_act(mob/user) + user.visible_message("[user] is trying to impale [user.p_them()]self with [src]! It might be a suicide attempt if it weren't so shitty.", \ + "You try to impale yourself with [src], but it's USELESS...") + return SHAME + +/obj/item/weapon/claymore + name = "claymore" + desc = "What are you standing around staring at this for? Get to killing!" + icon_state = "claymore" + item_state = "claymore" + hitsound = 'sound/weapons/bladeslice.ogg' + flags = CONDUCT + slot_flags = SLOT_BELT | SLOT_BACK + force = 40 + throwforce = 10 + w_class = WEIGHT_CLASS_NORMAL + attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + block_chance = 50 + sharpness = IS_SHARP + obj_integrity = 200 + max_integrity = 200 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50) + resistance_flags = FIRE_PROOF + +/obj/item/weapon/claymore/suicide_act(mob/user) + user.visible_message("[user] is falling on [src]! It looks like [user.p_theyre()] trying to commit suicide!") + return(BRUTELOSS) + +/obj/item/weapon/claymore/highlander //ALL COMMENTS MADE REGARDING THIS SWORD MUST BE MADE IN ALL CAPS + desc = "THERE CAN BE ONLY ONE, AND IT WILL BE YOU!!!\nActivate it in your hand to point to the nearest victim." + flags = CONDUCT | NODROP | DROPDEL + slot_flags = null + block_chance = 0 //RNG WON'T HELP YOU NOW, PANSY + luminosity = 3 + attack_verb = list("brutalized", "eviscerated", "disemboweled", "hacked", "carved", "cleaved") //ONLY THE MOST VISCERAL ATTACK VERBS + var/notches = 0 //HOW MANY PEOPLE HAVE BEEN SLAIN WITH THIS BLADE + var/obj/item/weapon/disk/nuclear/nuke_disk //OUR STORED NUKE DISK + +/obj/item/weapon/claymore/highlander/New() + ..() + START_PROCESSING(SSobj, src) + +/obj/item/weapon/claymore/highlander/Destroy() + if(nuke_disk) + nuke_disk.forceMove(get_turf(src)) + nuke_disk.visible_message("The nuke disk is vulnerable!") + nuke_disk = null + STOP_PROCESSING(SSobj, src) + return ..() + +/obj/item/weapon/claymore/highlander/process() + if(ishuman(loc)) + var/mob/living/carbon/human/H = loc + loc.layer = LARGE_MOB_LAYER //NO HIDING BEHIND PLANTS FOR YOU, DICKWEED (HA GET IT, BECAUSE WEEDS ARE PLANTS) + H.bleedsuppress = TRUE //AND WE WON'T BLEED OUT LIKE COWARDS + else + if(!admin_spawned) + qdel(src) + + +/obj/item/weapon/claymore/highlander/pickup(mob/living/user) + to_chat(user, "The power of Scotland protects you! You are shielded from all stuns and knockdowns.") + user.add_stun_absorption("highlander", INFINITY, 1, " is protected by the power of Scotland!", "The power of Scotland absorbs the stun!", " is protected by the power of Scotland!") + user.status_flags += IGNORESLOWDOWN + +/obj/item/weapon/claymore/highlander/dropped(mob/living/user) + user.status_flags -= IGNORESLOWDOWN + qdel(src) //If this ever happens, it's because you lost an arm + +/obj/item/weapon/claymore/highlander/examine(mob/user) + ..() + to_chat(user, "It has [!notches ? "nothing" : "[notches] notches"] scratched into the blade.") + if(nuke_disk) + to_chat(user, "It's holding the nuke disk!") + +/obj/item/weapon/claymore/highlander/attack(mob/living/target, mob/living/user) + . = ..() + if(target && target.stat == DEAD && target.mind && target.mind.special_role == "highlander") + user.fully_heal() //STEAL THE LIFE OF OUR FALLEN FOES + add_notch(user) + target.visible_message("[target] crumbles to dust beneath [user]'s blows!", "As you fall, your body crumbles to dust!") + target.dust() + +/obj/item/weapon/claymore/highlander/attack_self(mob/living/user) + var/closest_victim + var/closest_distance = 255 + for(var/mob/living/carbon/human/H in GLOB.player_list - user) + if(H.client && H.mind.special_role == "highlander" && (!closest_victim || get_dist(user, closest_victim) < closest_distance)) + closest_victim = H + if(!closest_victim) + to_chat(user, "[src] thrums for a moment and falls dark. Perhaps there's nobody nearby.") + return + to_chat(user, "[src] thrums and points to the [dir2text(get_dir(user, closest_victim))].") + +/obj/item/weapon/claymore/highlander/IsReflect() + return 1 //YOU THINK YOUR PUNY LASERS CAN STOP ME? + +/obj/item/weapon/claymore/highlander/proc/add_notch(mob/living/user) //DYNAMIC CLAYMORE PROGRESSION SYSTEM - THIS IS THE FUTURE + notches++ + force++ + var/new_name = name + switch(notches) + if(1) + to_chat(user, "Your first kill - hopefully one of many. You scratch a notch into [src]'s blade.") + to_chat(user, "You feel your fallen foe's soul entering your blade, restoring your wounds!") + new_name = "notched claymore" + if(2) + to_chat(user, "Another falls before you. Another soul fuses with your own. Another notch in the blade.") + new_name = "double-notched claymore" + add_atom_colour(rgb(255, 235, 235), ADMIN_COLOUR_PRIORITY) + if(3) + to_chat(user, "You're beginning to relish the thrill of battle.") + new_name = "triple-notched claymore" + add_atom_colour(rgb(255, 215, 215), ADMIN_COLOUR_PRIORITY) + if(4) + to_chat(user, "You've lost count of how many you've killed.") + new_name = "many-notched claymore" + add_atom_colour(rgb(255, 195, 195), ADMIN_COLOUR_PRIORITY) + if(5) + to_chat(user, "Five voices now echo in your mind, cheering the slaughter.") + new_name = "battle-tested claymore" + add_atom_colour(rgb(255, 175, 175), ADMIN_COLOUR_PRIORITY) + if(6) + to_chat(user, "Is this what the vikings felt like? Visions of glory fill your head as you slay your sixth foe.") + new_name = "battle-scarred claymore" + add_atom_colour(rgb(255, 155, 155), ADMIN_COLOUR_PRIORITY) + if(7) + to_chat(user, "Kill. Butcher. Conquer.") + new_name = "vicious claymore" + add_atom_colour(rgb(255, 135, 135), ADMIN_COLOUR_PRIORITY) + if(8) + to_chat(user, "IT NEVER GETS OLD. THE SCREAMING. THE BLOOD AS IT SPRAYS ACROSS YOUR FACE.") + new_name = "bloodthirsty claymore" + add_atom_colour(rgb(255, 115, 115), ADMIN_COLOUR_PRIORITY) + if(9) + to_chat(user, "ANOTHER ONE FALLS TO YOUR BLOWS. ANOTHER WEAKLING UNFIT TO LIVE.") + new_name = "gore-stained claymore" + add_atom_colour(rgb(255, 95, 95), ADMIN_COLOUR_PRIORITY) + if(10) + user.visible_message("[user]'s eyes light up with a vengeful fire!", \ + "YOU FEEL THE POWER OF VALHALLA FLOWING THROUGH YOU! THERE CAN BE ONLY ONE!!!") + user.update_icons() + new_name = "GORE-DRENCHED CLAYMORE OF [pick("THE WHIMSICAL SLAUGHTER", "A THOUSAND SLAUGHTERED CATTLE", "GLORY AND VALHALLA", "ANNIHILATION", "OBLITERATION")]" + icon_state = "claymore_valhalla" + item_state = "cultblade" + remove_atom_colour(ADMIN_COLOUR_PRIORITY) + + name = new_name + playsound(user, 'sound/items/Screwdriver2.ogg', 50, 1) + +/obj/item/weapon/katana + name = "katana" + desc = "Woefully underpowered in D20" + icon_state = "katana" + item_state = "katana" + flags = CONDUCT + slot_flags = SLOT_BELT | SLOT_BACK + force = 40 + throwforce = 10 + w_class = WEIGHT_CLASS_NORMAL + hitsound = 'sound/weapons/bladeslice.ogg' + attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + block_chance = 50 + sharpness = IS_SHARP + obj_integrity = 200 + max_integrity = 200 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50) + resistance_flags = FIRE_PROOF + +/obj/item/weapon/katana/cursed + slot_flags = null + +/obj/item/weapon/katana/suicide_act(mob/user) + user.visible_message("[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!") + return(BRUTELOSS) + +/obj/item/weapon/wirerod + name = "wired rod" + desc = "A rod with some wire wrapped around the top. It'd be easy to attach something to the top bit." + icon_state = "wiredrod" + item_state = "rods" + flags = CONDUCT + force = 9 + throwforce = 10 + w_class = WEIGHT_CLASS_NORMAL + materials = list(MAT_METAL=1150, MAT_GLASS=75) + attack_verb = list("hit", "bludgeoned", "whacked", "bonked") + +/obj/item/weapon/wirerod/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/weapon/shard)) + var/obj/item/weapon/twohanded/spear/S = new /obj/item/weapon/twohanded/spear + + remove_item_from_storage(user) + qdel(I) + qdel(src) + + user.put_in_hands(S) + to_chat(user, "You fasten the glass shard to the top of the rod with the cable.") + + else if(istype(I, /obj/item/device/assembly/igniter) && !(I.flags & NODROP)) + var/obj/item/weapon/melee/baton/cattleprod/P = new /obj/item/weapon/melee/baton/cattleprod + + remove_item_from_storage(user) + + to_chat(user, "You fasten [I] to the top of the rod with the cable.") + + qdel(I) + qdel(src) + + user.put_in_hands(P) + else + return ..() + + +/obj/item/weapon/throwing_star + name = "throwing star" + desc = "An ancient weapon still used to this day due to it's ease of lodging itself into victim's body parts" + icon_state = "throwingstar" + item_state = "eshield0" + force = 2 + throwforce = 20 //This is never used on mobs since this has a 100% embed chance. + throw_speed = 4 + embedded_pain_multiplier = 4 + w_class = WEIGHT_CLASS_SMALL + embed_chance = 100 + embedded_fall_chance = 0 //Hahaha! + sharpness = IS_SHARP + materials = list(MAT_METAL=500, MAT_GLASS=500) + resistance_flags = FIRE_PROOF + + +/obj/item/weapon/switchblade + name = "switchblade" + icon_state = "switchblade" + desc = "A sharp, concealable, spring-loaded knife." + flags = CONDUCT + force = 3 + w_class = WEIGHT_CLASS_SMALL + throwforce = 5 + throw_speed = 3 + throw_range = 6 + materials = list(MAT_METAL=12000) + origin_tech = "engineering=3;combat=2" + hitsound = 'sound/weapons/Genhit.ogg' + attack_verb = list("stubbed", "poked") + resistance_flags = FIRE_PROOF + var/extended = 0 + +/obj/item/weapon/switchblade/attack_self(mob/user) + extended = !extended + playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1) + if(extended) + force = 20 + w_class = WEIGHT_CLASS_NORMAL + throwforce = 23 + icon_state = "switchblade_ext" + attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + hitsound = 'sound/weapons/bladeslice.ogg' + sharpness = IS_SHARP + else + force = 3 + w_class = WEIGHT_CLASS_SMALL + throwforce = 5 + icon_state = "switchblade" + attack_verb = list("stubbed", "poked") + hitsound = 'sound/weapons/Genhit.ogg' + sharpness = IS_BLUNT + +/obj/item/weapon/switchblade/suicide_act(mob/user) + user.visible_message("[user] is slitting [user.p_their()] own throat with [src]! It looks like [user.p_theyre()] trying to commit suicide!") + return (BRUTELOSS) + +/obj/item/weapon/phone + name = "red phone" + desc = "Should anything ever go wrong..." + icon = 'icons/obj/items.dmi' + icon_state = "red_phone" + force = 3 + throwforce = 2 + throw_speed = 3 + throw_range = 4 + w_class = WEIGHT_CLASS_SMALL + attack_verb = list("called", "rang") + hitsound = 'sound/weapons/ring.ogg' + +/obj/item/weapon/phone/suicide_act(mob/user) + if(locate(/obj/structure/chair/stool) in user.loc) + user.visible_message("[user] begins to tie a noose with [src]'s cord! It looks like [user.p_theyre()] trying to commit suicide!") + else + user.visible_message("[user] is strangling [user.p_them()]self with [src]'s cord! It looks like [user.p_theyre()] trying to commit suicide!") + return(OXYLOSS) + +/obj/item/weapon/cane + name = "cane" + desc = "A cane used by a true gentleman. Or a clown." + icon = 'icons/obj/weapons.dmi' + icon_state = "cane" + item_state = "stick" + force = 5 + throwforce = 5 + w_class = WEIGHT_CLASS_SMALL + materials = list(MAT_METAL=50) + attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed") + +/obj/item/weapon/staff + name = "wizard staff" + desc = "Apparently a staff used by the wizard." + icon = 'icons/obj/wizard.dmi' + icon_state = "staff" + force = 3 + throwforce = 5 + throw_speed = 2 + throw_range = 5 + w_class = WEIGHT_CLASS_SMALL + armour_penetration = 100 + attack_verb = list("bludgeoned", "whacked", "disciplined") + resistance_flags = FLAMMABLE + +/obj/item/weapon/staff/broom + name = "broom" + desc = "Used for sweeping, and flying into the night while cackling. Black cat not included." + icon = 'icons/obj/wizard.dmi' + icon_state = "broom" + resistance_flags = FLAMMABLE + +/obj/item/weapon/staff/stick + name = "stick" + desc = "A great tool to drag someone else's drinks across the bar." + icon = 'icons/obj/weapons.dmi' + icon_state = "stick" + item_state = "stick" + force = 3 + throwforce = 5 + throw_speed = 2 + throw_range = 5 + w_class = WEIGHT_CLASS_SMALL + +/obj/item/weapon/ectoplasm + name = "ectoplasm" + desc = "spooky" + gender = PLURAL + icon = 'icons/obj/wizard.dmi' + icon_state = "ectoplasm" + +/obj/item/weapon/ectoplasm/suicide_act(mob/user) + user.visible_message("[user] is inhaling [src]! It looks like [user.p_theyre()] trying to visit the astral plane.") + return (OXYLOSS) + +/obj/item/weapon/mounted_chainsaw + name = "mounted chainsaw" + desc = "A chainsaw that has replaced your arm." + icon_state = "chainsaw_on" + item_state = "mounted_chainsaw" + flags = NODROP | ABSTRACT | DROPDEL + w_class = WEIGHT_CLASS_HUGE + force = 21 + throwforce = 0 + throw_range = 0 + throw_speed = 0 + sharpness = IS_SHARP + attack_verb = list("sawed", "torn", "cut", "chopped", "diced") + hitsound = 'sound/weapons/chainsawhit.ogg' + +/obj/item/weapon/mounted_chainsaw/Destroy() + var/obj/item/bodypart/part + new /obj/item/weapon/twohanded/required/chainsaw(get_turf(src)) + if(iscarbon(loc)) + var/mob/living/carbon/holder = loc + var/index = holder.get_held_index_of_item(src) + if(index) + part = holder.hand_bodyparts[index] + . = ..() + if(part) + part.drop_limb() + +/obj/item/weapon/statuebust + name = "bust" + desc = "A priceless ancient marble bust, the kind that belongs in a museum." //or you can hit people with it + icon = 'icons/obj/statue.dmi' + icon_state = "bust" + force = 15 + throwforce = 10 + throw_speed = 5 + throw_range = 2 + attack_verb = list("busted") + +/obj/item/weapon/tailclub + name = "tail club" + desc = "For the beating to death of lizards with their own tails." + icon_state = "tailclub" + force = 14 + throwforce = 1 // why are you throwing a club do you even weapon + throw_speed = 1 + throw_range = 1 + attack_verb = list("clubbed", "bludgeoned") + +/obj/item/weapon/melee/chainofcommand/tailwhip + name = "liz o' nine tails" + desc = "A whip fashioned from the severed tails of lizards." + icon_state = "tailwhip" + origin_tech = "engineering=3;combat=3;biotech=3" + needs_permit = 0 + +/obj/item/weapon/melee/skateboard + name = "skateboard" + desc = "A skateboard. It can be placed on its wheels and ridden, or used as a strong weapon." + icon_state = "skateboard" + item_state = "skateboard" + force = 12 + throwforce = 4 + w_class = WEIGHT_CLASS_HUGE + attack_verb = list("smacked", "whacked", "slammed", "smashed") + +/obj/item/weapon/melee/skateboard/attack_self(mob/user) + new /obj/vehicle/scooter/skateboard(get_turf(user)) + qdel(src) + +/obj/item/weapon/melee/baseball_bat + name = "baseball bat" + desc = "There ain't a skull in the league that can withstand a swatter." + icon = 'icons/obj/items.dmi' + icon_state = "baseball_bat" + item_state = "baseball_bat" + force = 10 + throwforce = 12 + attack_verb = list("beat", "smacked") + w_class = WEIGHT_CLASS_HUGE + var/homerun_ready = 0 + var/homerun_able = 0 + +/obj/item/weapon/melee/baseball_bat/homerun + name = "home run bat" + desc = "This thing looks dangerous... Dangerously good at baseball, that is." + homerun_able = 1 + +/obj/item/weapon/melee/baseball_bat/attack_self(mob/user) + if(!homerun_able) + ..() + return + if(homerun_ready) + to_chat(user, "You're already ready to do a home run!") + ..() + return + to_chat(user, "You begin gathering strength...") + playsound(get_turf(src), 'sound/magic/lightning_chargeup.ogg', 65, 1) + if(do_after(user, 90, target = src)) + to_chat(user, "You gather power! Time for a home run!") + homerun_ready = 1 + ..() + +/obj/item/weapon/melee/baseball_bat/attack(mob/living/target, mob/living/user) + . = ..() + var/atom/throw_target = get_edge_target_turf(target, user.dir) + if(homerun_ready) + user.visible_message("It's a home run!") + target.throw_at(throw_target, rand(8,10), 14, user) + target.ex_act(2) + playsound(get_turf(src), 'sound/weapons/HOMERUN.ogg', 100, 1) + homerun_ready = 0 + return + else if(!target.anchored) + target.throw_at(throw_target, rand(1,2), 7, user) + +/obj/item/weapon/melee/baseball_bat/ablative + name = "metal baseball bat" + desc = "This bat is made of highly reflective, highly armored material." + icon_state = "baseball_bat_metal" + item_state = "baseball_bat_metal" + force = 12 + throwforce = 15 + +/obj/item/weapon/melee/baseball_bat/ablative/IsReflect()//some day this will reflect thrown items instead of lasers + var/picksound = rand(1,2) + var/turf = get_turf(src) + if(picksound == 1) + playsound(turf, 'sound/weapons/effects/batreflect1.ogg', 50, 1) + if(picksound == 2) + playsound(turf, 'sound/weapons/effects/batreflect2.ogg', 50, 1) + return 1 + +/obj/item/weapon/melee/flyswatter + name = "Flyswatter" + desc = "Useful for killing insects of all sizes." + icon = 'icons/obj/weapons.dmi' + icon_state = "flyswatter" + item_state = "flyswatter" + force = 1 + throwforce = 1 + attack_verb = list("swatted", "smacked") + hitsound = 'sound/effects/snap.ogg' + w_class = WEIGHT_CLASS_SMALL + //Things in this list will be instantly splatted. Flyman weakness is handled in the flyman species weakness proc. + var/list/strong_against + +/obj/item/weapon/melee/flyswatter/New() + ..() + strong_against = typecacheof(list( + /mob/living/simple_animal/hostile/poison/bees/, + /mob/living/simple_animal/butterfly, + /mob/living/simple_animal/cockroach, + /obj/item/queen_bee + )) + + +/obj/item/weapon/melee/flyswatter/afterattack(atom/target, mob/user, proximity_flag) + if(proximity_flag) + if(is_type_in_typecache(target, strong_against)) + new /obj/effect/decal/cleanable/deadcockroach(get_turf(target)) + to_chat(user, "You easily splat the [target].") + if(istype(target, /mob/living/)) + var/mob/living/bug = target + bug.death(1) + else + qdel(target) diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index e3aed96516..36730239ea 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -1,316 +1,316 @@ -/* -CONTAINS: -BEDSHEETS -LINEN BINS -*/ - -/obj/item/weapon/bedsheet - name = "bedsheet" - desc = "A surprisingly soft linen bedsheet." - icon = 'icons/obj/bedsheets.dmi' - icon_state = "sheetwhite" - item_state = "bedsheet" - slot_flags = SLOT_NECK - layer = MOB_LAYER - throwforce = 0 - throw_speed = 1 - throw_range = 2 - w_class = WEIGHT_CLASS_TINY - item_color = "white" - resistance_flags = FLAMMABLE - - dog_fashion = /datum/dog_fashion/head/ghost - -/obj/item/weapon/bedsheet/attack(mob/living/M, mob/user) - if(!attempt_initiate_surgery(src, M, user)) - ..() - -/obj/item/weapon/bedsheet/attack_self(mob/user) - user.drop_item() - if(layer == initial(layer)) - layer = ABOVE_MOB_LAYER - to_chat(user, "You cover yourself with [src].") - else - layer = initial(layer) - to_chat(user, "You smooth [src] out beneath you.") - add_fingerprint(user) - return - -/obj/item/weapon/bedsheet/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/weapon/wirecutters) || I.is_sharp()) - var/obj/item/stack/sheet/cloth/C = new (get_turf(src), 3) - transfer_fingerprints_to(C) - C.add_fingerprint(user) - qdel(src) - to_chat(user, "You tear [src] up.") - else - return ..() - -/obj/item/weapon/bedsheet/blue - icon_state = "sheetblue" - item_color = "blue" - -/obj/item/weapon/bedsheet/green - icon_state = "sheetgreen" - item_color = "green" - -/obj/item/weapon/bedsheet/orange - icon_state = "sheetorange" - item_color = "orange" - -/obj/item/weapon/bedsheet/purple - icon_state = "sheetpurple" - item_color = "purple" - -/obj/item/weapon/bedsheet/patriot - name = "patriotic bedsheet" - desc = "You've never felt more free than when sleeping on this." - icon_state = "sheetUSA" - item_color = "sheetUSA" - -/obj/item/weapon/bedsheet/rainbow - name = "rainbow bedsheet" - desc = "A multicolored blanket. It's actually several different sheets cut up and sewn together." - icon_state = "sheetrainbow" - item_color = "rainbow" - -/obj/item/weapon/bedsheet/red - icon_state = "sheetred" - item_color = "red" - -/obj/item/weapon/bedsheet/yellow - icon_state = "sheetyellow" - item_color = "yellow" - -/obj/item/weapon/bedsheet/mime - name = "mime's blanket" - desc = "A very soothing striped blanket. All the noise just seems to fade out when you're under the covers in this." - icon_state = "sheetmime" - item_color = "mime" - -/obj/item/weapon/bedsheet/clown - name = "clown's blanket" - desc = "A rainbow blanket with a clown mask woven in. It smells faintly of bananas." - icon_state = "sheetclown" - item_color = "clown" - -/obj/item/weapon/bedsheet/captain - name = "captain's bedsheet" - desc = "It has a Nanotrasen symbol on it, and was woven with a revolutionary new kind of thread guaranteed to have 0.01% permeability for most non-chemical substances, popular among most modern captains." - icon_state = "sheetcaptain" - item_color = "captain" - -/obj/item/weapon/bedsheet/rd - name = "research director's bedsheet" - desc = "It appears to have a beaker emblem, and is made out of fire-resistant material, although it probably won't protect you in the event of fires you're familiar with every day." - icon_state = "sheetrd" - item_color = "director" - -// for Free Golems. -/obj/item/weapon/bedsheet/rd/royal_cape - name = "Royal Cape of the Liberator" - desc = "Majestic." - -/obj/item/weapon/bedsheet/medical - name = "medical blanket" - desc = "It's a sterilized* blanket commonly used in the Medbay. *Sterilization is voided if a virologist is present onboard the station." - icon_state = "sheetmedical" - item_color = "medical" - -/obj/item/weapon/bedsheet/cmo - name = "chief medical officer's bedsheet" - desc = "It's a sterilized blanket that has a cross emblem. There's some cat fur on it, likely from Runtime." - icon_state = "sheetcmo" - item_color = "cmo" - -/obj/item/weapon/bedsheet/hos - name = "head of security's bedsheet" - desc = "It is decorated with a shield emblem. While crime doesn't sleep, you do, but you are still THE LAW!" - icon_state = "sheethos" - item_color = "hosred" - -/obj/item/weapon/bedsheet/hop - name = "head of personnel's bedsheet" - desc = "It is decorated with a key emblem. For those rare moments when you can rest and cuddle with Ian without someone screaming for you over the radio." - icon_state = "sheethop" - item_color = "hop" - -/obj/item/weapon/bedsheet/ce - name = "chief engineer's bedsheet" - desc = "It is decorated with a wrench emblem. It's highly reflective and stain resistant, so you don't need to worry about ruining it with oil." - icon_state = "sheetce" - item_color = "chief" - -/obj/item/weapon/bedsheet/qm - name = "quartermaster's bedsheet" - desc = "It is decorated with a crate emblem in silver lining. It's rather tough, and just the thing to lie on after a hard day of pushing paper." - icon_state = "sheetqm" - item_color = "qm" - -/obj/item/weapon/bedsheet/brown - icon_state = "sheetbrown" - item_color = "cargo" - -/obj/item/weapon/bedsheet/black - icon_state = "sheetblack" - item_color = "black" - -/obj/item/weapon/bedsheet/centcom - name = "\improper Centcom bedsheet" - desc = "Woven with advanced nanothread for warmth as well as being very decorated, essential for all officials." - icon_state = "sheetcentcom" - item_color = "centcom" - -/obj/item/weapon/bedsheet/syndie - name = "syndicate bedsheet" - desc = "It has a syndicate emblem and it has an aura of evil." - icon_state = "sheetsyndie" - item_color = "syndie" - -/obj/item/weapon/bedsheet/cult - name = "cultist's bedsheet" - desc = "You might dream of Nar'Sie if you sleep with this. It seems rather tattered and glows of an eldritch presence." - icon_state = "sheetcult" - item_color = "cult" - -/obj/item/weapon/bedsheet/wiz - name = "wizard's bedsheet" - desc = "A special fabric enchanted with magic so you can have an enchanted night. It even glows!" - icon_state = "sheetwiz" - item_color = "wiz" - -/obj/item/weapon/bedsheet/nanotrasen - name = "nanotrasen bedsheet" - desc = "It has the Nanotrasen logo on it and has an aura of duty." - icon_state = "sheetNT" - item_color = "nanotrasen" - -/obj/item/weapon/bedsheet/ian - icon_state = "sheetian" - item_color = "ian" - - -/obj/item/weapon/bedsheet/random - icon_state = "sheetrainbow" - item_color = "rainbow" - name = "random bedsheet" - desc = "If you're reading this description ingame, something has gone wrong! Honk!" - -/obj/item/weapon/bedsheet/random/New() - var/obj/item/weapon/bedsheet/B = pick(subtypesof(/obj/item/weapon/bedsheet) - /obj/item/weapon/bedsheet/random) - name = initial(B.name) - desc = initial(B.desc) - icon_state = initial(B.icon_state) - item_state = initial(B.item_state) - item_color = initial(B.item_color) - -/obj/structure/bedsheetbin - name = "linen bin" - desc = "It looks rather cosy." - icon = 'icons/obj/structures.dmi' - icon_state = "linenbin-full" - anchored = 1 - resistance_flags = FLAMMABLE - obj_integrity = 70 - max_integrity = 70 - var/amount = 10 - var/list/sheets = list() - var/obj/item/hidden = null - - -/obj/structure/bedsheetbin/examine(mob/user) - ..() - if(amount < 1) - to_chat(user, "There are no bed sheets in the bin.") - else if(amount == 1) - to_chat(user, "There is one bed sheet in the bin.") - else - to_chat(user, "There are [amount] bed sheets in the bin.") - - -/obj/structure/bedsheetbin/update_icon() - switch(amount) - if(0) - icon_state = "linenbin-empty" - if(1 to 5) - icon_state = "linenbin-half" - else - icon_state = "linenbin-full" - -/obj/structure/bedsheetbin/fire_act(exposed_temperature, exposed_volume) - if(amount) - amount = 0 - update_icon() - ..() - -/obj/structure/bedsheetbin/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/weapon/bedsheet)) - if(!user.drop_item()) - return - I.loc = src - sheets.Add(I) - amount++ - to_chat(user, "You put [I] in [src].") - update_icon() - else if(amount && !hidden && I.w_class < WEIGHT_CLASS_BULKY) //make sure there's sheets to hide it among, make sure nothing else is hidden in there. - if(!user.drop_item()) - to_chat(user, "\The [I] is stuck to your hand, you cannot hide it among the sheets!") - return - I.loc = src - hidden = I - to_chat(user, "You hide [I] among the sheets.") - - - -/obj/structure/bedsheetbin/attack_paw(mob/user) - return attack_hand(user) - - -/obj/structure/bedsheetbin/attack_hand(mob/user) - if(user.lying) - return - if(amount >= 1) - amount-- - - var/obj/item/weapon/bedsheet/B - if(sheets.len > 0) - B = sheets[sheets.len] - sheets.Remove(B) - - else - B = new /obj/item/weapon/bedsheet(loc) - - B.loc = user.loc - user.put_in_hands(B) - to_chat(user, "You take [B] out of [src].") - update_icon() - - if(hidden) - hidden.loc = user.loc - to_chat(user, "[hidden] falls out of [B]!") - hidden = null - - - add_fingerprint(user) -/obj/structure/bedsheetbin/attack_tk(mob/user) - if(amount >= 1) - amount-- - - var/obj/item/weapon/bedsheet/B - if(sheets.len > 0) - B = sheets[sheets.len] - sheets.Remove(B) - - else - B = new /obj/item/weapon/bedsheet(loc) - - B.loc = loc - to_chat(user, "You telekinetically remove [B] from [src].") - update_icon() - - if(hidden) - hidden.loc = loc - hidden = null - - - add_fingerprint(user) +/* +CONTAINS: +BEDSHEETS +LINEN BINS +*/ + +/obj/item/weapon/bedsheet + name = "bedsheet" + desc = "A surprisingly soft linen bedsheet." + icon = 'icons/obj/bedsheets.dmi' + icon_state = "sheetwhite" + item_state = "bedsheet" + slot_flags = SLOT_NECK + layer = MOB_LAYER + throwforce = 0 + throw_speed = 1 + throw_range = 2 + w_class = WEIGHT_CLASS_TINY + item_color = "white" + resistance_flags = FLAMMABLE + + dog_fashion = /datum/dog_fashion/head/ghost + +/obj/item/weapon/bedsheet/attack(mob/living/M, mob/user) + if(!attempt_initiate_surgery(src, M, user)) + ..() + +/obj/item/weapon/bedsheet/attack_self(mob/user) + user.drop_item() + if(layer == initial(layer)) + layer = ABOVE_MOB_LAYER + to_chat(user, "You cover yourself with [src].") + else + layer = initial(layer) + to_chat(user, "You smooth [src] out beneath you.") + add_fingerprint(user) + return + +/obj/item/weapon/bedsheet/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/weapon/wirecutters) || I.is_sharp()) + var/obj/item/stack/sheet/cloth/C = new (get_turf(src), 3) + transfer_fingerprints_to(C) + C.add_fingerprint(user) + qdel(src) + to_chat(user, "You tear [src] up.") + else + return ..() + +/obj/item/weapon/bedsheet/blue + icon_state = "sheetblue" + item_color = "blue" + +/obj/item/weapon/bedsheet/green + icon_state = "sheetgreen" + item_color = "green" + +/obj/item/weapon/bedsheet/orange + icon_state = "sheetorange" + item_color = "orange" + +/obj/item/weapon/bedsheet/purple + icon_state = "sheetpurple" + item_color = "purple" + +/obj/item/weapon/bedsheet/patriot + name = "patriotic bedsheet" + desc = "You've never felt more free than when sleeping on this." + icon_state = "sheetUSA" + item_color = "sheetUSA" + +/obj/item/weapon/bedsheet/rainbow + name = "rainbow bedsheet" + desc = "A multicolored blanket. It's actually several different sheets cut up and sewn together." + icon_state = "sheetrainbow" + item_color = "rainbow" + +/obj/item/weapon/bedsheet/red + icon_state = "sheetred" + item_color = "red" + +/obj/item/weapon/bedsheet/yellow + icon_state = "sheetyellow" + item_color = "yellow" + +/obj/item/weapon/bedsheet/mime + name = "mime's blanket" + desc = "A very soothing striped blanket. All the noise just seems to fade out when you're under the covers in this." + icon_state = "sheetmime" + item_color = "mime" + +/obj/item/weapon/bedsheet/clown + name = "clown's blanket" + desc = "A rainbow blanket with a clown mask woven in. It smells faintly of bananas." + icon_state = "sheetclown" + item_color = "clown" + +/obj/item/weapon/bedsheet/captain + name = "captain's bedsheet" + desc = "It has a Nanotrasen symbol on it, and was woven with a revolutionary new kind of thread guaranteed to have 0.01% permeability for most non-chemical substances, popular among most modern captains." + icon_state = "sheetcaptain" + item_color = "captain" + +/obj/item/weapon/bedsheet/rd + name = "research director's bedsheet" + desc = "It appears to have a beaker emblem, and is made out of fire-resistant material, although it probably won't protect you in the event of fires you're familiar with every day." + icon_state = "sheetrd" + item_color = "director" + +// for Free Golems. +/obj/item/weapon/bedsheet/rd/royal_cape + name = "Royal Cape of the Liberator" + desc = "Majestic." + +/obj/item/weapon/bedsheet/medical + name = "medical blanket" + desc = "It's a sterilized* blanket commonly used in the Medbay. *Sterilization is voided if a virologist is present onboard the station." + icon_state = "sheetmedical" + item_color = "medical" + +/obj/item/weapon/bedsheet/cmo + name = "chief medical officer's bedsheet" + desc = "It's a sterilized blanket that has a cross emblem. There's some cat fur on it, likely from Runtime." + icon_state = "sheetcmo" + item_color = "cmo" + +/obj/item/weapon/bedsheet/hos + name = "head of security's bedsheet" + desc = "It is decorated with a shield emblem. While crime doesn't sleep, you do, but you are still THE LAW!" + icon_state = "sheethos" + item_color = "hosred" + +/obj/item/weapon/bedsheet/hop + name = "head of personnel's bedsheet" + desc = "It is decorated with a key emblem. For those rare moments when you can rest and cuddle with Ian without someone screaming for you over the radio." + icon_state = "sheethop" + item_color = "hop" + +/obj/item/weapon/bedsheet/ce + name = "chief engineer's bedsheet" + desc = "It is decorated with a wrench emblem. It's highly reflective and stain resistant, so you don't need to worry about ruining it with oil." + icon_state = "sheetce" + item_color = "chief" + +/obj/item/weapon/bedsheet/qm + name = "quartermaster's bedsheet" + desc = "It is decorated with a crate emblem in silver lining. It's rather tough, and just the thing to lie on after a hard day of pushing paper." + icon_state = "sheetqm" + item_color = "qm" + +/obj/item/weapon/bedsheet/brown + icon_state = "sheetbrown" + item_color = "cargo" + +/obj/item/weapon/bedsheet/black + icon_state = "sheetblack" + item_color = "black" + +/obj/item/weapon/bedsheet/centcom + name = "\improper Centcom bedsheet" + desc = "Woven with advanced nanothread for warmth as well as being very decorated, essential for all officials." + icon_state = "sheetcentcom" + item_color = "centcom" + +/obj/item/weapon/bedsheet/syndie + name = "syndicate bedsheet" + desc = "It has a syndicate emblem and it has an aura of evil." + icon_state = "sheetsyndie" + item_color = "syndie" + +/obj/item/weapon/bedsheet/cult + name = "cultist's bedsheet" + desc = "You might dream of Nar'Sie if you sleep with this. It seems rather tattered and glows of an eldritch presence." + icon_state = "sheetcult" + item_color = "cult" + +/obj/item/weapon/bedsheet/wiz + name = "wizard's bedsheet" + desc = "A special fabric enchanted with magic so you can have an enchanted night. It even glows!" + icon_state = "sheetwiz" + item_color = "wiz" + +/obj/item/weapon/bedsheet/nanotrasen + name = "nanotrasen bedsheet" + desc = "It has the Nanotrasen logo on it and has an aura of duty." + icon_state = "sheetNT" + item_color = "nanotrasen" + +/obj/item/weapon/bedsheet/ian + icon_state = "sheetian" + item_color = "ian" + + +/obj/item/weapon/bedsheet/random + icon_state = "sheetrainbow" + item_color = "rainbow" + name = "random bedsheet" + desc = "If you're reading this description ingame, something has gone wrong! Honk!" + +/obj/item/weapon/bedsheet/random/New() + var/obj/item/weapon/bedsheet/B = pick(subtypesof(/obj/item/weapon/bedsheet) - /obj/item/weapon/bedsheet/random) + name = initial(B.name) + desc = initial(B.desc) + icon_state = initial(B.icon_state) + item_state = initial(B.item_state) + item_color = initial(B.item_color) + +/obj/structure/bedsheetbin + name = "linen bin" + desc = "It looks rather cosy." + icon = 'icons/obj/structures.dmi' + icon_state = "linenbin-full" + anchored = 1 + resistance_flags = FLAMMABLE + obj_integrity = 70 + max_integrity = 70 + var/amount = 10 + var/list/sheets = list() + var/obj/item/hidden = null + + +/obj/structure/bedsheetbin/examine(mob/user) + ..() + if(amount < 1) + to_chat(user, "There are no bed sheets in the bin.") + else if(amount == 1) + to_chat(user, "There is one bed sheet in the bin.") + else + to_chat(user, "There are [amount] bed sheets in the bin.") + + +/obj/structure/bedsheetbin/update_icon() + switch(amount) + if(0) + icon_state = "linenbin-empty" + if(1 to 5) + icon_state = "linenbin-half" + else + icon_state = "linenbin-full" + +/obj/structure/bedsheetbin/fire_act(exposed_temperature, exposed_volume) + if(amount) + amount = 0 + update_icon() + ..() + +/obj/structure/bedsheetbin/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/weapon/bedsheet)) + if(!user.drop_item()) + return + I.loc = src + sheets.Add(I) + amount++ + to_chat(user, "You put [I] in [src].") + update_icon() + else if(amount && !hidden && I.w_class < WEIGHT_CLASS_BULKY) //make sure there's sheets to hide it among, make sure nothing else is hidden in there. + if(!user.drop_item()) + to_chat(user, "\The [I] is stuck to your hand, you cannot hide it among the sheets!") + return + I.loc = src + hidden = I + to_chat(user, "You hide [I] among the sheets.") + + + +/obj/structure/bedsheetbin/attack_paw(mob/user) + return attack_hand(user) + + +/obj/structure/bedsheetbin/attack_hand(mob/user) + if(user.lying) + return + if(amount >= 1) + amount-- + + var/obj/item/weapon/bedsheet/B + if(sheets.len > 0) + B = sheets[sheets.len] + sheets.Remove(B) + + else + B = new /obj/item/weapon/bedsheet(loc) + + B.loc = user.loc + user.put_in_hands(B) + to_chat(user, "You take [B] out of [src].") + update_icon() + + if(hidden) + hidden.loc = user.loc + to_chat(user, "[hidden] falls out of [B]!") + hidden = null + + + add_fingerprint(user) +/obj/structure/bedsheetbin/attack_tk(mob/user) + if(amount >= 1) + amount-- + + var/obj/item/weapon/bedsheet/B + if(sheets.len > 0) + B = sheets[sheets.len] + sheets.Remove(B) + + else + B = new /obj/item/weapon/bedsheet(loc) + + B.loc = loc + to_chat(user, "You telekinetically remove [B] from [src].") + update_icon() + + if(hidden) + hidden.loc = loc + hidden = null + + + add_fingerprint(user) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index eb66e9c9b0..98a52994e9 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -1,283 +1,283 @@ -/obj/structure/closet/secure_closet/captains - name = "\proper captain's locker" - req_access = list(GLOB.access_captain) - icon_state = "cap" - -/obj/structure/closet/secure_closet/captains/PopulateContents() - ..() - new /obj/item/clothing/suit/hooded/wintercoat/captain(src) - if(prob(50)) - new /obj/item/weapon/storage/backpack/captain(src) - else - new /obj/item/weapon/storage/backpack/satchel/cap(src) - new /obj/item/clothing/neck/cloak/cap(src) - new /obj/item/weapon/storage/daki(src) - new /obj/item/weapon/storage/backpack/dufflebag/captain(src) - new /obj/item/clothing/head/crown/fancy(src) - new /obj/item/clothing/suit/captunic(src) - new /obj/item/clothing/under/captainparade(src) - new /obj/item/clothing/head/caphat/parade(src) - new /obj/item/clothing/under/rank/captain(src) - new /obj/item/clothing/suit/armor/vest/capcarapace/alt(src) - new /obj/item/weapon/cartridge/captain(src) - new /obj/item/clothing/shoes/sneakers/brown(src) - new /obj/item/weapon/storage/box/silver_ids(src) - new /obj/item/device/radio/headset/heads/captain/alt(src) - new /obj/item/device/radio/headset/heads/captain(src) - new /obj/item/clothing/glasses/sunglasses/gar/supergar(src) - new /obj/item/clothing/gloves/color/captain(src) - new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) - new /obj/item/weapon/storage/belt/sabre(src) - new /obj/item/weapon/gun/energy/e_gun(src) - new /obj/item/weapon/door_remote/captain(src) - -/obj/structure/closet/secure_closet/hop - name = "\proper head of personnel's locker" - req_access = list(GLOB.access_hop) - icon_state = "hop" - -/obj/structure/closet/secure_closet/hop/PopulateContents() - ..() - new /obj/item/clothing/neck/cloak/hop(src) - new /obj/item/clothing/under/rank/head_of_personnel(src) - new /obj/item/clothing/head/hopcap(src) - new /obj/item/weapon/cartridge/hop(src) - new /obj/item/device/radio/headset/heads/hop(src) - new /obj/item/clothing/shoes/sneakers/brown(src) - new /obj/item/weapon/storage/box/ids(src) - new /obj/item/weapon/storage/box/ids(src) - new /obj/item/device/megaphone/command(src) - new /obj/item/clothing/suit/armor/vest/alt(src) - new /obj/item/device/assembly/flash/handheld(src) - new /obj/item/clothing/glasses/sunglasses(src) - new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) - new /obj/item/weapon/gun/energy/e_gun(src) - new /obj/item/clothing/neck/petcollar(src) - new /obj/item/weapon/door_remote/civillian(src) - -/obj/structure/closet/secure_closet/hos - name = "\proper head of security's locker" - req_access = list(GLOB.access_hos) - icon_state = "hos" - -/obj/structure/closet/secure_closet/hos/PopulateContents() - ..() - new /obj/item/clothing/neck/cloak/hos(src) - new /obj/item/weapon/cartridge/hos(src) - new /obj/item/device/radio/headset/heads/hos(src) - new /obj/item/clothing/under/hosparadefem(src) - new /obj/item/clothing/under/hosparademale(src) - new /obj/item/clothing/suit/armor/vest/leather(src) - new /obj/item/clothing/suit/armor/hos(src) - new /obj/item/clothing/under/rank/head_of_security/alt(src) - new /obj/item/clothing/head/HoS(src) - new /obj/item/clothing/glasses/hud/security/sunglasses/eyepatch(src) - new /obj/item/clothing/glasses/hud/security/sunglasses/gars/supergars(src) - new /obj/item/device/megaphone/sec(src) - new /obj/item/weapon/holosign_creator/security(src) - new /obj/item/weapon/storage/lockbox/loyalty(src) - new /obj/item/clothing/mask/gas/sechailer/swat(src) - new /obj/item/weapon/storage/box/flashbangs(src) - new /obj/item/weapon/shield/riot/tele(src) - new /obj/item/weapon/storage/belt/security/full(src) - new /obj/item/weapon/gun/energy/e_gun/hos(src) - new /obj/item/device/flashlight/seclite(src) - new /obj/item/weapon/pinpointer(src) - -/obj/structure/closet/secure_closet/warden - name = "\proper warden's locker" - req_access = list(GLOB.access_armory) - icon_state = "warden" - -/obj/structure/closet/secure_closet/warden/PopulateContents() - ..() - new /obj/item/device/radio/headset/headset_sec(src) - new /obj/item/clothing/suit/armor/vest/warden(src) - new /obj/item/clothing/head/warden(src) - new /obj/item/clothing/head/beret/sec/navywarden(src) - new /obj/item/clothing/suit/armor/vest/warden/alt(src) - new /obj/item/clothing/under/rank/warden/navyblue(src) - new /obj/item/clothing/glasses/hud/security/sunglasses(src) - new /obj/item/weapon/holosign_creator/security(src) - new /obj/item/clothing/mask/gas/sechailer(src) - new /obj/item/weapon/storage/box/zipties(src) - new /obj/item/weapon/storage/box/flashbangs(src) - new /obj/item/weapon/storage/belt/security/full(src) - new /obj/item/device/flashlight/seclite(src) - new /obj/item/clothing/gloves/krav_maga/sec(src) - new /obj/item/weapon/door_remote/head_of_security(src) - new /obj/item/weapon/gun/ballistic/shotgun/automatic/dual_tube(src) - -/obj/structure/closet/secure_closet/security - name = "security officer's locker" - req_access = list(GLOB.access_security) - icon_state = "sec" - -/obj/structure/closet/secure_closet/security/PopulateContents() - ..() - new /obj/item/clothing/suit/armor/vest(src) - new /obj/item/clothing/head/helmet/sec(src) - new /obj/item/device/radio/headset/headset_sec(src) - new /obj/item/device/radio/headset/headset_sec/alt(src) - new /obj/item/clothing/glasses/hud/security/sunglasses(src) - new /obj/item/device/flashlight/seclite(src) - -/obj/structure/closet/secure_closet/security/sec - -/obj/structure/closet/secure_closet/security/sec/PopulateContents() - ..() - new /obj/item/weapon/storage/belt/security/full(src) - -/obj/structure/closet/secure_closet/security/cargo - -/obj/structure/closet/secure_closet/security/cargo/PopulateContents() - ..() - new /obj/item/clothing/tie/armband/cargo(src) - new /obj/item/device/encryptionkey/headset_cargo(src) - -/obj/structure/closet/secure_closet/security/engine - -/obj/structure/closet/secure_closet/security/engine/PopulateContents() - ..() - new /obj/item/clothing/tie/armband/engine(src) - new /obj/item/device/encryptionkey/headset_eng(src) - -/obj/structure/closet/secure_closet/security/science - -/obj/structure/closet/secure_closet/security/science/PopulateContents() - ..() - new /obj/item/clothing/tie/armband/science(src) - new /obj/item/device/encryptionkey/headset_sci(src) - -/obj/structure/closet/secure_closet/security/med - -/obj/structure/closet/secure_closet/security/med/PopulateContents() - ..() - new /obj/item/clothing/tie/armband/medblue(src) - new /obj/item/device/encryptionkey/headset_med(src) - -/obj/structure/closet/secure_closet/detective - name = "\proper detective's cabinet" - req_access = list(GLOB.access_forensics_lockers) - icon_state = "cabinet" - resistance_flags = FLAMMABLE - obj_integrity = 70 - max_integrity = 70 - -/obj/structure/closet/secure_closet/detective/PopulateContents() - ..() - new /obj/item/clothing/under/rank/det(src) - new /obj/item/clothing/suit/det_suit(src) - new /obj/item/clothing/head/det_hat(src) - new /obj/item/clothing/gloves/color/black(src) - new /obj/item/clothing/under/rank/det/grey(src) - new /obj/item/clothing/tie/waistcoat(src) - new /obj/item/clothing/suit/det_suit/grey(src) - new /obj/item/clothing/head/fedora(src) - new /obj/item/clothing/shoes/laceup(src) - new /obj/item/weapon/storage/box/evidence(src) - new /obj/item/device/radio/headset/headset_sec(src) - new /obj/item/device/detective_scanner(src) - new /obj/item/device/flashlight/seclite(src) - new /obj/item/weapon/holosign_creator/security(src) - new /obj/item/weapon/reagent_containers/spray/pepper(src) - new /obj/item/clothing/suit/armor/vest/det_suit(src) - new /obj/item/weapon/storage/belt/holster/full(src) - -/obj/structure/closet/secure_closet/injection - name = "lethal injections" - req_access = list(GLOB.access_hos) - -/obj/structure/closet/secure_closet/injection/PopulateContents() - ..() - for(var/i in 1 to 5) - new /obj/item/weapon/reagent_containers/syringe/lethal/execution(src) - -/obj/structure/closet/secure_closet/brig - name = "brig locker" - req_access = list(GLOB.access_brig) - anchored = 1 - var/id = null - -/obj/structure/closet/secure_closet/brig/PopulateContents() - ..() - new /obj/item/clothing/under/rank/prisoner( src ) - new /obj/item/clothing/shoes/sneakers/orange( src ) - -/obj/structure/closet/secure_closet/courtroom - name = "courtroom locker" - req_access = list(GLOB.access_court) - -/obj/structure/closet/secure_closet/courtroom/PopulateContents() - ..() - new /obj/item/clothing/shoes/sneakers/brown(src) - for(var/i in 1 to 3) - new /obj/item/weapon/paper/Court (src) - new /obj/item/weapon/pen (src) - new /obj/item/clothing/suit/judgerobe (src) - new /obj/item/clothing/head/powdered_wig (src) - new /obj/item/weapon/storage/briefcase(src) - -/obj/structure/closet/secure_closet/armory1 - name = "armory armor locker" - req_access = list(GLOB.access_armory) - icon_state = "armory" - -/obj/structure/closet/secure_closet/armory1/PopulateContents() - ..() - new /obj/item/clothing/suit/armor/laserproof(src) - for(var/i in 1 to 3) - new /obj/item/clothing/suit/armor/riot(src) - for(var/i in 1 to 3) - new /obj/item/clothing/head/helmet/riot(src) - for(var/i in 1 to 3) - new /obj/item/weapon/shield/riot(src) - -/obj/structure/closet/secure_closet/armory2 - name = "armory ballistics locker" - req_access = list(GLOB.access_armory) - icon_state = "armory" - -/obj/structure/closet/secure_closet/armory2/PopulateContents() - ..() - new /obj/item/weapon/storage/box/firingpins(src) - for(var/i in 1 to 3) - new /obj/item/weapon/storage/box/rubbershot(src) - for(var/i in 1 to 3) - new /obj/item/weapon/gun/ballistic/shotgun/riot(src) - -/obj/structure/closet/secure_closet/armory3 - name = "armory energy gun locker" - req_access = list(GLOB.access_armory) - icon_state = "armory" - -/obj/structure/closet/secure_closet/armory3/PopulateContents() - ..() - new /obj/item/weapon/storage/box/firingpins(src) - new /obj/item/weapon/gun/energy/ionrifle(src) - for(var/i in 1 to 3) - new /obj/item/weapon/gun/energy/e_gun(src) - for(var/i in 1 to 3) - new /obj/item/weapon/gun/energy/laser(src) - -/obj/structure/closet/secure_closet/tac - name = "armory tac locker" - req_access = list(GLOB.access_armory) - icon_state = "tac" - -/obj/structure/closet/secure_closet/tac/PopulateContents() - ..() - new /obj/item/weapon/gun/ballistic/automatic/wt550(src) - new /obj/item/clothing/head/helmet/alt(src) - new /obj/item/clothing/mask/gas/sechailer(src) - new /obj/item/clothing/suit/armor/bulletproof(src) - -/obj/structure/closet/secure_closet/lethalshots - name = "shotgun lethal rounds" - req_access = list(GLOB.access_armory) - icon_state = "tac" - -/obj/structure/closet/secure_closet/lethalshots/PopulateContents() - ..() - for(var/i in 1 to 3) - new /obj/item/weapon/storage/box/lethalshot(src) +/obj/structure/closet/secure_closet/captains + name = "\proper captain's locker" + req_access = list(GLOB.access_captain) + icon_state = "cap" + +/obj/structure/closet/secure_closet/captains/PopulateContents() + ..() + new /obj/item/clothing/suit/hooded/wintercoat/captain(src) + if(prob(50)) + new /obj/item/weapon/storage/backpack/captain(src) + else + new /obj/item/weapon/storage/backpack/satchel/cap(src) + new /obj/item/clothing/neck/cloak/cap(src) + new /obj/item/weapon/storage/daki(src) + new /obj/item/weapon/storage/backpack/dufflebag/captain(src) + new /obj/item/clothing/head/crown/fancy(src) + new /obj/item/clothing/suit/captunic(src) + new /obj/item/clothing/under/captainparade(src) + new /obj/item/clothing/head/caphat/parade(src) + new /obj/item/clothing/under/rank/captain(src) + new /obj/item/clothing/suit/armor/vest/capcarapace/alt(src) + new /obj/item/weapon/cartridge/captain(src) + new /obj/item/clothing/shoes/sneakers/brown(src) + new /obj/item/weapon/storage/box/silver_ids(src) + new /obj/item/device/radio/headset/heads/captain/alt(src) + new /obj/item/device/radio/headset/heads/captain(src) + new /obj/item/clothing/glasses/sunglasses/gar/supergar(src) + new /obj/item/clothing/gloves/color/captain(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/storage/belt/sabre(src) + new /obj/item/weapon/gun/energy/e_gun(src) + new /obj/item/weapon/door_remote/captain(src) + +/obj/structure/closet/secure_closet/hop + name = "\proper head of personnel's locker" + req_access = list(GLOB.access_hop) + icon_state = "hop" + +/obj/structure/closet/secure_closet/hop/PopulateContents() + ..() + new /obj/item/clothing/neck/cloak/hop(src) + new /obj/item/clothing/under/rank/head_of_personnel(src) + new /obj/item/clothing/head/hopcap(src) + new /obj/item/weapon/cartridge/hop(src) + new /obj/item/device/radio/headset/heads/hop(src) + new /obj/item/clothing/shoes/sneakers/brown(src) + new /obj/item/weapon/storage/box/ids(src) + new /obj/item/weapon/storage/box/ids(src) + new /obj/item/device/megaphone/command(src) + new /obj/item/clothing/suit/armor/vest/alt(src) + new /obj/item/device/assembly/flash/handheld(src) + new /obj/item/clothing/glasses/sunglasses(src) + new /obj/item/weapon/restraints/handcuffs/cable/zipties(src) + new /obj/item/weapon/gun/energy/e_gun(src) + new /obj/item/clothing/neck/petcollar(src) + new /obj/item/weapon/door_remote/civillian(src) + +/obj/structure/closet/secure_closet/hos + name = "\proper head of security's locker" + req_access = list(GLOB.access_hos) + icon_state = "hos" + +/obj/structure/closet/secure_closet/hos/PopulateContents() + ..() + new /obj/item/clothing/neck/cloak/hos(src) + new /obj/item/weapon/cartridge/hos(src) + new /obj/item/device/radio/headset/heads/hos(src) + new /obj/item/clothing/under/hosparadefem(src) + new /obj/item/clothing/under/hosparademale(src) + new /obj/item/clothing/suit/armor/vest/leather(src) + new /obj/item/clothing/suit/armor/hos(src) + new /obj/item/clothing/under/rank/head_of_security/alt(src) + new /obj/item/clothing/head/HoS(src) + new /obj/item/clothing/glasses/hud/security/sunglasses/eyepatch(src) + new /obj/item/clothing/glasses/hud/security/sunglasses/gars/supergars(src) + new /obj/item/device/megaphone/sec(src) + new /obj/item/weapon/holosign_creator/security(src) + new /obj/item/weapon/storage/lockbox/loyalty(src) + new /obj/item/clothing/mask/gas/sechailer/swat(src) + new /obj/item/weapon/storage/box/flashbangs(src) + new /obj/item/weapon/shield/riot/tele(src) + new /obj/item/weapon/storage/belt/security/full(src) + new /obj/item/weapon/gun/energy/e_gun/hos(src) + new /obj/item/device/flashlight/seclite(src) + new /obj/item/weapon/pinpointer(src) + +/obj/structure/closet/secure_closet/warden + name = "\proper warden's locker" + req_access = list(GLOB.access_armory) + icon_state = "warden" + +/obj/structure/closet/secure_closet/warden/PopulateContents() + ..() + new /obj/item/device/radio/headset/headset_sec(src) + new /obj/item/clothing/suit/armor/vest/warden(src) + new /obj/item/clothing/head/warden(src) + new /obj/item/clothing/head/beret/sec/navywarden(src) + new /obj/item/clothing/suit/armor/vest/warden/alt(src) + new /obj/item/clothing/under/rank/warden/navyblue(src) + new /obj/item/clothing/glasses/hud/security/sunglasses(src) + new /obj/item/weapon/holosign_creator/security(src) + new /obj/item/clothing/mask/gas/sechailer(src) + new /obj/item/weapon/storage/box/zipties(src) + new /obj/item/weapon/storage/box/flashbangs(src) + new /obj/item/weapon/storage/belt/security/full(src) + new /obj/item/device/flashlight/seclite(src) + new /obj/item/clothing/gloves/krav_maga/sec(src) + new /obj/item/weapon/door_remote/head_of_security(src) + new /obj/item/weapon/gun/ballistic/shotgun/automatic/dual_tube(src) + +/obj/structure/closet/secure_closet/security + name = "security officer's locker" + req_access = list(GLOB.access_security) + icon_state = "sec" + +/obj/structure/closet/secure_closet/security/PopulateContents() + ..() + new /obj/item/clothing/suit/armor/vest(src) + new /obj/item/clothing/head/helmet/sec(src) + new /obj/item/device/radio/headset/headset_sec(src) + new /obj/item/device/radio/headset/headset_sec/alt(src) + new /obj/item/clothing/glasses/hud/security/sunglasses(src) + new /obj/item/device/flashlight/seclite(src) + +/obj/structure/closet/secure_closet/security/sec + +/obj/structure/closet/secure_closet/security/sec/PopulateContents() + ..() + new /obj/item/weapon/storage/belt/security/full(src) + +/obj/structure/closet/secure_closet/security/cargo + +/obj/structure/closet/secure_closet/security/cargo/PopulateContents() + ..() + new /obj/item/clothing/tie/armband/cargo(src) + new /obj/item/device/encryptionkey/headset_cargo(src) + +/obj/structure/closet/secure_closet/security/engine + +/obj/structure/closet/secure_closet/security/engine/PopulateContents() + ..() + new /obj/item/clothing/tie/armband/engine(src) + new /obj/item/device/encryptionkey/headset_eng(src) + +/obj/structure/closet/secure_closet/security/science + +/obj/structure/closet/secure_closet/security/science/PopulateContents() + ..() + new /obj/item/clothing/tie/armband/science(src) + new /obj/item/device/encryptionkey/headset_sci(src) + +/obj/structure/closet/secure_closet/security/med + +/obj/structure/closet/secure_closet/security/med/PopulateContents() + ..() + new /obj/item/clothing/tie/armband/medblue(src) + new /obj/item/device/encryptionkey/headset_med(src) + +/obj/structure/closet/secure_closet/detective + name = "\proper detective's cabinet" + req_access = list(GLOB.access_forensics_lockers) + icon_state = "cabinet" + resistance_flags = FLAMMABLE + obj_integrity = 70 + max_integrity = 70 + +/obj/structure/closet/secure_closet/detective/PopulateContents() + ..() + new /obj/item/clothing/under/rank/det(src) + new /obj/item/clothing/suit/det_suit(src) + new /obj/item/clothing/head/det_hat(src) + new /obj/item/clothing/gloves/color/black(src) + new /obj/item/clothing/under/rank/det/grey(src) + new /obj/item/clothing/tie/waistcoat(src) + new /obj/item/clothing/suit/det_suit/grey(src) + new /obj/item/clothing/head/fedora(src) + new /obj/item/clothing/shoes/laceup(src) + new /obj/item/weapon/storage/box/evidence(src) + new /obj/item/device/radio/headset/headset_sec(src) + new /obj/item/device/detective_scanner(src) + new /obj/item/device/flashlight/seclite(src) + new /obj/item/weapon/holosign_creator/security(src) + new /obj/item/weapon/reagent_containers/spray/pepper(src) + new /obj/item/clothing/suit/armor/vest/det_suit(src) + new /obj/item/weapon/storage/belt/holster/full(src) + +/obj/structure/closet/secure_closet/injection + name = "lethal injections" + req_access = list(GLOB.access_hos) + +/obj/structure/closet/secure_closet/injection/PopulateContents() + ..() + for(var/i in 1 to 5) + new /obj/item/weapon/reagent_containers/syringe/lethal/execution(src) + +/obj/structure/closet/secure_closet/brig + name = "brig locker" + req_access = list(GLOB.access_brig) + anchored = 1 + var/id = null + +/obj/structure/closet/secure_closet/brig/PopulateContents() + ..() + new /obj/item/clothing/under/rank/prisoner( src ) + new /obj/item/clothing/shoes/sneakers/orange( src ) + +/obj/structure/closet/secure_closet/courtroom + name = "courtroom locker" + req_access = list(GLOB.access_court) + +/obj/structure/closet/secure_closet/courtroom/PopulateContents() + ..() + new /obj/item/clothing/shoes/sneakers/brown(src) + for(var/i in 1 to 3) + new /obj/item/weapon/paper/Court (src) + new /obj/item/weapon/pen (src) + new /obj/item/clothing/suit/judgerobe (src) + new /obj/item/clothing/head/powdered_wig (src) + new /obj/item/weapon/storage/briefcase(src) + +/obj/structure/closet/secure_closet/armory1 + name = "armory armor locker" + req_access = list(GLOB.access_armory) + icon_state = "armory" + +/obj/structure/closet/secure_closet/armory1/PopulateContents() + ..() + new /obj/item/clothing/suit/armor/laserproof(src) + for(var/i in 1 to 3) + new /obj/item/clothing/suit/armor/riot(src) + for(var/i in 1 to 3) + new /obj/item/clothing/head/helmet/riot(src) + for(var/i in 1 to 3) + new /obj/item/weapon/shield/riot(src) + +/obj/structure/closet/secure_closet/armory2 + name = "armory ballistics locker" + req_access = list(GLOB.access_armory) + icon_state = "armory" + +/obj/structure/closet/secure_closet/armory2/PopulateContents() + ..() + new /obj/item/weapon/storage/box/firingpins(src) + for(var/i in 1 to 3) + new /obj/item/weapon/storage/box/rubbershot(src) + for(var/i in 1 to 3) + new /obj/item/weapon/gun/ballistic/shotgun/riot(src) + +/obj/structure/closet/secure_closet/armory3 + name = "armory energy gun locker" + req_access = list(GLOB.access_armory) + icon_state = "armory" + +/obj/structure/closet/secure_closet/armory3/PopulateContents() + ..() + new /obj/item/weapon/storage/box/firingpins(src) + new /obj/item/weapon/gun/energy/ionrifle(src) + for(var/i in 1 to 3) + new /obj/item/weapon/gun/energy/e_gun(src) + for(var/i in 1 to 3) + new /obj/item/weapon/gun/energy/laser(src) + +/obj/structure/closet/secure_closet/tac + name = "armory tac locker" + req_access = list(GLOB.access_armory) + icon_state = "tac" + +/obj/structure/closet/secure_closet/tac/PopulateContents() + ..() + new /obj/item/weapon/gun/ballistic/automatic/wt550(src) + new /obj/item/clothing/head/helmet/alt(src) + new /obj/item/clothing/mask/gas/sechailer(src) + new /obj/item/clothing/suit/armor/bulletproof(src) + +/obj/structure/closet/secure_closet/lethalshots + name = "shotgun lethal rounds" + req_access = list(GLOB.access_armory) + icon_state = "tac" + +/obj/structure/closet/secure_closet/lethalshots/PopulateContents() + ..() + for(var/i in 1 to 3) + new /obj/item/weapon/storage/box/lethalshot(src) diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index ada75846e7..4c57c55e6a 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -1,221 +1,221 @@ -//NOT using the existing /obj/machinery/door type, since that has some complications on its own, mainly based on its -//machineryness - -/obj/structure/mineral_door - name = "metal door" - density = 1 - anchored = 1 - opacity = 1 - - icon = 'icons/obj/doors/mineral_doors.dmi' - icon_state = "metal" - - var/initial_state - var/state = 0 //closed, 1 == open - var/isSwitchingStates = 0 - var/close_delay = -1 //-1 if does not auto close. - obj_integrity = 200 - max_integrity = 200 - armor = list(melee = 10, bullet = 0, laser = 0, energy = 100, bomb = 10, bio = 100, rad = 100, fire = 50, acid = 50) - var/sheetType = /obj/item/stack/sheet/metal - var/sheetAmount = 7 - var/openSound = 'sound/effects/stonedoor_openclose.ogg' - var/closeSound = 'sound/effects/stonedoor_openclose.ogg' - CanAtmosPass = ATMOS_PASS_DENSITY - -/obj/structure/mineral_door/New(location) - ..() - initial_state = icon_state - air_update_turf(1) - -/obj/structure/mineral_door/Destroy() - density = 0 - air_update_turf(1) - return ..() - -/obj/structure/mineral_door/Move() - var/turf/T = loc - ..() - move_update_air(T) - -/obj/structure/mineral_door/Bumped(atom/user) - ..() - if(!state) - return TryToSwitchState(user) - -/obj/structure/mineral_door/attack_ai(mob/user) //those aren't machinery, they're just big fucking slabs of a mineral - if(isAI(user)) //so the AI can't open it - return - else if(iscyborg(user)) //but cyborgs can - if(get_dist(user,src) <= 1) //not remotely though - return TryToSwitchState(user) - -/obj/structure/mineral_door/attack_paw(mob/user) - return TryToSwitchState(user) - -/obj/structure/mineral_door/attack_hand(mob/user) - return TryToSwitchState(user) - -/obj/structure/mineral_door/CanPass(atom/movable/mover, turf/target, height=0) - if(istype(mover, /obj/effect/beam)) - return !opacity - return !density - -/obj/structure/mineral_door/proc/TryToSwitchState(atom/user) - if(isSwitchingStates) - return - if(isliving(user)) - var/mob/living/M = user - if(world.time - M.last_bumped <= 60) - return //NOTE do we really need that? - if(M.client) - if(iscarbon(M)) - var/mob/living/carbon/C = M - if(!C.handcuffed) - SwitchState() - else - SwitchState() - else if(istype(user, /obj/mecha)) - SwitchState() - -/obj/structure/mineral_door/proc/SwitchState() - if(state) - Close() - else - Open() - -/obj/structure/mineral_door/proc/Open() - isSwitchingStates = 1 - playsound(loc, openSound, 100, 1) - flick("[initial_state]opening",src) - sleep(10) - density = 0 - opacity = 0 - state = 1 - air_update_turf(1) - update_icon() - isSwitchingStates = 0 - - if(close_delay != -1) - addtimer(CALLBACK(src, .proc/Close), close_delay) - -/obj/structure/mineral_door/proc/Close() - if(isSwitchingStates || state != 1) - return - var/turf/T = get_turf(src) - for(var/mob/living/L in T) - return - isSwitchingStates = 1 - playsound(loc, closeSound, 100, 1) - flick("[initial_state]closing",src) - sleep(10) - density = 1 - opacity = 1 - state = 0 - air_update_turf(1) - update_icon() - isSwitchingStates = 0 - -/obj/structure/mineral_door/update_icon() - if(state) - icon_state = "[initial_state]open" - else - icon_state = initial_state - -/obj/structure/mineral_door/attackby(obj/item/weapon/W, mob/user, params) - if(istype(W,/obj/item/weapon/pickaxe)) - var/obj/item/weapon/pickaxe/digTool = W - to_chat(user, "You start digging the [name]...") - if(do_after(user,digTool.digspeed*(1+round(max_integrity*0.01)), target = src) && src) - to_chat(user, "You finish digging.") - deconstruct(TRUE) - else if(user.a_intent != INTENT_HARM) - attack_hand(user) - else - return ..() - -/obj/structure/mineral_door/deconstruct(disassembled = TRUE) - var/turf/T = get_turf(src) - if(disassembled) - new sheetType(T, sheetAmount) - else - new sheetType(T, max(sheetAmount - 2, 1)) - qdel(src) - -/obj/structure/mineral_door/iron - name = "iron door" - obj_integrity = 300 - max_integrity = 300 - -/obj/structure/mineral_door/silver - name = "silver door" - icon_state = "silver" - sheetType = /obj/item/stack/sheet/mineral/silver - obj_integrity = 300 - max_integrity = 300 - -/obj/structure/mineral_door/gold - name = "gold door" - icon_state = "gold" - sheetType = /obj/item/stack/sheet/mineral/gold - -/obj/structure/mineral_door/uranium - name = "uranium door" - icon_state = "uranium" - sheetType = /obj/item/stack/sheet/mineral/uranium - obj_integrity = 300 - max_integrity = 300 - light_range = 2 - -/obj/structure/mineral_door/sandstone - name = "sandstone door" - icon_state = "sandstone" - sheetType = /obj/item/stack/sheet/mineral/sandstone - obj_integrity = 100 - max_integrity = 100 - -/obj/structure/mineral_door/transparent - opacity = 0 - -/obj/structure/mineral_door/transparent/Close() - ..() - opacity = 0 - -/obj/structure/mineral_door/transparent/plasma - name = "plasma door" - icon_state = "plasma" - sheetType = /obj/item/stack/sheet/mineral/plasma - -/obj/structure/mineral_door/transparent/plasma/attackby(obj/item/weapon/W, mob/user, params) - if(W.is_hot()) - var/turf/T = get_turf(src) - message_admins("Plasma mineral door ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(T)]",0,1) - log_game("Plasma mineral door ignited by [key_name(user)] in [COORD(T)]") - TemperatureAct() - else - return ..() - -/obj/structure/mineral_door/transparent/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - if(exposed_temperature > 300) - TemperatureAct() - -/obj/structure/mineral_door/transparent/plasma/proc/TemperatureAct() - atmos_spawn_air("plasma=500;TEMP=1000") - deconstruct(FALSE) - -/obj/structure/mineral_door/transparent/diamond - name = "diamond door" - icon_state = "diamond" - sheetType = /obj/item/stack/sheet/mineral/diamond - obj_integrity = 1000 - max_integrity = 1000 - -/obj/structure/mineral_door/wood - name = "wood door" - icon_state = "wood" - openSound = 'sound/effects/doorcreaky.ogg' - closeSound = 'sound/effects/doorcreaky.ogg' - sheetType = /obj/item/stack/sheet/mineral/wood - resistance_flags = FLAMMABLE - obj_integrity = 200 - max_integrity = 200 +//NOT using the existing /obj/machinery/door type, since that has some complications on its own, mainly based on its +//machineryness + +/obj/structure/mineral_door + name = "metal door" + density = 1 + anchored = 1 + opacity = 1 + + icon = 'icons/obj/doors/mineral_doors.dmi' + icon_state = "metal" + + var/initial_state + var/state = 0 //closed, 1 == open + var/isSwitchingStates = 0 + var/close_delay = -1 //-1 if does not auto close. + obj_integrity = 200 + max_integrity = 200 + armor = list(melee = 10, bullet = 0, laser = 0, energy = 100, bomb = 10, bio = 100, rad = 100, fire = 50, acid = 50) + var/sheetType = /obj/item/stack/sheet/metal + var/sheetAmount = 7 + var/openSound = 'sound/effects/stonedoor_openclose.ogg' + var/closeSound = 'sound/effects/stonedoor_openclose.ogg' + CanAtmosPass = ATMOS_PASS_DENSITY + +/obj/structure/mineral_door/New(location) + ..() + initial_state = icon_state + air_update_turf(1) + +/obj/structure/mineral_door/Destroy() + density = 0 + air_update_turf(1) + return ..() + +/obj/structure/mineral_door/Move() + var/turf/T = loc + ..() + move_update_air(T) + +/obj/structure/mineral_door/Bumped(atom/user) + ..() + if(!state) + return TryToSwitchState(user) + +/obj/structure/mineral_door/attack_ai(mob/user) //those aren't machinery, they're just big fucking slabs of a mineral + if(isAI(user)) //so the AI can't open it + return + else if(iscyborg(user)) //but cyborgs can + if(get_dist(user,src) <= 1) //not remotely though + return TryToSwitchState(user) + +/obj/structure/mineral_door/attack_paw(mob/user) + return TryToSwitchState(user) + +/obj/structure/mineral_door/attack_hand(mob/user) + return TryToSwitchState(user) + +/obj/structure/mineral_door/CanPass(atom/movable/mover, turf/target, height=0) + if(istype(mover, /obj/effect/beam)) + return !opacity + return !density + +/obj/structure/mineral_door/proc/TryToSwitchState(atom/user) + if(isSwitchingStates) + return + if(isliving(user)) + var/mob/living/M = user + if(world.time - M.last_bumped <= 60) + return //NOTE do we really need that? + if(M.client) + if(iscarbon(M)) + var/mob/living/carbon/C = M + if(!C.handcuffed) + SwitchState() + else + SwitchState() + else if(istype(user, /obj/mecha)) + SwitchState() + +/obj/structure/mineral_door/proc/SwitchState() + if(state) + Close() + else + Open() + +/obj/structure/mineral_door/proc/Open() + isSwitchingStates = 1 + playsound(loc, openSound, 100, 1) + flick("[initial_state]opening",src) + sleep(10) + density = 0 + opacity = 0 + state = 1 + air_update_turf(1) + update_icon() + isSwitchingStates = 0 + + if(close_delay != -1) + addtimer(CALLBACK(src, .proc/Close), close_delay) + +/obj/structure/mineral_door/proc/Close() + if(isSwitchingStates || state != 1) + return + var/turf/T = get_turf(src) + for(var/mob/living/L in T) + return + isSwitchingStates = 1 + playsound(loc, closeSound, 100, 1) + flick("[initial_state]closing",src) + sleep(10) + density = 1 + opacity = 1 + state = 0 + air_update_turf(1) + update_icon() + isSwitchingStates = 0 + +/obj/structure/mineral_door/update_icon() + if(state) + icon_state = "[initial_state]open" + else + icon_state = initial_state + +/obj/structure/mineral_door/attackby(obj/item/weapon/W, mob/user, params) + if(istype(W,/obj/item/weapon/pickaxe)) + var/obj/item/weapon/pickaxe/digTool = W + to_chat(user, "You start digging the [name]...") + if(do_after(user,digTool.digspeed*(1+round(max_integrity*0.01)), target = src) && src) + to_chat(user, "You finish digging.") + deconstruct(TRUE) + else if(user.a_intent != INTENT_HARM) + attack_hand(user) + else + return ..() + +/obj/structure/mineral_door/deconstruct(disassembled = TRUE) + var/turf/T = get_turf(src) + if(disassembled) + new sheetType(T, sheetAmount) + else + new sheetType(T, max(sheetAmount - 2, 1)) + qdel(src) + +/obj/structure/mineral_door/iron + name = "iron door" + obj_integrity = 300 + max_integrity = 300 + +/obj/structure/mineral_door/silver + name = "silver door" + icon_state = "silver" + sheetType = /obj/item/stack/sheet/mineral/silver + obj_integrity = 300 + max_integrity = 300 + +/obj/structure/mineral_door/gold + name = "gold door" + icon_state = "gold" + sheetType = /obj/item/stack/sheet/mineral/gold + +/obj/structure/mineral_door/uranium + name = "uranium door" + icon_state = "uranium" + sheetType = /obj/item/stack/sheet/mineral/uranium + obj_integrity = 300 + max_integrity = 300 + light_range = 2 + +/obj/structure/mineral_door/sandstone + name = "sandstone door" + icon_state = "sandstone" + sheetType = /obj/item/stack/sheet/mineral/sandstone + obj_integrity = 100 + max_integrity = 100 + +/obj/structure/mineral_door/transparent + opacity = 0 + +/obj/structure/mineral_door/transparent/Close() + ..() + opacity = 0 + +/obj/structure/mineral_door/transparent/plasma + name = "plasma door" + icon_state = "plasma" + sheetType = /obj/item/stack/sheet/mineral/plasma + +/obj/structure/mineral_door/transparent/plasma/attackby(obj/item/weapon/W, mob/user, params) + if(W.is_hot()) + var/turf/T = get_turf(src) + message_admins("Plasma mineral door ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(T)]",0,1) + log_game("Plasma mineral door ignited by [key_name(user)] in [COORD(T)]") + TemperatureAct() + else + return ..() + +/obj/structure/mineral_door/transparent/plasma/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) + if(exposed_temperature > 300) + TemperatureAct() + +/obj/structure/mineral_door/transparent/plasma/proc/TemperatureAct() + atmos_spawn_air("plasma=500;TEMP=1000") + deconstruct(FALSE) + +/obj/structure/mineral_door/transparent/diamond + name = "diamond door" + icon_state = "diamond" + sheetType = /obj/item/stack/sheet/mineral/diamond + obj_integrity = 1000 + max_integrity = 1000 + +/obj/structure/mineral_door/wood + name = "wood door" + icon_state = "wood" + openSound = 'sound/effects/doorcreaky.ogg' + closeSound = 'sound/effects/doorcreaky.ogg' + sheetType = /obj/item/stack/sheet/mineral/wood + resistance_flags = FLAMMABLE + obj_integrity = 200 + max_integrity = 200 diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 6ead5a263e..b82d1f65e2 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -387,8 +387,8 @@ Traitors and the like can also be revived with the previous role mostly intact. 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() + 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 @@ -586,7 +586,7 @@ Traitors and the like can also be revived with the previous role mostly intact. 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])") + 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 diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index 44c77bb19a..d8c6427477 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -1,115 +1,115 @@ -/obj/item/device/assembly/timer - name = "timer" - desc = "Used to time things. Works well with contraptions which has to count down. Tick tock." - icon_state = "timer" - materials = list(MAT_METAL=500, MAT_GLASS=50) - origin_tech = "magnets=1;engineering=1" - attachable = 1 - - var/timing = 0 - var/time = 5 - var/saved_time = 5 - var/loop = 0 - - -/obj/item/device/assembly/timer/New() - ..() - START_PROCESSING(SSobj, src) - -/obj/item/device/assembly/timer/describe() - if(timing) - return "The timer is counting down from [time]!" - return "The timer is set for [time] seconds." - - -/obj/item/device/assembly/timer/activate() - if(!..()) - return 0//Cooldown check - timing = !timing - update_icon() - return 1 - - -/obj/item/device/assembly/timer/toggle_secure() - secured = !secured - if(secured) - START_PROCESSING(SSobj, src) - else - timing = 0 - STOP_PROCESSING(SSobj, src) - update_icon() - return secured - - -/obj/item/device/assembly/timer/proc/timer_end() - if(!secured || next_activate > world.time) - return FALSE - pulse(0) - audible_message("\icon[src] *beep* *beep*", null, 3) - if(loop) - timing = 1 - update_icon() - - -/obj/item/device/assembly/timer/process() - if(timing) - time-- - if(time <= 0) - timing = 0 - timer_end() - time = saved_time - - -/obj/item/device/assembly/timer/update_icon() - cut_overlays() - attached_overlays = list() - if(timing) - add_overlay("timer_timing") - attached_overlays += "timer_timing" - if(holder) - holder.update_icon() - - -/obj/item/device/assembly/timer/interact(mob/user)//TODO: Have this use the wires - if(is_secured(user)) - var/second = time % 60 - var/minute = (time - second) / 60 - var/dat = "Timing Unit\n[(timing ? "Timing" : "Not Timing")] [minute]:[second]\n- - + +\n" - dat += "

Stop repeating" : "1'>Set to repeat")]" - dat += "

Refresh" - dat += "

Close" - var/datum/browser/popup = new(user, "timer", name) - popup.set_content(dat) - popup.open() - - -/obj/item/device/assembly/timer/Topic(href, href_list) - ..() - if(usr.incapacitated() || !in_range(loc, usr)) - usr << browse(null, "window=timer") - onclose(usr, "timer") - return - - if(href_list["time"]) - timing = text2num(href_list["time"]) - if(timing && istype(holder, /obj/item/device/transfer_valve)) - var/timer_message = "[ADMIN_LOOKUPFLW(usr)] activated [src] attachment on [holder]." - message_admins(timer_message) - GLOB.bombers += timer_message - log_game("[key_name(usr)] activated [src] attachment on [holder]") - update_icon() - if(href_list["repeat"]) - loop = text2num(href_list["repeat"]) - - if(href_list["tp"]) - var/tp = text2num(href_list["tp"]) - time += tp - time = min(max(round(time), 1), 600) - saved_time = time - - if(href_list["close"]) - usr << browse(null, "window=timer") - return - - if(usr) - attack_self(usr) +/obj/item/device/assembly/timer + name = "timer" + desc = "Used to time things. Works well with contraptions which has to count down. Tick tock." + icon_state = "timer" + materials = list(MAT_METAL=500, MAT_GLASS=50) + origin_tech = "magnets=1;engineering=1" + attachable = 1 + + var/timing = 0 + var/time = 5 + var/saved_time = 5 + var/loop = 0 + + +/obj/item/device/assembly/timer/New() + ..() + START_PROCESSING(SSobj, src) + +/obj/item/device/assembly/timer/describe() + if(timing) + return "The timer is counting down from [time]!" + return "The timer is set for [time] seconds." + + +/obj/item/device/assembly/timer/activate() + if(!..()) + return 0//Cooldown check + timing = !timing + update_icon() + return 1 + + +/obj/item/device/assembly/timer/toggle_secure() + secured = !secured + if(secured) + START_PROCESSING(SSobj, src) + else + timing = 0 + STOP_PROCESSING(SSobj, src) + update_icon() + return secured + + +/obj/item/device/assembly/timer/proc/timer_end() + if(!secured || next_activate > world.time) + return FALSE + pulse(0) + audible_message("\icon[src] *beep* *beep*", null, 3) + if(loop) + timing = 1 + update_icon() + + +/obj/item/device/assembly/timer/process() + if(timing) + time-- + if(time <= 0) + timing = 0 + timer_end() + time = saved_time + + +/obj/item/device/assembly/timer/update_icon() + cut_overlays() + attached_overlays = list() + if(timing) + add_overlay("timer_timing") + attached_overlays += "timer_timing" + if(holder) + holder.update_icon() + + +/obj/item/device/assembly/timer/interact(mob/user)//TODO: Have this use the wires + if(is_secured(user)) + var/second = time % 60 + var/minute = (time - second) / 60 + var/dat = "Timing Unit\n[(timing ? "Timing" : "Not Timing")] [minute]:[second]\n- - + +\n" + dat += "

Stop repeating" : "1'>Set to repeat")]" + dat += "

Refresh" + dat += "

Close" + var/datum/browser/popup = new(user, "timer", name) + popup.set_content(dat) + popup.open() + + +/obj/item/device/assembly/timer/Topic(href, href_list) + ..() + if(usr.incapacitated() || !in_range(loc, usr)) + usr << browse(null, "window=timer") + onclose(usr, "timer") + return + + if(href_list["time"]) + timing = text2num(href_list["time"]) + if(timing && istype(holder, /obj/item/device/transfer_valve)) + var/timer_message = "[ADMIN_LOOKUPFLW(usr)] activated [src] attachment on [holder]." + message_admins(timer_message) + GLOB.bombers += timer_message + log_game("[key_name(usr)] activated [src] attachment on [holder]") + update_icon() + if(href_list["repeat"]) + loop = text2num(href_list["repeat"]) + + if(href_list["tp"]) + var/tp = text2num(href_list["tp"]) + time += tp + time = min(max(round(time), 1), 600) + saved_time = time + + if(href_list["close"]) + usr << browse(null, "window=timer") + return + + if(usr) + attack_self(usr) diff --git a/code/modules/atmospherics/machinery/portable/pump.dm b/code/modules/atmospherics/machinery/portable/pump.dm index 376e907ab6..16c786c044 100644 --- a/code/modules/atmospherics/machinery/portable/pump.dm +++ b/code/modules/atmospherics/machinery/portable/pump.dm @@ -1,142 +1,142 @@ -#define PUMP_OUT "out" -#define PUMP_IN "in" -#define PUMP_MAX_PRESSURE (ONE_ATMOSPHERE * 30) -#define PUMP_MIN_PRESSURE (ONE_ATMOSPHERE / 10) -#define PUMP_DEFAULT_PRESSURE (ONE_ATMOSPHERE) - -/obj/machinery/portable_atmospherics/pump - name = "portable air pump" - icon_state = "psiphon:0" - density = 1 - - var/on = FALSE - var/direction = PUMP_OUT - var/obj/machinery/atmospherics/components/binary/pump/pump - - volume = 1000 - -/obj/machinery/portable_atmospherics/pump/Initialize() - ..() - pump = new(src, FALSE) - pump.on = TRUE - pump.stat = 0 - pump.build_network() - -/obj/machinery/portable_atmospherics/pump/Destroy() - var/turf/T = get_turf(src) - T.assume_air(air_contents) - air_update_turf() - qdel(pump) - pump = null - return ..() - -/obj/machinery/portable_atmospherics/pump/update_icon() - icon_state = "psiphon:[on]" - - cut_overlays() - if(holding) - add_overlay("siphon-open") - if(connected_port) - add_overlay("siphon-connector") - -/obj/machinery/portable_atmospherics/pump/process_atmos() - ..() - if(!on) - pump.AIR1 = null - pump.AIR2 = null - return - - var/turf/T = get_turf(src) - if(direction == PUMP_OUT) // Hook up the internal pump. - pump.AIR1 = holding ? holding.air_contents : air_contents - pump.AIR2 = holding ? air_contents : T.return_air() - else - pump.AIR1 = holding ? air_contents : T.return_air() - pump.AIR2 = holding ? holding.air_contents : air_contents - - pump.process_atmos() // Pump gas. - if(!holding) - air_update_turf() // Update the environment if needed. - -/obj/machinery/portable_atmospherics/pump/emp_act(severity) - if(is_operational()) - if(prob(50 / severity)) - on = !on - if(prob(100 / severity)) - direction = PUMP_OUT - pump.target_pressure = rand(0, 100 * ONE_ATMOSPHERE) - update_icon() - ..() - - -/obj/machinery/portable_atmospherics/pump/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \ - 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, "portable_pump", name, 420, 415, master_ui, state) - ui.open() - -/obj/machinery/portable_atmospherics/pump/ui_data() - var/data = list() - data["on"] = on - data["direction"] = direction - data["connected"] = connected_port ? 1 : 0 - data["pressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0) - data["target_pressure"] = round(pump.target_pressure ? pump.target_pressure : 0) - data["default_pressure"] = round(PUMP_DEFAULT_PRESSURE) - data["min_pressure"] = round(PUMP_MIN_PRESSURE) - data["max_pressure"] = round(PUMP_MAX_PRESSURE) - - if(holding) - data["holding"] = list() - data["holding"]["name"] = holding.name - data["holding"]["pressure"] = round(holding.air_contents.return_pressure()) - return data - -/obj/machinery/portable_atmospherics/pump/ui_act(action, params) - if(..()) - return - switch(action) - if("power") - on = !on - if(on && !holding) - var/plasma = air_contents.gases["plasma"] - var/n2o = air_contents.gases["n2o"] - if(n2o || plasma) - var/area/A = get_area(src) - message_admins("[ADMIN_LOOKUPFLW(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [A][ADMIN_JMP(src)]") - log_admin("[key_name(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [A][COORD(src)]") - . = TRUE - if("direction") - if(direction == PUMP_OUT) - direction = PUMP_IN - else - direction = PUMP_OUT - . = TRUE - if("pressure") - var/pressure = params["pressure"] - if(pressure == "reset") - pressure = PUMP_DEFAULT_PRESSURE - . = TRUE - else if(pressure == "min") - pressure = PUMP_MIN_PRESSURE - . = TRUE - else if(pressure == "max") - pressure = PUMP_MAX_PRESSURE - . = TRUE - else if(pressure == "input") - pressure = input("New release pressure ([PUMP_MIN_PRESSURE]-[PUMP_MAX_PRESSURE] kPa):", name, pump.target_pressure) as num|null - if(!isnull(pressure) && !..()) - . = TRUE - else if(text2num(pressure) != null) - pressure = text2num(pressure) - . = TRUE - if(.) - pump.target_pressure = Clamp(round(pressure), PUMP_MIN_PRESSURE, PUMP_MAX_PRESSURE) - investigate_log("was set to [pump.target_pressure] kPa by [key_name(usr)].", "atmos") - if("eject") - if(holding) - holding.loc = get_turf(src) - holding = null - . = TRUE +#define PUMP_OUT "out" +#define PUMP_IN "in" +#define PUMP_MAX_PRESSURE (ONE_ATMOSPHERE * 30) +#define PUMP_MIN_PRESSURE (ONE_ATMOSPHERE / 10) +#define PUMP_DEFAULT_PRESSURE (ONE_ATMOSPHERE) + +/obj/machinery/portable_atmospherics/pump + name = "portable air pump" + icon_state = "psiphon:0" + density = 1 + + var/on = FALSE + var/direction = PUMP_OUT + var/obj/machinery/atmospherics/components/binary/pump/pump + + volume = 1000 + +/obj/machinery/portable_atmospherics/pump/Initialize() + ..() + pump = new(src, FALSE) + pump.on = TRUE + pump.stat = 0 + pump.build_network() + +/obj/machinery/portable_atmospherics/pump/Destroy() + var/turf/T = get_turf(src) + T.assume_air(air_contents) + air_update_turf() + qdel(pump) + pump = null + return ..() + +/obj/machinery/portable_atmospherics/pump/update_icon() + icon_state = "psiphon:[on]" + + cut_overlays() + if(holding) + add_overlay("siphon-open") + if(connected_port) + add_overlay("siphon-connector") + +/obj/machinery/portable_atmospherics/pump/process_atmos() + ..() + if(!on) + pump.AIR1 = null + pump.AIR2 = null + return + + var/turf/T = get_turf(src) + if(direction == PUMP_OUT) // Hook up the internal pump. + pump.AIR1 = holding ? holding.air_contents : air_contents + pump.AIR2 = holding ? air_contents : T.return_air() + else + pump.AIR1 = holding ? air_contents : T.return_air() + pump.AIR2 = holding ? holding.air_contents : air_contents + + pump.process_atmos() // Pump gas. + if(!holding) + air_update_turf() // Update the environment if needed. + +/obj/machinery/portable_atmospherics/pump/emp_act(severity) + if(is_operational()) + if(prob(50 / severity)) + on = !on + if(prob(100 / severity)) + direction = PUMP_OUT + pump.target_pressure = rand(0, 100 * ONE_ATMOSPHERE) + update_icon() + ..() + + +/obj/machinery/portable_atmospherics/pump/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \ + 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, "portable_pump", name, 420, 415, master_ui, state) + ui.open() + +/obj/machinery/portable_atmospherics/pump/ui_data() + var/data = list() + data["on"] = on + data["direction"] = direction + data["connected"] = connected_port ? 1 : 0 + data["pressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0) + data["target_pressure"] = round(pump.target_pressure ? pump.target_pressure : 0) + data["default_pressure"] = round(PUMP_DEFAULT_PRESSURE) + data["min_pressure"] = round(PUMP_MIN_PRESSURE) + data["max_pressure"] = round(PUMP_MAX_PRESSURE) + + if(holding) + data["holding"] = list() + data["holding"]["name"] = holding.name + data["holding"]["pressure"] = round(holding.air_contents.return_pressure()) + return data + +/obj/machinery/portable_atmospherics/pump/ui_act(action, params) + if(..()) + return + switch(action) + if("power") + on = !on + if(on && !holding) + var/plasma = air_contents.gases["plasma"] + var/n2o = air_contents.gases["n2o"] + if(n2o || plasma) + var/area/A = get_area(src) + message_admins("[ADMIN_LOOKUPFLW(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [A][ADMIN_JMP(src)]") + log_admin("[key_name(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [A][COORD(src)]") + . = TRUE + if("direction") + if(direction == PUMP_OUT) + direction = PUMP_IN + else + direction = PUMP_OUT + . = TRUE + if("pressure") + var/pressure = params["pressure"] + if(pressure == "reset") + pressure = PUMP_DEFAULT_PRESSURE + . = TRUE + else if(pressure == "min") + pressure = PUMP_MIN_PRESSURE + . = TRUE + else if(pressure == "max") + pressure = PUMP_MAX_PRESSURE + . = TRUE + else if(pressure == "input") + pressure = input("New release pressure ([PUMP_MIN_PRESSURE]-[PUMP_MAX_PRESSURE] kPa):", name, pump.target_pressure) as num|null + if(!isnull(pressure) && !..()) + . = TRUE + else if(text2num(pressure) != null) + pressure = text2num(pressure) + . = TRUE + if(.) + pump.target_pressure = Clamp(round(pressure), PUMP_MIN_PRESSURE, PUMP_MAX_PRESSURE) + investigate_log("was set to [pump.target_pressure] kPa by [key_name(usr)].", "atmos") + if("eject") + if(holding) + holding.loc = get_turf(src) + holding = null + . = TRUE update_icon() \ No newline at end of file diff --git a/code/modules/jobs/job_types/job.dm b/code/modules/jobs/job_types/job.dm index 9b5876c239..4d5d4eb80c 100644 --- a/code/modules/jobs/job_types/job.dm +++ b/code/modules/jobs/job_types/job.dm @@ -75,8 +75,6 @@ H.dna.features["ears"] = "None" H.regenerate_icons() - handle_roundstart_items(H) - /datum/job/proc/get_access() if(!config) //Needed for robots. return src.minimal_access.Copy() diff --git a/code/modules/mapping/ruins.dm b/code/modules/mapping/ruins.dm index a5d07591b5..f4824a96a2 100644 --- a/code/modules/mapping/ruins.dm +++ b/code/modules/mapping/ruins.dm @@ -1,93 +1,93 @@ - - -/proc/seedRuins(list/z_levels = null, budget = 0, whitelist = /area/space, list/potentialRuins) - if(!z_levels || !z_levels.len) - WARNING("No Z levels provided - Not generating ruins") - return - - for(var/zl in z_levels) - var/turf/T = locate(1, 1, zl) - if(!T) - WARNING("Z level [zl] does not exist - Not generating ruins") - return - - var/overall_sanity = 100 - var/list/ruins = potentialRuins.Copy() - - while(budget > 0 && overall_sanity > 0) - // Pick a ruin - var/datum/map_template/ruin/ruin = null - if(ruins && ruins.len) - ruin = ruins[pick(ruins)] - else - log_world("Ruin loader had no ruins to pick from with [budget] left to spend.") - break - // Can we afford it - if(ruin.cost > budget) - overall_sanity-- - continue - // If so, try to place it - var/sanity = 100 - // And if we can't fit it anywhere, give up, try again - - while(sanity > 0) - sanity-- - var/width_border = TRANSITIONEDGE + SPACERUIN_MAP_EDGE_PAD + round(ruin.width / 2) - var/height_border = TRANSITIONEDGE + SPACERUIN_MAP_EDGE_PAD + round(ruin.height / 2) - var/z_level = pick(z_levels) - var/turf/T = locate(rand(width_border, world.maxx - width_border), rand(height_border, world.maxy - height_border), z_level) - var/valid = TRUE - - for(var/turf/check in ruin.get_affected_turfs(T,1)) - var/area/new_area = get_area(check) - if(!(istype(new_area, whitelist))) - valid = FALSE - break - - if(!valid) - continue - - log_world("Ruin \"[ruin.name]\" placed at ([T.x], [T.y], [T.z])") - - var/obj/effect/ruin_loader/R = new /obj/effect/ruin_loader(T) - R.Load(ruins,ruin) - budget -= ruin.cost - if(!ruin.allow_duplicates) - ruins -= ruin.name - break - - if(!overall_sanity) - log_world("Ruin loader gave up with [budget] left to spend.") - - -/obj/effect/ruin_loader - name = "random ruin" - icon = 'icons/obj/weapons.dmi' - icon_state = "syndballoon" - invisibility = 0 - -/obj/effect/ruin_loader/proc/Load(list/potentialRuins, datum/map_template/template) - var/list/possible_ruins = list() - for(var/A in potentialRuins) - var/datum/map_template/T = potentialRuins[A] - if(!T.loaded) - possible_ruins += T - if(!template && possible_ruins.len) - template = safepick(possible_ruins) - if(!template) - return FALSE - var/turf/central_turf = get_turf(src) - for(var/i in template.get_affected_turfs(central_turf, 1)) - var/turf/T = i - for(var/mob/living/simple_animal/monster in T) - qdel(monster) - for(var/obj/structure/flora/ash/plant in T) - qdel(plant) - template.load(central_turf,centered = TRUE) - template.loaded++ - var/datum/map_template/ruin = template - if(istype(ruin)) - new /obj/effect/landmark/ruin(central_turf, ruin) - - qdel(src) - return TRUE + + +/proc/seedRuins(list/z_levels = null, budget = 0, whitelist = /area/space, list/potentialRuins) + if(!z_levels || !z_levels.len) + WARNING("No Z levels provided - Not generating ruins") + return + + for(var/zl in z_levels) + var/turf/T = locate(1, 1, zl) + if(!T) + WARNING("Z level [zl] does not exist - Not generating ruins") + return + + var/overall_sanity = 100 + var/list/ruins = potentialRuins.Copy() + + while(budget > 0 && overall_sanity > 0) + // Pick a ruin + var/datum/map_template/ruin/ruin = null + if(ruins && ruins.len) + ruin = ruins[pick(ruins)] + else + log_world("Ruin loader had no ruins to pick from with [budget] left to spend.") + break + // Can we afford it + if(ruin.cost > budget) + overall_sanity-- + continue + // If so, try to place it + var/sanity = 100 + // And if we can't fit it anywhere, give up, try again + + while(sanity > 0) + sanity-- + var/width_border = TRANSITIONEDGE + SPACERUIN_MAP_EDGE_PAD + round(ruin.width / 2) + var/height_border = TRANSITIONEDGE + SPACERUIN_MAP_EDGE_PAD + round(ruin.height / 2) + var/z_level = pick(z_levels) + var/turf/T = locate(rand(width_border, world.maxx - width_border), rand(height_border, world.maxy - height_border), z_level) + var/valid = TRUE + + for(var/turf/check in ruin.get_affected_turfs(T,1)) + var/area/new_area = get_area(check) + if(!(istype(new_area, whitelist))) + valid = FALSE + break + + if(!valid) + continue + + log_world("Ruin \"[ruin.name]\" placed at ([T.x], [T.y], [T.z])") + + var/obj/effect/ruin_loader/R = new /obj/effect/ruin_loader(T) + R.Load(ruins,ruin) + budget -= ruin.cost + if(!ruin.allow_duplicates) + ruins -= ruin.name + break + + if(!overall_sanity) + log_world("Ruin loader gave up with [budget] left to spend.") + + +/obj/effect/ruin_loader + name = "random ruin" + icon = 'icons/obj/weapons.dmi' + icon_state = "syndballoon" + invisibility = 0 + +/obj/effect/ruin_loader/proc/Load(list/potentialRuins, datum/map_template/template) + var/list/possible_ruins = list() + for(var/A in potentialRuins) + var/datum/map_template/T = potentialRuins[A] + if(!T.loaded) + possible_ruins += T + if(!template && possible_ruins.len) + template = safepick(possible_ruins) + if(!template) + return FALSE + var/turf/central_turf = get_turf(src) + for(var/i in template.get_affected_turfs(central_turf, 1)) + var/turf/T = i + for(var/mob/living/simple_animal/monster in T) + qdel(monster) + for(var/obj/structure/flora/ash/plant in T) + qdel(plant) + template.load(central_turf,centered = TRUE) + template.loaded++ + var/datum/map_template/ruin = template + if(istype(ruin)) + new /obj/effect/landmark/ruin(central_turf, ruin) + + qdel(src) + return TRUE diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index c22418cbd6..e3943d07e6 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -24,10 +24,10 @@ loc = pick(GLOB.newplayer_start) else loc = locate(1,1,1) - . = ..() - -/mob/dead/new_player/prepare_huds() - return + . = ..() + +/mob/dead/new_player/prepare_huds() + return /mob/dead/new_player/proc/new_player_panel() @@ -146,7 +146,7 @@ return 1 if(href_list["late_join"]) - if(!SSticker || !SSticker.IsRoundInProgress()) + if(!SSticker || !SSticker.IsRoundInProgress()) to_chat(usr, "The round is either not ready, or has already finished...") return @@ -371,7 +371,6 @@ if(SHUTTLE_CALL) if(SSshuttle.emergency.timeLeft(1) > initial(SSshuttle.emergencyCallTime)*0.5) SSticker.mode.make_antag_chance(humanc) - handle_roundstart_items(character) qdel(src) /mob/dead/new_player/proc/AddEmploymentContract(mob/living/carbon/human/employee) diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 4a650ae165..2c3b8bdbd4 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -354,8 +354,8 @@ dropItemToGround(I) drop_all_held_items() -/obj/item/proc/equip_to_best_slot(var/mob/M, override_held_check = FALSE) - if((src != M.get_active_held_item()) && !override_held_check) +/obj/item/proc/equip_to_best_slot(var/mob/M) + if(src != M.get_active_held_item()) to_chat(M, "You are not holding anything to equip!") return FALSE diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 1b5518008e..21e1a5648e 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -1,245 +1,245 @@ -/mob/living/carbon/human/can_equip(obj/item/I, slot, disable_warning = 0) - return dna.species.can_equip(I, slot, disable_warning, src) - -// Return the item currently in the slot ID -/mob/living/carbon/human/get_item_by_slot(slot_id) - switch(slot_id) - if(slot_back) - return back - if(slot_wear_mask) - return wear_mask - if(slot_neck) - return wear_neck - if(slot_handcuffed) - return handcuffed - if(slot_legcuffed) - return legcuffed - if(slot_belt) - return belt - if(slot_wear_id) - return wear_id - if(slot_ears) - return ears - if(slot_glasses) - return glasses - if(slot_gloves) - return gloves - if(slot_head) - return head - if(slot_shoes) - return shoes - if(slot_wear_suit) - return wear_suit - if(slot_w_uniform) - return w_uniform - if(slot_l_store) - return l_store - if(slot_r_store) - return r_store - if(slot_s_store) - return s_store - return null - -/mob/living/carbon/human/proc/get_all_slots() - . = get_head_slots() | get_body_slots() - -/mob/living/carbon/human/proc/get_body_slots() - return list( - back, - s_store, - handcuffed, - legcuffed, - wear_suit, - gloves, - shoes, - belt, - wear_id, - l_store, - r_store, - w_uniform - ) - -/mob/living/carbon/human/proc/get_head_slots() - return list( - head, - wear_mask, - glasses, - ears, - ) - -/mob/living/carbon/human/proc/get_storage_slots() - return list( - back, - belt, - l_store, - r_store, - s_store, - ) - -//This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible() -/mob/living/carbon/human/equip_to_slot(obj/item/I, slot) - if(!..()) //a check failed or the item has already found its slot - return - - var/not_handled = FALSE //Added in case we make this type path deeper one day - switch(slot) - if(slot_belt) - belt = I - update_inv_belt() - if(slot_wear_id) - wear_id = I - sec_hud_set_ID() - update_inv_wear_id() - if(slot_ears) - ears = I - update_inv_ears() - if(slot_glasses) - glasses = I - var/obj/item/clothing/glasses/G = I - if(G.glass_colour_type) - update_glasses_color(G, 1) - if(G.tint) - update_tint() - if(G.vision_correction) - clear_fullscreen("nearsighted") - if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha)) - update_sight() - update_inv_glasses() - if(slot_gloves) - gloves = I - update_inv_gloves() - if(slot_shoes) - shoes = I - update_inv_shoes() - if(slot_wear_suit) - wear_suit = I - if(I.flags_inv & HIDEJUMPSUIT) - update_inv_w_uniform() - if(wear_suit.breakouttime) //when equipping a straightjacket - stop_pulling() //can't pull if restrained - update_action_buttons_icon() //certain action buttons will no longer be usable. - update_inv_wear_suit() - if(slot_w_uniform) - w_uniform = I - update_suit_sensors() - update_inv_w_uniform() - if(slot_l_store) - l_store = I - update_inv_pockets() - if(slot_r_store) - r_store = I - update_inv_pockets() - if(slot_s_store) - s_store = I - update_inv_s_store() - else - to_chat(src, "You are trying to equip this item to an unsupported inventory slot. Report this to a coder!") - - //Item is handled and in slot, valid to call callback, for this proc should always be true - if(!not_handled) - I.equipped(src, slot) - - return not_handled //For future deeper overrides - -/mob/living/carbon/human/doUnEquip(obj/item/I, force, newloc, no_move, invdrop = TRUE) - var/index = get_held_index_of_item(I) - . = ..() //See mob.dm for an explanation on this and some rage about people copypasting instead of calling ..() like they should. - if(!. || !I) - return - if(index && dna.species.mutanthands) - put_in_hand(new dna.species.mutanthands(), index) - if(I == wear_suit) - if(s_store && invdrop) - dropItemToGround(s_store, TRUE) //It makes no sense for your suit storage to stay on you if you drop your suit. - if(wear_suit.breakouttime) //when unequipping a straightjacket - update_action_buttons_icon() //certain action buttons may be usable again. - wear_suit = null - if(I.flags_inv & HIDEJUMPSUIT) - update_inv_w_uniform() - update_inv_wear_suit() - else if(I == w_uniform) - if(invdrop) - if(r_store) - dropItemToGround(r_store, TRUE) //Again, makes sense for pockets to drop. - if(l_store) - dropItemToGround(l_store, TRUE) - if(wear_id) - dropItemToGround(wear_id) - if(belt) - dropItemToGround(belt) - w_uniform = null - update_suit_sensors() - update_inv_w_uniform(invdrop) - else if(I == gloves) - gloves = null - update_inv_gloves() - else if(I == glasses) - glasses = null - var/obj/item/clothing/glasses/G = I - if(G.glass_colour_type) - update_glasses_color(G, 0) - if(G.tint) - update_tint() - if(G.vision_correction) - if(disabilities & NEARSIGHT) - overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1) - if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha)) - update_sight() - update_inv_glasses() - else if(I == ears) - ears = null - update_inv_ears() - else if(I == shoes) - shoes = null - update_inv_shoes() - else if(I == belt) - belt = null - update_inv_belt() - else if(I == wear_id) - wear_id = null - sec_hud_set_ID() - update_inv_wear_id() - else if(I == r_store) - r_store = null - update_inv_pockets() - else if(I == l_store) - l_store = null - update_inv_pockets() - else if(I == s_store) - s_store = null - update_inv_s_store() - -/mob/living/carbon/human/wear_mask_update(obj/item/clothing/C, toggle_off = 1) - if((C.flags_inv & (HIDEHAIR|HIDEFACIALHAIR)) || (initial(C.flags_inv) & (HIDEHAIR|HIDEFACIALHAIR))) - update_hair() - if(toggle_off && internal && !getorganslot("breathing_tube")) - update_internals_hud_icon(0) - internal = null - if(C.flags_inv & HIDEEYES) - update_inv_glasses() - sec_hud_set_security_status() - ..() - -/mob/living/carbon/human/head_update(obj/item/I, forced) - if((I.flags_inv & (HIDEHAIR|HIDEFACIALHAIR)) || forced) - update_hair() - if(I.flags_inv & HIDEEYES || forced) - update_inv_glasses() - if(I.flags_inv & HIDEEARS || forced) - update_body() - sec_hud_set_security_status() - ..() - -/mob/living/carbon/human/proc/equipOutfit(outfit, visualsOnly = FALSE) - var/datum/outfit/O = null - - if(ispath(outfit)) - O = new outfit - else - O = outfit - if(!istype(O)) - return 0 - if(!O) - return 0 - - return O.equip(src, visualsOnly) +/mob/living/carbon/human/can_equip(obj/item/I, slot, disable_warning = 0) + return dna.species.can_equip(I, slot, disable_warning, src) + +// Return the item currently in the slot ID +/mob/living/carbon/human/get_item_by_slot(slot_id) + switch(slot_id) + if(slot_back) + return back + if(slot_wear_mask) + return wear_mask + if(slot_neck) + return wear_neck + if(slot_handcuffed) + return handcuffed + if(slot_legcuffed) + return legcuffed + if(slot_belt) + return belt + if(slot_wear_id) + return wear_id + if(slot_ears) + return ears + if(slot_glasses) + return glasses + if(slot_gloves) + return gloves + if(slot_head) + return head + if(slot_shoes) + return shoes + if(slot_wear_suit) + return wear_suit + if(slot_w_uniform) + return w_uniform + if(slot_l_store) + return l_store + if(slot_r_store) + return r_store + if(slot_s_store) + return s_store + return null + +/mob/living/carbon/human/proc/get_all_slots() + . = get_head_slots() | get_body_slots() + +/mob/living/carbon/human/proc/get_body_slots() + return list( + back, + s_store, + handcuffed, + legcuffed, + wear_suit, + gloves, + shoes, + belt, + wear_id, + l_store, + r_store, + w_uniform + ) + +/mob/living/carbon/human/proc/get_head_slots() + return list( + head, + wear_mask, + glasses, + ears, + ) + +/mob/living/carbon/human/proc/get_storage_slots() + return list( + back, + belt, + l_store, + r_store, + s_store, + ) + +//This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible() +/mob/living/carbon/human/equip_to_slot(obj/item/I, slot) + if(!..()) //a check failed or the item has already found its slot + return + + var/not_handled = FALSE //Added in case we make this type path deeper one day + switch(slot) + if(slot_belt) + belt = I + update_inv_belt() + if(slot_wear_id) + wear_id = I + sec_hud_set_ID() + update_inv_wear_id() + if(slot_ears) + ears = I + update_inv_ears() + if(slot_glasses) + glasses = I + var/obj/item/clothing/glasses/G = I + if(G.glass_colour_type) + update_glasses_color(G, 1) + if(G.tint) + update_tint() + if(G.vision_correction) + clear_fullscreen("nearsighted") + if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha)) + update_sight() + update_inv_glasses() + if(slot_gloves) + gloves = I + update_inv_gloves() + if(slot_shoes) + shoes = I + update_inv_shoes() + if(slot_wear_suit) + wear_suit = I + if(I.flags_inv & HIDEJUMPSUIT) + update_inv_w_uniform() + if(wear_suit.breakouttime) //when equipping a straightjacket + stop_pulling() //can't pull if restrained + update_action_buttons_icon() //certain action buttons will no longer be usable. + update_inv_wear_suit() + if(slot_w_uniform) + w_uniform = I + update_suit_sensors() + update_inv_w_uniform() + if(slot_l_store) + l_store = I + update_inv_pockets() + if(slot_r_store) + r_store = I + update_inv_pockets() + if(slot_s_store) + s_store = I + update_inv_s_store() + else + to_chat(src, "You are trying to equip this item to an unsupported inventory slot. Report this to a coder!") + + //Item is handled and in slot, valid to call callback, for this proc should always be true + if(!not_handled) + I.equipped(src, slot) + + return not_handled //For future deeper overrides + +/mob/living/carbon/human/doUnEquip(obj/item/I, force, newloc, no_move, invdrop = TRUE) + var/index = get_held_index_of_item(I) + . = ..() //See mob.dm for an explanation on this and some rage about people copypasting instead of calling ..() like they should. + if(!. || !I) + return + if(index && dna.species.mutanthands) + put_in_hand(new dna.species.mutanthands(), index) + if(I == wear_suit) + if(s_store && invdrop) + dropItemToGround(s_store, TRUE) //It makes no sense for your suit storage to stay on you if you drop your suit. + if(wear_suit.breakouttime) //when unequipping a straightjacket + update_action_buttons_icon() //certain action buttons may be usable again. + wear_suit = null + if(I.flags_inv & HIDEJUMPSUIT) + update_inv_w_uniform() + update_inv_wear_suit() + else if(I == w_uniform) + if(invdrop) + if(r_store) + dropItemToGround(r_store, TRUE) //Again, makes sense for pockets to drop. + if(l_store) + dropItemToGround(l_store, TRUE) + if(wear_id) + dropItemToGround(wear_id) + if(belt) + dropItemToGround(belt) + w_uniform = null + update_suit_sensors() + update_inv_w_uniform(invdrop) + else if(I == gloves) + gloves = null + update_inv_gloves() + else if(I == glasses) + glasses = null + var/obj/item/clothing/glasses/G = I + if(G.glass_colour_type) + update_glasses_color(G, 0) + if(G.tint) + update_tint() + if(G.vision_correction) + if(disabilities & NEARSIGHT) + overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1) + if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha)) + update_sight() + update_inv_glasses() + else if(I == ears) + ears = null + update_inv_ears() + else if(I == shoes) + shoes = null + update_inv_shoes() + else if(I == belt) + belt = null + update_inv_belt() + else if(I == wear_id) + wear_id = null + sec_hud_set_ID() + update_inv_wear_id() + else if(I == r_store) + r_store = null + update_inv_pockets() + else if(I == l_store) + l_store = null + update_inv_pockets() + else if(I == s_store) + s_store = null + update_inv_s_store() + +/mob/living/carbon/human/wear_mask_update(obj/item/clothing/C, toggle_off = 1) + if((C.flags_inv & (HIDEHAIR|HIDEFACIALHAIR)) || (initial(C.flags_inv) & (HIDEHAIR|HIDEFACIALHAIR))) + update_hair() + if(toggle_off && internal && !getorganslot("breathing_tube")) + update_internals_hud_icon(0) + internal = null + if(C.flags_inv & HIDEEYES) + update_inv_glasses() + sec_hud_set_security_status() + ..() + +/mob/living/carbon/human/head_update(obj/item/I, forced) + if((I.flags_inv & (HIDEHAIR|HIDEFACIALHAIR)) || forced) + update_hair() + if(I.flags_inv & HIDEEYES || forced) + update_inv_glasses() + if(I.flags_inv & HIDEEARS || forced) + update_body() + sec_hud_set_security_status() + ..() + +/mob/living/carbon/human/proc/equipOutfit(outfit, visualsOnly = FALSE) + var/datum/outfit/O = null + + if(ispath(outfit)) + O = new outfit + else + O = outfit + if(!istype(O)) + return 0 + if(!O) + return 0 + + return O.equip(src, visualsOnly) diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index af24d7b6c4..aba76f570a 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -1,699 +1,699 @@ -/datum/species/golem - // Animated beings of stone. They have increased defenses, and do not need to breathe. They're also slow as fuuuck. - name = "Golem" - id = "iron golem" - species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR) - mutant_organs = list(/obj/item/organ/adamantine_resonator) - speedmod = 2 - armor = 55 - siemens_coeff = 0 - punchdamagelow = 5 - punchdamagehigh = 14 - punchstunthreshold = 11 //about 40% chance to stun - no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform, slot_s_store) - nojumpsuit = 1 - sexes = 1 - damage_overlay_type = "" - meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem - // To prevent golem subtypes from overwhelming the odds when random species - // changes, only the Random Golem type can be chosen - blacklisted = TRUE - dangerous_existence = TRUE - limbs_id = "golem" - fixed_mut_color = "aaa" - var/info_text = "As an Iron Golem, you don't have any special traits." - - var/prefix = "Iron" - var/list/special_names - var/human_surname_chance = 3 - var/special_name_chance = 5 - -/datum/species/golem/random_name(gender,unique,lastname) - var/golem_surname = pick(GLOB.golem_names) - // 3% chance that our golem has a human surname, because - // cultural contamination - if(prob(human_surname_chance)) - golem_surname = pick(GLOB.last_names) - else if(special_names && special_names.len && prob(special_name_chance)) - golem_surname = pick(special_names) - - var/golem_name = "[prefix] [golem_surname]" - return golem_name - -/datum/species/golem/random - name = "Random Golem" - blacklisted = FALSE - dangerous_existence = FALSE - -/datum/species/golem/random/on_species_gain(mob/living/carbon/C, datum/species/old_species) - ..() - var/list/golem_types = typesof(/datum/species/golem) - src.type - var/datum/species/golem/golem_type = pick(golem_types) - var/mob/living/carbon/human/H = C - H.set_species(golem_type) - to_chat(H, "[initial(golem_type.info_text)]") - -/datum/species/golem/adamantine - name = "Adamantine Golem" - id = "adamantine golem" - meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem/adamantine - mutant_organs = list(/obj/item/organ/adamantine_resonator, /obj/item/organ/vocal_cords/adamantine) - fixed_mut_color = "4ed" - info_text = "As an Adamantine Golem, you possess special vocal cords allowing you to \"resonate\" messages to all golems." - prefix = "Adamantine" - -//The suicide bombers of golemkind -/datum/species/golem/plasma - name = "Plasma Golem" - id = "plasma golem" - fixed_mut_color = "a3d" - meat = /obj/item/weapon/ore/plasma - //Can burn and takes damage from heat - species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR) - info_text = "As a Plasma Golem, you burn easily. Be careful, if you get hot enough while burning, you'll blow up!" - heatmod = 0 //fine until they blow up - prefix = "Plasma" - special_names = list("Flood","Fire","Bar","Man") - var/boom_warning = FALSE - var/datum/action/innate/ignite/ignite - -/datum/species/golem/plasma/spec_life(mob/living/carbon/human/H) - if(H.bodytemperature > 750) - if(!boom_warning && H.on_fire) - to_chat(H, "You feel like you could blow up at any moment!") - boom_warning = TRUE - else - if(boom_warning) - to_chat(H, "You feel more stable.") - boom_warning = FALSE - - if(H.bodytemperature > 850 && H.on_fire && prob(25)) - explosion(get_turf(H),1,2,4,flame_range = 5) - if(H) - H.gib() - if(H.fire_stacks < 2) //flammable - H.adjust_fire_stacks(1) - ..() - -/datum/species/golem/plasma/on_species_gain(mob/living/carbon/C, datum/species/old_species) - ..() - if(ishuman(C)) - ignite = new - ignite.Grant(C) - -/datum/species/golem/plasma/on_species_loss(mob/living/carbon/C) - if(ignite) - ignite.Remove(C) - ..() - -/datum/action/innate/ignite - name = "Ignite" - desc = "Set yourself aflame, bringing yourself closer to exploding!" - check_flags = AB_CHECK_CONSCIOUS - button_icon_state = "sacredflame" - -/datum/action/innate/ignite/Activate() - if(ishuman(owner)) - var/mob/living/carbon/human/H = owner - if(H.fire_stacks) - to_chat(owner, "You ignite yourself!") - else - to_chat(owner, "You try ignite yourself, but fail!") - H.IgniteMob() //firestacks are already there passively - -//Harder to hurt -/datum/species/golem/diamond - name = "Diamond Golem" - id = "diamond golem" - fixed_mut_color = "0ff" - armor = 70 //up from 55 - meat = /obj/item/weapon/ore/diamond - info_text = "As a Diamond Golem, you are more resistant than the average golem." - prefix = "Diamond" - special_names = list("Back") - -//Faster but softer and less armoured -/datum/species/golem/gold - name = "Gold Golem" - id = "gold golem" - fixed_mut_color = "cc0" - speedmod = 1 - armor = 25 //down from 55 - meat = /obj/item/weapon/ore/gold - info_text = "As a Gold Golem, you are faster but less resistant than the average golem." - prefix = "Golden" - -//Heavier, thus higher chance of stunning when punching -/datum/species/golem/silver - name = "Silver Golem" - id = "silver golem" - fixed_mut_color = "ddd" - punchstunthreshold = 9 //60% chance, from 40% - meat = /obj/item/weapon/ore/silver - info_text = "As a Silver Golem, your attacks are heavier and have a higher chance of stunning." - prefix = "Silver" - special_names = list("Surfer", "Chariot", "Lining") - -//Harder to stun, deals more damage, but it's even slower -/datum/species/golem/plasteel - name = "Plasteel Golem" - id = "plasteel golem" - fixed_mut_color = "bbb" - stunmod = 0.40 - punchdamagelow = 12 - punchdamagehigh = 21 - punchstunthreshold = 18 //still 40% stun chance - speedmod = 4 //pretty fucking slow - meat = /obj/item/weapon/ore/iron - info_text = "As a Plasteel Golem, you are slower, but harder to stun, and hit very hard when punching." - attack_verb = "smash" - attack_sound = 'sound/effects/meteorimpact.ogg' //hits pretty hard - prefix = "Plasteel" - -//Immune to ash storms -/datum/species/golem/titanium - name = "Titanium Golem" - id = "titanium golem" - fixed_mut_color = "fff" - meat = /obj/item/weapon/ore/titanium - info_text = "As a Titanium Golem, you are immune to ash storms, and slightly more resistant to burn damage." - burnmod = 0.9 - prefix = "Titanium" - -/datum/species/golem/titanium/on_species_gain(mob/living/carbon/C, datum/species/old_species) - . = ..() - C.weather_immunities |= "ash" - -/datum/species/golem/titanium/on_species_loss(mob/living/carbon/C) - . = ..() - C.weather_immunities -= "ash" - -//Immune to ash storms and lava -/datum/species/golem/plastitanium - name = "Plastitanium Golem" - id = "plastitanium golem" - fixed_mut_color = "888" - meat = /obj/item/weapon/ore/titanium - info_text = "As a Plastitanium Golem, you are immune to both ash storms and lava, and slightly more resistant to burn damage." - burnmod = 0.8 - prefix = "Plastitanium" - -/datum/species/golem/plastitanium/on_species_gain(mob/living/carbon/C, datum/species/old_species) - . = ..() - C.weather_immunities |= "lava" - C.weather_immunities |= "ash" - -/datum/species/golem/plastitanium/on_species_loss(mob/living/carbon/C) - . = ..() - C.weather_immunities -= "ash" - C.weather_immunities -= "lava" - -//Fast and regenerates... but can only speak like an abductor -/datum/species/golem/alloy - name = "Alien Alloy Golem" - id = "alloy golem" - fixed_mut_color = "333" - meat = /obj/item/stack/sheet/mineral/abductor - mutanttongue = /obj/item/organ/tongue/abductor - speedmod = 1 //faster - info_text = "As an Alloy Golem, you are made of advanced alien materials: you are faster and regenerate over time. You are, however, only able to be heard by other alloy golems." - prefix = "Alien" - special_names = list("Outsider", "Technology", "Watcher", "Stranger") //ominous and unknown - -//Regenerates because self-repairing super-advanced alien tech -/datum/species/golem/alloy/spec_life(mob/living/carbon/human/H) - if(H.stat == DEAD) - return - H.heal_overall_damage(2,2) - H.adjustToxLoss(-2) - H.adjustOxyLoss(-2) - -//Since this will usually be created from a collaboration between podpeople and free golems, wood golems are a mix between the two races -/datum/species/golem/wood - name = "Wood Golem" - id = "wood golem" - fixed_mut_color = "49311c" - meat = /obj/item/stack/sheet/mineral/wood - //Can burn and take damage from heat - species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR) - armor = 30 - burnmod = 1.25 - heatmod = 1.5 - info_text = "As a Wooden Golem, you have plant-like traits: you take damage from extreme temperatures, can be set on fire, and have lower armor than a normal golem. You regenerate when in the light and wither in the darkness." - prefix = "Wooden" - special_names = list("Tomato", "Potato", "Broccoli", "Carrot", "Ambrosia", "Pumpkin", "Ivy", "Kudzu", "Banana", "Moss", "Flower", "Bloom", "Root", "Bark", "Glowshroom", "Petal", "Leaf", "Venus", "Sprout","Cocoa", "Strawberry", "Citrus", "Oak", "Cactus", "Pepper", "Juniper") - human_surname_chance = 0 - special_name_chance = 100 - -/datum/species/golem/wood/on_species_gain(mob/living/carbon/C, datum/species/old_species) - . = ..() - C.faction |= "plants" - C.faction |= "vines" - -/datum/species/golem/wood/on_species_loss(mob/living/carbon/C) - . = ..() - C.faction -= "plants" - C.faction -= "vines" - -/datum/species/golem/wood/spec_life(mob/living/carbon/human/H) - if(H.stat == DEAD) - return - var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing - if(isturf(H.loc)) //else, there's considered to be no light - var/turf/T = H.loc - light_amount = min(1,T.get_lumcount()) - 0.5 - H.nutrition += light_amount * 10 - if(H.nutrition > NUTRITION_LEVEL_FULL) - H.nutrition = NUTRITION_LEVEL_FULL - if(light_amount > 0.2) //if there's enough light, heal - H.heal_overall_damage(1,1) - H.adjustToxLoss(-1) - H.adjustOxyLoss(-1) - - if(H.nutrition < NUTRITION_LEVEL_STARVING + 50) - H.take_overall_damage(2,0) - -/datum/species/golem/wood/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H) - if(chem.id == "plantbgone") - H.adjustToxLoss(3) - H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM) - return 1 - -//Radioactive -/datum/species/golem/uranium - name = "Uranium Golem" - id = "uranium golem" - fixed_mut_color = "7f0" - meat = /obj/item/weapon/ore/uranium - info_text = "As an Uranium Golem, you emit radiation pulses every once in a while. It won't harm fellow golems, but organic lifeforms will be affected." - - var/last_event = 0 - var/active = null - prefix = "Uranium" - -/datum/species/golem/uranium/spec_life(mob/living/carbon/human/H) - if(!active) - if(world.time > last_event+30) - active = 1 - radiation_pulse(get_turf(H), 3, 3, 5, 0) - last_event = world.time - active = null - ..() - -//Immune to physical bullets and resistant to brute, but very vulnerable to burn damage. Dusts on death. -/datum/species/golem/sand - name = "Sand Golem" - id = "sand golem" - fixed_mut_color = "ffdc8f" - meat = /obj/item/weapon/ore/glass //this is sand - armor = 0 - burnmod = 3 //melts easily - brutemod = 0.25 - info_text = "As a Sand Golem, you are immune to physical bullets and take very little brute damage, but are extremely vulnerable to burn damage. You will also turn to sand when dying, preventing any form of recovery." - attack_sound = 'sound/effects/shovel_dig.ogg' - prefix = "Sand" - -/datum/species/golem/sand/spec_death(gibbed, mob/living/carbon/human/H) - H.visible_message("[H] turns into a pile of sand!") - for(var/obj/item/W in H) - H.dropItemToGround(W) - for(var/i=1, i <= rand(3,5), i++) - new /obj/item/weapon/ore/glass(get_turf(H)) - qdel(H) - -/datum/species/golem/sand/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H) - if(!(P.original == H && P.firer == H)) - if(P.flag == "bullet" || P.flag == "bomb") - playsound(H, 'sound/effects/shovel_dig.ogg', 70, 1) - H.visible_message("The [P.name] sinks harmlessly in [H]'s sandy body!", \ - "The [P.name] sinks harmlessly in [H]'s sandy body!") - return 2 - return 0 - -//Reflects lasers and resistant to burn damage, but very vulnerable to brute damage. Shatters on death. -/datum/species/golem/glass - name = "Glass Golem" - id = "glass golem" - fixed_mut_color = "5a96b4aa" //transparent body - meat = /obj/item/weapon/shard - armor = 0 - brutemod = 3 //very fragile - burnmod = 0.25 - info_text = "As a Glass Golem, you reflect lasers and energy weapons, and are very resistant to burn damage, but you are extremely vulnerable to brute damage. On death, you'll shatter beyond any hope of recovery." - attack_sound = 'sound/effects/Glassbr2.ogg' - prefix = "Glass" - -/datum/species/golem/glass/spec_death(gibbed, mob/living/carbon/human/H) - playsound(H, "shatter", 70, 1) - H.visible_message("[H] shatters!") - for(var/obj/item/W in H) - H.dropItemToGround(W) - for(var/i=1, i <= rand(3,5), i++) - new /obj/item/weapon/shard(get_turf(H)) - qdel(H) - -/datum/species/golem/glass/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H) - if(!(P.original == H && P.firer == H)) //self-shots don't reflect - if(P.flag == "laser" || P.flag == "energy") - H.visible_message("The [P.name] gets reflected by [H]'s glass skin!", \ - "The [P.name] gets reflected by [H]'s glass skin!") - if(P.starting) - var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) - var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) - var/turf/curloc = get_turf(H) - - // redirect the projectile - P.original = locate(new_x, new_y, P.z) - P.starting = curloc - P.current = curloc - P.firer = H - P.yo = new_y - curloc.y - P.xo = new_x - curloc.x - P.Angle = null - return -1 - return 0 - -//Teleports when hit or when it wants to -/datum/species/golem/bluespace - name = "Bluespace Golem" - id = "bluespace golem" - fixed_mut_color = "33f" - meat = /obj/item/weapon/ore/bluespace_crystal - info_text = "As a Bluespace Golem, are spatially unstable: you will teleport when hit, and you can teleport manually at a long distance." - attack_verb = "bluespace punch" - attack_sound = 'sound/effects/phasein.ogg' - prefix = "Bluespace" - special_names = list("Crystal", "Polycrystal") - - var/datum/action/innate/unstable_teleport/unstable_teleport - var/teleport_cooldown = 100 - var/last_teleport = 0 - -/datum/species/golem/bluespace/proc/reactive_teleport(mob/living/carbon/human/H) - H.visible_message("[H] teleports!", "You destabilize and teleport!") - new /obj/effect/particle_effect/sparks(get_turf(H)) - playsound(get_turf(H), "sparks", 50, 1) - do_teleport(H, get_turf(H), 6, asoundin = 'sound/weapons/emitter2.ogg') - last_teleport = world.time - -/datum/species/golem/bluespace/spec_hitby(atom/movable/AM, mob/living/carbon/human/H) - ..() - var/obj/item/I - if(istype(AM, /obj/item)) - I = AM - if(I.thrownby == H) //No throwing stuff at yourself to trigger the teleport - return 0 - else - reactive_teleport(H) - -/datum/species/golem/bluespace/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art) - ..() - if(world.time > last_teleport + teleport_cooldown && M != H && M.a_intent != INTENT_HELP) - reactive_teleport(H) - -/datum/species/golem/bluespace/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H) - ..() - if(world.time > last_teleport + teleport_cooldown && user != H) - reactive_teleport(H) - -/datum/species/golem/bluespace/on_hit(obj/item/projectile/P, mob/living/carbon/human/H) - ..() - if(world.time > last_teleport + teleport_cooldown) - reactive_teleport(H) - -/datum/species/golem/bluespace/on_species_gain(mob/living/carbon/C, datum/species/old_species) - ..() - if(ishuman(C)) - unstable_teleport = new - unstable_teleport.Grant(C) - -/datum/species/golem/bluespace/on_species_loss(mob/living/carbon/C) - if(unstable_teleport) - unstable_teleport.Remove(C) - ..() - -/datum/action/innate/unstable_teleport - name = "Unstable Teleport" - check_flags = AB_CHECK_CONSCIOUS - button_icon_state = "jaunt" - var/cooldown = 150 - var/last_teleport = 0 - -/datum/action/innate/unstable_teleport/IsAvailable() - if(..()) - if(world.time > last_teleport + cooldown) - return 1 - return 0 - -/datum/action/innate/unstable_teleport/Activate() - var/mob/living/carbon/human/H = owner - H.visible_message("[H] starts vibrating!", "You start charging your bluespace core...") - playsound(get_turf(H), 'sound/weapons/flash.ogg', 25, 1) - addtimer(CALLBACK(src, .proc/teleport, H), 15) - -/datum/action/innate/unstable_teleport/proc/teleport(mob/living/carbon/human/H) - H.visible_message("[H] disappears in a shower of sparks!", "You teleport!") - var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread - spark_system.set_up(10, 0, src) - spark_system.attach(H) - spark_system.start() - do_teleport(H, get_turf(H), 12, asoundin = 'sound/weapons/emitter2.ogg') - last_teleport = world.time - UpdateButtonIcon() //action icon looks unavailable - sleep(cooldown + 5) - UpdateButtonIcon() //action icon looks available again - - -//honk -/datum/species/golem/bananium - name = "Bananium Golem" - id = "bananium golem" - fixed_mut_color = "ff0" - say_mod = "honks" - punchdamagelow = 0 - punchdamagehigh = 1 - punchstunthreshold = 2 //Harmless and can't stun - meat = /obj/item/weapon/ore/bananium - info_text = "As a Bananium Golem, you are made for pranking. Your body emits natural honks, and you cannot hurt people when punching them. Your skin also emits bananas when damaged." - attack_verb = "honk" - attack_sound = 'sound/items/AirHorn2.ogg' - prefix = "Bananium" - - var/last_honk = 0 - var/honkooldown = 0 - var/last_banana = 0 - var/banana_cooldown = 100 - var/active = null - -/datum/species/golem/bananium/random_name(gender,unique,lastname) - var/clown_name = pick(GLOB.clown_names) - var/golem_name = "[uppertext(clown_name)]" - return golem_name - -/datum/species/golem/bananium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art) - ..() - if(world.time > last_banana + banana_cooldown && M != H && M.a_intent != INTENT_HELP) - new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(H)) - last_banana = world.time - -/datum/species/golem/bananium/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H) - ..() - if(world.time > last_banana + banana_cooldown && user != H) - new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(H)) - last_banana = world.time - -/datum/species/golem/bananium/on_hit(obj/item/projectile/P, mob/living/carbon/human/H) - ..() - if(world.time > last_banana + banana_cooldown) - new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(H)) - last_banana = world.time - -/datum/species/golem/bananium/spec_hitby(atom/movable/AM, mob/living/carbon/human/H) - ..() - var/obj/item/I - if(istype(AM, /obj/item)) - I = AM - if(I.thrownby == H) //No throwing stuff at yourself to make bananas - return 0 - else - new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(H)) - last_banana = world.time - -/datum/species/golem/bananium/spec_life(mob/living/carbon/human/H) - if(!active) - if(world.time > last_honk + honkooldown) - active = 1 - playsound(get_turf(H), 'sound/items/bikehorn.ogg', 50, 1) - last_honk = world.time - honkooldown = rand(20, 80) - active = null - ..() - -/datum/species/golem/bananium/spec_death(gibbed, mob/living/carbon/human/H) - playsound(get_turf(H), 'sound/misc/sadtrombone.ogg', 70, 0) - -/datum/species/golem/bananium/get_spans() - return list(SPAN_CLOWN) - - -/datum/species/golem/runic - name = "Runic Golem" - id = "runic golem" - limbs_id = "cultgolem" - sexes = FALSE - info_text = "As a Runic Golem, you possess eldritch powers granted by the Elder God Nar'Sie." - species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR) //no mutcolors - prefix = "Runic" - - var/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/golem/phase_shift - var/obj/effect/proc_holder/spell/targeted/abyssal_gaze/abyssal_gaze - var/obj/effect/proc_holder/spell/targeted/dominate/dominate - -/datum/species/golem/runic/random_name(gender,unique,lastname) - var/edgy_first_name = pick("Razor","Blood","Dark","Evil","Cold","Pale","Black","Silent","Chaos","Deadly") - var/edgy_last_name = pick("Edge","Night","Death","Razor","Blade","Steel","Calamity","Twilight","Shadow","Nightmare") //dammit Razor Razor - var/golem_name = "[edgy_first_name] [edgy_last_name]" - return golem_name - -/datum/species/golem/runic/on_species_gain(mob/living/carbon/C, datum/species/old_species) - . = ..() - C.faction |= "cult" - phase_shift = new - C.AddSpell(phase_shift) - abyssal_gaze = new - C.AddSpell(abyssal_gaze) - dominate = new - C.AddSpell(dominate) - -/datum/species/golem/runic/on_species_loss(mob/living/carbon/C) - . = ..() - C.faction -= "cult" - if(phase_shift) - C.RemoveSpell(phase_shift) - if(abyssal_gaze) - C.RemoveSpell(abyssal_gaze) - if(dominate) - C.RemoveSpell(dominate) - -/datum/species/golem/runic/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H) - if(chem.id == "holywater") - H.adjustFireLoss(4) - H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM) - - if(chem.id == "unholywater") - H.adjustBruteLoss(-4) - H.adjustFireLoss(-4) - H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM) - -/datum/species/golem/cloth - name = "Cloth Golem" - id = "cloth golem" - limbs_id = "clothgolem" - sexes = FALSE - info_text = "As a Cloth Golem, you are able to reform yourself after death, provided your remains aren't burned or destroyed. You are, of course, very flammable." - species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR) //no mutcolors, and can burn - armor = 15 //feels no pain, but not too resistant - burnmod = 2 // don't get burned - speedmod = 1 // not as heavy as stone - punchdamagelow = 4 - punchstunthreshold = 7 - punchdamagehigh = 8 // not as heavy as stone - prefix = "Cloth" - -/datum/species/golem/cloth/random_name(gender,unique,lastname) - var/pharaoh_name = pick("Neferkare", "Hudjefa", "Khufu", "Mentuhotep", "Ahmose", "Amenhotep", "Thutmose", "Hatshepsut", "Tutankhamun", "Ramses", "Seti", \ - "Merenptah", "Djer", "Semerkhet", "Nynetjer", "Khafre", "Pepi", "Intef", "Ay") //yes, Ay was an actual pharaoh - var/golem_name = "[pharaoh_name] \Roman[rand(1,99)]" - return golem_name - -/datum/species/golem/cloth/spec_life(mob/living/carbon/human/H) - if(H.fire_stacks < 1) - H.adjust_fire_stacks(1) //always prone to burning - ..() - -/datum/species/golem/cloth/spec_death(gibbed, mob/living/carbon/human/H) - if(gibbed) - return - if(H.on_fire) - H.visible_message("[H] burns into ash!") - H.dust(just_ash = TRUE) - return - - H.visible_message("[H] falls apart into a pile of bandages!") - new /obj/structure/cloth_pile(get_turf(H), H) - ..() - -/obj/structure/cloth_pile - name = "pile of bandages" - desc = "It emits a strange aura, as if there was still life within it..." - obj_integrity = 50 - max_integrity = 50 - armor = list(melee = 90, bullet = 90, laser = 25, energy = 80, bomb = 50, bio = 100, fire = -50, acid = -50) - icon = 'icons/obj/items.dmi' - icon_state = "pile_bandages" - resistance_flags = FLAMMABLE - - var/revive_time = 900 - var/mob/living/carbon/human/cloth_golem - -/obj/structure/cloth_pile/Initialize(mapload, mob/living/carbon/human/H) - if(!QDELETED(H) && is_species(H, /datum/species/golem/cloth)) - H.unequip_everything() - H.forceMove(src) - cloth_golem = H - to_chat(cloth_golem, "You start gathering your life energy, preparing to rise again...") - addtimer(CALLBACK(src, .proc/revive), revive_time) - else - qdel(src) - -/obj/structure/cloth_pile/Destroy() - if(cloth_golem) - QDEL_NULL(cloth_golem) - return ..() - -/obj/structure/cloth_pile/burn() - visible_message("[src] burns into ash!") - new /obj/effect/decal/cleanable/ash(get_turf(src)) - ..() - -/obj/structure/cloth_pile/proc/revive() - if(QDELETED(src) || QDELETED(cloth_golem)) //QDELETED also checks for null, so if no cloth golem is set this won't runtime - return - if(cloth_golem.suiciding || cloth_golem.disabilities & NOCLONE) - QDEL_NULL(cloth_golem) - return - - invisibility = INVISIBILITY_MAXIMUM //disappear before the animation - new /obj/effect/overlay/temp/mummy_animation(get_turf(src)) - if(cloth_golem.revive(full_heal = TRUE, admin_revive = TRUE)) - cloth_golem.grab_ghost() //won't pull if it's a suicide - sleep(20) - cloth_golem.forceMove(get_turf(src)) - cloth_golem.visible_message("[src] rises and reforms into [cloth_golem]!","You reform into yourself!") - cloth_golem = null - qdel(src) - -/obj/structure/cloth_pile/attackby(obj/item/weapon/P, mob/living/carbon/human/user, params) - . = ..() - - if(resistance_flags & ON_FIRE) - return - - if(P.is_hot()) - visible_message("[src] bursts into flames!") - fire_act() - -/datum/species/golem/plastic - name = "Plastic" - id = "plastic golem" - prefix = "Plastic" - fixed_mut_color = "fff" - info_text = "As a Plastic Golem, you are capable of ventcrawling, and passing through plastic flaps." - -/datum/species/golem/plastic/on_species_gain(mob/living/carbon/C, datum/species/old_species) - . = ..() - C.ventcrawler = VENTCRAWLER_NUDE - -/datum/species/golem/plastic/on_species_loss(mob/living/carbon/C) - . = ..() +/datum/species/golem + // Animated beings of stone. They have increased defenses, and do not need to breathe. They're also slow as fuuuck. + name = "Golem" + id = "iron golem" + species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR) + mutant_organs = list(/obj/item/organ/adamantine_resonator) + speedmod = 2 + armor = 55 + siemens_coeff = 0 + punchdamagelow = 5 + punchdamagehigh = 14 + punchstunthreshold = 11 //about 40% chance to stun + no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform, slot_s_store) + nojumpsuit = 1 + sexes = 1 + damage_overlay_type = "" + meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem + // To prevent golem subtypes from overwhelming the odds when random species + // changes, only the Random Golem type can be chosen + blacklisted = TRUE + dangerous_existence = TRUE + limbs_id = "golem" + fixed_mut_color = "aaa" + var/info_text = "As an Iron Golem, you don't have any special traits." + + var/prefix = "Iron" + var/list/special_names + var/human_surname_chance = 3 + var/special_name_chance = 5 + +/datum/species/golem/random_name(gender,unique,lastname) + var/golem_surname = pick(GLOB.golem_names) + // 3% chance that our golem has a human surname, because + // cultural contamination + if(prob(human_surname_chance)) + golem_surname = pick(GLOB.last_names) + else if(special_names && special_names.len && prob(special_name_chance)) + golem_surname = pick(special_names) + + var/golem_name = "[prefix] [golem_surname]" + return golem_name + +/datum/species/golem/random + name = "Random Golem" + blacklisted = FALSE + dangerous_existence = FALSE + +/datum/species/golem/random/on_species_gain(mob/living/carbon/C, datum/species/old_species) + ..() + var/list/golem_types = typesof(/datum/species/golem) - src.type + var/datum/species/golem/golem_type = pick(golem_types) + var/mob/living/carbon/human/H = C + H.set_species(golem_type) + to_chat(H, "[initial(golem_type.info_text)]") + +/datum/species/golem/adamantine + name = "Adamantine Golem" + id = "adamantine golem" + meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem/adamantine + mutant_organs = list(/obj/item/organ/adamantine_resonator, /obj/item/organ/vocal_cords/adamantine) + fixed_mut_color = "4ed" + info_text = "As an Adamantine Golem, you possess special vocal cords allowing you to \"resonate\" messages to all golems." + prefix = "Adamantine" + +//The suicide bombers of golemkind +/datum/species/golem/plasma + name = "Plasma Golem" + id = "plasma golem" + fixed_mut_color = "a3d" + meat = /obj/item/weapon/ore/plasma + //Can burn and takes damage from heat + species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR) + info_text = "As a Plasma Golem, you burn easily. Be careful, if you get hot enough while burning, you'll blow up!" + heatmod = 0 //fine until they blow up + prefix = "Plasma" + special_names = list("Flood","Fire","Bar","Man") + var/boom_warning = FALSE + var/datum/action/innate/ignite/ignite + +/datum/species/golem/plasma/spec_life(mob/living/carbon/human/H) + if(H.bodytemperature > 750) + if(!boom_warning && H.on_fire) + to_chat(H, "You feel like you could blow up at any moment!") + boom_warning = TRUE + else + if(boom_warning) + to_chat(H, "You feel more stable.") + boom_warning = FALSE + + if(H.bodytemperature > 850 && H.on_fire && prob(25)) + explosion(get_turf(H),1,2,4,flame_range = 5) + if(H) + H.gib() + if(H.fire_stacks < 2) //flammable + H.adjust_fire_stacks(1) + ..() + +/datum/species/golem/plasma/on_species_gain(mob/living/carbon/C, datum/species/old_species) + ..() + if(ishuman(C)) + ignite = new + ignite.Grant(C) + +/datum/species/golem/plasma/on_species_loss(mob/living/carbon/C) + if(ignite) + ignite.Remove(C) + ..() + +/datum/action/innate/ignite + name = "Ignite" + desc = "Set yourself aflame, bringing yourself closer to exploding!" + check_flags = AB_CHECK_CONSCIOUS + button_icon_state = "sacredflame" + +/datum/action/innate/ignite/Activate() + if(ishuman(owner)) + var/mob/living/carbon/human/H = owner + if(H.fire_stacks) + to_chat(owner, "You ignite yourself!") + else + to_chat(owner, "You try ignite yourself, but fail!") + H.IgniteMob() //firestacks are already there passively + +//Harder to hurt +/datum/species/golem/diamond + name = "Diamond Golem" + id = "diamond golem" + fixed_mut_color = "0ff" + armor = 70 //up from 55 + meat = /obj/item/weapon/ore/diamond + info_text = "As a Diamond Golem, you are more resistant than the average golem." + prefix = "Diamond" + special_names = list("Back") + +//Faster but softer and less armoured +/datum/species/golem/gold + name = "Gold Golem" + id = "gold golem" + fixed_mut_color = "cc0" + speedmod = 1 + armor = 25 //down from 55 + meat = /obj/item/weapon/ore/gold + info_text = "As a Gold Golem, you are faster but less resistant than the average golem." + prefix = "Golden" + +//Heavier, thus higher chance of stunning when punching +/datum/species/golem/silver + name = "Silver Golem" + id = "silver golem" + fixed_mut_color = "ddd" + punchstunthreshold = 9 //60% chance, from 40% + meat = /obj/item/weapon/ore/silver + info_text = "As a Silver Golem, your attacks are heavier and have a higher chance of stunning." + prefix = "Silver" + special_names = list("Surfer", "Chariot", "Lining") + +//Harder to stun, deals more damage, but it's even slower +/datum/species/golem/plasteel + name = "Plasteel Golem" + id = "plasteel golem" + fixed_mut_color = "bbb" + stunmod = 0.40 + punchdamagelow = 12 + punchdamagehigh = 21 + punchstunthreshold = 18 //still 40% stun chance + speedmod = 4 //pretty fucking slow + meat = /obj/item/weapon/ore/iron + info_text = "As a Plasteel Golem, you are slower, but harder to stun, and hit very hard when punching." + attack_verb = "smash" + attack_sound = 'sound/effects/meteorimpact.ogg' //hits pretty hard + prefix = "Plasteel" + +//Immune to ash storms +/datum/species/golem/titanium + name = "Titanium Golem" + id = "titanium golem" + fixed_mut_color = "fff" + meat = /obj/item/weapon/ore/titanium + info_text = "As a Titanium Golem, you are immune to ash storms, and slightly more resistant to burn damage." + burnmod = 0.9 + prefix = "Titanium" + +/datum/species/golem/titanium/on_species_gain(mob/living/carbon/C, datum/species/old_species) + . = ..() + C.weather_immunities |= "ash" + +/datum/species/golem/titanium/on_species_loss(mob/living/carbon/C) + . = ..() + C.weather_immunities -= "ash" + +//Immune to ash storms and lava +/datum/species/golem/plastitanium + name = "Plastitanium Golem" + id = "plastitanium golem" + fixed_mut_color = "888" + meat = /obj/item/weapon/ore/titanium + info_text = "As a Plastitanium Golem, you are immune to both ash storms and lava, and slightly more resistant to burn damage." + burnmod = 0.8 + prefix = "Plastitanium" + +/datum/species/golem/plastitanium/on_species_gain(mob/living/carbon/C, datum/species/old_species) + . = ..() + C.weather_immunities |= "lava" + C.weather_immunities |= "ash" + +/datum/species/golem/plastitanium/on_species_loss(mob/living/carbon/C) + . = ..() + C.weather_immunities -= "ash" + C.weather_immunities -= "lava" + +//Fast and regenerates... but can only speak like an abductor +/datum/species/golem/alloy + name = "Alien Alloy Golem" + id = "alloy golem" + fixed_mut_color = "333" + meat = /obj/item/stack/sheet/mineral/abductor + mutanttongue = /obj/item/organ/tongue/abductor + speedmod = 1 //faster + info_text = "As an Alloy Golem, you are made of advanced alien materials: you are faster and regenerate over time. You are, however, only able to be heard by other alloy golems." + prefix = "Alien" + special_names = list("Outsider", "Technology", "Watcher", "Stranger") //ominous and unknown + +//Regenerates because self-repairing super-advanced alien tech +/datum/species/golem/alloy/spec_life(mob/living/carbon/human/H) + if(H.stat == DEAD) + return + H.heal_overall_damage(2,2) + H.adjustToxLoss(-2) + H.adjustOxyLoss(-2) + +//Since this will usually be created from a collaboration between podpeople and free golems, wood golems are a mix between the two races +/datum/species/golem/wood + name = "Wood Golem" + id = "wood golem" + fixed_mut_color = "49311c" + meat = /obj/item/stack/sheet/mineral/wood + //Can burn and take damage from heat + species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR) + armor = 30 + burnmod = 1.25 + heatmod = 1.5 + info_text = "As a Wooden Golem, you have plant-like traits: you take damage from extreme temperatures, can be set on fire, and have lower armor than a normal golem. You regenerate when in the light and wither in the darkness." + prefix = "Wooden" + special_names = list("Tomato", "Potato", "Broccoli", "Carrot", "Ambrosia", "Pumpkin", "Ivy", "Kudzu", "Banana", "Moss", "Flower", "Bloom", "Root", "Bark", "Glowshroom", "Petal", "Leaf", "Venus", "Sprout","Cocoa", "Strawberry", "Citrus", "Oak", "Cactus", "Pepper", "Juniper") + human_surname_chance = 0 + special_name_chance = 100 + +/datum/species/golem/wood/on_species_gain(mob/living/carbon/C, datum/species/old_species) + . = ..() + C.faction |= "plants" + C.faction |= "vines" + +/datum/species/golem/wood/on_species_loss(mob/living/carbon/C) + . = ..() + C.faction -= "plants" + C.faction -= "vines" + +/datum/species/golem/wood/spec_life(mob/living/carbon/human/H) + if(H.stat == DEAD) + return + var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing + if(isturf(H.loc)) //else, there's considered to be no light + var/turf/T = H.loc + light_amount = min(1,T.get_lumcount()) - 0.5 + H.nutrition += light_amount * 10 + if(H.nutrition > NUTRITION_LEVEL_FULL) + H.nutrition = NUTRITION_LEVEL_FULL + if(light_amount > 0.2) //if there's enough light, heal + H.heal_overall_damage(1,1) + H.adjustToxLoss(-1) + H.adjustOxyLoss(-1) + + if(H.nutrition < NUTRITION_LEVEL_STARVING + 50) + H.take_overall_damage(2,0) + +/datum/species/golem/wood/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H) + if(chem.id == "plantbgone") + H.adjustToxLoss(3) + H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM) + return 1 + +//Radioactive +/datum/species/golem/uranium + name = "Uranium Golem" + id = "uranium golem" + fixed_mut_color = "7f0" + meat = /obj/item/weapon/ore/uranium + info_text = "As an Uranium Golem, you emit radiation pulses every once in a while. It won't harm fellow golems, but organic lifeforms will be affected." + + var/last_event = 0 + var/active = null + prefix = "Uranium" + +/datum/species/golem/uranium/spec_life(mob/living/carbon/human/H) + if(!active) + if(world.time > last_event+30) + active = 1 + radiation_pulse(get_turf(H), 3, 3, 5, 0) + last_event = world.time + active = null + ..() + +//Immune to physical bullets and resistant to brute, but very vulnerable to burn damage. Dusts on death. +/datum/species/golem/sand + name = "Sand Golem" + id = "sand golem" + fixed_mut_color = "ffdc8f" + meat = /obj/item/weapon/ore/glass //this is sand + armor = 0 + burnmod = 3 //melts easily + brutemod = 0.25 + info_text = "As a Sand Golem, you are immune to physical bullets and take very little brute damage, but are extremely vulnerable to burn damage. You will also turn to sand when dying, preventing any form of recovery." + attack_sound = 'sound/effects/shovel_dig.ogg' + prefix = "Sand" + +/datum/species/golem/sand/spec_death(gibbed, mob/living/carbon/human/H) + H.visible_message("[H] turns into a pile of sand!") + for(var/obj/item/W in H) + H.dropItemToGround(W) + for(var/i=1, i <= rand(3,5), i++) + new /obj/item/weapon/ore/glass(get_turf(H)) + qdel(H) + +/datum/species/golem/sand/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H) + if(!(P.original == H && P.firer == H)) + if(P.flag == "bullet" || P.flag == "bomb") + playsound(H, 'sound/effects/shovel_dig.ogg', 70, 1) + H.visible_message("The [P.name] sinks harmlessly in [H]'s sandy body!", \ + "The [P.name] sinks harmlessly in [H]'s sandy body!") + return 2 + return 0 + +//Reflects lasers and resistant to burn damage, but very vulnerable to brute damage. Shatters on death. +/datum/species/golem/glass + name = "Glass Golem" + id = "glass golem" + fixed_mut_color = "5a96b4aa" //transparent body + meat = /obj/item/weapon/shard + armor = 0 + brutemod = 3 //very fragile + burnmod = 0.25 + info_text = "As a Glass Golem, you reflect lasers and energy weapons, and are very resistant to burn damage, but you are extremely vulnerable to brute damage. On death, you'll shatter beyond any hope of recovery." + attack_sound = 'sound/effects/Glassbr2.ogg' + prefix = "Glass" + +/datum/species/golem/glass/spec_death(gibbed, mob/living/carbon/human/H) + playsound(H, "shatter", 70, 1) + H.visible_message("[H] shatters!") + for(var/obj/item/W in H) + H.dropItemToGround(W) + for(var/i=1, i <= rand(3,5), i++) + new /obj/item/weapon/shard(get_turf(H)) + qdel(H) + +/datum/species/golem/glass/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H) + if(!(P.original == H && P.firer == H)) //self-shots don't reflect + if(P.flag == "laser" || P.flag == "energy") + H.visible_message("The [P.name] gets reflected by [H]'s glass skin!", \ + "The [P.name] gets reflected by [H]'s glass skin!") + if(P.starting) + var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) + var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2) + var/turf/curloc = get_turf(H) + + // redirect the projectile + P.original = locate(new_x, new_y, P.z) + P.starting = curloc + P.current = curloc + P.firer = H + P.yo = new_y - curloc.y + P.xo = new_x - curloc.x + P.Angle = null + return -1 + return 0 + +//Teleports when hit or when it wants to +/datum/species/golem/bluespace + name = "Bluespace Golem" + id = "bluespace golem" + fixed_mut_color = "33f" + meat = /obj/item/weapon/ore/bluespace_crystal + info_text = "As a Bluespace Golem, are spatially unstable: you will teleport when hit, and you can teleport manually at a long distance." + attack_verb = "bluespace punch" + attack_sound = 'sound/effects/phasein.ogg' + prefix = "Bluespace" + special_names = list("Crystal", "Polycrystal") + + var/datum/action/innate/unstable_teleport/unstable_teleport + var/teleport_cooldown = 100 + var/last_teleport = 0 + +/datum/species/golem/bluespace/proc/reactive_teleport(mob/living/carbon/human/H) + H.visible_message("[H] teleports!", "You destabilize and teleport!") + new /obj/effect/particle_effect/sparks(get_turf(H)) + playsound(get_turf(H), "sparks", 50, 1) + do_teleport(H, get_turf(H), 6, asoundin = 'sound/weapons/emitter2.ogg') + last_teleport = world.time + +/datum/species/golem/bluespace/spec_hitby(atom/movable/AM, mob/living/carbon/human/H) + ..() + var/obj/item/I + if(istype(AM, /obj/item)) + I = AM + if(I.thrownby == H) //No throwing stuff at yourself to trigger the teleport + return 0 + else + reactive_teleport(H) + +/datum/species/golem/bluespace/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art) + ..() + if(world.time > last_teleport + teleport_cooldown && M != H && M.a_intent != INTENT_HELP) + reactive_teleport(H) + +/datum/species/golem/bluespace/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H) + ..() + if(world.time > last_teleport + teleport_cooldown && user != H) + reactive_teleport(H) + +/datum/species/golem/bluespace/on_hit(obj/item/projectile/P, mob/living/carbon/human/H) + ..() + if(world.time > last_teleport + teleport_cooldown) + reactive_teleport(H) + +/datum/species/golem/bluespace/on_species_gain(mob/living/carbon/C, datum/species/old_species) + ..() + if(ishuman(C)) + unstable_teleport = new + unstable_teleport.Grant(C) + +/datum/species/golem/bluespace/on_species_loss(mob/living/carbon/C) + if(unstable_teleport) + unstable_teleport.Remove(C) + ..() + +/datum/action/innate/unstable_teleport + name = "Unstable Teleport" + check_flags = AB_CHECK_CONSCIOUS + button_icon_state = "jaunt" + var/cooldown = 150 + var/last_teleport = 0 + +/datum/action/innate/unstable_teleport/IsAvailable() + if(..()) + if(world.time > last_teleport + cooldown) + return 1 + return 0 + +/datum/action/innate/unstable_teleport/Activate() + var/mob/living/carbon/human/H = owner + H.visible_message("[H] starts vibrating!", "You start charging your bluespace core...") + playsound(get_turf(H), 'sound/weapons/flash.ogg', 25, 1) + addtimer(CALLBACK(src, .proc/teleport, H), 15) + +/datum/action/innate/unstable_teleport/proc/teleport(mob/living/carbon/human/H) + H.visible_message("[H] disappears in a shower of sparks!", "You teleport!") + var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread + spark_system.set_up(10, 0, src) + spark_system.attach(H) + spark_system.start() + do_teleport(H, get_turf(H), 12, asoundin = 'sound/weapons/emitter2.ogg') + last_teleport = world.time + UpdateButtonIcon() //action icon looks unavailable + sleep(cooldown + 5) + UpdateButtonIcon() //action icon looks available again + + +//honk +/datum/species/golem/bananium + name = "Bananium Golem" + id = "bananium golem" + fixed_mut_color = "ff0" + say_mod = "honks" + punchdamagelow = 0 + punchdamagehigh = 1 + punchstunthreshold = 2 //Harmless and can't stun + meat = /obj/item/weapon/ore/bananium + info_text = "As a Bananium Golem, you are made for pranking. Your body emits natural honks, and you cannot hurt people when punching them. Your skin also emits bananas when damaged." + attack_verb = "honk" + attack_sound = 'sound/items/AirHorn2.ogg' + prefix = "Bananium" + + var/last_honk = 0 + var/honkooldown = 0 + var/last_banana = 0 + var/banana_cooldown = 100 + var/active = null + +/datum/species/golem/bananium/random_name(gender,unique,lastname) + var/clown_name = pick(GLOB.clown_names) + var/golem_name = "[uppertext(clown_name)]" + return golem_name + +/datum/species/golem/bananium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art) + ..() + if(world.time > last_banana + banana_cooldown && M != H && M.a_intent != INTENT_HELP) + new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(H)) + last_banana = world.time + +/datum/species/golem/bananium/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H) + ..() + if(world.time > last_banana + banana_cooldown && user != H) + new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(H)) + last_banana = world.time + +/datum/species/golem/bananium/on_hit(obj/item/projectile/P, mob/living/carbon/human/H) + ..() + if(world.time > last_banana + banana_cooldown) + new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(H)) + last_banana = world.time + +/datum/species/golem/bananium/spec_hitby(atom/movable/AM, mob/living/carbon/human/H) + ..() + var/obj/item/I + if(istype(AM, /obj/item)) + I = AM + if(I.thrownby == H) //No throwing stuff at yourself to make bananas + return 0 + else + new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(H)) + last_banana = world.time + +/datum/species/golem/bananium/spec_life(mob/living/carbon/human/H) + if(!active) + if(world.time > last_honk + honkooldown) + active = 1 + playsound(get_turf(H), 'sound/items/bikehorn.ogg', 50, 1) + last_honk = world.time + honkooldown = rand(20, 80) + active = null + ..() + +/datum/species/golem/bananium/spec_death(gibbed, mob/living/carbon/human/H) + playsound(get_turf(H), 'sound/misc/sadtrombone.ogg', 70, 0) + +/datum/species/golem/bananium/get_spans() + return list(SPAN_CLOWN) + + +/datum/species/golem/runic + name = "Runic Golem" + id = "runic golem" + limbs_id = "cultgolem" + sexes = FALSE + info_text = "As a Runic Golem, you possess eldritch powers granted by the Elder God Nar'Sie." + species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR) //no mutcolors + prefix = "Runic" + + var/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/golem/phase_shift + var/obj/effect/proc_holder/spell/targeted/abyssal_gaze/abyssal_gaze + var/obj/effect/proc_holder/spell/targeted/dominate/dominate + +/datum/species/golem/runic/random_name(gender,unique,lastname) + var/edgy_first_name = pick("Razor","Blood","Dark","Evil","Cold","Pale","Black","Silent","Chaos","Deadly") + var/edgy_last_name = pick("Edge","Night","Death","Razor","Blade","Steel","Calamity","Twilight","Shadow","Nightmare") //dammit Razor Razor + var/golem_name = "[edgy_first_name] [edgy_last_name]" + return golem_name + +/datum/species/golem/runic/on_species_gain(mob/living/carbon/C, datum/species/old_species) + . = ..() + C.faction |= "cult" + phase_shift = new + C.AddSpell(phase_shift) + abyssal_gaze = new + C.AddSpell(abyssal_gaze) + dominate = new + C.AddSpell(dominate) + +/datum/species/golem/runic/on_species_loss(mob/living/carbon/C) + . = ..() + C.faction -= "cult" + if(phase_shift) + C.RemoveSpell(phase_shift) + if(abyssal_gaze) + C.RemoveSpell(abyssal_gaze) + if(dominate) + C.RemoveSpell(dominate) + +/datum/species/golem/runic/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H) + if(chem.id == "holywater") + H.adjustFireLoss(4) + H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM) + + if(chem.id == "unholywater") + H.adjustBruteLoss(-4) + H.adjustFireLoss(-4) + H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM) + +/datum/species/golem/cloth + name = "Cloth Golem" + id = "cloth golem" + limbs_id = "clothgolem" + sexes = FALSE + info_text = "As a Cloth Golem, you are able to reform yourself after death, provided your remains aren't burned or destroyed. You are, of course, very flammable." + species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR) //no mutcolors, and can burn + armor = 15 //feels no pain, but not too resistant + burnmod = 2 // don't get burned + speedmod = 1 // not as heavy as stone + punchdamagelow = 4 + punchstunthreshold = 7 + punchdamagehigh = 8 // not as heavy as stone + prefix = "Cloth" + +/datum/species/golem/cloth/random_name(gender,unique,lastname) + var/pharaoh_name = pick("Neferkare", "Hudjefa", "Khufu", "Mentuhotep", "Ahmose", "Amenhotep", "Thutmose", "Hatshepsut", "Tutankhamun", "Ramses", "Seti", \ + "Merenptah", "Djer", "Semerkhet", "Nynetjer", "Khafre", "Pepi", "Intef", "Ay") //yes, Ay was an actual pharaoh + var/golem_name = "[pharaoh_name] \Roman[rand(1,99)]" + return golem_name + +/datum/species/golem/cloth/spec_life(mob/living/carbon/human/H) + if(H.fire_stacks < 1) + H.adjust_fire_stacks(1) //always prone to burning + ..() + +/datum/species/golem/cloth/spec_death(gibbed, mob/living/carbon/human/H) + if(gibbed) + return + if(H.on_fire) + H.visible_message("[H] burns into ash!") + H.dust(just_ash = TRUE) + return + + H.visible_message("[H] falls apart into a pile of bandages!") + new /obj/structure/cloth_pile(get_turf(H), H) + ..() + +/obj/structure/cloth_pile + name = "pile of bandages" + desc = "It emits a strange aura, as if there was still life within it..." + obj_integrity = 50 + max_integrity = 50 + armor = list(melee = 90, bullet = 90, laser = 25, energy = 80, bomb = 50, bio = 100, fire = -50, acid = -50) + icon = 'icons/obj/items.dmi' + icon_state = "pile_bandages" + resistance_flags = FLAMMABLE + + var/revive_time = 900 + var/mob/living/carbon/human/cloth_golem + +/obj/structure/cloth_pile/Initialize(mapload, mob/living/carbon/human/H) + if(!QDELETED(H) && is_species(H, /datum/species/golem/cloth)) + H.unequip_everything() + H.forceMove(src) + cloth_golem = H + to_chat(cloth_golem, "You start gathering your life energy, preparing to rise again...") + addtimer(CALLBACK(src, .proc/revive), revive_time) + else + qdel(src) + +/obj/structure/cloth_pile/Destroy() + if(cloth_golem) + QDEL_NULL(cloth_golem) + return ..() + +/obj/structure/cloth_pile/burn() + visible_message("[src] burns into ash!") + new /obj/effect/decal/cleanable/ash(get_turf(src)) + ..() + +/obj/structure/cloth_pile/proc/revive() + if(QDELETED(src) || QDELETED(cloth_golem)) //QDELETED also checks for null, so if no cloth golem is set this won't runtime + return + if(cloth_golem.suiciding || cloth_golem.disabilities & NOCLONE) + QDEL_NULL(cloth_golem) + return + + invisibility = INVISIBILITY_MAXIMUM //disappear before the animation + new /obj/effect/overlay/temp/mummy_animation(get_turf(src)) + if(cloth_golem.revive(full_heal = TRUE, admin_revive = TRUE)) + cloth_golem.grab_ghost() //won't pull if it's a suicide + sleep(20) + cloth_golem.forceMove(get_turf(src)) + cloth_golem.visible_message("[src] rises and reforms into [cloth_golem]!","You reform into yourself!") + cloth_golem = null + qdel(src) + +/obj/structure/cloth_pile/attackby(obj/item/weapon/P, mob/living/carbon/human/user, params) + . = ..() + + if(resistance_flags & ON_FIRE) + return + + if(P.is_hot()) + visible_message("[src] bursts into flames!") + fire_act() + +/datum/species/golem/plastic + name = "Plastic" + id = "plastic golem" + prefix = "Plastic" + fixed_mut_color = "fff" + info_text = "As a Plastic Golem, you are capable of ventcrawling, and passing through plastic flaps." + +/datum/species/golem/plastic/on_species_gain(mob/living/carbon/C, datum/species/old_species) + . = ..() + C.ventcrawler = VENTCRAWLER_NUDE + +/datum/species/golem/plastic/on_species_loss(mob/living/carbon/C) + . = ..() C.ventcrawler = initial(C.ventcrawler) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm index fd64850882..239d901e5c 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -1,50 +1,50 @@ -/datum/species/zombie - // 1spooky - name = "High Functioning Zombie" - id = "zombie" - say_mod = "moans" - sexes = 0 - blacklisted = 1 - meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/zombie - species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,NOZOMBIE,EASYDISMEMBER,EASYLIMBATTACHMENT) - mutant_organs = list(/obj/item/organ/tongue/zombie) - -/datum/species/zombie/infectious - name = "Infectious Zombie" - id = "memezombies" - limbs_id = "zombie" - mutanthands = /obj/item/zombie_hand - no_equip = list(slot_wear_mask, slot_head) - armor = 20 // 120 damage to KO a zombie, which kills it - speedmod = 2 - mutanteyes = /obj/item/organ/eyes/night_vision/zombie - -/datum/species/zombie/infectious/spec_life(mob/living/carbon/C) - . = ..() - C.a_intent = INTENT_HARM // THE SUFFERING MUST FLOW - if(C.InCritical()) - C.death() - // Zombies only move around when not in crit, they instantly - // succumb otherwise, and will standup again soon - -/datum/species/zombie/infectious/on_species_gain(mob/living/carbon/C, datum/species/old_species) - . = ..() - - // Deal with the source of this zombie corruption - // Infection organ needs to be handled separately from mutant_organs - // because it persists through species transitions - var/obj/item/organ/zombie_infection/infection - infection = C.getorganslot("zombie_infection") - if(!infection) - infection = new() - infection.Insert(C) - - -// Your skin falls off -/datum/species/krokodil_addict - name = "Human" - id = "goofzombies" - limbs_id = "zombie" //They look like zombies - sexes = 0 - meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/zombie - mutant_organs = list(/obj/item/organ/tongue/zombie) +/datum/species/zombie + // 1spooky + name = "High Functioning Zombie" + id = "zombie" + say_mod = "moans" + sexes = 0 + blacklisted = 1 + meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/zombie + species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,NOZOMBIE,EASYDISMEMBER,EASYLIMBATTACHMENT) + mutant_organs = list(/obj/item/organ/tongue/zombie) + +/datum/species/zombie/infectious + name = "Infectious Zombie" + id = "memezombies" + limbs_id = "zombie" + mutanthands = /obj/item/zombie_hand + no_equip = list(slot_wear_mask, slot_head) + armor = 20 // 120 damage to KO a zombie, which kills it + speedmod = 2 + mutanteyes = /obj/item/organ/eyes/night_vision/zombie + +/datum/species/zombie/infectious/spec_life(mob/living/carbon/C) + . = ..() + C.a_intent = INTENT_HARM // THE SUFFERING MUST FLOW + if(C.InCritical()) + C.death() + // Zombies only move around when not in crit, they instantly + // succumb otherwise, and will standup again soon + +/datum/species/zombie/infectious/on_species_gain(mob/living/carbon/C, datum/species/old_species) + . = ..() + + // Deal with the source of this zombie corruption + // Infection organ needs to be handled separately from mutant_organs + // because it persists through species transitions + var/obj/item/organ/zombie_infection/infection + infection = C.getorganslot("zombie_infection") + if(!infection) + infection = new() + infection.Insert(C) + + +// Your skin falls off +/datum/species/krokodil_addict + name = "Human" + id = "goofzombies" + limbs_id = "zombie" //They look like zombies + sexes = 0 + meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/zombie + mutant_organs = list(/obj/item/organ/tongue/zombie) diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 6de5fe8836..159aec35af 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -1,274 +1,274 @@ -//Cat -/mob/living/simple_animal/pet/cat - name = "cat" - desc = "Kitty!!" - icon = 'icons/mob/pets.dmi' - icon_state = "cat2" - icon_living = "cat2" - icon_dead = "cat2_dead" - gender = MALE - speak = list("Meow!", "Esp!", "Purr!", "HSSSSS") - speak_emote = list("purrs", "meows") - emote_hear = list("meows", "mews") - emote_see = list("shakes its head", "shivers") - speak_chance = 1 - turns_per_move = 5 - see_in_dark = 6 - ventcrawler = VENTCRAWLER_ALWAYS - pass_flags = PASSTABLE - mob_size = MOB_SIZE_SMALL - minbodytemp = 200 - maxbodytemp = 400 - unsuitable_atmos_damage = 1 - animal_species = /mob/living/simple_animal/pet/cat - childtype = list(/mob/living/simple_animal/pet/cat/kitten) - butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 2) - response_help = "pets" - response_disarm = "gently pushes aside" - response_harm = "kicks" - var/turns_since_scan = 0 - var/mob/living/simple_animal/mouse/movement_target - gold_core_spawnable = 2 - devourable = TRUE - -/mob/living/simple_animal/pet/cat/Initialize() - ..() - verbs += /mob/living/proc/lay_down - -/mob/living/simple_animal/pet/cat/update_canmove() - ..() - if(client) - if (resting) - icon_state = "[icon_living]_rest" - else - icon_state = "[icon_living]" - - -/mob/living/simple_animal/pet/cat/space - name = "space cat" - desc = "It's a cat... in space!" - icon_state = "spacecat" - icon_living = "spacecat" - icon_dead = "spacecat_dead" - unsuitable_atmos_damage = 0 - minbodytemp = TCMB - maxbodytemp = T0C + 40 - -/mob/living/simple_animal/pet/cat/original - name = "Batsy" - desc = "The product of alien DNA and bored geneticists." - gender = FEMALE - icon_state = "original" - icon_living = "original" - icon_dead = "original_dead" - -/mob/living/simple_animal/pet/cat/kitten - name = "kitten" - desc = "D'aaawwww." - icon_state = "kitten" - icon_living = "kitten" - icon_dead = "kitten_dead" - density = 0 - pass_flags = PASSMOB - mob_size = MOB_SIZE_SMALL - -//RUNTIME IS ALIVE! SQUEEEEEEEE~ -/mob/living/simple_animal/pet/cat/Runtime - name = "Runtime" - desc = "GCAT" - icon_state = "cat" - icon_living = "cat" - icon_dead = "cat_dead" - gender = FEMALE - gold_core_spawnable = 0 - var/list/family = list()//var restored from savefile, has count of each child type - var/list/children = list()//Actual mob instances of children - var/cats_deployed = 0 - var/memory_saved = 0 - -/mob/living/simple_animal/pet/cat/Runtime/Initialize() - if(prob(5)) - icon_state = "original" - icon_living = "original" - icon_dead = "original_dead" - Read_Memory() - ..() - -/mob/living/simple_animal/pet/cat/Runtime/Life() - if(!cats_deployed && SSticker.current_state >= GAME_STATE_SETTING_UP) - Deploy_The_Cats() - if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved) - Write_Memory() - ..() - -/mob/living/simple_animal/pet/cat/Runtime/make_babies() - var/mob/baby = ..() - if(baby) - children += baby - return baby - -/mob/living/simple_animal/pet/cat/Runtime/death() - if(!memory_saved) - Write_Memory(1) - ..() - -/mob/living/simple_animal/pet/cat/Runtime/proc/Read_Memory() - var/savefile/S = new /savefile("data/npc_saves/Runtime.sav") - S["family"] >> family - - if(isnull(family)) - family = list() - -/mob/living/simple_animal/pet/cat/Runtime/proc/Write_Memory(dead) - var/savefile/S = new /savefile("data/npc_saves/Runtime.sav") - family = list() - if(!dead) - for(var/mob/living/simple_animal/pet/cat/kitten/C in children) - if(istype(C,type) || C.stat || !C.z || !C.butcher_results) //That last one is a work around for hologram cats - continue - if(C.type in family) - family[C.type] += 1 - else - family[C.type] = 1 - S["family"] << family - memory_saved = 1 - -/mob/living/simple_animal/pet/cat/Runtime/proc/Deploy_The_Cats() - cats_deployed = 1 - for(var/cat_type in family) - if(family[cat_type] > 0) - for(var/i in 1 to min(family[cat_type],100)) //Limits to about 500 cats, you wouldn't think this would be needed (BUT IT IS) - new cat_type(loc) - -/mob/living/simple_animal/pet/cat/Proc - name = "Proc" - gender = MALE - gold_core_spawnable = 0 - -/mob/living/simple_animal/pet/cat/Life() - if(!stat && !buckled && !client) - if(prob(1)) - emote("me", 1, pick("stretches out for a belly rub.", "wags its tail.", "lies down.")) - icon_state = "[icon_living]_rest" - resting = 1 - update_canmove() - else if (prob(1)) - emote("me", 1, pick("sits down.", "crouches on its hind legs.", "looks alert.")) - icon_state = "[icon_living]_sit" - resting = 1 - update_canmove() - else if (prob(1)) - if (resting) - emote("me", 1, pick("gets up and meows.", "walks around.", "stops resting.")) - icon_state = "[icon_living]" - resting = 0 - update_canmove() - else - emote("me", 1, pick("grooms its fur.", "twitches its whiskers.", "shakes out its coat.")) - - //MICE! - if((src.loc) && isturf(src.loc)) - if(!stat && !resting && !buckled) - for(var/mob/living/simple_animal/mouse/M in view(1,src)) - if(!M.stat && Adjacent(M)) - emote("me", 1, "splats \the [M]!") - M.splat() - movement_target = null - stop_automated_movement = 0 - break - for(var/obj/item/toy/cattoy/T in view(1,src)) - if (T.cooldown < (world.time - 400)) - emote("me", 1, "bats \the [T] around with its paw!") - T.cooldown = world.time - - ..() - - make_babies() - - if(!stat && !resting && !buckled) - turns_since_scan++ - if(turns_since_scan > 5) - walk_to(src,0) - turns_since_scan = 0 - if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) )) - movement_target = null - stop_automated_movement = 0 - if( !movement_target || !(movement_target.loc in oview(src, 3)) ) - movement_target = null - stop_automated_movement = 0 - for(var/mob/living/simple_animal/mouse/snack in oview(src,3)) - if(isturf(snack.loc) && !snack.stat) - movement_target = snack - break - if(movement_target) - stop_automated_movement = 1 - walk_to(src,movement_target,0,3) - -/mob/living/simple_animal/pet/cat/attack_hand(mob/living/carbon/human/M) - . = ..() - switch(M.a_intent) - if("help") - wuv(1, M) - if("harm") - wuv(-1, M) - -/mob/living/simple_animal/pet/cat/proc/wuv(change, mob/M) - if(change) - if(change > 0) - if(M && stat != DEAD) - new /obj/effect/overlay/temp/heart(loc) - emote("me", 1, "purrs!") - else - if(M && stat != DEAD) - emote("me", 1, "hisses!") - -/mob/living/simple_animal/pet/cat/cak //I told you I'd do it, Remie - name = "Keeki" - desc = "It's a cat made out of cake." - icon_state = "cak" - icon_living = "cak" - icon_dead = "cak_dead" - health = 50 - maxHealth = 50 - gender = FEMALE - harm_intent_damage = 10 - butcher_results = list(/obj/item/organ/brain = 1, /obj/item/organ/heart = 1, /obj/item/weapon/reagent_containers/food/snacks/cakeslice/birthday = 3, \ - /obj/item/weapon/reagent_containers/food/snacks/meat/slab = 2) - response_harm = "takes a bite out of" - attacked_sound = 'sound/items/eatfood.ogg' - deathmessage = "loses its false life and collapses!" - death_sound = "bodyfall" - -/mob/living/simple_animal/pet/cat/cak/CheckParts(list/parts) - ..() - var/obj/item/organ/brain/B = locate(/obj/item/organ/brain) in contents - if(!B || !B.brainmob || !B.brainmob.mind) - return - B.brainmob.mind.transfer_to(src) - to_chat(src, "You are a cak! You're a harmless cat/cake hybrid that everyone loves. People can take bites out of you if they're hungry, but you regenerate health \ - so quickly that it generally doesn't matter. You're remarkably resilient to any damage besides this and it's hard for you to really die at all. You should go around and bring happiness and \ - free cake to the station!") - var/new_name = stripped_input(src, "Enter your name, or press \"Cancel\" to stick with Keeki.", "Name Change") - if(new_name) - to_chat(src, "Your name is now \"new_name\"!") - name = new_name - -/mob/living/simple_animal/pet/cat/cak/Life() - ..() - if(stat) - return - if(health < maxHealth) - adjustBruteLoss(-8) //Fast life regen - for(var/obj/item/weapon/reagent_containers/food/snacks/donut/D in range(1, src)) //Frosts nearby donuts! - if(D.icon_state != "donut2") - D.name = "frosted donut" - D.icon_state = "donut2" - D.reagents.add_reagent("sprinkles", 2) - D.bonus_reagents = list("sprinkles" = 2, "sugar" = 1) - D.filling_color = "#FF69B4" - -/mob/living/simple_animal/pet/cat/cak/attack_hand(mob/living/L) - ..() - if(L.a_intent == INTENT_HARM && L.reagents && !stat) - L.reagents.add_reagent("nutriment", 0.4) - L.reagents.add_reagent("vitamin", 0.4) +//Cat +/mob/living/simple_animal/pet/cat + name = "cat" + desc = "Kitty!!" + icon = 'icons/mob/pets.dmi' + icon_state = "cat2" + icon_living = "cat2" + icon_dead = "cat2_dead" + gender = MALE + speak = list("Meow!", "Esp!", "Purr!", "HSSSSS") + speak_emote = list("purrs", "meows") + emote_hear = list("meows", "mews") + emote_see = list("shakes its head", "shivers") + speak_chance = 1 + turns_per_move = 5 + see_in_dark = 6 + ventcrawler = VENTCRAWLER_ALWAYS + pass_flags = PASSTABLE + mob_size = MOB_SIZE_SMALL + minbodytemp = 200 + maxbodytemp = 400 + unsuitable_atmos_damage = 1 + animal_species = /mob/living/simple_animal/pet/cat + childtype = list(/mob/living/simple_animal/pet/cat/kitten) + butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab = 2) + response_help = "pets" + response_disarm = "gently pushes aside" + response_harm = "kicks" + var/turns_since_scan = 0 + var/mob/living/simple_animal/mouse/movement_target + gold_core_spawnable = 2 + devourable = TRUE + +/mob/living/simple_animal/pet/cat/Initialize() + ..() + verbs += /mob/living/proc/lay_down + +/mob/living/simple_animal/pet/cat/update_canmove() + ..() + if(client) + if (resting) + icon_state = "[icon_living]_rest" + else + icon_state = "[icon_living]" + + +/mob/living/simple_animal/pet/cat/space + name = "space cat" + desc = "It's a cat... in space!" + icon_state = "spacecat" + icon_living = "spacecat" + icon_dead = "spacecat_dead" + unsuitable_atmos_damage = 0 + minbodytemp = TCMB + maxbodytemp = T0C + 40 + +/mob/living/simple_animal/pet/cat/original + name = "Batsy" + desc = "The product of alien DNA and bored geneticists." + gender = FEMALE + icon_state = "original" + icon_living = "original" + icon_dead = "original_dead" + +/mob/living/simple_animal/pet/cat/kitten + name = "kitten" + desc = "D'aaawwww." + icon_state = "kitten" + icon_living = "kitten" + icon_dead = "kitten_dead" + density = 0 + pass_flags = PASSMOB + mob_size = MOB_SIZE_SMALL + +//RUNTIME IS ALIVE! SQUEEEEEEEE~ +/mob/living/simple_animal/pet/cat/Runtime + name = "Runtime" + desc = "GCAT" + icon_state = "cat" + icon_living = "cat" + icon_dead = "cat_dead" + gender = FEMALE + gold_core_spawnable = 0 + var/list/family = list()//var restored from savefile, has count of each child type + var/list/children = list()//Actual mob instances of children + var/cats_deployed = 0 + var/memory_saved = 0 + +/mob/living/simple_animal/pet/cat/Runtime/Initialize() + if(prob(5)) + icon_state = "original" + icon_living = "original" + icon_dead = "original_dead" + Read_Memory() + ..() + +/mob/living/simple_animal/pet/cat/Runtime/Life() + if(!cats_deployed && SSticker.current_state >= GAME_STATE_SETTING_UP) + Deploy_The_Cats() + if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved) + Write_Memory() + ..() + +/mob/living/simple_animal/pet/cat/Runtime/make_babies() + var/mob/baby = ..() + if(baby) + children += baby + return baby + +/mob/living/simple_animal/pet/cat/Runtime/death() + if(!memory_saved) + Write_Memory(1) + ..() + +/mob/living/simple_animal/pet/cat/Runtime/proc/Read_Memory() + var/savefile/S = new /savefile("data/npc_saves/Runtime.sav") + S["family"] >> family + + if(isnull(family)) + family = list() + +/mob/living/simple_animal/pet/cat/Runtime/proc/Write_Memory(dead) + var/savefile/S = new /savefile("data/npc_saves/Runtime.sav") + family = list() + if(!dead) + for(var/mob/living/simple_animal/pet/cat/kitten/C in children) + if(istype(C,type) || C.stat || !C.z || !C.butcher_results) //That last one is a work around for hologram cats + continue + if(C.type in family) + family[C.type] += 1 + else + family[C.type] = 1 + S["family"] << family + memory_saved = 1 + +/mob/living/simple_animal/pet/cat/Runtime/proc/Deploy_The_Cats() + cats_deployed = 1 + for(var/cat_type in family) + if(family[cat_type] > 0) + for(var/i in 1 to min(family[cat_type],100)) //Limits to about 500 cats, you wouldn't think this would be needed (BUT IT IS) + new cat_type(loc) + +/mob/living/simple_animal/pet/cat/Proc + name = "Proc" + gender = MALE + gold_core_spawnable = 0 + +/mob/living/simple_animal/pet/cat/Life() + if(!stat && !buckled && !client) + if(prob(1)) + emote("me", 1, pick("stretches out for a belly rub.", "wags its tail.", "lies down.")) + icon_state = "[icon_living]_rest" + resting = 1 + update_canmove() + else if (prob(1)) + emote("me", 1, pick("sits down.", "crouches on its hind legs.", "looks alert.")) + icon_state = "[icon_living]_sit" + resting = 1 + update_canmove() + else if (prob(1)) + if (resting) + emote("me", 1, pick("gets up and meows.", "walks around.", "stops resting.")) + icon_state = "[icon_living]" + resting = 0 + update_canmove() + else + emote("me", 1, pick("grooms its fur.", "twitches its whiskers.", "shakes out its coat.")) + + //MICE! + if((src.loc) && isturf(src.loc)) + if(!stat && !resting && !buckled) + for(var/mob/living/simple_animal/mouse/M in view(1,src)) + if(!M.stat && Adjacent(M)) + emote("me", 1, "splats \the [M]!") + M.splat() + movement_target = null + stop_automated_movement = 0 + break + for(var/obj/item/toy/cattoy/T in view(1,src)) + if (T.cooldown < (world.time - 400)) + emote("me", 1, "bats \the [T] around with its paw!") + T.cooldown = world.time + + ..() + + make_babies() + + if(!stat && !resting && !buckled) + turns_since_scan++ + if(turns_since_scan > 5) + walk_to(src,0) + turns_since_scan = 0 + if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) )) + movement_target = null + stop_automated_movement = 0 + if( !movement_target || !(movement_target.loc in oview(src, 3)) ) + movement_target = null + stop_automated_movement = 0 + for(var/mob/living/simple_animal/mouse/snack in oview(src,3)) + if(isturf(snack.loc) && !snack.stat) + movement_target = snack + break + if(movement_target) + stop_automated_movement = 1 + walk_to(src,movement_target,0,3) + +/mob/living/simple_animal/pet/cat/attack_hand(mob/living/carbon/human/M) + . = ..() + switch(M.a_intent) + if("help") + wuv(1, M) + if("harm") + wuv(-1, M) + +/mob/living/simple_animal/pet/cat/proc/wuv(change, mob/M) + if(change) + if(change > 0) + if(M && stat != DEAD) + new /obj/effect/overlay/temp/heart(loc) + emote("me", 1, "purrs!") + else + if(M && stat != DEAD) + emote("me", 1, "hisses!") + +/mob/living/simple_animal/pet/cat/cak //I told you I'd do it, Remie + name = "Keeki" + desc = "It's a cat made out of cake." + icon_state = "cak" + icon_living = "cak" + icon_dead = "cak_dead" + health = 50 + maxHealth = 50 + gender = FEMALE + harm_intent_damage = 10 + butcher_results = list(/obj/item/organ/brain = 1, /obj/item/organ/heart = 1, /obj/item/weapon/reagent_containers/food/snacks/cakeslice/birthday = 3, \ + /obj/item/weapon/reagent_containers/food/snacks/meat/slab = 2) + response_harm = "takes a bite out of" + attacked_sound = 'sound/items/eatfood.ogg' + deathmessage = "loses its false life and collapses!" + death_sound = "bodyfall" + +/mob/living/simple_animal/pet/cat/cak/CheckParts(list/parts) + ..() + var/obj/item/organ/brain/B = locate(/obj/item/organ/brain) in contents + if(!B || !B.brainmob || !B.brainmob.mind) + return + B.brainmob.mind.transfer_to(src) + to_chat(src, "You are a cak! You're a harmless cat/cake hybrid that everyone loves. People can take bites out of you if they're hungry, but you regenerate health \ + so quickly that it generally doesn't matter. You're remarkably resilient to any damage besides this and it's hard for you to really die at all. You should go around and bring happiness and \ + free cake to the station!") + var/new_name = stripped_input(src, "Enter your name, or press \"Cancel\" to stick with Keeki.", "Name Change") + if(new_name) + to_chat(src, "Your name is now \"new_name\"!") + name = new_name + +/mob/living/simple_animal/pet/cat/cak/Life() + ..() + if(stat) + return + if(health < maxHealth) + adjustBruteLoss(-8) //Fast life regen + for(var/obj/item/weapon/reagent_containers/food/snacks/donut/D in range(1, src)) //Frosts nearby donuts! + if(D.icon_state != "donut2") + D.name = "frosted donut" + D.icon_state = "donut2" + D.reagents.add_reagent("sprinkles", 2) + D.bonus_reagents = list("sprinkles" = 2, "sugar" = 1) + D.filling_color = "#FF69B4" + +/mob/living/simple_animal/pet/cat/cak/attack_hand(mob/living/L) + ..() + if(L.a_intent == INTENT_HARM && L.reagents && !stat) + L.reagents.add_reagent("nutriment", 0.4) + L.reagents.add_reagent("vitamin", 0.4) diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm index 3c92be3888..ca2bcd3ba2 100644 --- a/code/modules/paperwork/clipboard.dm +++ b/code/modules/paperwork/clipboard.dm @@ -1,122 +1,122 @@ -/obj/item/weapon/clipboard - name = "clipboard" - icon = 'icons/obj/bureaucracy.dmi' - icon_state = "clipboard" - item_state = "clipboard" - throwforce = 0 - w_class = WEIGHT_CLASS_SMALL - throw_speed = 3 - throw_range = 7 - var/obj/item/weapon/pen/haspen //The stored pen. - var/obj/item/weapon/paper/toppaper //The topmost piece of paper. - slot_flags = SLOT_BELT - resistance_flags = FLAMMABLE - -/obj/item/weapon/clipboard/Initialize() - update_icon() - . = ..() - -/obj/item/weapon/clipboard/Destroy() - QDEL_NULL(haspen) - QDEL_NULL(toppaper) //let movable/Destroy handle the rest - return ..() - -/obj/item/weapon/clipboard/update_icon() - cut_overlays() - if(toppaper) - add_overlay(toppaper.icon_state) - copy_overlays(toppaper) - if(haspen) - add_overlay("clipboard_pen") - add_overlay("clipboard_over") - - -/obj/item/weapon/clipboard/attackby(obj/item/weapon/W, mob/user, params) - if(istype(W, /obj/item/weapon/paper)) - if(!user.transferItemToLoc(W, src)) - return - toppaper = W - to_chat(user, "You clip the paper onto \the [src].") - update_icon() - else if(toppaper) - toppaper.attackby(user.get_active_held_item(), user) - update_icon() - - -/obj/item/weapon/clipboard/attack_self(mob/user) - var/dat = "Clipboard" - if(haspen) - dat += "Remove Pen

" - else - dat += "Add Pen

" - - //The topmost paper. You can't organise contents directly in byond, so this is what we're stuck with. -Pete - if(toppaper) - var/obj/item/weapon/paper/P = toppaper - dat += "Write Remove - [P.name]

" - - for(P in src) - if(P == toppaper) - continue - dat += "Write Remove Move to top - [P.name]
" - user << browse(dat, "window=clipboard") - onclose(user, "clipboard") - add_fingerprint(usr) - - -/obj/item/weapon/clipboard/Topic(href, href_list) - ..() - if(usr.stat || usr.restrained()) - return - - if(usr.contents.Find(src)) - - if(href_list["pen"]) - if(haspen) - haspen.loc = usr.loc - usr.put_in_hands(haspen) - haspen = null - - if(href_list["addpen"]) - if(!haspen) - var/obj/item/held = usr.get_active_held_item() - if(istype(held, /obj/item/weapon/pen)) - var/obj/item/weapon/pen/W = held - if(!usr.transferItemToLoc(W, src)) - return - haspen = W - to_chat(usr, "You slot [W] into [src].") - - if(href_list["write"]) - var/obj/item/P = locate(href_list["write"]) - if(istype(P) && P.loc == src) - if(usr.get_active_held_item()) - P.attackby(usr.get_active_held_item(), usr) - - if(href_list["remove"]) - var/obj/item/P = locate(href_list["remove"]) - if(istype(P) && P.loc == src) - P.loc = usr.loc - usr.put_in_hands(P) - if(P == toppaper) - toppaper = null - var/obj/item/weapon/paper/newtop = locate(/obj/item/weapon/paper) in src - if(newtop && (newtop != P)) - toppaper = newtop - else - toppaper = null - - if(href_list["read"]) - var/obj/item/weapon/paper/P = locate(href_list["read"]) - if(istype(P) && P.loc == src) - usr.examinate(P) - - if(href_list["top"]) - var/obj/item/P = locate(href_list["top"]) - if(istype(P) && P.loc == src) - toppaper = P - to_chat(usr, "You move [P.name] to the top.") - - //Update everything - attack_self(usr) - update_icon() +/obj/item/weapon/clipboard + name = "clipboard" + icon = 'icons/obj/bureaucracy.dmi' + icon_state = "clipboard" + item_state = "clipboard" + throwforce = 0 + w_class = WEIGHT_CLASS_SMALL + throw_speed = 3 + throw_range = 7 + var/obj/item/weapon/pen/haspen //The stored pen. + var/obj/item/weapon/paper/toppaper //The topmost piece of paper. + slot_flags = SLOT_BELT + resistance_flags = FLAMMABLE + +/obj/item/weapon/clipboard/Initialize() + update_icon() + . = ..() + +/obj/item/weapon/clipboard/Destroy() + QDEL_NULL(haspen) + QDEL_NULL(toppaper) //let movable/Destroy handle the rest + return ..() + +/obj/item/weapon/clipboard/update_icon() + cut_overlays() + if(toppaper) + add_overlay(toppaper.icon_state) + copy_overlays(toppaper) + if(haspen) + add_overlay("clipboard_pen") + add_overlay("clipboard_over") + + +/obj/item/weapon/clipboard/attackby(obj/item/weapon/W, mob/user, params) + if(istype(W, /obj/item/weapon/paper)) + if(!user.transferItemToLoc(W, src)) + return + toppaper = W + to_chat(user, "You clip the paper onto \the [src].") + update_icon() + else if(toppaper) + toppaper.attackby(user.get_active_held_item(), user) + update_icon() + + +/obj/item/weapon/clipboard/attack_self(mob/user) + var/dat = "Clipboard" + if(haspen) + dat += "Remove Pen

" + else + dat += "Add Pen

" + + //The topmost paper. You can't organise contents directly in byond, so this is what we're stuck with. -Pete + if(toppaper) + var/obj/item/weapon/paper/P = toppaper + dat += "Write Remove - [P.name]

" + + for(P in src) + if(P == toppaper) + continue + dat += "Write Remove Move to top - [P.name]
" + user << browse(dat, "window=clipboard") + onclose(user, "clipboard") + add_fingerprint(usr) + + +/obj/item/weapon/clipboard/Topic(href, href_list) + ..() + if(usr.stat || usr.restrained()) + return + + if(usr.contents.Find(src)) + + if(href_list["pen"]) + if(haspen) + haspen.loc = usr.loc + usr.put_in_hands(haspen) + haspen = null + + if(href_list["addpen"]) + if(!haspen) + var/obj/item/held = usr.get_active_held_item() + if(istype(held, /obj/item/weapon/pen)) + var/obj/item/weapon/pen/W = held + if(!usr.transferItemToLoc(W, src)) + return + haspen = W + to_chat(usr, "You slot [W] into [src].") + + if(href_list["write"]) + var/obj/item/P = locate(href_list["write"]) + if(istype(P) && P.loc == src) + if(usr.get_active_held_item()) + P.attackby(usr.get_active_held_item(), usr) + + if(href_list["remove"]) + var/obj/item/P = locate(href_list["remove"]) + if(istype(P) && P.loc == src) + P.loc = usr.loc + usr.put_in_hands(P) + if(P == toppaper) + toppaper = null + var/obj/item/weapon/paper/newtop = locate(/obj/item/weapon/paper) in src + if(newtop && (newtop != P)) + toppaper = newtop + else + toppaper = null + + if(href_list["read"]) + var/obj/item/weapon/paper/P = locate(href_list["read"]) + if(istype(P) && P.loc == src) + usr.examinate(P) + + if(href_list["top"]) + var/obj/item/P = locate(href_list["top"]) + if(istype(P) && P.loc == src) + toppaper = P + to_chat(usr, "You move [P.name] to the top.") + + //Update everything + attack_self(usr) + update_icon() diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm index c83d53bf3f..f98cb5d0e9 100644 --- a/code/modules/paperwork/folders.dm +++ b/code/modules/paperwork/folders.dm @@ -78,8 +78,8 @@ name = "folder- 'TOP SECRET'" desc = "A folder stamped \"Top Secret - Property of Nanotrasen Corporation. Unauthorized distribution is punishable by death.\"" -/obj/item/weapon/folder/documents/Initialize() - . = ..() +/obj/item/weapon/folder/documents/Initialize() + . = ..() new /obj/item/documents/nanotrasen(src) update_icon() @@ -91,20 +91,20 @@ /obj/item/weapon/folder/syndicate/red icon_state = "folder_sred" -/obj/item/weapon/folder/syndicate/red/Initialize() - . = ..() +/obj/item/weapon/folder/syndicate/red/Initialize() + . = ..() new /obj/item/documents/syndicate/red(src) update_icon() /obj/item/weapon/folder/syndicate/blue icon_state = "folder_sblue" -/obj/item/weapon/folder/syndicate/blue/Initialize() - . = ..() +/obj/item/weapon/folder/syndicate/blue/Initialize() + . = ..() new /obj/item/documents/syndicate/blue(src) update_icon() -/obj/item/weapon/folder/syndicate/mining/Initialize() - . = ..() +/obj/item/weapon/folder/syndicate/mining/Initialize() + . = ..() new /obj/item/documents/syndicate/mining(src) - update_icon() + update_icon() diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index 3517757de5..a1d544c2e4 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -20,7 +20,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne /obj/machinery/gravity_generator name = "gravitational generator" - desc = "A device which produces a graviton field when set up." + desc = "A device which produces a graviton field when set up." icon = 'icons/obj/machines/gravity_generator.dmi' anchored = 1 density = 1 @@ -304,17 +304,17 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne // Sound the alert if gravity was just enabled or disabled. var/alert = 0 var/area/A = get_area(src) - if(SSticker.IsRoundInProgress()) - if(on) // If we turned on and the game is live. - if(gravity_in_level() == 0) - alert = 1 - investigate_log("was brought online and is now producing gravity for this level.", "gravity") - message_admins("The gravity generator was brought online [A][ADMIN_COORDJMP(src)]") - else - if(gravity_in_level() == 1) - alert = 1 - investigate_log("was brought offline and there is now no gravity for this level.", "gravity") - message_admins("The gravity generator was brought offline with no backup generator. [A][ADMIN_COORDJMP(src)]") + if(SSticker.IsRoundInProgress()) + if(on) // If we turned on and the game is live. + if(gravity_in_level() == 0) + alert = 1 + investigate_log("was brought online and is now producing gravity for this level.", "gravity") + message_admins("The gravity generator was brought online [A][ADMIN_COORDJMP(src)]") + else + if(gravity_in_level() == 1) + alert = 1 + investigate_log("was brought offline and there is now no gravity for this level.", "gravity") + message_admins("The gravity generator was brought offline with no backup generator. [A][ADMIN_COORDJMP(src)]") update_icon() update_list() diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index b7a298d6b3..9d37173c9f 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -1,493 +1,493 @@ -/obj/machinery/power/emitter - name = "Emitter" - desc = "A heavy duty industrial laser.\nAlt-click to rotate it clockwise." - icon = 'icons/obj/singularity.dmi' - icon_state = "emitter" - var/icon_state_on = "emitter_+a" - anchored = 0 - density = 1 - req_access = list(GLOB.access_engine_equip) - - // The following 3 vars are mostly for the prototype - var/manual = FALSE - var/charge = 0 - var/atom/target = null - - use_power = 0 - idle_power_usage = 10 - active_power_usage = 300 - - var/active = 0 - var/powered = 0 - var/fire_delay = 100 - var/maximum_fire_delay = 100 - var/minimum_fire_delay = 20 - var/last_shot = 0 - var/shot_number = 0 - var/state = 0 - var/locked = 0 - - var/projectile_type = /obj/item/projectile/beam/emitter - - var/projectile_sound = 'sound/weapons/emitter.ogg' - - var/datum/effect_system/spark_spread/sparks - -/obj/machinery/power/emitter/New() - ..() - var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/emitter(null) - B.apply_default_parts(src) - RefreshParts() - wires = new /datum/wires/emitter(src) - -/obj/item/weapon/circuitboard/machine/emitter - name = "Emitter (Machine Board)" - build_path = /obj/machinery/power/emitter - origin_tech = "programming=3;powerstorage=4;engineering=4" - req_components = list( - /obj/item/weapon/stock_parts/micro_laser = 1, - /obj/item/weapon/stock_parts/manipulator = 1) - -/obj/machinery/power/emitter/RefreshParts() - var/max_firedelay = 120 - var/firedelay = 120 - var/min_firedelay = 24 - var/power_usage = 350 - for(var/obj/item/weapon/stock_parts/micro_laser/L in component_parts) - max_firedelay -= 20 * L.rating - min_firedelay -= 4 * L.rating - firedelay -= 20 * L.rating - maximum_fire_delay = max_firedelay - minimum_fire_delay = min_firedelay - fire_delay = firedelay - for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) - power_usage -= 50 * M.rating - active_power_usage = power_usage - -/obj/machinery/power/emitter/verb/rotate() - set name = "Rotate" - set category = "Object" - set src in oview(1) - - if(usr.stat || !usr.canmove || usr.restrained()) - return - if (src.anchored) - to_chat(usr, "It is fastened to the floor!") - return 0 - src.setDir(turn(src.dir, 270)) - return 1 - -/obj/machinery/power/emitter/AltClick(mob/user) - ..() - if(user.incapacitated()) - to_chat(user, "You can't do that right now!") - return - if(!in_range(src, user)) - return - else - rotate() - -/obj/machinery/power/emitter/Initialize() - . = ..() - if(state == 2 && anchored) - connect_to_network() - - sparks = new - sparks.attach(src) - sparks.set_up(5, TRUE, src) - -/obj/machinery/power/emitter/Destroy() - if(SSticker && SSticker.IsRoundInProgress()) - message_admins("Emitter deleted at ([x],[y],[z] - JMP)",0,1) - log_game("Emitter deleted at ([x],[y],[z])") - investigate_log("deleted at ([x],[y],[z]) at [get_area(src)]","singulo") - QDEL_NULL(sparks) - return ..() - -/obj/machinery/power/emitter/update_icon() - if (active && powernet && avail(active_power_usage)) - icon_state = icon_state_on - else - icon_state = initial(icon_state) - - -/obj/machinery/power/emitter/attack_hand(mob/user) - src.add_fingerprint(user) - if(state == 2) - if(!powernet) - to_chat(user, "The emitter isn't connected to a wire!") - return 1 - if(!src.locked) - if(src.active==1) - src.active = 0 - to_chat(user, "You turn off \the [src].") - message_admins("Emitter turned off by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(src)]",0,1) - log_game("Emitter turned off by [key_name(user)] in [COORD(src)]") - investigate_log("turned off by [key_name(user)] at [get_area(src)]","singulo") - else - src.active = 1 - to_chat(user, "You turn on \the [src].") - src.shot_number = 0 - src.fire_delay = maximum_fire_delay - investigate_log("turned on by [key_name(user)] at [get_area(src)]","singulo") - update_icon() - else - to_chat(user, "The controls are locked!") - else - to_chat(user, "The [src] needs to be firmly secured to the floor first!") - return 1 - -/obj/machinery/power/emitter/attack_animal(mob/living/simple_animal/M) - if(ismegafauna(M) && anchored) - state = 0 - anchored = FALSE - M.visible_message("[M] rips [src] free from its moorings!") - else - ..() - if(!anchored) - step(src, get_dir(M, src)) - - -/obj/machinery/power/emitter/emp_act(severity)//Emitters are hardened but still might have issues -// add_load(1000) -/* if((severity == 1)&&prob(1)&&prob(1)) - if(src.active) - src.active = 0 - src.use_power = 1 */ - return 1 - - -/obj/machinery/power/emitter/process() - if(stat & (BROKEN)) - return - if(src.state != 2 || (!powernet && active_power_usage)) - src.active = 0 - update_icon() - return - if(src.active == 1) - if(!active_power_usage || avail(active_power_usage)) - add_load(active_power_usage) - if(!powered) - powered = 1 - update_icon() - investigate_log("regained power and turned on at [get_area(src)]","singulo") - else - if(powered) - powered = 0 - update_icon() - investigate_log("lost power and turned off at [get_area(src)]","singulo") - log_game("Emitter lost power in ([x],[y],[z])") - return - if(charge <=80) - charge+=5 - if(!check_delay() || manual == TRUE) - return FALSE - fire_beam(target) - -/obj/machinery/power/emitter/proc/check_delay() - if((src.last_shot + src.fire_delay) <= world.time) - return TRUE - return FALSE - -/obj/machinery/power/emitter/proc/fire_beam_pulse() - if(!check_delay()) - return FALSE - if(state != 2) - return FALSE - if(avail(active_power_usage)) - add_load(active_power_usage) - fire_beam() - -/obj/machinery/power/emitter/proc/fire_beam(atom/targeted_atom, mob/user) - var/turf/targets_from = get_turf(src) - if(targeted_atom && (targeted_atom == user || targeted_atom == targets_from || targeted_atom == src)) - return - var/obj/item/projectile/P = new projectile_type(targets_from) - playsound(src.loc, projectile_sound, 50, 1) - if(prob(35)) - sparks.start() - switch(dir) - if(NORTH) - P.yo = 20 - P.xo = 0 - if(NORTHEAST) - P.yo = 20 - P.xo = 20 - if(EAST) - P.yo = 0 - P.xo = 20 - if(SOUTHEAST) - P.yo = -20 - P.xo = 20 - if(WEST) - P.yo = 0 - P.xo = -20 - if(SOUTHWEST) - P.yo = -20 - P.xo = -20 - if(NORTHWEST) - P.yo = 20 - P.xo = -20 - else // Any other - P.yo = -20 - P.xo = 0 - if(target) - P.yo = targeted_atom.y - targets_from.y - P.xo = targeted_atom.x - targets_from.x - P.current = targets_from - P.starting = targets_from - P.firer = src - P.original = targeted_atom - if(!manual) - last_shot = world.time - if(shot_number < 3) - fire_delay = 20 - shot_number ++ - else - fire_delay = rand(minimum_fire_delay,maximum_fire_delay) - shot_number = 0 - if(!target) - P.setDir(src.dir) - P.starting = loc - else - if(QDELETED(target)) - target = null - P.fire() - return P - -/obj/machinery/power/emitter/can_be_unfasten_wrench(mob/user, silent) - if(state == EM_WELDED) - if(!silent) - to_chat(user, "[src] is welded to the floor!") - return FAILED_UNFASTEN - return ..() - -/obj/machinery/power/emitter/default_unfasten_wrench(mob/user, obj/item/weapon/wrench/W, time = 20) - . = ..() - if(. == SUCCESSFUL_UNFASTEN) - if(anchored) - state = EM_SECURED - else - state = EM_UNSECURED - -/obj/machinery/power/emitter/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/weapon/wrench)) - if(active) - to_chat(user, "Turn \the [src] off first!") - return - default_unfasten_wrench(user, W, 0) - return - - if(istype(W, /obj/item/weapon/weldingtool)) - var/obj/item/weapon/weldingtool/WT = W - if(active) - to_chat(user, "Turn \the [src] off first.") - return - switch(state) - if(EM_UNSECURED) - to_chat(user, "The [src.name] needs to be wrenched to the floor!") - if(EM_SECURED) - if(WT.remove_fuel(0,user)) - playsound(loc, WT.usesound, 50, 1) - user.visible_message("[user.name] starts to weld the [name] to the floor.", \ - "You start to weld \the [src] to the floor...", \ - "You hear welding.") - if(do_after(user,20*W.toolspeed, target = src) && WT.isOn()) - state = EM_WELDED - to_chat(user, "You weld \the [src] to the floor.") - connect_to_network() - if(EM_WELDED) - if(WT.remove_fuel(0,user)) - playsound(loc, WT.usesound, 50, 1) - user.visible_message("[user.name] starts to cut the [name] free from the floor.", \ - "You start to cut \the [src] free from the floor...", \ - "You hear welding.") - if(do_after(user,20*W.toolspeed, target = src) && WT.isOn()) - state = EM_SECURED - to_chat(user, "You cut \the [src] free from the floor.") - disconnect_from_network() - return - - if(W.GetID()) - if(emagged) - to_chat(user, "The lock seems to be broken!") - return - if(allowed(user)) - if(active) - locked = !locked - to_chat(user, "You [src.locked ? "lock" : "unlock"] the controls.") - else - to_chat(user, "The controls can only be locked when \the [src] is online!") - else - to_chat(user, "Access denied.") - return - - if(is_wire_tool(W) && panel_open) - wires.interact(user) - return - - if(default_deconstruction_screwdriver(user, "emitter_open", "emitter", W)) - return - - if(exchange_parts(user, W)) - return - - if(default_pry_open(W)) - return - - if(default_deconstruction_crowbar(W)) - return - - return ..() - -/obj/machinery/power/emitter/emag_act(mob/user) - if(!emagged) - locked = 0 - emagged = 1 - if(user) - user.visible_message("[user.name] emags the [src.name].","You short out the lock.") - - -/obj/machinery/power/emitter/prototype - name = "Prototype Emitter" - icon = 'icons/obj/turrets.dmi' - icon_state = "protoemitter" - icon_state_on = "protoemitter_+a" - can_buckle = TRUE - buckle_lying = 0 - var/view_range = 12 - var/datum/action/innate/protoemitter/firing/auto - -//BUCKLE HOOKS - -/obj/machinery/power/emitter/prototype/unbuckle_mob(mob/living/buckled_mob,force = 0) - playsound(src,'sound/mecha/mechmove01.ogg', 50, 1) - manual = FALSE - for(var/obj/item/I in buckled_mob.held_items) - if(istype(I, /obj/item/weapon/turret_control)) - qdel(I) - if(istype(buckled_mob)) - buckled_mob.pixel_x = 0 - buckled_mob.pixel_y = 0 - if(buckled_mob.client) - buckled_mob.client.change_view(world.view) - auto.Remove(buckled_mob) - . = ..() - -/obj/machinery/power/emitter/prototype/user_buckle_mob(mob/living/M, mob/living/carbon/user) - if(user.incapacitated() || !istype(user)) - return - for(var/atom/movable/A in get_turf(src)) - if(A.density && (A != src && A != M)) - return - M.forceMove(get_turf(src)) - ..() - playsound(src,'sound/mecha/mechmove01.ogg', 50, 1) - M.pixel_y = 14 - layer = 4.1 - if(M.client) - M.client.change_view(view_range) - if(!auto) - auto = new() - auto.Grant(M, src) - -/datum/action/innate/protoemitter - check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUNNED | AB_CHECK_CONSCIOUS - var/obj/machinery/power/emitter/prototype/PE - var/mob/living/carbon/U - - -/datum/action/innate/protoemitter/Grant(mob/living/carbon/L, obj/machinery/power/emitter/prototype/proto) - PE = proto - U = L - . = ..() - -/datum/action/innate/protoemitter/firing - name = "Switch to Manual Firing" - desc = "The emitter will only fire on your command and at your designated target" - button_icon_state = "mech_zoom_on" - -/datum/action/innate/protoemitter/firing/Activate() - if(PE.manual) - playsound(PE,'sound/mecha/mechmove01.ogg', 50, 1) - PE.manual = FALSE - name = "Switch to Manual Firing" - desc = "The emitter will only fire on your command and at your designated target" - button_icon_state = "mech_zoom_on" - for(var/obj/item/I in U.held_items) - if(istype(I, /obj/item/weapon/turret_control)) - qdel(I) - UpdateButtonIcon() - return - else - playsound(PE,'sound/mecha/mechmove01.ogg', 50, 1) - name = "Switch to Automatic Firing" - desc = "Emitters will switch to periodic firing at your last target" - button_icon_state = "mech_zoom_off" - PE.manual = TRUE - for(var/V in U.held_items) - var/obj/item/I = V - if(istype(I)) - if(U.dropItemToGround(I)) - var/obj/item/weapon/turret_control/TC = new /obj/item/weapon/turret_control() - U.put_in_hands(TC) - else //Entries in the list should only ever be items or null, so if it's not an item, we can assume it's an empty hand - var/obj/item/weapon/turret_control/TC = new /obj/item/weapon/turret_control() - U.put_in_hands(TC) - UpdateButtonIcon() - - -/obj/item/weapon/turret_control - name = "turret controls" - icon_state = "offhand" - w_class = WEIGHT_CLASS_HUGE - flags = ABSTRACT | NODROP - resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF | NOBLUDGEON - var/delay = 0 - -/obj/item/weapon/turret_control/afterattack(atom/targeted_atom, mob/user) - ..() - var/obj/machinery/power/emitter/E = user.buckled - E.setDir(get_dir(E,targeted_atom)) - user.setDir(E.dir) - switch(E.dir) - if(NORTH) - E.layer = 3.9 - user.pixel_x = 0 - user.pixel_y = -14 - if(NORTHEAST) - E.layer = 3.9 - user.pixel_x = -8 - user.pixel_y = -12 - if(EAST) - E.layer = 4.1 - user.pixel_x = -14 - user.pixel_y = 0 - if(SOUTHEAST) - E.layer = 3.9 - user.pixel_x = -8 - user.pixel_y = 12 - if(SOUTH) - E.layer = 4.1 - user.pixel_x = 0 - user.pixel_y = 14 - if(SOUTHWEST) - E.layer = 3.9 - user.pixel_x = 8 - user.pixel_y = 12 - if(WEST) - E.layer = 4.1 - user.pixel_x = 14 - user.pixel_y = 0 - if(NORTHWEST) - E.layer = 3.9 - user.pixel_x = 8 - user.pixel_y = -12 - - if(E.charge >= 10 && world.time > delay) - E.charge -= 10 - E.target = targeted_atom - E.fire_beam(targeted_atom, user) - delay = world.time + 10 - else if (E.charge < 10) - playsound(get_turf(user),'sound/machines/buzz-sigh.ogg', 50, 1) +/obj/machinery/power/emitter + name = "Emitter" + desc = "A heavy duty industrial laser.\nAlt-click to rotate it clockwise." + icon = 'icons/obj/singularity.dmi' + icon_state = "emitter" + var/icon_state_on = "emitter_+a" + anchored = 0 + density = 1 + req_access = list(GLOB.access_engine_equip) + + // The following 3 vars are mostly for the prototype + var/manual = FALSE + var/charge = 0 + var/atom/target = null + + use_power = 0 + idle_power_usage = 10 + active_power_usage = 300 + + var/active = 0 + var/powered = 0 + var/fire_delay = 100 + var/maximum_fire_delay = 100 + var/minimum_fire_delay = 20 + var/last_shot = 0 + var/shot_number = 0 + var/state = 0 + var/locked = 0 + + var/projectile_type = /obj/item/projectile/beam/emitter + + var/projectile_sound = 'sound/weapons/emitter.ogg' + + var/datum/effect_system/spark_spread/sparks + +/obj/machinery/power/emitter/New() + ..() + var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/emitter(null) + B.apply_default_parts(src) + RefreshParts() + wires = new /datum/wires/emitter(src) + +/obj/item/weapon/circuitboard/machine/emitter + name = "Emitter (Machine Board)" + build_path = /obj/machinery/power/emitter + origin_tech = "programming=3;powerstorage=4;engineering=4" + req_components = list( + /obj/item/weapon/stock_parts/micro_laser = 1, + /obj/item/weapon/stock_parts/manipulator = 1) + +/obj/machinery/power/emitter/RefreshParts() + var/max_firedelay = 120 + var/firedelay = 120 + var/min_firedelay = 24 + var/power_usage = 350 + for(var/obj/item/weapon/stock_parts/micro_laser/L in component_parts) + max_firedelay -= 20 * L.rating + min_firedelay -= 4 * L.rating + firedelay -= 20 * L.rating + maximum_fire_delay = max_firedelay + minimum_fire_delay = min_firedelay + fire_delay = firedelay + for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts) + power_usage -= 50 * M.rating + active_power_usage = power_usage + +/obj/machinery/power/emitter/verb/rotate() + set name = "Rotate" + set category = "Object" + set src in oview(1) + + if(usr.stat || !usr.canmove || usr.restrained()) + return + if (src.anchored) + to_chat(usr, "It is fastened to the floor!") + return 0 + src.setDir(turn(src.dir, 270)) + return 1 + +/obj/machinery/power/emitter/AltClick(mob/user) + ..() + if(user.incapacitated()) + to_chat(user, "You can't do that right now!") + return + if(!in_range(src, user)) + return + else + rotate() + +/obj/machinery/power/emitter/Initialize() + . = ..() + if(state == 2 && anchored) + connect_to_network() + + sparks = new + sparks.attach(src) + sparks.set_up(5, TRUE, src) + +/obj/machinery/power/emitter/Destroy() + if(SSticker && SSticker.IsRoundInProgress()) + message_admins("Emitter deleted at ([x],[y],[z] - JMP)",0,1) + log_game("Emitter deleted at ([x],[y],[z])") + investigate_log("deleted at ([x],[y],[z]) at [get_area(src)]","singulo") + QDEL_NULL(sparks) + return ..() + +/obj/machinery/power/emitter/update_icon() + if (active && powernet && avail(active_power_usage)) + icon_state = icon_state_on + else + icon_state = initial(icon_state) + + +/obj/machinery/power/emitter/attack_hand(mob/user) + src.add_fingerprint(user) + if(state == 2) + if(!powernet) + to_chat(user, "The emitter isn't connected to a wire!") + return 1 + if(!src.locked) + if(src.active==1) + src.active = 0 + to_chat(user, "You turn off \the [src].") + message_admins("Emitter turned off by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(src)]",0,1) + log_game("Emitter turned off by [key_name(user)] in [COORD(src)]") + investigate_log("turned off by [key_name(user)] at [get_area(src)]","singulo") + else + src.active = 1 + to_chat(user, "You turn on \the [src].") + src.shot_number = 0 + src.fire_delay = maximum_fire_delay + investigate_log("turned on by [key_name(user)] at [get_area(src)]","singulo") + update_icon() + else + to_chat(user, "The controls are locked!") + else + to_chat(user, "The [src] needs to be firmly secured to the floor first!") + return 1 + +/obj/machinery/power/emitter/attack_animal(mob/living/simple_animal/M) + if(ismegafauna(M) && anchored) + state = 0 + anchored = FALSE + M.visible_message("[M] rips [src] free from its moorings!") + else + ..() + if(!anchored) + step(src, get_dir(M, src)) + + +/obj/machinery/power/emitter/emp_act(severity)//Emitters are hardened but still might have issues +// add_load(1000) +/* if((severity == 1)&&prob(1)&&prob(1)) + if(src.active) + src.active = 0 + src.use_power = 1 */ + return 1 + + +/obj/machinery/power/emitter/process() + if(stat & (BROKEN)) + return + if(src.state != 2 || (!powernet && active_power_usage)) + src.active = 0 + update_icon() + return + if(src.active == 1) + if(!active_power_usage || avail(active_power_usage)) + add_load(active_power_usage) + if(!powered) + powered = 1 + update_icon() + investigate_log("regained power and turned on at [get_area(src)]","singulo") + else + if(powered) + powered = 0 + update_icon() + investigate_log("lost power and turned off at [get_area(src)]","singulo") + log_game("Emitter lost power in ([x],[y],[z])") + return + if(charge <=80) + charge+=5 + if(!check_delay() || manual == TRUE) + return FALSE + fire_beam(target) + +/obj/machinery/power/emitter/proc/check_delay() + if((src.last_shot + src.fire_delay) <= world.time) + return TRUE + return FALSE + +/obj/machinery/power/emitter/proc/fire_beam_pulse() + if(!check_delay()) + return FALSE + if(state != 2) + return FALSE + if(avail(active_power_usage)) + add_load(active_power_usage) + fire_beam() + +/obj/machinery/power/emitter/proc/fire_beam(atom/targeted_atom, mob/user) + var/turf/targets_from = get_turf(src) + if(targeted_atom && (targeted_atom == user || targeted_atom == targets_from || targeted_atom == src)) + return + var/obj/item/projectile/P = new projectile_type(targets_from) + playsound(src.loc, projectile_sound, 50, 1) + if(prob(35)) + sparks.start() + switch(dir) + if(NORTH) + P.yo = 20 + P.xo = 0 + if(NORTHEAST) + P.yo = 20 + P.xo = 20 + if(EAST) + P.yo = 0 + P.xo = 20 + if(SOUTHEAST) + P.yo = -20 + P.xo = 20 + if(WEST) + P.yo = 0 + P.xo = -20 + if(SOUTHWEST) + P.yo = -20 + P.xo = -20 + if(NORTHWEST) + P.yo = 20 + P.xo = -20 + else // Any other + P.yo = -20 + P.xo = 0 + if(target) + P.yo = targeted_atom.y - targets_from.y + P.xo = targeted_atom.x - targets_from.x + P.current = targets_from + P.starting = targets_from + P.firer = src + P.original = targeted_atom + if(!manual) + last_shot = world.time + if(shot_number < 3) + fire_delay = 20 + shot_number ++ + else + fire_delay = rand(minimum_fire_delay,maximum_fire_delay) + shot_number = 0 + if(!target) + P.setDir(src.dir) + P.starting = loc + else + if(QDELETED(target)) + target = null + P.fire() + return P + +/obj/machinery/power/emitter/can_be_unfasten_wrench(mob/user, silent) + if(state == EM_WELDED) + if(!silent) + to_chat(user, "[src] is welded to the floor!") + return FAILED_UNFASTEN + return ..() + +/obj/machinery/power/emitter/default_unfasten_wrench(mob/user, obj/item/weapon/wrench/W, time = 20) + . = ..() + if(. == SUCCESSFUL_UNFASTEN) + if(anchored) + state = EM_SECURED + else + state = EM_UNSECURED + +/obj/machinery/power/emitter/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/weapon/wrench)) + if(active) + to_chat(user, "Turn \the [src] off first!") + return + default_unfasten_wrench(user, W, 0) + return + + if(istype(W, /obj/item/weapon/weldingtool)) + var/obj/item/weapon/weldingtool/WT = W + if(active) + to_chat(user, "Turn \the [src] off first.") + return + switch(state) + if(EM_UNSECURED) + to_chat(user, "The [src.name] needs to be wrenched to the floor!") + if(EM_SECURED) + if(WT.remove_fuel(0,user)) + playsound(loc, WT.usesound, 50, 1) + user.visible_message("[user.name] starts to weld the [name] to the floor.", \ + "You start to weld \the [src] to the floor...", \ + "You hear welding.") + if(do_after(user,20*W.toolspeed, target = src) && WT.isOn()) + state = EM_WELDED + to_chat(user, "You weld \the [src] to the floor.") + connect_to_network() + if(EM_WELDED) + if(WT.remove_fuel(0,user)) + playsound(loc, WT.usesound, 50, 1) + user.visible_message("[user.name] starts to cut the [name] free from the floor.", \ + "You start to cut \the [src] free from the floor...", \ + "You hear welding.") + if(do_after(user,20*W.toolspeed, target = src) && WT.isOn()) + state = EM_SECURED + to_chat(user, "You cut \the [src] free from the floor.") + disconnect_from_network() + return + + if(W.GetID()) + if(emagged) + to_chat(user, "The lock seems to be broken!") + return + if(allowed(user)) + if(active) + locked = !locked + to_chat(user, "You [src.locked ? "lock" : "unlock"] the controls.") + else + to_chat(user, "The controls can only be locked when \the [src] is online!") + else + to_chat(user, "Access denied.") + return + + if(is_wire_tool(W) && panel_open) + wires.interact(user) + return + + if(default_deconstruction_screwdriver(user, "emitter_open", "emitter", W)) + return + + if(exchange_parts(user, W)) + return + + if(default_pry_open(W)) + return + + if(default_deconstruction_crowbar(W)) + return + + return ..() + +/obj/machinery/power/emitter/emag_act(mob/user) + if(!emagged) + locked = 0 + emagged = 1 + if(user) + user.visible_message("[user.name] emags the [src.name].","You short out the lock.") + + +/obj/machinery/power/emitter/prototype + name = "Prototype Emitter" + icon = 'icons/obj/turrets.dmi' + icon_state = "protoemitter" + icon_state_on = "protoemitter_+a" + can_buckle = TRUE + buckle_lying = 0 + var/view_range = 12 + var/datum/action/innate/protoemitter/firing/auto + +//BUCKLE HOOKS + +/obj/machinery/power/emitter/prototype/unbuckle_mob(mob/living/buckled_mob,force = 0) + playsound(src,'sound/mecha/mechmove01.ogg', 50, 1) + manual = FALSE + for(var/obj/item/I in buckled_mob.held_items) + if(istype(I, /obj/item/weapon/turret_control)) + qdel(I) + if(istype(buckled_mob)) + buckled_mob.pixel_x = 0 + buckled_mob.pixel_y = 0 + if(buckled_mob.client) + buckled_mob.client.change_view(world.view) + auto.Remove(buckled_mob) + . = ..() + +/obj/machinery/power/emitter/prototype/user_buckle_mob(mob/living/M, mob/living/carbon/user) + if(user.incapacitated() || !istype(user)) + return + for(var/atom/movable/A in get_turf(src)) + if(A.density && (A != src && A != M)) + return + M.forceMove(get_turf(src)) + ..() + playsound(src,'sound/mecha/mechmove01.ogg', 50, 1) + M.pixel_y = 14 + layer = 4.1 + if(M.client) + M.client.change_view(view_range) + if(!auto) + auto = new() + auto.Grant(M, src) + +/datum/action/innate/protoemitter + check_flags = AB_CHECK_RESTRAINED | AB_CHECK_STUNNED | AB_CHECK_CONSCIOUS + var/obj/machinery/power/emitter/prototype/PE + var/mob/living/carbon/U + + +/datum/action/innate/protoemitter/Grant(mob/living/carbon/L, obj/machinery/power/emitter/prototype/proto) + PE = proto + U = L + . = ..() + +/datum/action/innate/protoemitter/firing + name = "Switch to Manual Firing" + desc = "The emitter will only fire on your command and at your designated target" + button_icon_state = "mech_zoom_on" + +/datum/action/innate/protoemitter/firing/Activate() + if(PE.manual) + playsound(PE,'sound/mecha/mechmove01.ogg', 50, 1) + PE.manual = FALSE + name = "Switch to Manual Firing" + desc = "The emitter will only fire on your command and at your designated target" + button_icon_state = "mech_zoom_on" + for(var/obj/item/I in U.held_items) + if(istype(I, /obj/item/weapon/turret_control)) + qdel(I) + UpdateButtonIcon() + return + else + playsound(PE,'sound/mecha/mechmove01.ogg', 50, 1) + name = "Switch to Automatic Firing" + desc = "Emitters will switch to periodic firing at your last target" + button_icon_state = "mech_zoom_off" + PE.manual = TRUE + for(var/V in U.held_items) + var/obj/item/I = V + if(istype(I)) + if(U.dropItemToGround(I)) + var/obj/item/weapon/turret_control/TC = new /obj/item/weapon/turret_control() + U.put_in_hands(TC) + else //Entries in the list should only ever be items or null, so if it's not an item, we can assume it's an empty hand + var/obj/item/weapon/turret_control/TC = new /obj/item/weapon/turret_control() + U.put_in_hands(TC) + UpdateButtonIcon() + + +/obj/item/weapon/turret_control + name = "turret controls" + icon_state = "offhand" + w_class = WEIGHT_CLASS_HUGE + flags = ABSTRACT | NODROP + resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF | NOBLUDGEON + var/delay = 0 + +/obj/item/weapon/turret_control/afterattack(atom/targeted_atom, mob/user) + ..() + var/obj/machinery/power/emitter/E = user.buckled + E.setDir(get_dir(E,targeted_atom)) + user.setDir(E.dir) + switch(E.dir) + if(NORTH) + E.layer = 3.9 + user.pixel_x = 0 + user.pixel_y = -14 + if(NORTHEAST) + E.layer = 3.9 + user.pixel_x = -8 + user.pixel_y = -12 + if(EAST) + E.layer = 4.1 + user.pixel_x = -14 + user.pixel_y = 0 + if(SOUTHEAST) + E.layer = 3.9 + user.pixel_x = -8 + user.pixel_y = 12 + if(SOUTH) + E.layer = 4.1 + user.pixel_x = 0 + user.pixel_y = 14 + if(SOUTHWEST) + E.layer = 3.9 + user.pixel_x = 8 + user.pixel_y = 12 + if(WEST) + E.layer = 4.1 + user.pixel_x = 14 + user.pixel_y = 0 + if(NORTHWEST) + E.layer = 3.9 + user.pixel_x = 8 + user.pixel_y = -12 + + if(E.charge >= 10 && world.time > delay) + E.charge -= 10 + E.target = targeted_atom + E.fire_beam(targeted_atom, user) + delay = world.time + 10 + else if (E.charge < 10) + playsound(get_turf(user),'sound/machines/buzz-sigh.ogg', 50, 1) diff --git a/code/modules/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm index 2045cb380c..136f9162cf 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_control.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm @@ -1,328 +1,328 @@ -/obj/machinery/particle_accelerator/control_box - name = "Particle Accelerator Control Console" - desc = "This controls the density of the particles." - icon = 'icons/obj/machines/particle_accelerator.dmi' - icon_state = "control_box" - anchored = 0 - density = 1 - use_power = 0 - idle_power_usage = 500 - active_power_usage = 10000 - dir = NORTH - var/strength_upper_limit = 2 - var/interface_control = 1 - var/list/obj/structure/particle_accelerator/connected_parts - var/assembled = 0 - var/construction_state = PA_CONSTRUCTION_UNSECURED - var/active = 0 - var/strength = 0 - var/powered = 0 - mouse_opacity = 2 - -/obj/machinery/particle_accelerator/control_box/New() - wires = new /datum/wires/particle_accelerator/control_box(src) - connected_parts = list() - ..() - -/obj/machinery/particle_accelerator/control_box/Destroy() - if(active) - toggle_power() - for(var/CP in connected_parts) - var/obj/structure/particle_accelerator/part = CP - part.master = null - connected_parts.Cut() - qdel(wires) - wires = null - return ..() - -/obj/machinery/particle_accelerator/control_box/attack_hand(mob/user) - if(construction_state == PA_CONSTRUCTION_COMPLETE) - interact(user) - else if(construction_state == PA_CONSTRUCTION_PANEL_OPEN) - wires.interact(user) - -/obj/machinery/particle_accelerator/control_box/proc/update_state() - if(construction_state < PA_CONSTRUCTION_COMPLETE) - use_power = 0 - assembled = 0 - active = 0 - for(var/CP in connected_parts) - var/obj/structure/particle_accelerator/part = CP - part.strength = null - part.powered = 0 - part.update_icon() - connected_parts.Cut() - return - if(!part_scan()) - use_power = 1 - active = 0 - connected_parts.Cut() - -/obj/machinery/particle_accelerator/control_box/update_icon() - if(active) - icon_state = "control_boxp1" - else - if(use_power) - if(assembled) - icon_state = "control_boxp" - else - icon_state = "ucontrol_boxp" - else - switch(construction_state) - if(PA_CONSTRUCTION_UNSECURED, PA_CONSTRUCTION_UNWIRED) - icon_state = "control_box" - if(PA_CONSTRUCTION_PANEL_OPEN) - icon_state = "control_boxw" - else - icon_state = "control_boxc" - -/obj/machinery/particle_accelerator/control_box/Topic(href, href_list) - if(..()) - return - - if(!interface_control) - to_chat(usr, "ERROR: Request timed out. Check wire contacts.") - return - - if(href_list["close"]) - usr << browse(null, "window=pacontrol") - usr.unset_machine() - return - if(href_list["togglep"]) - if(!wires.is_cut(WIRE_POWER)) - toggle_power() - - else if(href_list["scan"]) - part_scan() - - else if(href_list["strengthup"]) - if(!wires.is_cut(WIRE_STRENGTH)) - add_strength() - - else if(href_list["strengthdown"]) - if(!wires.is_cut(WIRE_STRENGTH)) - remove_strength() - - updateDialog() - update_icon() - -/obj/machinery/particle_accelerator/control_box/proc/strength_change() - for(var/CP in connected_parts) - var/obj/structure/particle_accelerator/part = CP - part.strength = strength - part.update_icon() - -/obj/machinery/particle_accelerator/control_box/proc/add_strength(s) - if(assembled && (strength < strength_upper_limit)) - strength++ - strength_change() - - message_admins("PA Control Computer increased to [strength] by [ADMIN_LOOKUPFLW(usr)] in [ADMIN_COORDJMP(src)]",0,1) - log_game("PA Control Computer increased to [strength] by [key_name(usr)] in [COORD(src)]") - investigate_log("increased to [strength] by [key_name(usr)]","singulo") - - -/obj/machinery/particle_accelerator/control_box/proc/remove_strength(s) - if(assembled && (strength > 0)) - strength-- - strength_change() - - message_admins("PA Control Computer decreased to [strength] by [ADMIN_LOOKUPFLW(usr)] in [ADMIN_COORDJMP(src)]",0,1) - log_game("PA Control Computer decreased to [strength] by [key_name(usr)] in [COORD(src)]") - investigate_log("decreased to [strength] by [key_name(usr)]","singulo") - - -/obj/machinery/particle_accelerator/control_box/power_change() - ..() - if(stat & NOPOWER) - active = 0 - use_power = 0 - else if(!stat && construction_state == PA_CONSTRUCTION_COMPLETE) - use_power = 1 - -/obj/machinery/particle_accelerator/control_box/process() - if(active) - //a part is missing! - if(connected_parts.len < 6) - investigate_log("lost a connected part; It powered down.","singulo") - toggle_power() - update_icon() - return - //emit some particles - for(var/obj/structure/particle_accelerator/particle_emitter/PE in connected_parts) - PE.emit_particle(strength) - -/obj/machinery/particle_accelerator/control_box/proc/part_scan() - var/ldir = turn(dir,-90) - var/rdir = turn(dir,90) - var/odir = turn(dir,180) - var/turf/T = loc - - assembled = 0 - critical_machine = FALSE - - var/obj/structure/particle_accelerator/fuel_chamber/F = locate() in orange(1,src) - if(!F) - return 0 - - setDir(F.dir) - connected_parts.Cut() - - T = get_step(T,rdir) - if(!check_part(T,/obj/structure/particle_accelerator/fuel_chamber)) - return 0 - T = get_step(T,odir) - if(!check_part(T,/obj/structure/particle_accelerator/end_cap)) - return 0 - T = get_step(T,dir) - T = get_step(T,dir) - if(!check_part(T,/obj/structure/particle_accelerator/power_box)) - return 0 - T = get_step(T,dir) - if(!check_part(T,/obj/structure/particle_accelerator/particle_emitter/center)) - return 0 - T = get_step(T,ldir) - if(!check_part(T,/obj/structure/particle_accelerator/particle_emitter/left)) - return 0 - T = get_step(T,rdir) - T = get_step(T,rdir) - if(!check_part(T,/obj/structure/particle_accelerator/particle_emitter/right)) - return 0 - - assembled = 1 - critical_machine = TRUE //Only counts if the PA is actually assembled. - return 1 - -/obj/machinery/particle_accelerator/control_box/proc/check_part(turf/T, type) - var/obj/structure/particle_accelerator/PA = locate(/obj/structure/particle_accelerator) in T - if(istype(PA, type) && (PA.construction_state == PA_CONSTRUCTION_COMPLETE)) - if(PA.connect_master(src)) - connected_parts.Add(PA) - return 1 - return 0 - - -/obj/machinery/particle_accelerator/control_box/proc/toggle_power() - active = !active - investigate_log("turned [active?"ON":"OFF"] by [usr ? key_name(usr) : "outside forces"]","singulo") - message_admins("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? key_name_admin(usr) : "outside forces"](?) (FLW) in ([x],[y],[z] - JMP)",0,1) - log_game("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? "[key_name(usr)]" : "outside forces"] in ([x],[y],[z])") - if(active) - use_power = 2 - for(var/CP in connected_parts) - var/obj/structure/particle_accelerator/part = CP - part.strength = strength - part.powered = 1 - part.update_icon() - else - use_power = 1 - for(var/CP in connected_parts) - var/obj/structure/particle_accelerator/part = CP - part.strength = null - part.powered = 0 - part.update_icon() - return 1 - - -/obj/machinery/particle_accelerator/control_box/interact(mob/user) - if((get_dist(src, user) > 1) || (stat & (BROKEN|NOPOWER))) - if(!issilicon(user)) - user.unset_machine() - user << browse(null, "window=pacontrol") - return - user.set_machine(src) - - var/dat = "" - dat += "Close

" - dat += "

Status

" - if(!assembled) - dat += "Unable to detect all parts!
" - dat += "Run Scan

" - else - dat += "All parts in place.

" - dat += "Power:" - if(active) - dat += "On
" - else - dat += "Off
" - dat += "Toggle Power

" - dat += "Particle Strength: [strength] " - dat += "--|++

" - - var/datum/browser/popup = new(user, "pacontrol", name, 420, 300) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) - popup.open() - -/obj/machinery/particle_accelerator/control_box/examine(mob/user) - ..() - switch(construction_state) - if(PA_CONSTRUCTION_UNSECURED) - to_chat(user, "Looks like it's not attached to the flooring") - if(PA_CONSTRUCTION_UNWIRED) - to_chat(user, "It is missing some cables") - if(PA_CONSTRUCTION_PANEL_OPEN) - to_chat(user, "The panel is open") - - -/obj/machinery/particle_accelerator/control_box/attackby(obj/item/W, mob/user, params) - var/did_something = FALSE - - switch(construction_state) - if(PA_CONSTRUCTION_UNSECURED) - if(istype(W, /obj/item/weapon/wrench) && !isinspace()) - playsound(loc, W.usesound, 75, 1) - anchored = 1 - user.visible_message("[user.name] secures the [name] to the floor.", \ - "You secure the external bolts.") - construction_state = PA_CONSTRUCTION_UNWIRED - did_something = TRUE - if(PA_CONSTRUCTION_UNWIRED) - if(istype(W, /obj/item/weapon/wrench)) - playsound(loc, W.usesound, 75, 1) - anchored = 0 - user.visible_message("[user.name] detaches the [name] from the floor.", \ - "You remove the external bolts.") - construction_state = PA_CONSTRUCTION_UNSECURED - did_something = TRUE - else if(istype(W, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/CC = W - if(CC.use(1)) - user.visible_message("[user.name] adds wires to the [name].", \ - "You add some wires.") - construction_state = PA_CONSTRUCTION_PANEL_OPEN - did_something = TRUE - if(PA_CONSTRUCTION_PANEL_OPEN) - if(istype(W, /obj/item/weapon/wirecutters))//TODO:Shock user if its on? - user.visible_message("[user.name] removes some wires from the [name].", \ - "You remove some wires.") - construction_state = PA_CONSTRUCTION_UNWIRED - did_something = TRUE - else if(istype(W, /obj/item/weapon/screwdriver)) - user.visible_message("[user.name] closes the [name]'s access panel.", \ - "You close the access panel.") - construction_state = PA_CONSTRUCTION_COMPLETE - did_something = TRUE - if(PA_CONSTRUCTION_COMPLETE) - if(istype(W, /obj/item/weapon/screwdriver)) - user.visible_message("[user.name] opens the [name]'s access panel.", \ - "You open the access panel.") - construction_state = PA_CONSTRUCTION_PANEL_OPEN - did_something = TRUE - - if(did_something) - user.changeNext_move(CLICK_CD_MELEE) - update_state() - update_icon() - return - - ..() - -/obj/machinery/particle_accelerator/control_box/blob_act(obj/structure/blob/B) - if(prob(50)) - qdel(src) - -#undef PA_CONSTRUCTION_UNSECURED -#undef PA_CONSTRUCTION_UNWIRED -#undef PA_CONSTRUCTION_PANEL_OPEN -#undef PA_CONSTRUCTION_COMPLETE +/obj/machinery/particle_accelerator/control_box + name = "Particle Accelerator Control Console" + desc = "This controls the density of the particles." + icon = 'icons/obj/machines/particle_accelerator.dmi' + icon_state = "control_box" + anchored = 0 + density = 1 + use_power = 0 + idle_power_usage = 500 + active_power_usage = 10000 + dir = NORTH + var/strength_upper_limit = 2 + var/interface_control = 1 + var/list/obj/structure/particle_accelerator/connected_parts + var/assembled = 0 + var/construction_state = PA_CONSTRUCTION_UNSECURED + var/active = 0 + var/strength = 0 + var/powered = 0 + mouse_opacity = 2 + +/obj/machinery/particle_accelerator/control_box/New() + wires = new /datum/wires/particle_accelerator/control_box(src) + connected_parts = list() + ..() + +/obj/machinery/particle_accelerator/control_box/Destroy() + if(active) + toggle_power() + for(var/CP in connected_parts) + var/obj/structure/particle_accelerator/part = CP + part.master = null + connected_parts.Cut() + qdel(wires) + wires = null + return ..() + +/obj/machinery/particle_accelerator/control_box/attack_hand(mob/user) + if(construction_state == PA_CONSTRUCTION_COMPLETE) + interact(user) + else if(construction_state == PA_CONSTRUCTION_PANEL_OPEN) + wires.interact(user) + +/obj/machinery/particle_accelerator/control_box/proc/update_state() + if(construction_state < PA_CONSTRUCTION_COMPLETE) + use_power = 0 + assembled = 0 + active = 0 + for(var/CP in connected_parts) + var/obj/structure/particle_accelerator/part = CP + part.strength = null + part.powered = 0 + part.update_icon() + connected_parts.Cut() + return + if(!part_scan()) + use_power = 1 + active = 0 + connected_parts.Cut() + +/obj/machinery/particle_accelerator/control_box/update_icon() + if(active) + icon_state = "control_boxp1" + else + if(use_power) + if(assembled) + icon_state = "control_boxp" + else + icon_state = "ucontrol_boxp" + else + switch(construction_state) + if(PA_CONSTRUCTION_UNSECURED, PA_CONSTRUCTION_UNWIRED) + icon_state = "control_box" + if(PA_CONSTRUCTION_PANEL_OPEN) + icon_state = "control_boxw" + else + icon_state = "control_boxc" + +/obj/machinery/particle_accelerator/control_box/Topic(href, href_list) + if(..()) + return + + if(!interface_control) + to_chat(usr, "ERROR: Request timed out. Check wire contacts.") + return + + if(href_list["close"]) + usr << browse(null, "window=pacontrol") + usr.unset_machine() + return + if(href_list["togglep"]) + if(!wires.is_cut(WIRE_POWER)) + toggle_power() + + else if(href_list["scan"]) + part_scan() + + else if(href_list["strengthup"]) + if(!wires.is_cut(WIRE_STRENGTH)) + add_strength() + + else if(href_list["strengthdown"]) + if(!wires.is_cut(WIRE_STRENGTH)) + remove_strength() + + updateDialog() + update_icon() + +/obj/machinery/particle_accelerator/control_box/proc/strength_change() + for(var/CP in connected_parts) + var/obj/structure/particle_accelerator/part = CP + part.strength = strength + part.update_icon() + +/obj/machinery/particle_accelerator/control_box/proc/add_strength(s) + if(assembled && (strength < strength_upper_limit)) + strength++ + strength_change() + + message_admins("PA Control Computer increased to [strength] by [ADMIN_LOOKUPFLW(usr)] in [ADMIN_COORDJMP(src)]",0,1) + log_game("PA Control Computer increased to [strength] by [key_name(usr)] in [COORD(src)]") + investigate_log("increased to [strength] by [key_name(usr)]","singulo") + + +/obj/machinery/particle_accelerator/control_box/proc/remove_strength(s) + if(assembled && (strength > 0)) + strength-- + strength_change() + + message_admins("PA Control Computer decreased to [strength] by [ADMIN_LOOKUPFLW(usr)] in [ADMIN_COORDJMP(src)]",0,1) + log_game("PA Control Computer decreased to [strength] by [key_name(usr)] in [COORD(src)]") + investigate_log("decreased to [strength] by [key_name(usr)]","singulo") + + +/obj/machinery/particle_accelerator/control_box/power_change() + ..() + if(stat & NOPOWER) + active = 0 + use_power = 0 + else if(!stat && construction_state == PA_CONSTRUCTION_COMPLETE) + use_power = 1 + +/obj/machinery/particle_accelerator/control_box/process() + if(active) + //a part is missing! + if(connected_parts.len < 6) + investigate_log("lost a connected part; It powered down.","singulo") + toggle_power() + update_icon() + return + //emit some particles + for(var/obj/structure/particle_accelerator/particle_emitter/PE in connected_parts) + PE.emit_particle(strength) + +/obj/machinery/particle_accelerator/control_box/proc/part_scan() + var/ldir = turn(dir,-90) + var/rdir = turn(dir,90) + var/odir = turn(dir,180) + var/turf/T = loc + + assembled = 0 + critical_machine = FALSE + + var/obj/structure/particle_accelerator/fuel_chamber/F = locate() in orange(1,src) + if(!F) + return 0 + + setDir(F.dir) + connected_parts.Cut() + + T = get_step(T,rdir) + if(!check_part(T,/obj/structure/particle_accelerator/fuel_chamber)) + return 0 + T = get_step(T,odir) + if(!check_part(T,/obj/structure/particle_accelerator/end_cap)) + return 0 + T = get_step(T,dir) + T = get_step(T,dir) + if(!check_part(T,/obj/structure/particle_accelerator/power_box)) + return 0 + T = get_step(T,dir) + if(!check_part(T,/obj/structure/particle_accelerator/particle_emitter/center)) + return 0 + T = get_step(T,ldir) + if(!check_part(T,/obj/structure/particle_accelerator/particle_emitter/left)) + return 0 + T = get_step(T,rdir) + T = get_step(T,rdir) + if(!check_part(T,/obj/structure/particle_accelerator/particle_emitter/right)) + return 0 + + assembled = 1 + critical_machine = TRUE //Only counts if the PA is actually assembled. + return 1 + +/obj/machinery/particle_accelerator/control_box/proc/check_part(turf/T, type) + var/obj/structure/particle_accelerator/PA = locate(/obj/structure/particle_accelerator) in T + if(istype(PA, type) && (PA.construction_state == PA_CONSTRUCTION_COMPLETE)) + if(PA.connect_master(src)) + connected_parts.Add(PA) + return 1 + return 0 + + +/obj/machinery/particle_accelerator/control_box/proc/toggle_power() + active = !active + investigate_log("turned [active?"ON":"OFF"] by [usr ? key_name(usr) : "outside forces"]","singulo") + message_admins("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? key_name_admin(usr) : "outside forces"](?) (FLW) in ([x],[y],[z] - JMP)",0,1) + log_game("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? "[key_name(usr)]" : "outside forces"] in ([x],[y],[z])") + if(active) + use_power = 2 + for(var/CP in connected_parts) + var/obj/structure/particle_accelerator/part = CP + part.strength = strength + part.powered = 1 + part.update_icon() + else + use_power = 1 + for(var/CP in connected_parts) + var/obj/structure/particle_accelerator/part = CP + part.strength = null + part.powered = 0 + part.update_icon() + return 1 + + +/obj/machinery/particle_accelerator/control_box/interact(mob/user) + if((get_dist(src, user) > 1) || (stat & (BROKEN|NOPOWER))) + if(!issilicon(user)) + user.unset_machine() + user << browse(null, "window=pacontrol") + return + user.set_machine(src) + + var/dat = "" + dat += "Close

" + dat += "

Status

" + if(!assembled) + dat += "Unable to detect all parts!
" + dat += "Run Scan

" + else + dat += "All parts in place.

" + dat += "Power:" + if(active) + dat += "On
" + else + dat += "Off
" + dat += "Toggle Power

" + dat += "Particle Strength: [strength] " + dat += "--|++

" + + var/datum/browser/popup = new(user, "pacontrol", name, 420, 300) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) + popup.open() + +/obj/machinery/particle_accelerator/control_box/examine(mob/user) + ..() + switch(construction_state) + if(PA_CONSTRUCTION_UNSECURED) + to_chat(user, "Looks like it's not attached to the flooring") + if(PA_CONSTRUCTION_UNWIRED) + to_chat(user, "It is missing some cables") + if(PA_CONSTRUCTION_PANEL_OPEN) + to_chat(user, "The panel is open") + + +/obj/machinery/particle_accelerator/control_box/attackby(obj/item/W, mob/user, params) + var/did_something = FALSE + + switch(construction_state) + if(PA_CONSTRUCTION_UNSECURED) + if(istype(W, /obj/item/weapon/wrench) && !isinspace()) + playsound(loc, W.usesound, 75, 1) + anchored = 1 + user.visible_message("[user.name] secures the [name] to the floor.", \ + "You secure the external bolts.") + construction_state = PA_CONSTRUCTION_UNWIRED + did_something = TRUE + if(PA_CONSTRUCTION_UNWIRED) + if(istype(W, /obj/item/weapon/wrench)) + playsound(loc, W.usesound, 75, 1) + anchored = 0 + user.visible_message("[user.name] detaches the [name] from the floor.", \ + "You remove the external bolts.") + construction_state = PA_CONSTRUCTION_UNSECURED + did_something = TRUE + else if(istype(W, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/CC = W + if(CC.use(1)) + user.visible_message("[user.name] adds wires to the [name].", \ + "You add some wires.") + construction_state = PA_CONSTRUCTION_PANEL_OPEN + did_something = TRUE + if(PA_CONSTRUCTION_PANEL_OPEN) + if(istype(W, /obj/item/weapon/wirecutters))//TODO:Shock user if its on? + user.visible_message("[user.name] removes some wires from the [name].", \ + "You remove some wires.") + construction_state = PA_CONSTRUCTION_UNWIRED + did_something = TRUE + else if(istype(W, /obj/item/weapon/screwdriver)) + user.visible_message("[user.name] closes the [name]'s access panel.", \ + "You close the access panel.") + construction_state = PA_CONSTRUCTION_COMPLETE + did_something = TRUE + if(PA_CONSTRUCTION_COMPLETE) + if(istype(W, /obj/item/weapon/screwdriver)) + user.visible_message("[user.name] opens the [name]'s access panel.", \ + "You open the access panel.") + construction_state = PA_CONSTRUCTION_PANEL_OPEN + did_something = TRUE + + if(did_something) + user.changeNext_move(CLICK_CD_MELEE) + update_state() + update_icon() + return + + ..() + +/obj/machinery/particle_accelerator/control_box/blob_act(obj/structure/blob/B) + if(prob(50)) + qdel(src) + +#undef PA_CONSTRUCTION_UNSECURED +#undef PA_CONSTRUCTION_UNWIRED +#undef PA_CONSTRUCTION_PANEL_OPEN +#undef PA_CONSTRUCTION_COMPLETE diff --git a/code/modules/projectiles/ammunition/energy.dm b/code/modules/projectiles/ammunition/energy.dm index bf695cffed..ba4770ebba 100644 --- a/code/modules/projectiles/ammunition/energy.dm +++ b/code/modules/projectiles/ammunition/energy.dm @@ -9,6 +9,7 @@ firing_effect_type = /obj/effect/overlay/temp/dir_setting/firing_effect/energy /obj/item/ammo_casing/energy/chameleon + projectile_type = /obj/item/projectile/energy/chameleon e_cost = 0 var/list/projectile_vars = list() diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 4e85ee3299..cceb77bee1 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -190,7 +190,7 @@ name = "dart" icon_state = "cbbolt" damage = 6 - var/piercing = FALSE + var/piercing = FALSE /obj/item/projectile/bullet/dart/New() ..() @@ -201,15 +201,15 @@ if(iscarbon(target)) var/mob/living/carbon/M = target if(blocked != 100) // not completely blocked - if(M.can_inject(null, FALSE, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body. + if(M.can_inject(null, FALSE, def_zone, piercing)) // Pass the hit zone to see if it can inject by whether it hit the head or the body. ..() reagents.reaction(M, INJECT) reagents.trans_to(M, reagents.total_volume) - return TRUE + return TRUE else blocked = 100 - target.visible_message("\The [src] was deflected!", \ - "You were protected against \the [src]!") + target.visible_message("\The [src] was deflected!", \ + "You were protected against \the [src]!") ..(target, blocked) reagents.set_reacting(TRUE) @@ -240,28 +240,28 @@ nodamage = 1 . = ..() // Execute the rest of the code. -/obj/item/projectile/bullet/dnainjector - name = "\improper DNA injector" - icon_state = "syringeproj" - var/obj/item/weapon/dnainjector/injector - -/obj/item/projectile/bullet/dnainjector/on_hit(atom/target, blocked = 0) - if(iscarbon(target)) - var/mob/living/carbon/M = target - if(blocked != 100) - if(M.can_inject(null, FALSE, def_zone, FALSE)) - if(injector.inject(M, firer)) - QDEL_NULL(injector) - return TRUE - else - blocked = 100 - target.visible_message("\The [src] was deflected!", \ - "You were protected against \the [src]!") - return ..() - -/obj/item/projectile/bullet/dnainjector/Destroy() - QDEL_NULL(injector) - return ..() +/obj/item/projectile/bullet/dnainjector + name = "\improper DNA injector" + icon_state = "syringeproj" + var/obj/item/weapon/dnainjector/injector + +/obj/item/projectile/bullet/dnainjector/on_hit(atom/target, blocked = 0) + if(iscarbon(target)) + var/mob/living/carbon/M = target + if(blocked != 100) + if(M.can_inject(null, FALSE, def_zone, FALSE)) + if(injector.inject(M, firer)) + QDEL_NULL(injector) + return TRUE + else + blocked = 100 + target.visible_message("\The [src] was deflected!", \ + "You were protected against \the [src]!") + return ..() + +/obj/item/projectile/bullet/dnainjector/Destroy() + QDEL_NULL(injector) + return ..() //// SNIPER BULLETS diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index 974ea935f2..cfa7727186 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -5,6 +5,8 @@ damage_type = BURN flag = "energy" +/obj/item/projectile/energy/chameleon + nodamage = TRUE /obj/item/projectile/energy/electrode name = "electrode" diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm old mode 100755 new mode 100644 diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm old mode 100755 new mode 100644 diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index df8f7927c0..cc38a44ffc 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -1,239 +1,239 @@ -/obj/item/weapon/reagent_containers/spray - name = "spray bottle" - desc = "A spray bottle, with an unscrewable top." - icon = 'icons/obj/janitor.dmi' - icon_state = "cleaner" - item_state = "cleaner" - flags = NOBLUDGEON - container_type = OPENCONTAINER - slot_flags = SLOT_BELT - throwforce = 0 - w_class = WEIGHT_CLASS_SMALL - throw_speed = 3 - throw_range = 7 - var/stream_mode = 0 //whether we use the more focused mode - var/current_range = 3 //the range of tiles the sprayer will reach. - var/spray_range = 3 //the range of tiles the sprayer will reach when in spray mode. - var/stream_range = 1 //the range of tiles the sprayer will reach when in stream mode. - var/stream_amount = 10 //the amount of reagents transfered when in stream mode. - amount_per_transfer_from_this = 5 - volume = 250 - possible_transfer_amounts = list(5,10,15,20,25,30,50,100) - - -/obj/item/weapon/reagent_containers/spray/afterattack(atom/A as mob|obj, mob/user) - if(istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart) || istype(A, /obj/machinery/hydroponics)) - return - - if(istype(A, /obj/structure/reagent_dispensers) && get_dist(src,A) <= 1) //this block copypasted from reagent_containers/glass, for lack of a better solution - if(!A.reagents.total_volume && A.reagents) - to_chat(user, "\The [A] is empty.") - return - - if(reagents.total_volume >= reagents.maximum_volume) - to_chat(user, "\The [src] is full.") - return - - var/trans = A.reagents.trans_to(src, 50) //transfer 50u , using the spray's transfer amount would take too long to refill - to_chat(user, "You fill \the [src] with [trans] units of the contents of \the [A].") - return - - if(reagents.total_volume < amount_per_transfer_from_this) - to_chat(user, "\The [src] is empty!") - return - - spray(A) - - playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6) - user.changeNext_move(CLICK_CD_RANGE*2) - user.newtonian_move(get_dir(A, user)) - var/turf/T = get_turf(src) - var/area/area = get_area(src) - if(reagents.has_reagent("sacid")) - message_admins("[ADMIN_LOOKUPFLW(user)] fired sulphuric acid from \a [src] at [area] [ADMIN_COORDJMP(T)].") - log_game("[key_name(user)] fired sulphuric acid from \a [src] at [area] ([T.x], [T.y], [T.z]).") - if(reagents.has_reagent("facid")) - message_admins("[ADMIN_LOOKUPFLW(user)] fired Fluacid from \a [src] at [area] [ADMIN_COORDJMP(T)].") - log_game("[key_name(user)] fired Fluacid from \a [src] at [area] [COORD(T)].") - if(reagents.has_reagent("lube")) - message_admins("[ADMIN_LOOKUPFLW(user)] fired Space lube from \a [src] at [area] [ADMIN_COORDJMP(T)].") - log_game("[key_name(user)] fired Space lube from \a [src] at [area] [COORD(T)].") - return - - -/obj/item/weapon/reagent_containers/spray/proc/spray(atom/A) - var/range = max(min(current_range, get_dist(src, A)), 1) - var/obj/effect/decal/chempuff/D = new /obj/effect/decal/chempuff(get_turf(src)) - D.create_reagents(amount_per_transfer_from_this) - var/puff_reagent_left = range //how many turf, mob or dense objet we can react with before we consider the chem puff consumed - if(stream_mode) - reagents.trans_to(D, amount_per_transfer_from_this) - puff_reagent_left = 1 - else - reagents.trans_to(D, amount_per_transfer_from_this, 1/range) - D.color = mix_color_from_reagents(D.reagents.reagent_list) - var/wait_step = max(round(2+3/range), 2) - spawn(0) - var/range_left = range - for(var/i=0, i 0 && (!stream_mode || !range_left)) - D.reagents.reaction(get_turf(D), VAPOR) - puff_reagent_left -= 1 - - if(puff_reagent_left <= 0) // we used all the puff so we delete it. - qdel(D) - return - qdel(D) - -/obj/item/weapon/reagent_containers/spray/attack_self(mob/user) - stream_mode = !stream_mode - if(stream_mode) - amount_per_transfer_from_this = stream_amount - current_range = stream_range - else - amount_per_transfer_from_this = initial(amount_per_transfer_from_this) - current_range = spray_range - to_chat(user, "You switch the nozzle setting to [stream_mode ? "\"stream\"":"\"spray\""]. You'll now use [amount_per_transfer_from_this] units per use.") - -/obj/item/weapon/reagent_containers/spray/verb/empty() - set name = "Empty Spray Bottle" - set category = "Object" - set src in usr - if(usr.incapacitated()) - return - if (alert(usr, "Are you sure you want to empty that?", "Empty Bottle:", "Yes", "No") != "Yes") - return - if(isturf(usr.loc) && src.loc == usr) - to_chat(usr, "You empty \the [src] onto the floor.") - reagents.reaction(usr.loc) - src.reagents.clear_reagents() - -//space cleaner -/obj/item/weapon/reagent_containers/spray/cleaner - name = "space cleaner" - desc = "BLAM!-brand non-foaming space cleaner!" - list_reagents = list("cleaner" = 250) - -//spray tan -/obj/item/weapon/reagent_containers/spray/spraytan - name = "spray tan" - volume = 50 - desc = "Gyaro brand spray tan. Do not spray near eyes or other orifices." - list_reagents = list("spraytan" = 50) - - -/obj/item/weapon/reagent_containers/spray/medical - name = "medical spray" - icon = 'icons/obj/chemical.dmi' - icon_state = "medspray" - volume = 100 - - -/obj/item/weapon/reagent_containers/spray/medical/sterilizer - name = "sterilizer spray" - desc = "Spray bottle loaded with non-toxic sterilizer. Useful in preparation for surgery." - list_reagents = list("sterilizine" = 100) - - -//pepperspray -/obj/item/weapon/reagent_containers/spray/pepper - name = "pepperspray" - desc = "Manufactured by UhangInc, used to blind and down an opponent quickly." - icon = 'icons/obj/weapons.dmi' - icon_state = "pepperspray" - item_state = "pepperspray" - volume = 40 - stream_range = 4 - amount_per_transfer_from_this = 5 - list_reagents = list("condensedcapsaicin" = 40) - -// Fix pepperspraying yourself -/obj/item/weapon/reagent_containers/spray/pepper/afterattack(atom/A as mob|obj, mob/user) - if (A.loc == user) - return - ..() - -//water flower -/obj/item/weapon/reagent_containers/spray/waterflower - name = "water flower" - desc = "A seemingly innocent sunflower...with a twist." - icon = 'icons/obj/hydroponics/harvest.dmi' - icon_state = "sunflower" - item_state = "sunflower" - amount_per_transfer_from_this = 1 - volume = 10 - list_reagents = list("water" = 10) - -/obj/item/weapon/reagent_containers/spray/waterflower/attack_self(mob/user) //Don't allow changing how much the flower sprays - return - -//chemsprayer -/obj/item/weapon/reagent_containers/spray/chemsprayer - name = "chem sprayer" - desc = "A utility used to spray large amounts of reagents in a given area." - icon = 'icons/obj/guns/projectile.dmi' - icon_state = "chemsprayer" - item_state = "chemsprayer" - throwforce = 0 - w_class = WEIGHT_CLASS_NORMAL - stream_mode = 1 - current_range = 7 - spray_range = 4 - stream_range = 7 - amount_per_transfer_from_this = 10 - volume = 600 - origin_tech = "combat=3;materials=3;engineering=3" - -/obj/item/weapon/reagent_containers/spray/chemsprayer/afterattack(atom/A as mob|obj, mob/user) - // Make it so the bioterror spray doesn't spray yourself when you click your inventory items - if (A.loc == user) - return - ..() - -/obj/item/weapon/reagent_containers/spray/chemsprayer/spray(atom/A) - var/direction = get_dir(src, A) - var/turf/T = get_turf(A) - var/turf/T1 = get_step(T,turn(direction, 90)) - var/turf/T2 = get_step(T,turn(direction, -90)) - var/list/the_targets = list(T,T1,T2) - - for(var/i=1, i<=3, i++) // intialize sprays - if(reagents.total_volume < 1) - return - ..(the_targets[i]) - -/obj/item/weapon/reagent_containers/spray/chemsprayer/bioterror - list_reagents = list("sodium_thiopental" = 100, "coniine" = 100, "venom" = 100, "condensedcapsaicin" = 100, "initropidril" = 100, "polonium" = 100) - -// Plant-B-Gone -/obj/item/weapon/reagent_containers/spray/plantbgone // -- Skie - name = "Plant-B-Gone" - desc = "Kills those pesky weeds!" - icon = 'icons/obj/hydroponics/equipment.dmi' - icon_state = "plantbgone" - item_state = "plantbgone" - volume = 100 - list_reagents = list("plantbgone" = 100) +/obj/item/weapon/reagent_containers/spray + name = "spray bottle" + desc = "A spray bottle, with an unscrewable top." + icon = 'icons/obj/janitor.dmi' + icon_state = "cleaner" + item_state = "cleaner" + flags = NOBLUDGEON + container_type = OPENCONTAINER + slot_flags = SLOT_BELT + throwforce = 0 + w_class = WEIGHT_CLASS_SMALL + throw_speed = 3 + throw_range = 7 + var/stream_mode = 0 //whether we use the more focused mode + var/current_range = 3 //the range of tiles the sprayer will reach. + var/spray_range = 3 //the range of tiles the sprayer will reach when in spray mode. + var/stream_range = 1 //the range of tiles the sprayer will reach when in stream mode. + var/stream_amount = 10 //the amount of reagents transfered when in stream mode. + amount_per_transfer_from_this = 5 + volume = 250 + possible_transfer_amounts = list(5,10,15,20,25,30,50,100) + + +/obj/item/weapon/reagent_containers/spray/afterattack(atom/A as mob|obj, mob/user) + if(istype(A, /obj/structure/sink) || istype(A, /obj/structure/janitorialcart) || istype(A, /obj/machinery/hydroponics)) + return + + if(istype(A, /obj/structure/reagent_dispensers) && get_dist(src,A) <= 1) //this block copypasted from reagent_containers/glass, for lack of a better solution + if(!A.reagents.total_volume && A.reagents) + to_chat(user, "\The [A] is empty.") + return + + if(reagents.total_volume >= reagents.maximum_volume) + to_chat(user, "\The [src] is full.") + return + + var/trans = A.reagents.trans_to(src, 50) //transfer 50u , using the spray's transfer amount would take too long to refill + to_chat(user, "You fill \the [src] with [trans] units of the contents of \the [A].") + return + + if(reagents.total_volume < amount_per_transfer_from_this) + to_chat(user, "\The [src] is empty!") + return + + spray(A) + + playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6) + user.changeNext_move(CLICK_CD_RANGE*2) + user.newtonian_move(get_dir(A, user)) + var/turf/T = get_turf(src) + var/area/area = get_area(src) + if(reagents.has_reagent("sacid")) + message_admins("[ADMIN_LOOKUPFLW(user)] fired sulphuric acid from \a [src] at [area] [ADMIN_COORDJMP(T)].") + log_game("[key_name(user)] fired sulphuric acid from \a [src] at [area] ([T.x], [T.y], [T.z]).") + if(reagents.has_reagent("facid")) + message_admins("[ADMIN_LOOKUPFLW(user)] fired Fluacid from \a [src] at [area] [ADMIN_COORDJMP(T)].") + log_game("[key_name(user)] fired Fluacid from \a [src] at [area] [COORD(T)].") + if(reagents.has_reagent("lube")) + message_admins("[ADMIN_LOOKUPFLW(user)] fired Space lube from \a [src] at [area] [ADMIN_COORDJMP(T)].") + log_game("[key_name(user)] fired Space lube from \a [src] at [area] [COORD(T)].") + return + + +/obj/item/weapon/reagent_containers/spray/proc/spray(atom/A) + var/range = max(min(current_range, get_dist(src, A)), 1) + var/obj/effect/decal/chempuff/D = new /obj/effect/decal/chempuff(get_turf(src)) + D.create_reagents(amount_per_transfer_from_this) + var/puff_reagent_left = range //how many turf, mob or dense objet we can react with before we consider the chem puff consumed + if(stream_mode) + reagents.trans_to(D, amount_per_transfer_from_this) + puff_reagent_left = 1 + else + reagents.trans_to(D, amount_per_transfer_from_this, 1/range) + D.color = mix_color_from_reagents(D.reagents.reagent_list) + var/wait_step = max(round(2+3/range), 2) + spawn(0) + var/range_left = range + for(var/i=0, i 0 && (!stream_mode || !range_left)) + D.reagents.reaction(get_turf(D), VAPOR) + puff_reagent_left -= 1 + + if(puff_reagent_left <= 0) // we used all the puff so we delete it. + qdel(D) + return + qdel(D) + +/obj/item/weapon/reagent_containers/spray/attack_self(mob/user) + stream_mode = !stream_mode + if(stream_mode) + amount_per_transfer_from_this = stream_amount + current_range = stream_range + else + amount_per_transfer_from_this = initial(amount_per_transfer_from_this) + current_range = spray_range + to_chat(user, "You switch the nozzle setting to [stream_mode ? "\"stream\"":"\"spray\""]. You'll now use [amount_per_transfer_from_this] units per use.") + +/obj/item/weapon/reagent_containers/spray/verb/empty() + set name = "Empty Spray Bottle" + set category = "Object" + set src in usr + if(usr.incapacitated()) + return + if (alert(usr, "Are you sure you want to empty that?", "Empty Bottle:", "Yes", "No") != "Yes") + return + if(isturf(usr.loc) && src.loc == usr) + to_chat(usr, "You empty \the [src] onto the floor.") + reagents.reaction(usr.loc) + src.reagents.clear_reagents() + +//space cleaner +/obj/item/weapon/reagent_containers/spray/cleaner + name = "space cleaner" + desc = "BLAM!-brand non-foaming space cleaner!" + list_reagents = list("cleaner" = 250) + +//spray tan +/obj/item/weapon/reagent_containers/spray/spraytan + name = "spray tan" + volume = 50 + desc = "Gyaro brand spray tan. Do not spray near eyes or other orifices." + list_reagents = list("spraytan" = 50) + + +/obj/item/weapon/reagent_containers/spray/medical + name = "medical spray" + icon = 'icons/obj/chemical.dmi' + icon_state = "medspray" + volume = 100 + + +/obj/item/weapon/reagent_containers/spray/medical/sterilizer + name = "sterilizer spray" + desc = "Spray bottle loaded with non-toxic sterilizer. Useful in preparation for surgery." + list_reagents = list("sterilizine" = 100) + + +//pepperspray +/obj/item/weapon/reagent_containers/spray/pepper + name = "pepperspray" + desc = "Manufactured by UhangInc, used to blind and down an opponent quickly." + icon = 'icons/obj/weapons.dmi' + icon_state = "pepperspray" + item_state = "pepperspray" + volume = 40 + stream_range = 4 + amount_per_transfer_from_this = 5 + list_reagents = list("condensedcapsaicin" = 40) + +// Fix pepperspraying yourself +/obj/item/weapon/reagent_containers/spray/pepper/afterattack(atom/A as mob|obj, mob/user) + if (A.loc == user) + return + ..() + +//water flower +/obj/item/weapon/reagent_containers/spray/waterflower + name = "water flower" + desc = "A seemingly innocent sunflower...with a twist." + icon = 'icons/obj/hydroponics/harvest.dmi' + icon_state = "sunflower" + item_state = "sunflower" + amount_per_transfer_from_this = 1 + volume = 10 + list_reagents = list("water" = 10) + +/obj/item/weapon/reagent_containers/spray/waterflower/attack_self(mob/user) //Don't allow changing how much the flower sprays + return + +//chemsprayer +/obj/item/weapon/reagent_containers/spray/chemsprayer + name = "chem sprayer" + desc = "A utility used to spray large amounts of reagents in a given area." + icon = 'icons/obj/guns/projectile.dmi' + icon_state = "chemsprayer" + item_state = "chemsprayer" + throwforce = 0 + w_class = WEIGHT_CLASS_NORMAL + stream_mode = 1 + current_range = 7 + spray_range = 4 + stream_range = 7 + amount_per_transfer_from_this = 10 + volume = 600 + origin_tech = "combat=3;materials=3;engineering=3" + +/obj/item/weapon/reagent_containers/spray/chemsprayer/afterattack(atom/A as mob|obj, mob/user) + // Make it so the bioterror spray doesn't spray yourself when you click your inventory items + if (A.loc == user) + return + ..() + +/obj/item/weapon/reagent_containers/spray/chemsprayer/spray(atom/A) + var/direction = get_dir(src, A) + var/turf/T = get_turf(A) + var/turf/T1 = get_step(T,turn(direction, 90)) + var/turf/T2 = get_step(T,turn(direction, -90)) + var/list/the_targets = list(T,T1,T2) + + for(var/i=1, i<=3, i++) // intialize sprays + if(reagents.total_volume < 1) + return + ..(the_targets[i]) + +/obj/item/weapon/reagent_containers/spray/chemsprayer/bioterror + list_reagents = list("sodium_thiopental" = 100, "coniine" = 100, "venom" = 100, "condensedcapsaicin" = 100, "initropidril" = 100, "polonium" = 100) + +// Plant-B-Gone +/obj/item/weapon/reagent_containers/spray/plantbgone // -- Skie + name = "Plant-B-Gone" + desc = "Kills those pesky weeds!" + icon = 'icons/obj/hydroponics/equipment.dmi' + icon_state = "plantbgone" + item_state = "plantbgone" + volume = 100 + list_reagents = list("plantbgone" = 100) diff --git a/code/modules/shuttle/ferry.dm b/code/modules/shuttle/ferry.dm index a5226abd58..8368fd58e5 100644 --- a/code/modules/shuttle/ferry.dm +++ b/code/modules/shuttle/ferry.dm @@ -1,33 +1,33 @@ -/obj/machinery/computer/shuttle/ferry - name = "transport ferry console" - circuit = /obj/item/weapon/circuitboard/computer/ferry - shuttleId = "ferry" - possible_destinations = "ferry_home;ferry_away" - req_access = list(GLOB.access_cent_general) - - var/aiControlDisabled = 1 - -/obj/machinery/computer/shuttle/ferry/proc/canAIControl(mob/user) - return ((aiControlDisabled != 1)); - -/obj/machinery/computer/shuttle/ferry/attack_ai(mob/user) - if(!src.canAIControl(user)) - return - -/obj/machinery/computer/shuttle/ferry/request - name = "ferry console" - circuit = /obj/item/weapon/circuitboard/computer/ferry/request - var/last_request //prevents spamming admins - var/cooldown = 600 - possible_destinations = "ferry_home;ferry_away" - req_access = list(GLOB.access_cent_general) - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF - -/obj/machinery/computer/shuttle/ferry/request/Topic(href, href_list) - ..() - if(href_list["request"]) - if(last_request && (last_request + cooldown > world.time)) - return - last_request = world.time - to_chat(usr, "Your request has been recieved by Centcom.") - to_chat(GLOB.admins, "FERRY: [ADMIN_LOOKUPFLW(usr)] (Move Ferry) is requesting to move the transport ferry to Centcom.") +/obj/machinery/computer/shuttle/ferry + name = "transport ferry console" + circuit = /obj/item/weapon/circuitboard/computer/ferry + shuttleId = "ferry" + possible_destinations = "ferry_home;ferry_away" + req_access = list(GLOB.access_cent_general) + + var/aiControlDisabled = 1 + +/obj/machinery/computer/shuttle/ferry/proc/canAIControl(mob/user) + return ((aiControlDisabled != 1)); + +/obj/machinery/computer/shuttle/ferry/attack_ai(mob/user) + if(!src.canAIControl(user)) + return + +/obj/machinery/computer/shuttle/ferry/request + name = "ferry console" + circuit = /obj/item/weapon/circuitboard/computer/ferry/request + var/last_request //prevents spamming admins + var/cooldown = 600 + possible_destinations = "ferry_home;ferry_away" + req_access = list(GLOB.access_cent_general) + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + +/obj/machinery/computer/shuttle/ferry/request/Topic(href, href_list) + ..() + if(href_list["request"]) + if(last_request && (last_request + cooldown > world.time)) + return + last_request = world.time + to_chat(usr, "Your request has been recieved by Centcom.") + to_chat(GLOB.admins, "FERRY: [ADMIN_LOOKUPFLW(usr)] (Move Ferry) is requesting to move the transport ferry to Centcom.") diff --git a/icons/emoji.dmi b/icons/emoji.dmi old mode 100755 new mode 100644 diff --git a/tgstation.dme b/tgstation.dme index 83c004c29e..ad998e8286 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -33,6 +33,7 @@ #include "code\__DEFINES\combat.dm" #include "code\__DEFINES\construction.dm" #include "code\__DEFINES\contracts.dm" +#include "code\__DEFINES\cult.dm" #include "code\__DEFINES\DNA.dm" #include "code\__DEFINES\events.dm" #include "code\__DEFINES\flags.dm" @@ -167,9 +168,6 @@ #include "code\citadel\cit_uniforms.dm" #include "code\citadel\cit_vendors.dm" #include "code\citadel\dogborgstuff.dm" -#include "code\citadel\custom_loadout\custom_items.dm" -#include "code\citadel\custom_loadout\load_to_mob.dm" -#include "code\citadel\custom_loadout\read_from_file.dm" #include "code\citadel\organs\breasts.dm" #include "code\citadel\organs\eggsack.dm" #include "code\citadel\organs\genitals.dm" @@ -199,12 +197,14 @@ #include "code\controllers\subsystem\dbcore.dm" #include "code\controllers\subsystem\disease.dm" #include "code\controllers\subsystem\events.dm" +#include "code\controllers\subsystem\fields.dm" #include "code\controllers\subsystem\fire_burning.dm" #include "code\controllers\subsystem\garbage.dm" #include "code\controllers\subsystem\icon_smooth.dm" #include "code\controllers\subsystem\inbounds.dm" #include "code\controllers\subsystem\ipintel.dm" #include "code\controllers\subsystem\job.dm" +#include "code\controllers\subsystem\language.dm" #include "code\controllers\subsystem\lighting.dm" #include "code\controllers\subsystem\machines.dm" #include "code\controllers\subsystem\mapping.dm" @@ -266,6 +266,7 @@ #include "code\datums\antagonists\antag_datum.dm" #include "code\datums\antagonists\datum_clockcult.dm" #include "code\datums\antagonists\datum_cult.dm" +#include "code\datums\antagonists\ninja.dm" #include "code\datums\diseases\_disease.dm" #include "code\datums\diseases\_MobProcs.dm" #include "code\datums\diseases\anxiety.dm" @@ -470,7 +471,9 @@ #include "code\game\gamemodes\cult\cult_items.dm" #include "code\game\gamemodes\cult\cult_structures.dm" #include "code\game\gamemodes\cult\ritual.dm" +#include "code\game\gamemodes\cult\rune_spawn_action.dm" #include "code\game\gamemodes\cult\runes.dm" +#include "code\game\gamemodes\cult\supply.dm" #include "code\game\gamemodes\cult\talisman.dm" #include "code\game\gamemodes\devil\devil.dm" #include "code\game\gamemodes\devil\devil_game_mode.dm" @@ -556,6 +559,7 @@ #include "code\game\machinery\hologram.dm" #include "code\game\machinery\igniter.dm" #include "code\game\machinery\iv_drip.dm" +#include "code\game\machinery\launch_pad.dm" #include "code\game\machinery\lightswitch.dm" #include "code\game\machinery\limbgrower.dm" #include "code\game\machinery\machinery.dm" @@ -604,6 +608,7 @@ #include "code\game\machinery\computer\crew.dm" #include "code\game\machinery\computer\dna_console.dm" #include "code\game\machinery\computer\gulag_teleporter.dm" +#include "code\game\machinery\computer\launchpad_control.dm" #include "code\game\machinery\computer\law.dm" #include "code\game\machinery\computer\medical.dm" #include "code\game\machinery\computer\message.dm" @@ -726,6 +731,10 @@ #include "code\game\objects\effects\spawners\structure.dm" #include "code\game\objects\effects\spawners\vaultspawner.dm" #include "code\game\objects\effects\spawners\xeno_egg_delivery.dm" +#include "code\game\objects\effects\temporary_visuals\clockcult.dm" +#include "code\game\objects\effects\temporary_visuals\cult.dm" +#include "code\game\objects\effects\temporary_visuals\miscellaneous.dm" +#include "code\game\objects\effects\temporary_visuals\temporary_visual.dm" #include "code\game\objects\items\apc_frame.dm" #include "code\game\objects\items\blueprints.dm" #include "code\game\objects\items\body_egg.dm" @@ -809,7 +818,6 @@ #include "code\game\objects\items\weapons\defib.dm" #include "code\game\objects\items\weapons\dice.dm" #include "code\game\objects\items\weapons\dna_injector.dm" -#include "code\game\objects\items\weapons\explosives.dm" #include "code\game\objects\items\weapons\extinguisher.dm" #include "code\game\objects\items\weapons\flamethrower.dm" #include "code\game\objects\items\weapons\gift.dm" @@ -1304,6 +1312,9 @@ #include "code\modules\events\wizard\rpgloot.dm" #include "code\modules\events\wizard\shuffle.dm" #include "code\modules\events\wizard\summons.dm" +#include "code\modules\fields\fields.dm" +#include "code\modules\fields\peaceborg_dampener.dm" +#include "code\modules\fields\turf_objects.dm" #include "code\modules\flufftext\Dreaming.dm" #include "code\modules\flufftext\Hallucination.dm" #include "code\modules\flufftext\TextFilters.dm" @@ -1426,12 +1437,15 @@ #include "code\modules\jobs\job_types\security.dm" #include "code\modules\jobs\job_types\silicon.dm" #include "code\modules\language\common.dm" +#include "code\modules\language\draconic.dm" #include "code\modules\language\drone.dm" #include "code\modules\language\language.dm" +#include "code\modules\language\language_holder.dm" #include "code\modules\language\language_menu.dm" #include "code\modules\language\machine.dm" #include "code\modules\language\monkey.dm" -#include "code\modules\language\ratvar.dm" +#include "code\modules\language\narsian.dm" +#include "code\modules\language\ratvarian.dm" #include "code\modules\language\slime.dm" #include "code\modules\language\swarmer.dm" #include "code\modules\language\xenocommon.dm" @@ -1803,7 +1817,6 @@ #include "code\modules\modular_computers\NTNet\NTNet_relay.dm" #include "code\modules\modular_computers\NTNet\NTNRC\conversation.dm" #include "code\modules\ninja\__ninjaDefines.dm" -#include "code\modules\ninja\admin_ninja_verbs.dm" #include "code\modules\ninja\energy_katana.dm" #include "code\modules\ninja\ninja_event.dm" #include "code\modules\ninja\Ninja_Readme.dm" diff --git a/tools/tgstation-server/Start Server.bat b/tools/tgstation-server/Start Server.bat index 0312a22a5c..80efb9444b 100644 --- a/tools/tgstation-server/Start Server.bat +++ b/tools/tgstation-server/Start Server.bat @@ -3,37 +3,37 @@ call config.bat call bin\findbyond.bat -echo Welcome to the start server watch dog script, This will start the server and make sure it stays running. To continue, press any key or wait 30 seconds. -timeout 30 +echo Welcome to the start server watch dog script, This will start the server and make sure it stays running. To continue, press any key or wait 30 seconds. +timeout 30 if not exist gamedata\data\logs\runtimes mkdir gamedata\data\logs\runtimes\ -@call python bot\nudge.py "WATCHDOG" "Watch Dog online. Starting server" >nul 2>nul +@call python bot\nudge.py "WATCHDOG" "Watch Dog online. Starting server" >nul 2>nul :START - + call bin\getcurdate.bat - -call bin\getunixtime.bat UNIXTIME - -echo %UNIXTIME% - -set STARTTIME=%UNIXTIME% - + +call bin\getunixtime.bat UNIXTIME + +echo %UNIXTIME% + +set STARTTIME=%UNIXTIME% + cls echo Watch Dog. echo Server Running. Watching for server exits. -start /WAIT /ABOVENORMAL "" dreamdaemon.exe gamefolder\%PROJECTNAME%.dmb -port %PORT% -trusted -close -public -verbose +start /WAIT /ABOVENORMAL "" dreamdaemon.exe gamefolder\%PROJECTNAME%.dmb -port %PORT% -trusted -close -public -verbose cls - -call bin\getunixtime.bat UNIXTIME - -SET /A Result=%UNIXTIME% - %STARTTIME% -SET /A Result=180 - (%Result%/3) -if %Result% LSS 0 set /A Result=0 - + +call bin\getunixtime.bat UNIXTIME + +SET /A Result=%UNIXTIME% - %STARTTIME% +SET /A Result=180 - (%Result%/3) +if %Result% LSS 0 set /A Result=0 + echo Watch Dog. -echo Server exit detected. Restarting in %Result% seconds. -@python bot\nudge.py "WATCHDOG" "Server exit detected. Restarting server in %Result% seconds." >nul 2>nul -timeout %Result% +echo Server exit detected. Restarting in %Result% seconds. +@python bot\nudge.py "WATCHDOG" "Server exit detected. Restarting server in %Result% seconds." >nul 2>nul +timeout %Result% goto :START From 0508b613a577e60985b3078ef7b7da57fd5d4001 Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Mon, 22 May 2017 17:53:24 -0700 Subject: [PATCH 013/262] automatic config load and dme --- code/controllers/configuration.dm | 1 + tgstation.dme | 3 +++ 2 files changed, 4 insertions(+) diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index e9bdeca880..543225ec3c 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -285,6 +285,7 @@ load("config/config.txt") load("config/game_options.txt","game_options") loadsql("config/dbconfig.txt") + reload_custom_roundstart_items_list() if (maprotation) loadmaplist("config/maps.txt") diff --git a/tgstation.dme b/tgstation.dme index ad998e8286..646f483259 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -168,6 +168,9 @@ #include "code\citadel\cit_uniforms.dm" #include "code\citadel\cit_vendors.dm" #include "code\citadel\dogborgstuff.dm" +#include "code\citadel\custom_loadout\custom_items.dm" +#include "code\citadel\custom_loadout\load_to_mob.dm" +#include "code\citadel\custom_loadout\read_from_file.dm" #include "code\citadel\organs\breasts.dm" #include "code\citadel\organs\eggsack.dm" #include "code\citadel\organs\genitals.dm" From 1013cfac250e0bc0e3160f927a2419ca6c4185fd Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Sun, 28 May 2017 15:15:34 -0700 Subject: [PATCH 014/262] hooks --- code/modules/jobs/job_types/job.dm | 2 ++ code/modules/mob/dead/new_player/new_player.dm | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/code/modules/jobs/job_types/job.dm b/code/modules/jobs/job_types/job.dm index 4d5d4eb80c..1253ec2c37 100644 --- a/code/modules/jobs/job_types/job.dm +++ b/code/modules/jobs/job_types/job.dm @@ -188,3 +188,5 @@ for(var/implant_type in implants) var/obj/item/weapon/implant/I = new implant_type(H) I.implant(H, null, silent=TRUE) + + handle_roundstart_items(H) diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index e3943d07e6..4effac371d 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -24,10 +24,10 @@ loc = pick(GLOB.newplayer_start) else loc = locate(1,1,1) - . = ..() - -/mob/dead/new_player/prepare_huds() - return + . = ..() + +/mob/dead/new_player/prepare_huds() + return /mob/dead/new_player/proc/new_player_panel() @@ -146,7 +146,7 @@ return 1 if(href_list["late_join"]) - if(!SSticker || !SSticker.IsRoundInProgress()) + if(!SSticker || !SSticker.IsRoundInProgress()) to_chat(usr, "The round is either not ready, or has already finished...") return From 97f6bf4410a25c3754c2b5a608b351ef0ec7c987 Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Mon, 24 Jul 2017 04:12:17 -0700 Subject: [PATCH 015/262] character separation wip --- code/citadel/custom_loadout/read_from_file.dm | 52 ++++++++----------- config/custom_roundstart_items.txt | 11 ++-- tgstation.dme | 1 + 3 files changed, 27 insertions(+), 37 deletions(-) diff --git a/code/citadel/custom_loadout/read_from_file.dm b/code/citadel/custom_loadout/read_from_file.dm index a4d363bd06..e29fc74128 100644 --- a/code/citadel/custom_loadout/read_from_file.dm +++ b/code/citadel/custom_loadout/read_from_file.dm @@ -19,23 +19,30 @@ GLOBAL_LIST(custom_item_list) if(copytext(line,1,3) == "//") //Commented line, ignore. continue var/ckey_str_sep = findtext(line, "|") //Process our stuff.. - var/job_str_sep = findtext(line, "|", ckey_str_sep+1) + var/char_str_sep = findtext(line, "|", ckey_str_sep+1) + var/job_str_sep = findtext(line, "|", char_str_sep+1) var/item_str_sep = findtext(line, "|", job_str_sep+1) var/ckey_str = ckey(copytext(line, 1, ckey_str_sep)) - var/job_str = copytext(line, ckey_str_sep+1, job_str_sep) + var/char_str = copytext(line, ckey_str_sep+1, char_str_sep) + var/job_str = copytext(line, char_str_sep+1, job_str_sep) var/item_str = copytext(line, job_str_sep+1, item_str_sep) - if(!ckey_str || !job_str || !item_str || !length(ckey_str) || !length(job_str) || !length(item_str)) + if(!ckey_str || !!char_str || !job_str || !item_str || !length(ckey_str) || !length(char_str) || !length(job_str) || !length(item_str)) throw EXCEPTION("Errored Line") - world << "DEBUG: Line process: [line]" - world << "DEBUG: [ckey_str_sep], [job_str_sep], [item_str_sep], [ckey_str], [job_str], [item_str]." + to_chat(world, "DEBUG: Line process: [line]") + to_chat(world, "DEBUG: [ckey_str_sep], [char_str_sep], [job_str_sep], [item_str_sep], [ckey_str], [char_str], [job_str], [item_str].") if(!islist(GLOB.custom_item_list[ckey_str])) GLOB.custom_item_list[ckey_str] = list() //Initialize list for this ckey if it isn't initialized.. + var/list/characters = splittext(char_str, "/") + for(var/character in characters) + if(!islist(GLOB.custom_item_list[ckey_str][character])) + GLOB.custom_item_list[ckey_str][character] = list() var/list/jobs = splittext(job_str, "/") world << "DEBUG: Job string processed." world << "DEBUG: JOBS: [english_list(jobs)]" for(var/job in jobs) - if(!islist(GLOB.custom_item_list[ckey_str][job])) - GLOB.custom_item_list[ckey_str][job] = list() //Initialize item list for this job of this ckey if not already initialized. + for(var/character in characters) + if(!islist(GLOB.custom_item_list[ckey_str][character][job])) + GLOB.custom_item_list[ckey_str][character][job] = list() //Initialize item list for this job of this ckey if not already initialized. var/list/item_strings = splittext(item_str, ";") //Get item strings in format of /path/to/item=amount for(var/item_string in item_strings) var/path_str_sep = findtext(item_string, "=") @@ -47,11 +54,12 @@ GLOBAL_LIST(custom_item_list) if(!ispath(path) || !isnum(amount)) throw EXCEPTION("Errored line") world << "DEBUG: [path_str_sep], [path], [amount]" - for(var/job in jobs) - if(!GLOB.custom_item_list[ckey_str][job][path]) //Doesn't exist, make it exist! - GLOB.custom_item_list[ckey_str][job][path] = amount - else - GLOB.custom_item_list[ckey_str][job][path] += amount //Exists, we want more~ + for(var/character in characters) + for(var/job in jobs) + if(!GLOB.custom_item_list[ckey_str][character][job][path]) //Doesn't exist, make it exist! + GLOB.custom_item_list[ckey_str][character][job][path] = amount + else + GLOB.custom_item_list[ckey_str][character][job][path] += amount //Exists, we want more~ catch //Uh oh. var/msg = "Error processing line in [custom_filelist]. Line : [line]" message_admins(msg) @@ -60,26 +68,8 @@ GLOBAL_LIST(custom_item_list) continue return GLOB.custom_item_list -/proc/parse_custom_item_list_key_to_joblist(ckey) //First stage - if(!ckey || !GLOB.custom_item_list[ckey]) - return null - return GLOB.custom_item_list[ckey] +/proc/parse_custom_roundstart_items(ckey, char_name = "ANY", job_name = "ANY") -/proc/parse_custom_item_list_joblist_to_items(list, job) //Second stage - var/list/ret = list() - for(var/j in list) //for job in ckey-job-item list - if((j == job) || (j == "ALL") || (job == "ALL")) //job matches or is all jobs or we want everything. - for(var/i in list[j]) //for item in job-item list - if(!ret[i]) - world << "DEBUG: [i] initialized to return list" - ret[i] = list[j][i] //add to return with return value if not there - else - world << "DEBUG: [i] added to return list" - ret[i] += list[j][i] //else, add to that item in return value! - return ret //If done properly, you'll have a list of item typepaths with how many to spawn. - -/proc/parse_custom_items_by_key_and_job(ckey, job) - return parse_custom_item_list_joblist_to_items(parse_custom_item_list_key_to_joblist(ckey), job) /proc/debug_roundstart_items() reload_custom_roundstart_items_list() diff --git a/config/custom_roundstart_items.txt b/config/custom_roundstart_items.txt index 7d206d8d09..b71836fe53 100644 --- a/config/custom_roundstart_items.txt +++ b/config/custom_roundstart_items.txt @@ -1,10 +1,9 @@ -//File should be in the format of ckey|exact job name/exact job name/or put ALL instead of any job names|/path/to/item=amount;/path/to/item=amount +//File should be in the format of ckey|exact character name/exact second character name/ALL for all chars|exact job name/exact job name/or put ALL instead of any job names|/path/to/item=amount;/path/to/item=amount //Each ckey should be in a different line //if there's multiple entries of a single ckey the later ones will add to the earlier definitions. //is obviously a comment. //Recommend defining one job per line, but do what you want. -test1|testjob1/test job 2/ALL|/obj/item/weapon/gun/energy/laser=3;/obj/item/weapon/gun/energy/laser/retro=1;/obj/item/weapon/gun/energy=2 -test1|testjob1|/obj/item/device/aicard=3;/obj/item/device/flightpack=1;/obj/item/weapon/gun/energy=3 -kevinz000|ALL|/obj/item/weapon/bikehorn/airhorn=1 -kevinz000|Clown|/obj/item/weapon/bikehorn=1 - +test1|Secondary Memenamefortesting|testjob1/test job 2/ALL|/obj/item/weapon/gun/energy/laser=3;/obj/item/weapon/gun/energy/laser/retro=1;/obj/item/weapon/gun/energy=2 +test1|Memename Lastname|testjob1|/obj/item/device/aicard=3;/obj/item/device/flightpack=1;/obj/item/weapon/gun/energy=3 +kevinz000|Skylar Lineman|ALL|/obj/item/weapon/bikehorn/airhorn=1 +kevinz000|ALL|Clown|/obj/item/weapon/bikehorn=1 diff --git a/tgstation.dme b/tgstation.dme index 968f93d4d7..2b6762c36c 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -826,6 +826,7 @@ #include "code\game\objects\items\weapons\charter.dm" #include "code\game\objects\items\weapons\chrono_eraser.dm" #include "code\game\objects\items\weapons\cigs_lighters.dm" +#include "code\game\objects\items\weapons\clown.dm" #include "code\game\objects\items\weapons\clown_items.dm" #include "code\game\objects\items\weapons\cosmetics.dm" #include "code\game\objects\items\weapons\courtroom.dm" From 630a4a7bc72e641f71a04a37641b5d2a2e952ca7 Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Fri, 11 Aug 2017 13:05:12 -0700 Subject: [PATCH 016/262] parsing from file work, still working on mobloading. --- code/citadel/custom_loadout/load_to_mob.dm | 21 +--- code/citadel/custom_loadout/read_from_file.dm | 115 +++++++++--------- 2 files changed, 61 insertions(+), 75 deletions(-) diff --git a/code/citadel/custom_loadout/load_to_mob.dm b/code/citadel/custom_loadout/load_to_mob.dm index 9e8bddd677..65eeea3093 100644 --- a/code/citadel/custom_loadout/load_to_mob.dm +++ b/code/citadel/custom_loadout/load_to_mob.dm @@ -8,35 +8,20 @@ #define LOADING_TO_HUMAN 1 /proc/handle_roundstart_items(mob/living/M) - world << "handle_roundstart_items([M])" if(!istype(M) || !M.ckey || !M.mind) - world << "handle_roundstart_items: [M] has either no ckey or no mind!" - if(!M.mind) - world << "[M] has no mind!" return FALSE - var/list/items = parse_custom_items_by_key_and_job(M.ckey, M.mind.assigned_role) - if(M.mind.special_role) - var/list/items_special = parse_custom_items_by_key_and_job(M.ckey, M.mind.special_role) //And this way you can have snowflake antags! - for(var/thing in items_special) - if(!items[thing]) - items[thing] = items_special[thing] //don't have it, make it have it! - else - items[thing] += items_special[thing] //More~ - if(isnull(items)) - world << "handle_roundstart_items: itemlist null." - return FALSE - return load_itemlist_to_mob(M, items, TRUE, TRUE, FALSE) + return load_itemlist_to_mob(M, parse_custom_roundstart_items(M.ckey, M.name, M.mind.assigned_role, M.mind.special_role), TRUE, TRUE, FALSE) //Just incase there's extra mob selections in the future..... /proc/load_itemlist_to_mob(mob/living/L, list/itemlist, drop_on_floor_if_full = TRUE, load_to_all_slots = TRUE, replace_slots = FALSE) - world << "load_itemlist_to_mob([L], [itemlist], [drop_on_floor_if_full], [load_to_all_slots], [replace_slots])" + to_chat(world, "load_itemlist_to_mob([L], [itemlist], [drop_on_floor_if_full], [load_to_all_slots], [replace_slots])") if(!istype(L) || !islist(itemlist)) return FALSE var/loading_mode = DROP_TO_FLOOR var/turf/current_turf = get_turf(L) if(ishuman(L)) loading_mode = LOADING_TO_HUMAN - world << "load_itemlist_to_mob:loading_mode [loading_mode] current_turf [current_turf]" + to_chat(world, "load_itemlist_to_mob:loading_mode [loading_mode] current_turf [current_turf]") switch(loading_mode) if(DROP_TO_FLOOR) for(var/I in itemlist) diff --git a/code/citadel/custom_loadout/read_from_file.dm b/code/citadel/custom_loadout/read_from_file.dm index e29fc74128..f5b668da92 100644 --- a/code/citadel/custom_loadout/read_from_file.dm +++ b/code/citadel/custom_loadout/read_from_file.dm @@ -13,63 +13,64 @@ GLOBAL_LIST(custom_item_list) GLOB.custom_item_list = list() var/list/file_lines = world.file2list(custom_filelist) for(var/line in file_lines) - try //Lazy as fuck. - if(length(line) == 0) //Emptyline, no one cares. - continue - if(copytext(line,1,3) == "//") //Commented line, ignore. - continue - var/ckey_str_sep = findtext(line, "|") //Process our stuff.. - var/char_str_sep = findtext(line, "|", ckey_str_sep+1) - var/job_str_sep = findtext(line, "|", char_str_sep+1) - var/item_str_sep = findtext(line, "|", job_str_sep+1) - var/ckey_str = ckey(copytext(line, 1, ckey_str_sep)) - var/char_str = copytext(line, ckey_str_sep+1, char_str_sep) - var/job_str = copytext(line, char_str_sep+1, job_str_sep) - var/item_str = copytext(line, job_str_sep+1, item_str_sep) - if(!ckey_str || !!char_str || !job_str || !item_str || !length(ckey_str) || !length(char_str) || !length(job_str) || !length(item_str)) - throw EXCEPTION("Errored Line") - to_chat(world, "DEBUG: Line process: [line]") - to_chat(world, "DEBUG: [ckey_str_sep], [char_str_sep], [job_str_sep], [item_str_sep], [ckey_str], [char_str], [job_str], [item_str].") - if(!islist(GLOB.custom_item_list[ckey_str])) - GLOB.custom_item_list[ckey_str] = list() //Initialize list for this ckey if it isn't initialized.. - var/list/characters = splittext(char_str, "/") - for(var/character in characters) - if(!islist(GLOB.custom_item_list[ckey_str][character])) - GLOB.custom_item_list[ckey_str][character] = list() - var/list/jobs = splittext(job_str, "/") - world << "DEBUG: Job string processed." - world << "DEBUG: JOBS: [english_list(jobs)]" - for(var/job in jobs) - for(var/character in characters) - if(!islist(GLOB.custom_item_list[ckey_str][character][job])) - GLOB.custom_item_list[ckey_str][character][job] = list() //Initialize item list for this job of this ckey if not already initialized. - var/list/item_strings = splittext(item_str, ";") //Get item strings in format of /path/to/item=amount - for(var/item_string in item_strings) - var/path_str_sep = findtext(item_string, "=") - var/path = copytext(item_string, 1, path_str_sep) //Path to spawn - var/amount = copytext(item_string, path_str_sep+1) //Amount to spawn - world << "DEBUG: Item string [item_string] processed" - amount = text2num(amount) - path = text2path(path) - if(!ispath(path) || !isnum(amount)) - throw EXCEPTION("Errored line") - world << "DEBUG: [path_str_sep], [path], [amount]" - for(var/character in characters) - for(var/job in jobs) - if(!GLOB.custom_item_list[ckey_str][character][job][path]) //Doesn't exist, make it exist! - GLOB.custom_item_list[ckey_str][character][job][path] = amount - else - GLOB.custom_item_list[ckey_str][character][job][path] += amount //Exists, we want more~ - catch //Uh oh. - var/msg = "Error processing line in [custom_filelist]. Line : [line]" - message_admins(msg) - log_game(msg) - stack_trace(msg) + if(length(line) == 0) //Emptyline, no one cares. continue + if(copytext(line,1,3) == "//") //Commented line, ignore. + continue + var/ckey_str_sep = findtext(line, "|") //Process our stuff.. + var/char_str_sep = findtext(line, "|", ckey_str_sep+1) + var/job_str_sep = findtext(line, "|", char_str_sep+1) + var/item_str_sep = findtext(line, "|", job_str_sep+1) + var/ckey_str = ckey(copytext(line, 1, ckey_str_sep)) + var/char_str = copytext(line, ckey_str_sep+1, char_str_sep) + var/job_str = copytext(line, char_str_sep+1, job_str_sep) + var/item_str = copytext(line, job_str_sep+1, item_str_sep) + if(!ckey_str || !char_str || !job_str || !item_str || !length(ckey_str) || !length(char_str) || !length(job_str) || !length(item_str)) + log_admin("Errored custom_items_whitelist line: [line] - Component/separator missing!") + to_chat(world, "DEBUG: Line process: [line]") + to_chat(world, "DEBUG: [ckey_str_sep], [char_str_sep], [job_str_sep], [item_str_sep], [ckey_str], [char_str], [job_str], [item_str].") + if(!islist(GLOB.custom_item_list[ckey_str])) + GLOB.custom_item_list[ckey_str] = list() //Initialize list for this ckey if it isn't initialized.. + var/list/characters = splittext(char_str, "/") + for(var/character in characters) + if(!islist(GLOB.custom_item_list[ckey_str][character])) + GLOB.custom_item_list[ckey_str][character] = list() + var/list/jobs = splittext(job_str, "/") + world << "DEBUG: Job string processed." + world << "DEBUG: JOBS: [english_list(jobs)]" + for(var/job in jobs) + for(var/character in characters) + if(!islist(GLOB.custom_item_list[ckey_str][character][job])) + GLOB.custom_item_list[ckey_str][character][job] = list() //Initialize item list for this job of this ckey if not already initialized. + var/list/item_strings = splittext(item_str, ";") //Get item strings in format of /path/to/item=amount + for(var/item_string in item_strings) + var/path_str_sep = findtext(item_string, "=") + var/path = copytext(item_string, 1, path_str_sep) //Path to spawn + var/amount = copytext(item_string, path_str_sep+1) //Amount to spawn + world << "DEBUG: Item string [item_string] processed" + amount = text2num(amount) + path = text2path(path) + if(!ispath(path) || !isnum(amount)) + log_admin("Errored custom_items_whitelist line: [line] - Path/number for item missing or invalid.") + world << "DEBUG: [path_str_sep], [path], [amount]" + for(var/character in characters) + for(var/job in jobs) + if(!GLOB.custom_item_list[ckey_str][character][job][path]) //Doesn't exist, make it exist! + GLOB.custom_item_list[ckey_str][character][job][path] = amount + else + GLOB.custom_item_list[ckey_str][character][job][path] += amount //Exists, we want more~ return GLOB.custom_item_list -/proc/parse_custom_roundstart_items(ckey, char_name = "ANY", job_name = "ANY") - - -/proc/debug_roundstart_items() - reload_custom_roundstart_items_list() +/proc/parse_custom_roundstart_items(ckey, char_name = "ANY", job_name = "ANY", special_role) + var/list/ret = list() + if(GLOB.custom_item_list[ckey]) + for(var/char in GLOB.custom_item_list[ckey]) + if((char_name == char) || (char_name == "ANY") || (char == "ANY")) + for(var/job in GLOB.custom_item_list[ckey][char]) + if((job_name == job) || (job == "ANY") || (job_name == "ANY") || (special_role && (job == special_role))) + for(var/item_path in GLOB.custom_item_list[ckey][char][job]) + if(ret[item_path]) + ret[item_path] += GLOB.custom_item_list[ckey][char][job][item_path] + else + ret[item_path] = GLOB.custom_item_list[ckey][char][job][item_path] + return ret From 5eea01659370f96e7cd929d0c0b8659e4b1e4abe Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 19 Aug 2017 18:52:55 -0500 Subject: [PATCH 017/262] You can now click on symptoms in the Pandemic to see their description and stats --- code/controllers/subsystem/disease.dm | 9 +- code/datums/diseases/advance/presets.dm | 12 +- .../datums/diseases/advance/symptoms/beard.dm | 1 + .../diseases/advance/symptoms/choking.dm | 4 + .../diseases/advance/symptoms/confusion.dm | 4 + .../datums/diseases/advance/symptoms/cough.dm | 6 + .../diseases/advance/symptoms/deafness.dm | 3 + .../datums/diseases/advance/symptoms/dizzy.dm | 4 +- .../datums/diseases/advance/symptoms/fever.dm | 4 +- code/datums/diseases/advance/symptoms/fire.dm | 9 + .../diseases/advance/symptoms/flesh_eating.dm | 6 + .../diseases/advance/symptoms/genetics.dm | 5 +- .../diseases/advance/symptoms/hallucigen.dm | 4 +- .../diseases/advance/symptoms/headache.dm | 10 +- code/datums/diseases/advance/symptoms/heal.dm | 17 +- .../diseases/advance/symptoms/itching.dm | 3 + .../diseases/advance/symptoms/narcolepsy.dm | 3 + .../diseases/advance/symptoms/oxygen.dm | 2 + .../diseases/advance/symptoms/sensory.dm | 11 +- .../diseases/advance/symptoms/shedding.dm | 2 +- .../diseases/advance/symptoms/shivering.dm | 4 +- code/datums/diseases/advance/symptoms/skin.dm | 2 + .../diseases/advance/symptoms/sneeze.dm | 3 + .../diseases/advance/symptoms/symptoms.dm | 7 +- .../datums/diseases/advance/symptoms/viral.dm | 7 + .../diseases/advance/symptoms/vision.dm | 4 + .../diseases/advance/symptoms/voice_change.dm | 4 + .../datums/diseases/advance/symptoms/vomit.dm | 4 + .../diseases/advance/symptoms/weight.dm | 5 + .../datums/diseases/advance/symptoms/youth.dm | 2 + code/modules/cargo/packs.dm | 2 +- .../reagents/chemistry/machinery/pandemic.dm | 87 +++++--- .../chemistry/reagents/other_reagents.dm | 7 + .../reagents/reagent_containers/bottle.dm | 6 +- tgui/assets/tgui.js.rej | 20 +- tgui/src/interfaces/pandemic.ract | 185 ++++++++++-------- 36 files changed, 328 insertions(+), 140 deletions(-) diff --git a/code/controllers/subsystem/disease.dm b/code/controllers/subsystem/disease.dm index 451bd05606..ae5a6636eb 100644 --- a/code/controllers/subsystem/disease.dm +++ b/code/controllers/subsystem/disease.dm @@ -13,4 +13,11 @@ SUBSYSTEM_DEF(disease) diseases = subtypesof(/datum/disease) /datum/controller/subsystem/disease/stat_entry(msg) - ..("P:[active_diseases.len]") \ No newline at end of file + ..("P:[active_diseases.len]") + +/datum/controller/subsystem/disease/proc/get_disease_name(id) + var/datum/disease/advance/A = archive_diseases[id] + if(A.name) + return A.name + else + return "Unknown" \ No newline at end of file diff --git a/code/datums/diseases/advance/presets.dm b/code/datums/diseases/advance/presets.dm index 07809d3555..1a197f0f34 100644 --- a/code/datums/diseases/advance/presets.dm +++ b/code/datums/diseases/advance/presets.dm @@ -34,20 +34,20 @@ ..(process, D, copy) -// Hullucigen +// Hallucigen -/datum/disease/advance/hullucigen/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE) +/datum/disease/advance/hallucigen/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE) if(!D) - name = "Reality Impairment" + name = "Second Sight" symptoms = list(new/datum/symptom/hallucigen) ..(process, D, copy) // Sensory Restoration -/datum/disease/advance/sensory_restoration/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE) +/datum/disease/advance/mind_restoration/New(var/process = TRUE, var/datum/disease/advance/D, var/copy = FALSE) if(!D) - name = "Reality Enhancer" - symptoms = list(new/datum/symptom/sensory_restoration) + name = "Intelligence Booster" + symptoms = list(new/datum/symptom/mind_restoration) ..(process, D, copy) // Sensory Destruction diff --git a/code/datums/diseases/advance/symptoms/beard.dm b/code/datums/diseases/advance/symptoms/beard.dm index 2f8635301e..aa3919f3cf 100644 --- a/code/datums/diseases/advance/symptoms/beard.dm +++ b/code/datums/diseases/advance/symptoms/beard.dm @@ -17,6 +17,7 @@ BONUS /datum/symptom/beard name = "Facial Hypertrichosis" + desc = "The virus increases hair production significantly, causing rapid beard growth." stealth = -3 resistance = -1 stage_speed = -3 diff --git a/code/datums/diseases/advance/symptoms/choking.dm b/code/datums/diseases/advance/symptoms/choking.dm index a46ef690ef..f7f998f2b1 100644 --- a/code/datums/diseases/advance/symptoms/choking.dm +++ b/code/datums/diseases/advance/symptoms/choking.dm @@ -18,6 +18,7 @@ Bonus /datum/symptom/choking name = "Choking" + desc = "The virus causes inflammation of the host's air conduits, leading to intermittent choking." stealth = -3 resistance = -2 stage_speed = -2 @@ -27,6 +28,8 @@ Bonus base_message_chance = 15 symptom_delay_min = 10 symptom_delay_max = 30 + threshold_desc = "Stage Speed 8: Causes choking more frequently.
\ + Stealth 4: The symptom remains hidden until active." /datum/symptom/choking/Start(datum/disease/advance/A) ..() @@ -84,6 +87,7 @@ Bonus /datum/symptom/asphyxiation name = "Acute respiratory distress syndrome" + desc = "The virus causes shrinking of the host's lungs, causing severe asphyxiation. May also lead to heart attacks." stealth = -2 resistance = -0 stage_speed = -1 diff --git a/code/datums/diseases/advance/symptoms/confusion.dm b/code/datums/diseases/advance/symptoms/confusion.dm index 45bf5d6182..2e252267c4 100644 --- a/code/datums/diseases/advance/symptoms/confusion.dm +++ b/code/datums/diseases/advance/symptoms/confusion.dm @@ -18,6 +18,7 @@ Bonus /datum/symptom/confusion name = "Confusion" + desc = "The virus interferes with the proper function of the neural system, leading to bouts of confusion and erratic movement." stealth = 1 resistance = -1 stage_speed = -3 @@ -28,6 +29,9 @@ Bonus symptom_delay_min = 10 symptom_delay_max = 30 var/brain_damage = FALSE + threshold_desc = "Resistance 6: Causes brain damage over time.
\ + Transmission 6: Increases confusion duration.
\ + Stealth 4: The symptom remains hidden until active." /datum/symptom/confusion/Start(datum/disease/advance/A) ..() diff --git a/code/datums/diseases/advance/symptoms/cough.dm b/code/datums/diseases/advance/symptoms/cough.dm index a05d1d5e88..95577fe351 100644 --- a/code/datums/diseases/advance/symptoms/cough.dm +++ b/code/datums/diseases/advance/symptoms/cough.dm @@ -18,6 +18,7 @@ BONUS /datum/symptom/cough name = "Cough" + desc = "The virus irritates the throat of the host, causing occasional coughing." stealth = -1 resistance = 3 stage_speed = 1 @@ -28,6 +29,11 @@ BONUS symptom_delay_min = 2 symptom_delay_max = 15 var/infective = FALSE + threshold_desc = "Resistance 3: Host will drop small items when coughing.
\ + Resistance 10: Occasionally causes coughing fits that stun the host.
\ + Stage Speed 6: Increases cough frequency.
\ + If Airborne: Coughing will infect bystanders.
\ + Stealth 4: The symptom remains hidden until active." /datum/symptom/cough/Start(datum/disease/advance/A) ..() diff --git a/code/datums/diseases/advance/symptoms/deafness.dm b/code/datums/diseases/advance/symptoms/deafness.dm index b6163a72a1..c43970563d 100644 --- a/code/datums/diseases/advance/symptoms/deafness.dm +++ b/code/datums/diseases/advance/symptoms/deafness.dm @@ -18,6 +18,7 @@ Bonus /datum/symptom/deafness name = "Deafness" + desc = "The virus causes inflammation of the eardrums, causing intermittent deafness." stealth = -1 resistance = -2 stage_speed = -1 @@ -27,6 +28,8 @@ Bonus base_message_chance = 100 symptom_delay_min = 25 symptom_delay_max = 80 + threshold_desc = "Resistance 9: Causes permanent deafness, instead of intermittent.
\ + Stealth 4: The symptom remains hidden until active." /datum/symptom/deafness/Start(datum/disease/advance/A) ..() diff --git a/code/datums/diseases/advance/symptoms/dizzy.dm b/code/datums/diseases/advance/symptoms/dizzy.dm index 60e9989d4a..cb1bf11e63 100644 --- a/code/datums/diseases/advance/symptoms/dizzy.dm +++ b/code/datums/diseases/advance/symptoms/dizzy.dm @@ -18,7 +18,7 @@ Bonus /datum/symptom/dizzy // Not the egg name = "Dizziness" - stealth = 2 + desc = "The virus causes inflammation of the vestibular system, leading to bouts of dizziness." resistance = -2 stage_speed = -3 transmittable = -1 @@ -27,6 +27,8 @@ Bonus base_message_chance = 50 symptom_delay_min = 15 symptom_delay_max = 40 + threshold_desc = "Transmission 6: Also causes druggy vision.
\ + Stealth 4: The symptom remains hidden until active." /datum/symptom/dizzy/Start(datum/disease/advance/A) ..() diff --git a/code/datums/diseases/advance/symptoms/fever.dm b/code/datums/diseases/advance/symptoms/fever.dm index e69c3bf0a2..673835b0ed 100644 --- a/code/datums/diseases/advance/symptoms/fever.dm +++ b/code/datums/diseases/advance/symptoms/fever.dm @@ -16,8 +16,8 @@ Bonus */ /datum/symptom/fever - name = "Fever" + desc = "The virus causes a febrile response from the host, raising its body temperature." stealth = 0 resistance = 3 stage_speed = 3 @@ -28,6 +28,8 @@ Bonus symptom_delay_min = 10 symptom_delay_max = 30 var/unsafe = FALSE //over the heat threshold + threshold_desc = "Resistance 5: Increases fever intensity, fever can overheat and harm the host.
\ + Resistance 10: Further increases fever intensity." /datum/symptom/fever/Start(datum/disease/advance/A) ..() diff --git a/code/datums/diseases/advance/symptoms/fire.dm b/code/datums/diseases/advance/symptoms/fire.dm index b8d80b8023..e12e705350 100644 --- a/code/datums/diseases/advance/symptoms/fire.dm +++ b/code/datums/diseases/advance/symptoms/fire.dm @@ -18,6 +18,7 @@ Bonus /datum/symptom/fire name = "Spontaneous Combustion" + desc = "The virus turns fat into an extremely flammable compound, and raises the body's temperature, making the host burst into flames spontaneously." stealth = 1 resistance = -4 stage_speed = -4 @@ -28,6 +29,10 @@ Bonus symptom_delay_min = 20 symptom_delay_max = 75 var/infective = FALSE + threshold_desc = "Stage Speed 4: Increases the intensity of the flames.
\ + Stage Speed 8: Further increases flame intensity.
\ + Transmission 8: Host will spread the virus through skin flakes when bursting into flame.
\ + Stealth 4: The symptom remains hidden until active." /datum/symptom/fire/Start(datum/disease/advance/A) ..() @@ -94,6 +99,7 @@ Bonus /datum/symptom/alkali name = "Alkali perspiration" + desc = "The virus attaches to sudoriparous glands, synthesizing a chemical that bursts into flames when reacting with water, leading to self-immolation." stealth = 2 resistance = -2 stage_speed = -2 @@ -105,6 +111,9 @@ Bonus symptom_delay_max = 90 var/chems = FALSE var/explosion_power = 1 + threshold_desc = "Resistance 9: Doubles the intensity of the effect, but reduces its frequency.
\ + Stage Speed 8: Increases explosion radius when the host is wet.
\ + Transmission 8: Additionally synthesizes chlorine trifluoride and napalm inside the host." /datum/symptom/alkali/Start(datum/disease/advance/A) ..() diff --git a/code/datums/diseases/advance/symptoms/flesh_eating.dm b/code/datums/diseases/advance/symptoms/flesh_eating.dm index 838d4481b5..16e2b5c065 100644 --- a/code/datums/diseases/advance/symptoms/flesh_eating.dm +++ b/code/datums/diseases/advance/symptoms/flesh_eating.dm @@ -18,6 +18,7 @@ Bonus /datum/symptom/flesh_eating name = "Necrotizing Fasciitis" + desc = "The virus aggressively attacks body cells, necrotizing tissues and organs." stealth = -3 resistance = -4 stage_speed = 0 @@ -29,6 +30,8 @@ Bonus symptom_delay_max = 60 var/bleed = FALSE var/pain = FALSE + threshold_desc = "Resistance 7: Host will bleed profusely during necrosis.
\ + Transmission 8: Causes extreme pain to the host, weakening it." /datum/symptom/flesh_eating/Start(datum/disease/advance/A) ..() @@ -80,6 +83,7 @@ Bonus /datum/symptom/flesh_death name = "Autophagocytosis Necrosis" + desc = "The virus rapidly consumes infected cells, leading to heavy and widespread damage." stealth = -2 resistance = -2 stage_speed = 1 @@ -91,6 +95,8 @@ Bonus symptom_delay_max = 6 var/chems = FALSE var/zombie = FALSE + threshold_desc = "Stage Speed 7: Synthesizes Heparin and Lipolicide inside the host, causing increased bleeding and hunger.
\ + Stealth 5: The symptom remains hidden until active." /datum/symptom/flesh_death/Start(datum/disease/advance/A) ..() diff --git a/code/datums/diseases/advance/symptoms/genetics.dm b/code/datums/diseases/advance/symptoms/genetics.dm index 0b6ea5f808..1f654f2e97 100644 --- a/code/datums/diseases/advance/symptoms/genetics.dm +++ b/code/datums/diseases/advance/symptoms/genetics.dm @@ -16,8 +16,8 @@ Bonus */ /datum/symptom/genetic_mutation - name = "Deoxyribonucleic Acid Saboteur" + desc = "The virus bonds with the DNA of the host, causing damaging mutations until removed." stealth = -2 resistance = -3 stage_speed = 0 @@ -30,6 +30,9 @@ Bonus symptom_delay_min = 60 symptom_delay_max = 120 var/no_reset = FALSE + threshold_desc = "Resistance 8: Causes two harmful mutations at once.
\ + Stage Speed 10: Increases mutation frequency.
\ + Stealth 5: The mutations persist even if the virus is cured." /datum/symptom/genetic_mutation/Activate(datum/disease/advance/A) if(!..()) diff --git a/code/datums/diseases/advance/symptoms/hallucigen.dm b/code/datums/diseases/advance/symptoms/hallucigen.dm index 9bfd5b0baf..d4cda525ad 100644 --- a/code/datums/diseases/advance/symptoms/hallucigen.dm +++ b/code/datums/diseases/advance/symptoms/hallucigen.dm @@ -16,8 +16,8 @@ Bonus */ /datum/symptom/hallucigen - name = "Hallucigen" + desc = "The virus stimulates the brain, causing occasional hallucinations." stealth = -2 resistance = -3 stage_speed = -3 @@ -28,6 +28,8 @@ Bonus symptom_delay_min = 25 symptom_delay_max = 90 var/fake_healthy = FALSE + threshold_desc = "Stage Speed 7: Increases the amount of hallucinations.
\ + Stealth 4: The virus mimics positive symptoms.." /datum/symptom/hallucigen/Start(datum/disease/advance/A) ..() diff --git a/code/datums/diseases/advance/symptoms/headache.dm b/code/datums/diseases/advance/symptoms/headache.dm index 3baeedea19..b0665e0870 100644 --- a/code/datums/diseases/advance/symptoms/headache.dm +++ b/code/datums/diseases/advance/symptoms/headache.dm @@ -19,6 +19,7 @@ BONUS /datum/symptom/headache name = "Headache" + desc = "The virus causes inflammation inside the brain, causing constant headaches." stealth = -1 resistance = 4 stage_speed = 2 @@ -28,6 +29,9 @@ BONUS base_message_chance = 100 symptom_delay_min = 15 symptom_delay_max = 30 + threshold_desc = "Stage Speed 6: Headaches will cause severe pain, that weakens the host.
\ + Stage Speed 9: Headaches become less frequent but far more intense, preventing any action from the host.
\ + Stealth 4: Reduces headache frequency until later stages." /datum/symptom/headache/Start(datum/disease/advance/A) ..() @@ -45,11 +49,11 @@ BONUS return var/mob/living/M = A.affected_mob if(power < 2) - if(prob(base_message_chance)) + if(prob(base_message_chance) || A.stage >=4) to_chat(M, "[pick("Your head hurts.", "Your head pounds.")]") - if(power >= 2) + if(power >= 2 && A.stage >= 4) to_chat(M, "[pick("Your head hurts a lot.", "Your head pounds incessantly.")]") M.adjustStaminaLoss(25) - if(power >= 3) + if(power >= 3 && A.stage >= 5) to_chat(M, "[pick("Your head hurts!", "You feel a burning knife inside your brain!", "A wave of pain fills your head!")]") M.Stun(35) \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm index 7b31588240..5167b17e0d 100644 --- a/code/datums/diseases/advance/symptoms/heal.dm +++ b/code/datums/diseases/advance/symptoms/heal.dm @@ -1,5 +1,6 @@ /datum/symptom/heal name = "Basic Healing (does nothing)" //warning for adminspawn viruses + desc = "You should not be seeing this." stealth = 1 resistance = -4 stage_speed = -4 @@ -9,6 +10,9 @@ symptom_delay_min = 1 symptom_delay_max = 1 var/hide_healing = FALSE + threshold_desc = "Stage Speed 6: Doubles healing speed.
\ + Stage Speed 11: Triples healing speed.
\ + Stealth 4: Healing will no longer be visible to onlookers." /datum/symptom/heal/Start(datum/disease/advance/A) ..() @@ -51,6 +55,7 @@ Bonus /datum/symptom/heal/toxin name = "Toxic Filter" + desc = "The virus synthesizes regenerative chemicals in the bloodstream, repairing damage caused by toxins." stealth = 1 resistance = -4 stage_speed = -4 @@ -87,6 +92,7 @@ Bonus stage_speed = -2 transmittable = -2 level = 8 + desc = "The virus stimulates production of special stem cells in the bloodstream, causing rapid reparation of any damage caused by toxins." /datum/symptom/heal/toxin/plus/Heal(mob/living/M, datum/disease/advance/A) var/heal_amt = 2 * power @@ -115,6 +121,7 @@ Bonus /datum/symptom/heal/brute name = "Regeneration" + desc = "The virus stimulates the regenerative process in the host, causing faster wound healing." stealth = 1 resistance = -4 stage_speed = -4 @@ -158,6 +165,7 @@ Bonus /datum/symptom/heal/brute/plus name = "Flesh Mending" + desc = "The virus rapidly mutates into body cells, effectively allowing it to quickly fix the host's wounds." stealth = 0 resistance = 0 stage_speed = -2 @@ -207,6 +215,7 @@ Bonus /datum/symptom/heal/burn name = "Tissue Regrowth" + desc = "The virus recycles dead and burnt tissues, speeding up the healing of damage caused by burns." stealth = 1 resistance = -4 stage_speed = -4 @@ -248,7 +257,8 @@ Bonus /datum/symptom/heal/burn/plus - name = "Heat Resistance" + name = "Temperature Adaptation" + desc = "The virus quickly balances body heat, while also replacing tissues damaged by external sources." stealth = 0 resistance = 0 stage_speed = -2 @@ -297,6 +307,7 @@ Bonus /datum/symptom/heal/dna name = "Deoxyribonucleic Acid Restoration" + desc = "The virus repairs the host's genome, purging negative mutations." stealth = -1 resistance = -1 stage_speed = 0 @@ -304,9 +315,11 @@ Bonus level = 5 symptom_delay_min = 3 symptom_delay_max = 8 + threshold_desc = "Stage Speed 6: Additionally heals brain damage.
\ + Stage Speed 11: Increases brain damage healing." /datum/symptom/heal/dna/Heal(mob/living/carbon/M, datum/disease/advance/A) - var/amt_healed = 2 * power + var/amt_healed = 2 * (power - 1) M.adjustBrainLoss(-amt_healed) //Non-power mutations, excluding race, so the virus does not force monkey -> human transformations. var/list/unclean_mutations = (GLOB.not_good_mutations|GLOB.bad_mutations) - GLOB.mutations_list[RACEMUT] diff --git a/code/datums/diseases/advance/symptoms/itching.dm b/code/datums/diseases/advance/symptoms/itching.dm index 880ac1f3e6..119b04b48a 100644 --- a/code/datums/diseases/advance/symptoms/itching.dm +++ b/code/datums/diseases/advance/symptoms/itching.dm @@ -19,6 +19,7 @@ BONUS /datum/symptom/itching name = "Itching" + desc = "The virus irritates the skin, causing itching." stealth = 0 resistance = 3 stage_speed = 3 @@ -28,6 +29,8 @@ BONUS symptom_delay_min = 5 symptom_delay_max = 25 var/scratch = FALSE + threshold_desc = "Transmission 6: Increases frequency of itching.
\ + Stage Speed 7: The host will scrath itself when itching, causing superficial damage." /datum/symptom/itching/Start(datum/disease/advance/A) ..() diff --git a/code/datums/diseases/advance/symptoms/narcolepsy.dm b/code/datums/diseases/advance/symptoms/narcolepsy.dm index a5a2bd7a4c..d850d257cb 100644 --- a/code/datums/diseases/advance/symptoms/narcolepsy.dm +++ b/code/datums/diseases/advance/symptoms/narcolepsy.dm @@ -14,6 +14,7 @@ Bonus */ /datum/symptom/narcolepsy name = "Narcolepsy" + desc = "The virus causes a hormone imbalance, making the host sleepy and narcoleptic." stealth = -1 resistance = -2 stage_speed = -3 @@ -25,6 +26,8 @@ Bonus var/sleep_level = 0 var/sleepy_ticks = 0 var/stamina = FALSE + threshold_desc = "Transmission 7: Also relaxes the muscles, weakening and slowing the host.
\ + Resistance 10: Causes narcolepsy more often, increasing the chance of the host falling asleep." /datum/symptom/narcolepsy/Start(datum/disease/advance/A) ..() diff --git a/code/datums/diseases/advance/symptoms/oxygen.dm b/code/datums/diseases/advance/symptoms/oxygen.dm index 5949e84420..da085ab153 100644 --- a/code/datums/diseases/advance/symptoms/oxygen.dm +++ b/code/datums/diseases/advance/symptoms/oxygen.dm @@ -18,6 +18,7 @@ Bonus /datum/symptom/oxygen name = "Self-Respiration" + desc = "The virus rapidly synthesizes oxygen, effectively removing the need for breathing." stealth = 1 resistance = -3 stage_speed = -3 @@ -27,6 +28,7 @@ Bonus symptom_delay_min = 1 symptom_delay_max = 1 var/regenerate_blood = FALSE + threshold_desc = "Resistance 8:Additionally regenerates lost blood.
" /datum/symptom/oxygen/Start(datum/disease/advance/A) ..() diff --git a/code/datums/diseases/advance/symptoms/sensory.dm b/code/datums/diseases/advance/symptoms/sensory.dm index 3063ee06f6..dd417e50ed 100644 --- a/code/datums/diseases/advance/symptoms/sensory.dm +++ b/code/datums/diseases/advance/symptoms/sensory.dm @@ -15,8 +15,9 @@ Bonus ////////////////////////////////////// */ -/datum/symptom/sensory_restoration - name = "Sensory Restoration" +/datum/symptom/mind_restoration + name = "Mind Restoration" + desc = "The virus strengthens the bonds between neurons, reducing the duration of any ailments of the mind." stealth = -1 resistance = -4 stage_speed = -4 @@ -27,15 +28,17 @@ Bonus symptom_delay_max = 10 var/purge_alcohol = FALSE var/brain_heal = FALSE + threshold_desc = "Resistance 6: Heals brain damage.
\ + Transmission 8: Purges alcohol in the bloodstream." -/datum/symptom/sensory_restoration/Start(datum/disease/advance/A) +/datum/symptom/mind_restoration/Start(datum/disease/advance/A) ..() if(A.properties["resistance"] >= 6) //heal brain damage brain_heal = TRUE if(A.properties["transmittable"] >= 8) //purge alcohol purge_alcohol = TRUE -/datum/symptom/sensory_restoration/Activate(var/datum/disease/advance/A) +/datum/symptom/mind_restoration/Activate(var/datum/disease/advance/A) if(!..()) return var/mob/living/M = A.affected_mob diff --git a/code/datums/diseases/advance/symptoms/shedding.dm b/code/datums/diseases/advance/symptoms/shedding.dm index cf88fcf6db..a578289e17 100644 --- a/code/datums/diseases/advance/symptoms/shedding.dm +++ b/code/datums/diseases/advance/symptoms/shedding.dm @@ -15,8 +15,8 @@ BONUS */ /datum/symptom/shedding - name = "Alopecia" + desc = "The virus causes rapid shedding of head and body hair." stealth = 0 resistance = 1 stage_speed = -1 diff --git a/code/datums/diseases/advance/symptoms/shivering.dm b/code/datums/diseases/advance/symptoms/shivering.dm index 4c9ec94a2b..f40fd151d9 100644 --- a/code/datums/diseases/advance/symptoms/shivering.dm +++ b/code/datums/diseases/advance/symptoms/shivering.dm @@ -16,8 +16,8 @@ Bonus */ /datum/symptom/shivering - name = "Shivering" + desc = "The virus inhibits the body's thermoregulation, cooling the body down." stealth = 0 resistance = 2 stage_speed = 2 @@ -27,6 +27,8 @@ Bonus symptom_delay_min = 10 symptom_delay_max = 30 var/unsafe = FALSE //over the cold threshold + threshold_desc = "Stage Speed 5: Increases cooling speed; the host can fall below safe temperature levels.
\ + Stage Speed 10: Further increases cooling speed." /datum/symptom/fever/Start(datum/disease/advance/A) ..() diff --git a/code/datums/diseases/advance/symptoms/skin.dm b/code/datums/diseases/advance/symptoms/skin.dm index 09eea77520..014607eb44 100644 --- a/code/datums/diseases/advance/symptoms/skin.dm +++ b/code/datums/diseases/advance/symptoms/skin.dm @@ -17,6 +17,7 @@ BONUS /datum/symptom/vitiligo name = "Vitiligo" + desc = "The virus destroys skin pigment cells, causing rapid loss of pigmentation in the host." stealth = -3 resistance = -1 stage_speed = -1 @@ -61,6 +62,7 @@ BONUS /datum/symptom/revitiligo name = "Revitiligo" + desc = "The virus causes increased production of skin pigment cells, making the host's skin grow darker over time." stealth = -3 resistance = -1 stage_speed = -1 diff --git a/code/datums/diseases/advance/symptoms/sneeze.dm b/code/datums/diseases/advance/symptoms/sneeze.dm index fda1fc765c..085b5ff592 100644 --- a/code/datums/diseases/advance/symptoms/sneeze.dm +++ b/code/datums/diseases/advance/symptoms/sneeze.dm @@ -18,6 +18,7 @@ Bonus /datum/symptom/sneeze name = "Sneezing" + desc = "The virus causes irritation of the nasal cavity, making the host sneeze occasionally." stealth = -2 resistance = 3 stage_speed = 0 @@ -26,6 +27,8 @@ Bonus severity = 1 symptom_delay_min = 5 symptom_delay_max = 35 + threshold_desc = "Transmission 9: Increases sneezing range, spreading the virus over a larger area.
\ + Stealth 4: The symptom remains hidden until active." /datum/symptom/sneeze/Start(datum/disease/advance/A) ..() diff --git a/code/datums/diseases/advance/symptoms/symptoms.dm b/code/datums/diseases/advance/symptoms/symptoms.dm index 4bcb1b502f..8557375dbd 100644 --- a/code/datums/diseases/advance/symptoms/symptoms.dm +++ b/code/datums/diseases/advance/symptoms/symptoms.dm @@ -3,6 +3,8 @@ /datum/symptom // Buffs/Debuffs the symptom has to the overall engineered disease. var/name = "" + var/desc = "If you see this something went very wrong." //Basic symptom description + var/threshold_desc = "" //Description of threshold effects var/stealth = 0 var/resistance = 0 var/stage_speed = 0 @@ -25,6 +27,7 @@ var/power = 1 //A neutered symptom has no effect, and only affects statistics. var/neutered = FALSE + var/list/thresholds /datum/symptom/New() var/list/S = SSdisease.list_symptoms @@ -37,7 +40,6 @@ // Called when processing of the advance disease, which holds this symptom, starts. /datum/symptom/proc/Start(datum/disease/advance/A) next_activation = world.time + rand(symptom_delay_min * 10, symptom_delay_max * 10) //so it doesn't instantly activate on infection - return // Called when the advance disease is going to be deleted or when the advance disease stops processing. /datum/symptom/proc/End(datum/disease/advance/A) @@ -58,3 +60,6 @@ new_symp.id = id new_symp.neutered = neutered return new_symp + +/datum/symptom/proc/generate_threshold_desc() + return diff --git a/code/datums/diseases/advance/symptoms/viral.dm b/code/datums/diseases/advance/symptoms/viral.dm index 49bb2d674c..539c57c92e 100644 --- a/code/datums/diseases/advance/symptoms/viral.dm +++ b/code/datums/diseases/advance/symptoms/viral.dm @@ -15,6 +15,7 @@ BONUS */ /datum/symptom/viraladaptation name = "Viral self-adaptation" + desc = "The virus mimics the function of normal body cells, becoming harder to spot and to eradicate, but reducing its speed." stealth = 3 resistance = 5 stage_speed = -3 @@ -38,6 +39,8 @@ BONUS */ /datum/symptom/viralevolution name = "Viral evolutionary acceleration" + desc = "The virus quickly adapts to spread as fast as possible both outside and inside a host. \ + This, however, makes the virus easier to spot, and less able to fight off a cure." stealth = -2 resistance = -3 stage_speed = 5 @@ -65,6 +68,8 @@ Bonus /datum/symptom/viralreverse name = "Viral aggressive metabolism" + desc = "The virus sacrifices its long term survivability to gain a near-instant spread when inside a host. \ + The virus will start at the lastest stage, but will eventually decay and die off by itself." stealth = -2 resistance = 1 stage_speed = 3 @@ -73,6 +78,8 @@ Bonus symptom_delay_min = 1 symptom_delay_max = 1 var/time_to_cure + threshold_desc = "Resistance/Stage Speed: Highest between these determines the amount of time before self-curing.
\ + Stealth 4: Doubles the time before the virus self-cures." /datum/symptom/viralreverse/Activate(datum/disease/advance/A) if(!..()) diff --git a/code/datums/diseases/advance/symptoms/vision.dm b/code/datums/diseases/advance/symptoms/vision.dm index 9148139e50..04f5d72ba6 100644 --- a/code/datums/diseases/advance/symptoms/vision.dm +++ b/code/datums/diseases/advance/symptoms/vision.dm @@ -18,6 +18,7 @@ Bonus /datum/symptom/visionloss name = "Hyphema" + desc = "The virus causes inflammation of the retina, leading to eye damage and eventually blindness." stealth = -1 resistance = -4 stage_speed = -4 @@ -28,6 +29,8 @@ Bonus symptom_delay_min = 25 symptom_delay_max = 80 var/remove_eyes = FALSE + threshold_desc = "Resistance 12: Weakens extraocular muscles, eventually leading to complete detachment of the eyes.
\ + Stealth 4: The symptom remains hidden until active." /datum/symptom/visionloss/Start(datum/disease/advance/A) ..() @@ -88,6 +91,7 @@ Bonus /datum/symptom/visionaid name = "Ocular Restoration" + desc = "The virus stimulates the production and replacement of eye cells, causing the host to regenerate its eyes when damaged." stealth = -1 resistance = -3 stage_speed = -2 diff --git a/code/datums/diseases/advance/symptoms/voice_change.dm b/code/datums/diseases/advance/symptoms/voice_change.dm index 3abeb42f03..bdeb6321bc 100644 --- a/code/datums/diseases/advance/symptoms/voice_change.dm +++ b/code/datums/diseases/advance/symptoms/voice_change.dm @@ -18,6 +18,7 @@ Bonus /datum/symptom/voice_change name = "Voice Change" + desc = "The virus alters the pitch and tone of the host's vocal cords, changing how their voice sounds." stealth = -1 resistance = -2 stage_speed = -2 @@ -30,6 +31,9 @@ Bonus var/scramble_language = FALSE var/datum/language/current_language var/datum/language_holder/original_language + threshold_desc = "Transmission 14: The host's language center of the brain is damaged, leading to complete inability to speak or understand any language.
\ + Stage Speed 7: Changes voice more often.
\ + Stealth 3: The symptom remains hidden until active." /datum/symptom/voice_change/Start(datum/disease/advance/A) ..() diff --git a/code/datums/diseases/advance/symptoms/vomit.dm b/code/datums/diseases/advance/symptoms/vomit.dm index e2be924d6a..983d20a66d 100644 --- a/code/datums/diseases/advance/symptoms/vomit.dm +++ b/code/datums/diseases/advance/symptoms/vomit.dm @@ -22,6 +22,7 @@ Bonus /datum/symptom/vomit name = "Vomiting" + desc = "The virus causes nausea and irritates the stomach, causing occasional vomit." stealth = -2 resistance = -1 stage_speed = 0 @@ -33,6 +34,9 @@ Bonus symptom_delay_max = 80 var/vomit_blood = FALSE var/proj_vomit = 0 + threshold_desc = "Resistance 7: Host will vomit blood, causing internal damage.
\ + Transmission 7: Host will projectile vomit, increasing vomiting range.
\ + Stealth 4: The symptom remains hidden until active." /datum/symptom/vomit/Start(datum/disease/advance/A) ..() diff --git a/code/datums/diseases/advance/symptoms/weight.dm b/code/datums/diseases/advance/symptoms/weight.dm index ec371f1167..ea2577b800 100644 --- a/code/datums/diseases/advance/symptoms/weight.dm +++ b/code/datums/diseases/advance/symptoms/weight.dm @@ -18,6 +18,7 @@ Bonus /datum/symptom/weight_gain name = "Weight Gain" + desc = "The virus mutates the host's metabolism, making it gain weight much faster than normal." stealth = -3 resistance = -3 stage_speed = -2 @@ -27,6 +28,7 @@ Bonus base_message_chance = 100 symptom_delay_min = 15 symptom_delay_max = 45 + threshold_desc = "Stealth 4: The symptom is less noticeable." /datum/symptom/weight_gain/Start(datum/disease/advance/A) ..() @@ -66,6 +68,7 @@ Bonus /datum/symptom/weight_loss name = "Weight Loss" + desc = "The virus mutates the host's metabolism, making it almost unable to gain nutrition from food." stealth = -3 resistance = -2 stage_speed = -2 @@ -75,6 +78,7 @@ Bonus base_message_chance = 100 symptom_delay_min = 15 symptom_delay_max = 45 + threshold_desc = "Stealth 4: The symptom is less noticeable." /datum/symptom/weight_loss/Start(datum/disease/advance/A) ..() @@ -116,6 +120,7 @@ Bonus /datum/symptom/weight_even name = "Weight Even" + desc = "The virus alters the host's metabolism, making it far more efficient then normal, and synthesizing nutrients from normally unedible sources." stealth = -3 resistance = -2 stage_speed = -2 diff --git a/code/datums/diseases/advance/symptoms/youth.dm b/code/datums/diseases/advance/symptoms/youth.dm index 9793313354..6be34684e7 100644 --- a/code/datums/diseases/advance/symptoms/youth.dm +++ b/code/datums/diseases/advance/symptoms/youth.dm @@ -18,6 +18,8 @@ BONUS /datum/symptom/youth name = "Eternal Youth" + desc = "The virus becomes symbiotically connected to the cells in the host's body, preventing and reversing aging. \ + The virus, in turn, becomes more resistant, spreads faster, and is harder to spot, although it doesn't thrive as well without a host." stealth = 3 resistance = 4 stage_speed = 4 diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index 263b5c5d30..8cce6ee6be 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -807,7 +807,7 @@ /obj/item/weapon/reagent_containers/glass/bottle/magnitis, /obj/item/weapon/reagent_containers/glass/bottle/pierrot_throat, /obj/item/weapon/reagent_containers/glass/bottle/brainrot, - /obj/item/weapon/reagent_containers/glass/bottle/hullucigen_virion, + /obj/item/weapon/reagent_containers/glass/bottle/hallucigen_virion, /obj/item/weapon/reagent_containers/glass/bottle/anxiety, /obj/item/weapon/reagent_containers/glass/bottle/beesease, /obj/item/weapon/storage/box/syringes, diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm index 46597fb028..a31183fcf0 100644 --- a/code/modules/reagents/chemistry/machinery/pandemic.dm +++ b/code/modules/reagents/chemistry/machinery/pandemic.dm @@ -1,3 +1,6 @@ +#define MAIN_SCREEN 1 +#define SYMPTOM_DETAILS 2 + /obj/machinery/computer/pandemic name = "PanD.E.M.I.C 2200" desc = "Used to work with viruses." @@ -10,6 +13,8 @@ idle_power_usage = 20 resistance_flags = ACID_PROOF var/wait + var/mode = MAIN_SCREEN + var/datum/symptom/selected_symptom var/obj/item/weapon/reagent_containers/beaker /obj/machinery/computer/pandemic/Initialize() @@ -34,9 +39,7 @@ /obj/machinery/computer/pandemic/proc/get_viruses_data(datum/reagent/blood/B) . = list() - if(!islist(B.data["viruses"])) - return - var/list/V = B.data["viruses"] + var/list/V = B.get_diseases() var/index = 1 for(var/virus in V) var/datum/disease/D = virus @@ -47,21 +50,24 @@ this["name"] = D.name if(istype(D, /datum/disease/advance)) var/datum/disease/advance/A = D - var/datum/disease/advance/archived = SSdisease.archive_diseases[D.GetDiseaseID()] - if(archived.name == "Unknown") + var/disease_name = SSdisease.get_disease_name(A.GetDiseaseID()) + if(disease_name == "Unknown") this["can_rename"] = TRUE - this["name"] = archived.name + this["name"] = disease_name this["is_adv"] = TRUE - this["resistance"] = A.totalResistance() - this["stealth"] = A.totalStealth() - this["stage_speed"] = A.totalStageSpeed() - this["transmission"] = A.totalTransmittable() this["symptoms"] = list() + var/symptom_index = 1 for(var/symptom in A.symptoms) var/datum/symptom/S = symptom var/list/this_symptom = list() this_symptom["name"] = S.name + this_symptom["sym_index"] = symptom_index + symptom_index++ this["symptoms"] += list(this_symptom) + this["resistance"] = A.totalResistance() + this["stealth"] = A.totalStealth() + this["stage_speed"] = A.totalStageSpeed() + this["transmission"] = A.totalTransmittable() this["index"] = index++ this["agent"] = D.agent this["description"] = D.desc || "none" @@ -70,6 +76,20 @@ . += list(this) +/obj/machinery/computer/pandemic/proc/get_symptom_data(datum/symptom/S) + . = list() + var/list/this = list() + this["name"] = S.name + this["desc"] = S.desc + this["stealth"] = S.stealth + this["resistance"] = S.resistance + this["stage_speed"] = S.stage_speed + this["transmission"] = S.transmittable + this["level"] = S.level + this["neutered"] = S.neutered + this["threshold_desc"] = S.threshold_desc + . += this + /obj/machinery/computer/pandemic/proc/get_resistance_data(datum/reagent/blood/B) . = list() if(!islist(B.data["resistances"])) @@ -81,6 +101,7 @@ if(D) this["id"] = id this["name"] = D.name + . += list(this) /obj/machinery/computer/pandemic/proc/reset_replicator_cooldown() @@ -113,18 +134,23 @@ /obj/machinery/computer/pandemic/ui_data(mob/user) var/list/data = list() data["is_ready"] = !wait - if(beaker) - data["has_beaker"] = TRUE - if(!beaker.reagents.total_volume || !beaker.reagents.reagent_list) - data["beaker_empty"] = TRUE - var/datum/reagent/blood/B = locate() in beaker.reagents.reagent_list - if(B) - data["has_blood"] = TRUE - data["blood"] = list() - data["blood"]["dna"] = B.data["blood_DNA"] || "none" - data["blood"]["type"] = B.data["blood_type"] || "none" - data["viruses"] = get_viruses_data(B) - data["resistances"] = get_resistance_data(B) + data["mode"] = mode + switch(mode) + if(MAIN_SCREEN) + if(beaker) + data["has_beaker"] = TRUE + if(!beaker.reagents.total_volume || !beaker.reagents.reagent_list) + data["beaker_empty"] = TRUE + var/datum/reagent/blood/B = locate() in beaker.reagents.reagent_list + if(B) + data["has_blood"] = TRUE + data["blood"] = list() + data["blood"]["dna"] = B.data["blood_DNA"] || "none" + data["blood"]["type"] = B.data["blood_type"] || "none" + data["viruses"] = get_viruses_data(B) + data["resistances"] = get_resistance_data(B) + if(SYMPTOM_DETAILS) + data["symptom"] = get_symptom_data(selected_symptom) return data @@ -166,8 +192,8 @@ addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 50) . = TRUE if("create_vaccine_bottle") - var/index = params["index"] - var/datum/disease/D = SSdisease.archive_diseases[index] + var/index = text2num(params["index"]) + var/datum/disease/D = SSdisease.archive_diseases[get_virus_id_by_index(index)] var/obj/item/weapon/reagent_containers/glass/bottle/B = new(get_turf(src)) B.name = "[D.name] vaccine bottle" B.reagents.add_reagent("vaccine", 15, list(index)) @@ -175,6 +201,19 @@ update_icon() addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 200) . = TRUE + if("symptom_details") + var/picked_symptom_index = text2num(params["picked_symptom"]) + var/index = text2num(params["index"]) + var/datum/disease/advance/A = get_by_index("viruses", index) + var/datum/symptom/S = A.symptoms[picked_symptom_index] + mode = SYMPTOM_DETAILS + selected_symptom = S + . = TRUE + if("back") + mode = MAIN_SCREEN + selected_symptom = null + . = TRUE + /obj/machinery/computer/pandemic/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/weapon/reagent_containers) && (I.container_type & OPENCONTAINER)) diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 876029e128..48dcd62de0 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -62,6 +62,13 @@ data["viruses"] = preserve return 1 +/datum/reagent/blood/proc/get_diseases() + . = list() + if(data && data["viruses"]) + for(var/thing in data["viruses"]) + var/datum/disease/D = thing + . += D + /datum/reagent/blood/reaction_turf(turf/T, reac_volume)//splash the blood all over the place if(!istype(T)) return diff --git a/code/modules/reagents/reagent_containers/bottle.dm b/code/modules/reagents/reagent_containers/bottle.dm index 2325a9645e..6e9f361fb1 100644 --- a/code/modules/reagents/reagent_containers/bottle.dm +++ b/code/modules/reagents/reagent_containers/bottle.dm @@ -270,11 +270,11 @@ icon_state = "bottle3" spawned_disease = /datum/disease/advance/heal -/obj/item/weapon/reagent_containers/glass/bottle/hullucigen_virion - name = "Hullucigen virion culture bottle" +/obj/item/weapon/reagent_containers/glass/bottle/hallucigen_virion + name = "Hallucigen virion culture bottle" desc = "A small bottle. Contains hullucigen virion culture in synthblood medium." icon_state = "bottle3" - spawned_disease = /datum/disease/advance/hullucigen + spawned_disease = /datum/disease/advance/hallucigen /obj/item/weapon/reagent_containers/glass/bottle/pierrot_throat name = "Pierrot's Throat culture bottle" diff --git a/tgui/assets/tgui.js.rej b/tgui/assets/tgui.js.rej index 7a19430f92..06b7c3a2e3 100644 --- a/tgui/assets/tgui.js.rej +++ b/tgui/assets/tgui.js.rej @@ -1,15 +1,13 @@ diff a/tgui/assets/tgui.js b/tgui/assets/tgui.js (rejected hunks) -@@ -7,10 +7,10 @@ return t.set(e,+a+n)}function O(t,e){return Jo(this,t,void 0===e?1:+e)}function - real:8476,trade:8482,alefsym:8501,larr:8592,uarr:8593,rarr:8594,darr:8595,harr:8596,crarr:8629,lArr:8656,uArr:8657,rArr:8658,dArr:8659,hArr:8660,forall:8704,part:8706,exist:8707,empty:8709,nabla:8711,isin:8712,notin:8713,ni:8715,prod:8719,sum:8721,minus:8722,lowast:8727,radic:8730,prop:8733,infin:8734,ang:8736,and:8743,or:8744,cap:8745,cup:8746,"int":8747,there4:8756,sim:8764,cong:8773,asymp:8776,ne:8800,equiv:8801,le:8804,ge:8805,sub:8834,sup:8835,nsub:8836,sube:8838,supe:8839,oplus:8853,otimes:8855,perp:8869,sdot:8901,lceil:8968,rceil:8969,lfloor:8970,rfloor:8971,lang:9001,rang:9002,loz:9674,spades:9824,clubs:9827,hearts:9829,diams:9830},sc=[8364,129,8218,402,8222,8230,8224,8225,710,8240,352,8249,338,141,381,143,144,8216,8217,8220,8221,8226,8211,8212,732,8482,353,8250,339,157,382,376],uc=RegExp("&(#?(?:x[\\w\\d]+|\\d+|"+Object.keys(oc).join("|")+"));?","g"),pc=//g,lc=/&/g;var gc=function(){return e(this.node)},bc=function(t){this.type=kp,this.text=t.template};bc.prototype={detach:gc,firstNode:function(){return this.node},render:function(){return this.node||(this.node=document.createTextNode(this.text)),this.node},toString:function(t){return t?Ee(this.text):this.text},unrender:function(t){return t?this.detach():void 0}};var yc=bc,xc=Se,_c=Ce,wc=function(t,e,n){var a;this.ref=e,this.resolved=!1,this.root=t.root,this.parentFragment=t.parentFragment,this.callback=n,a=ls(t.root,e,t.parentFragment),void 0!=a?this.resolve(a):bs.addUnresolved(this)};wc.prototype={resolve:function(t){this.keypath&&!t&&bs.addUnresolved(this),this.resolved=!0,this.keypath=t,this.callback(t)},forceResolution:function(){this.resolve(E(this.ref))},rebind:function(t,e){var n;void 0!=this.keypath&&(n=this.keypath.replace(t,e),void 0!==n&&this.resolve(n))},unbind:function(){this.resolved||bs.removeUnresolved(this)}};var kc=wc,Ec=function(t,e,n){this.parentFragment=t.parentFragment,this.ref=e,this.callback=n,this.rebind()},Sc={"@keypath":{prefix:"c",prop:["context"]},"@index":{prefix:"i",prop:["index"]},"@key":{prefix:"k",prop:["key","index"]}};Ec.prototype={rebind:function(){var t,e=this.ref,n=this.parentFragment,a=Sc[e];if(!a)throw Error('Unknown special reference "'+e+'" - valid references are @index, @key and @keypath');if(this.cached)return this.callback(E("@"+a.prefix+Pe(this.cached,a)));if(-1!==a.prop.indexOf("index")||-1!==a.prop.indexOf("key"))for(;n;){if(n.owner.currentSubtype===Bp&&void 0!==(t=Pe(n,a)))return this.cached=n,n.registerIndexRef(this),this.callback(E("@"+a.prefix+t));n=!n.parent&&n.owner&&n.owner.component&&n.owner.component.parentFragment&&!n.owner.component.instance.isolated?n.owner.component.parentFragment:n.parent}else for(;n;){if(void 0!==(t=Pe(n,a)))return this.callback(E("@"+a.prefix+t.str));n=n.parent}},unbind:function(){this.cached&&this.cached.unregisterIndexRef(this)}};var Cc=Ec,Pc=function(t,e,n){this.parentFragment=t.parentFragment,this.ref=e,this.callback=n,e.ref.fragment.registerIndexRef(this),this.rebind()};Pc.prototype={rebind:function(){var t,e=this.ref.ref;t="k"===e.ref.t?"k"+e.fragment.key:"i"+e.fragment.index,void 0!==t&&this.callback(E("@"+t))},unbind:function(){this.ref.ref.fragment.unregisterIndexRef(this)}};var Ac=Pc,Oc=Ae;Ae.resolve=function(t){var e,n,a={};for(e in t.refs)n=t.refs[e],a[n.ref.n]="k"===n.ref.t?n.fragment.key:n.fragment.index;return a};var Tc,Mc=Oe,Rc=Te,jc={},Lc=Function.prototype.bind;Tc=function(t,e,n,a){var r,i=this;r=t.root,this.root=r,this.parentFragment=e,this.callback=a,this.owner=t,this.str=n.s,this.keypaths=[],this.pending=n.r.length,this.refResolvers=n.r.map(function(t,e){return Mc(i,t,function(t){i.resolve(e,t)})}),this.ready=!0,this.bubble()},Tc.prototype={bubble:function(){this.ready&&(this.uniqueString=Re(this.str,this.keypaths),this.keypath=je(this.uniqueString),this.createEvaluator(),this.callback(this.keypath))},unbind:function(){for(var t;t=this.refResolvers.pop();)t.unbind()},resolve:function(t,e){this.keypaths[t]=e,this.bubble()},createEvaluator:function(){var t,e,n,a,r,i=this;a=this.keypath,t=this.root.viewmodel.computations[a.str],t?this.root.viewmodel.mark(a):(r=Rc(this.str,this.refResolvers.length),e=this.keypaths.map(function(t){var e;return"undefined"===t?function(){}:t.isSpecial?(e=t.value,function(){return e}):function(){var e=i.root.viewmodel.get(t,{noUnwrap:!0,fullRootGet:!0});return"function"==typeof e&&(e=De(e,i.root)),e}}),n={deps:this.keypaths.filter(Le),getter:function(){var t=e.map(Me);return r.apply(null,t)}},t=this.root.viewmodel.compute(a,n))},rebind:function(t,e){this.refResolvers.forEach(function(n){return n.rebind(t,e)})}};var Dc=Tc,Nc=function(t,e,n){var a=this;this.resolver=e,this.root=e.root,this.parentFragment=n,this.viewmodel=e.root.viewmodel,"string"==typeof t?this.value=t:t.t===Np?this.refResolver=Mc(this,t.n,function(t){a.resolve(t)}):new Dc(e,n,t,function(t){a.resolve(t)})};Nc.prototype={resolve:function(t){this.keypath&&this.viewmodel.unregister(this.keypath,this),this.keypath=t,this.value=this.viewmodel.get(t),this.bind(),this.resolver.bubble()},bind:function(){this.viewmodel.register(this.keypath,this)},rebind:function(t,e){this.refResolver&&this.refResolver.rebind(t,e)},setValue:function(t){this.value=t,this.resolver.bubble()},unbind:function(){this.keypath&&this.viewmodel.unregister(this.keypath,this),this.refResolver&&this.refResolver.unbind()},forceResolution:function(){this.refResolver&&this.refResolver.forceResolution()}};var Fc=Nc,Ic=function(t,e,n){var a,r,i,o,s=this;this.parentFragment=o=t.parentFragment,this.root=a=t.root,this.mustache=t,this.ref=r=e.r,this.callback=n,this.unresolved=[],(i=ls(a,r,o))?this.base=i:this.baseResolver=new kc(this,r,function(t){s.base=t,s.baseResolver=null,s.bubble()}),this.members=e.m.map(function(t){return new Fc(t,s,o)}),this.ready=!0,this.bubble()};Ic.prototype={getKeypath:function(){var t=this.members.map(Ne);return!t.every(Fe)||this.baseResolver?null:this.base.join(t.join("."))},bubble:function(){this.ready&&!this.baseResolver&&this.callback(this.getKeypath())},unbind:function(){this.members.forEach(K)},rebind:function(t,e){var n;if(this.base){var a=this.base.replace(t,e);a&&a!==this.base&&(this.base=a,n=!0)}this.members.forEach(function(a){a.rebind(t,e)&&(n=!0)}),n&&this.bubble()},forceResolution:function(){this.baseResolver&&(this.base=E(this.ref),this.baseResolver.unbind(),this.baseResolver=null),this.members.forEach(Ie),this.bubble()}};var Bc=Ic,qc=Be,Uc=qe,Gc=Ue,Vc={getValue:_c,init:qc,resolve:Uc,rebind:Gc},zc=function(t){this.type=Ep,Vc.init(this,t)};zc.prototype={update:function(){this.node.data=void 0==this.value?"":this.value},resolve:Vc.resolve,rebind:Vc.rebind,detach:gc,unbind:xc,render:function(){return this.node||(this.node=document.createTextNode(n(this.value))),this.node},unrender:function(t){t&&e(this.node)},getValue:Vc.getValue,setValue:function(t){var e;this.keypath&&(e=this.root.viewmodel.wrapped[this.keypath.str])&&(t=e.get()),s(t,this.value)||(this.value=t,this.parentFragment.bubble(),this.node&&bs.addView(this))},firstNode:function(){return this.node},toString:function(t){var e=""+n(this.value);return t?Ee(e):e}};var Wc=zc,Hc=Ge,Kc=Ve,Qc=ze,$c=We,Yc=He,Jc=Ke,Xc=Qe,Zc=$e,tl=Ye,el=function(t,e){Vc.rebind.call(this,t,e)},nl=Xe,al=Ze,rl=ln,il=fn,ol=dn,sl=vn,ul=function(t){this.type=Cp,this.subtype=this.currentSubtype=t.template.n,this.inverted=this.subtype===Ip,this.pElement=t.pElement,this.fragments=[],this.fragmentsToCreate=[],this.fragmentsToRender=[],this.fragmentsToUnrender=[],t.template.i&&(this.indexRefs=t.template.i.split(",").map(function(t,e){return{n:t,t:0===e?"k":"i"}})),this.renderedFragments=[],this.length=0,Vc.init(this,t)};ul.prototype={bubble:Hc,detach:Kc,find:Qc,findAll:$c,findAllComponents:Yc,findComponent:Jc,findNextNode:Xc,firstNode:Zc,getIndexRef:function(t){if(this.indexRefs)for(var e=this.indexRefs.length;e--;){var n=this.indexRefs[e];if(n.n===t)return n}},getValue:Vc.getValue,shuffle:tl,rebind:el,render:nl,resolve:Vc.resolve,setValue:al,toString:rl,unbind:il,unrender:ol,update:sl};var pl,cl,ll=ul,fl=gn,dl=bn,hl=yn,ml=xn,vl={};try{co("table").innerHTML="foo"}catch(Ao){pl=!0,cl={TABLE:['',"
"],THEAD:['',"
"],TBODY:['',"
"],TR:['',"
"],SELECT:['"]}}var gl=function(t,e,n){var a,r,i,o,s,u=[];if(null!=t&&""!==t){for(pl&&(r=cl[e.tagName])?(a=_n("DIV"),a.innerHTML=r[0]+t+r[1],a=a.querySelector(".x"),"SELECT"===a.tagName&&(i=a.options[a.selectedIndex])):e.namespaceURI===no.svg?(a=_n("DIV"),a.innerHTML=''+t+"",a=a.querySelector(".x")):(a=_n(e.tagName),a.innerHTML=t,"SELECT"===a.tagName&&(i=a.options[a.selectedIndex]));o=a.firstChild;)u.push(o),n.appendChild(o);if("SELECT"===e.tagName)for(s=u.length;s--;)u[s]!==i&&(u[s].selected=!1)}return u},bl=wn,yl=En,xl=Sn,_l=Cn,wl=Pn,kl=An,El=function(t){this.type=Sp,Vc.init(this,t)};El.prototype={detach:fl,find:dl,findAll:hl,firstNode:ml,getValue:Vc.getValue,rebind:Vc.rebind,render:yl,resolve:Vc.resolve,setValue:xl,toString:_l,unbind:xc,unrender:wl,update:kl};var Sl,Cl,Pl,Al,Ol=El,Tl=function(){this.parentFragment.bubble()},Ml=On,Rl=function(t){return this.node?lo(this.node,t)?this.node:this.fragment&&this.fragment.find?this.fragment.find(t):void 0:null},jl=function(t,e){e._test(this,!0)&&e.live&&(this.liveQueries||(this.liveQueries=[])).push(e),this.fragment&&this.fragment.findAll(t,e)},Ll=function(t,e){this.fragment&&this.fragment.findAllComponents(t,e)},Dl=function(t){return this.fragment?this.fragment.findComponent(t):void 0},Nl=Tn,Fl=Mn,Il=Rn,Bl=/^true|on|yes|1$/i,ql=/^[0-9]+$/,Ul=function(t,e){var n,a,r;return r=e.a||{},a={},n=r.twoway,void 0!==n&&(a.twoway=0===n||Bl.test(n)),n=r.lazy,void 0!==n&&(0!==n&&ql.test(n)?a.lazy=parseInt(n):a.lazy=0===n||Bl.test(n)),a},Gl=jn;Sl="altGlyph altGlyphDef altGlyphItem animateColor animateMotion animateTransform clipPath feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence foreignObject glyphRef linearGradient radialGradient textPath vkern".split(" "),Cl="attributeName attributeType baseFrequency baseProfile calcMode clipPathUnits contentScriptType contentStyleType diffuseConstant edgeMode externalResourcesRequired filterRes filterUnits glyphRef gradientTransform gradientUnits kernelMatrix kernelUnitLength keyPoints keySplines keyTimes lengthAdjust limitingConeAngle markerHeight markerUnits markerWidth maskContentUnits maskUnits numOctaves pathLength patternContentUnits patternTransform patternUnits pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits refX refY repeatCount repeatDur requiredExtensions requiredFeatures specularConstant specularExponent spreadMethod startOffset stdDeviation stitchTiles surfaceScale systemLanguage tableValues targetX targetY textLength viewBox viewTarget xChannelSelector yChannelSelector zoomAndPan".split(" "),Pl=function(t){for(var e={},n=t.length;n--;)e[t[n].toLowerCase()]=t[n];return e},Al=Pl(Sl.concat(Cl));var Vl=function(t){var e=t.toLowerCase();return Al[e]||e},zl=function(t,e){var n,a;if(n=e.indexOf(":"),-1===n||(a=e.substr(0,n),"xmlns"===a))t.name=t.element.namespace!==no.html?Vl(e):e;else if(e=e.substring(n+1),t.name=Vl(e),t.namespace=no[a.toLowerCase()],t.namespacePrefix=a,!t.namespace)throw'Unknown namespace ("'+a+'")'},Wl=Ln,Hl=Dn,Kl=Nn,Ql=Fn,$l={"accept-charset":"acceptCharset",accesskey:"accessKey",bgcolor:"bgColor","class":"className",codebase:"codeBase",colspan:"colSpan",contenteditable:"contentEditable",datetime:"dateTime",dirname:"dirName","for":"htmlFor","http-equiv":"httpEquiv",ismap:"isMap",maxlength:"maxLength",novalidate:"noValidate",pubdate:"pubDate",readonly:"readOnly",rowspan:"rowSpan",tabindex:"tabIndex",usemap:"useMap"},Yl=In,Jl=qn,Xl=Un,Zl=Gn,tf=Vn,ef=zn,nf=Wn,af=Hn,rf=Kn,of=Qn,sf=$n,uf=Yn,pf=Jn,cf=Xn,lf=Zn,ff=function(t){this.init(t)};ff.prototype={bubble:Gl,init:Hl,rebind:Kl,render:Ql,toString:Yl,unbind:Jl,update:lf};var df,hf=ff,mf=function(t,e){var n,a,r=[];for(n in e)"twoway"!==n&&"lazy"!==n&&e.hasOwnProperty(n)&&(a=new hf({element:t,name:n,value:e[n],root:t.root}),r[n]=a,"value"!==n&&r.push(a));return(a=r.value)&&r.push(a),r};"undefined"!=typeof document&&(df=co("div"));var vf=function(t,e){this.element=t,this.root=t.root,this.parentFragment=t.parentFragment,this.attributes=[],this.fragment=new rv({root:t.root,owner:this,template:[e]})};vf.prototype={bubble:function(){this.node&&this.update(),this.element.bubble()},rebind:function(t,e){this.fragment.rebind(t,e)},render:function(t){this.node=t,this.isSvg=t.namespaceURI===no.svg,this.update()},unbind:function(){this.fragment.unbind()},update:function(){var t,e,n=this;t=""+this.fragment,e=ta(t,this.isSvg),this.attributes.filter(function(t){return ea(e,t)}).forEach(function(t){n.node.removeAttribute(t.name)}),e.forEach(function(t){n.node.setAttribute(t.name,t.value)}),this.attributes=e},toString:function(){return""+this.fragment}};var gf=vf,bf=function(t,e){return e?e.map(function(e){return new gf(t,e)}):[]},yf=function(t){var e,n,a,r;if(this.element=t,this.root=t.root,this.attribute=t.attributes[this.name||"value"],e=this.attribute.interpolator,e.twowayBinding=this,n=e.keypath){if("}"===n.str.slice(-1))return v("Two-way binding does not work with expressions (`%s` on <%s>)",e.resolver.uniqueString,t.name,{ractive:this.root}),!1;if(n.isSpecial)return v("Two-way binding does not work with %s",e.resolver.ref,{ractive:this.root}),!1}else{var i=e.template.r?"'"+e.template.r+"' reference":"expression";m("The %s being used for two-way binding is ambiguous, and may cause unexpected results. Consider initialising your data to eliminate the ambiguity",i,{ractive:this.root}),e.resolver.forceResolution(),n=e.keypath}this.attribute.isTwoway=!0,this.keypath=n,a=this.root.viewmodel.get(n),void 0===a&&this.getInitialValue&&(a=this.getInitialValue(),void 0!==a&&this.root.viewmodel.set(n,a)),(r=na(t))&&(this.resetValue=a,r.formBindings.push(this))};yf.prototype={handleChange:function(){var t=this;bs.start(this.root),this.attribute.locked=!0,this.root.viewmodel.set(this.keypath,this.getValue()),bs.scheduleTask(function(){return t.attribute.locked=!1}),bs.end()},rebound:function(){var t,e,n;e=this.keypath,n=this.attribute.interpolator.keypath,e!==n&&(N(this.root._twowayBindings[e.str],this),this.keypath=n,t=this.root._twowayBindings[n.str]||(this.root._twowayBindings[n.str]=[]),t.push(this))},unbind:function(){}},yf.extend=function(t){var e,n=this;return e=function(t){yf.call(this,t),this.init&&this.init()},e.prototype=Eo(n.prototype),a(e.prototype,t),e.extend=yf.extend,e};var xf,_f=yf,wf=aa;xf=_f.extend({getInitialValue:function(){return""},getValue:function(){return this.element.node.value},render:function(){var t,e=this.element.node,n=!1;this.rendered=!0,t=this.root.lazy,this.element.lazy===!0?t=!0:this.element.lazy===!1?t=!1:u(this.element.lazy)?(t=!1,n=+this.element.lazy):u(t||"")&&(n=+t,t=!1,this.element.lazy=n),this.handler=n?ia:wf,e.addEventListener("change",wf,!1),t||(e.addEventListener("input",this.handler,!1),e.attachEvent&&e.addEventListener("keyup",this.handler,!1)),e.addEventListener("blur",ra,!1)},unrender:function(){var t=this.element.node;this.rendered=!1,t.removeEventListener("change",wf,!1),t.removeEventListener("input",this.handler,!1),t.removeEventListener("keyup",this.handler,!1),t.removeEventListener("blur",ra,!1)}});var kf=xf,Ef=kf.extend({getInitialValue:function(){return this.element.fragment?""+this.element.fragment:""},getValue:function(){return this.element.node.innerHTML}}),Sf=Ef,Cf=oa,Pf={},Af=_f.extend({name:"checked",init:function(){this.siblings=Cf(this.root._guid,"radio",this.element.getAttribute("name")),this.siblings.push(this)},render:function(){var t=this.element.node;t.addEventListener("change",wf,!1),t.attachEvent&&t.addEventListener("click",wf,!1)},unrender:function(){var t=this.element.node;t.removeEventListener("change",wf,!1),t.removeEventListener("click",wf,!1)},handleChange:function(){bs.start(this.root),this.siblings.forEach(function(t){t.root.viewmodel.set(t.keypath,t.getValue())}),bs.end()},getValue:function(){return this.element.node.checked},unbind:function(){N(this.siblings,this)}}),Of=Af,Tf=_f.extend({name:"name",init:function(){this.siblings=Cf(this.root._guid,"radioname",this.keypath.str),this.siblings.push(this),this.radioName=!0},getInitialValue:function(){return this.element.getAttribute("checked")?this.element.getAttribute("value"):void 0},render:function(){var t=this.element.node;t.name="{{"+this.keypath.str+"}}",t.checked=this.root.viewmodel.get(this.keypath)==this.element.getAttribute("value"),t.addEventListener("change",wf,!1),t.attachEvent&&t.addEventListener("click",wf,!1)},unrender:function(){var t=this.element.node;t.removeEventListener("change",wf,!1),t.removeEventListener("click",wf,!1)},getValue:function(){var t=this.element.node;return t._ractive?t._ractive.value:t.value},handleChange:function(){this.element.node.checked&&_f.prototype.handleChange.call(this)},rebound:function(t,e){var n;_f.prototype.rebound.call(this,t,e),(n=this.element.node)&&(n.name="{{"+this.keypath.str+"}}")},unbind:function(){N(this.siblings,this)}}),Mf=Tf,Rf=_f.extend({name:"name",getInitialValue:function(){return this.noInitialValue=!0,[]},init:function(){var t,e;this.checkboxName=!0,this.siblings=Cf(this.root._guid,"checkboxes",this.keypath.str),this.siblings.push(this),this.noInitialValue&&(this.siblings.noInitialValue=!0),this.siblings.noInitialValue&&this.element.getAttribute("checked")&&(t=this.root.viewmodel.get(this.keypath),e=this.element.getAttribute("value"),t.push(e))},unbind:function(){N(this.siblings,this)},render:function(){var t,e,n=this.element.node;t=this.root.viewmodel.get(this.keypath),e=this.element.getAttribute("value"),i(t)?this.isChecked=R(t,e):this.isChecked=t==e,n.name="{{"+this.keypath.str+"}}",n.checked=this.isChecked,n.addEventListener("change",wf,!1),n.attachEvent&&n.addEventListener("click",wf,!1)},unrender:function(){var t=this.element.node;t.removeEventListener("change",wf,!1),t.removeEventListener("click",wf,!1)},changed:function(){var t=!!this.isChecked;return this.isChecked=this.element.node.checked,this.isChecked===t},handleChange:function(){this.isChecked=this.element.node.checked,_f.prototype.handleChange.call(this)},getValue:function(){return this.siblings.filter(sa).map(ua)}}),jf=Rf,Lf=_f.extend({name:"checked",render:function(){var t=this.element.node;t.addEventListener("change",wf,!1),t.attachEvent&&t.addEventListener("click",wf,!1)},unrender:function(){var t=this.element.node;t.removeEventListener("change",wf,!1),t.removeEventListener("click",wf,!1)},getValue:function(){return this.element.node.checked}}),Df=Lf,Nf=_f.extend({getInitialValue:function(){var t,e,n,a,r=this.element.options;if(void 0===this.element.getAttribute("value")&&(e=t=r.length,t)){for(;e--;)if(r[e].getAttribute("selected")){n=r[e].getAttribute("value"),a=!0;break}if(!a)for(;++ee;e+=1)if(a=t[e],t[e].selected)return r=a._ractive?a._ractive.value:a.value},forceUpdate:function(){var t=this,e=this.getValue();void 0!==e&&(this.attribute.locked=!0,bs.scheduleTask(function(){return t.attribute.locked=!1}),this.root.viewmodel.set(this.keypath,e))}}),Ff=Nf,If=Ff.extend({getInitialValue:function(){return this.element.options.filter(function(t){return t.getAttribute("selected")}).map(function(t){return t.getAttribute("value")})},render:function(){var t;this.element.node.addEventListener("change",wf,!1),t=this.root.viewmodel.get(this.keypath),void 0===t&&this.handleChange()},unrender:function(){this.element.node.removeEventListener("change",wf,!1)},setValue:function(){throw Error("TODO not implemented yet")},getValue:function(){var t,e,n,a,r,i;for(t=[],e=this.element.node.options,a=e.length,n=0;a>n;n+=1)r=e[n],r.selected&&(i=r._ractive?r._ractive.value:r.value,t.push(i));return t},handleChange:function(){var t,e,n;return t=this.attribute,e=t.value,n=this.getValue(),void 0!==e&&j(n,e)||Ff.prototype.handleChange.call(this),this},forceUpdate:function(){var t=this,e=this.getValue();void 0!==e&&(this.attribute.locked=!0,bs.scheduleTask(function(){return t.attribute.locked=!1}),this.root.viewmodel.set(this.keypath,e))},updateModel:function(){void 0!==this.attribute.value&&this.attribute.value.length||this.root.viewmodel.set(this.keypath,this.initialValue)}}),Bf=If,qf=_f.extend({render:function(){this.element.node.addEventListener("change",wf,!1)},unrender:function(){this.element.node.removeEventListener("change",wf,!1)},getValue:function(){return this.element.node.files}}),Uf=qf,Gf=kf.extend({getInitialValue:function(){},getValue:function(){var t=parseFloat(this.element.node.value);return isNaN(t)?void 0:t}}),Vf=pa,zf=la,Wf=fa,Hf=da,Kf=ha,Qf=/^event(?:\.(.+))?/,$f=ba,Yf=ya,Jf={},Xf={touchstart:!0,touchmove:!0,touchend:!0,touchcancel:!0,touchleave:!0},Zf=_a,td=wa,ed=ka,nd=Ea,ad=Sa,rd=function(t,e,n){this.init(t,e,n)};rd.prototype={bubble:zf,fire:Wf,getAction:Hf,init:Kf,listen:Yf,rebind:Zf,render:td,resolve:ed,unbind:nd,unrender:ad};var id=rd,od=function(t,e){var n,a,r,i,o=[];for(a in e)if(e.hasOwnProperty(a))for(r=a.split("-"),n=r.length;n--;)i=new id(t,r[n],e[a]),o.push(i);return o},sd=function(t,e){var n,a,r,i=this;this.element=t,this.root=n=t.root,a=e.n||e,("string"==typeof a||(r=new rv({template:a,root:n,owner:t}),a=""+r,r.unbind(),""!==a))&&(e.a?this.params=e.a:e.d&&(this.fragment=new rv({template:e.d,root:n,owner:t}),this.params=this.fragment.getArgsList(),this.fragment.bubble=function(){this.dirtyArgs=this.dirtyValue=!0,i.params=this.getArgsList(),i.ready&&i.update()}),this.fn=g("decorators",n,a),this.fn||l(Io(a,"decorator")))};sd.prototype={init:function(){var t,e,n;if(t=this.element.node,this.params?(n=[t].concat(this.params),e=this.fn.apply(this.root,n)):e=this.fn.call(this.root,t),!e||!e.teardown)throw Error("Decorator definition must return an object with a teardown method");this.actual=e,this.ready=!0},update:function(){this.actual.update?this.actual.update.apply(this.root,this.params):(this.actual.teardown(!0),this.init())},rebind:function(t,e){this.fragment&&this.fragment.rebind(t,e)},teardown:function(t){this.torndown=!0,this.ready&&this.actual.teardown(),!t&&this.fragment&&this.fragment.unbind()}};var ud,pd,cd,ld=sd,fd=Ra,dd=ja,hd=Ba,md=function(t){return t.replace(/-([a-zA-Z])/g,function(t,e){return e.toUpperCase()})};Xi?(pd={},cd=co("div").style,ud=function(t){var e,n,a;if(t=md(t),!pd[t])if(void 0!==cd[t])pd[t]=t;else for(a=t.charAt(0).toUpperCase()+t.substring(1),e=ro.length;e--;)if(n=ro[e],void 0!==cd[n+a]){pd[t]=n+a;break}return pd[t]}):ud=null;var vd,gd,bd=ud;Xi?(gd=window.getComputedStyle||Po.getComputedStyle,vd=function(t){var e,n,a,r,o;if(e=gd(this.node),"string"==typeof t)return o=e[bd(t)],"0px"===o&&(o=0),o;if(!i(t))throw Error("Transition$getStyle must be passed a string, or an array of strings representing CSS properties");for(n={},a=t.length;a--;)r=t[a],o=e[bd(r)],"0px"===o&&(o=0),n[r]=o;return n}):vd=null;var yd=vd,xd=function(t,e){var n;if("string"==typeof t)this.node.style[bd(t)]=e;else for(n in t)t.hasOwnProperty(n)&&(this.node.style[bd(n)]=t[n]);return this},_d=function(t){var e;this.duration=t.duration,this.step=t.step,this.complete=t.complete,"string"==typeof t.easing?(e=t.root.easing[t.easing],e||(v(Io(t.easing,"easing")),e=qa)):e="function"==typeof t.easing?t.easing:qa,this.easing=e,this.start=ns(),this.end=this.start+this.duration,this.running=!0,_s.add(this)};_d.prototype={tick:function(t){var e,n;return this.running?t>this.end?(this.step&&this.step(1),this.complete&&this.complete(1),!1):(e=t-this.start,n=this.easing(e/this.duration),this.step&&this.step(n),!0):!1},stop:function(){this.abort&&this.abort(),this.running=!1}};var wd,kd,Ed,Sd,Cd,Pd,Ad,Od,Td=_d,Md=RegExp("^-(?:"+ro.join("|")+")-"),Rd=function(t){return t.replace(Md,"")},jd=RegExp("^(?:"+ro.join("|")+")([A-Z])"),Ld=function(t){var e;return t?(jd.test(t)&&(t="-"+t),e=t.replace(/[A-Z]/g,function(t){return"-"+t.toLowerCase()})):""},Dd={},Nd={};Xi?(kd=co("div").style,function(){void 0!==kd.transition?(Ed="transition",Sd="transitionend",Cd=!0):void 0!==kd.webkitTransition?(Ed="webkitTransition",Sd="webkitTransitionEnd",Cd=!0):Cd=!1}(),Ed&&(Pd=Ed+"Duration",Ad=Ed+"Property",Od=Ed+"TimingFunction"),wd=function(t,e,n,a,r){setTimeout(function(){var i,o,s,u,p;u=function(){o&&s&&(t.root.fire(t.name+":end",t.node,t.isIntro),r())},i=(t.node.namespaceURI||"")+t.node.tagName,t.node.style[Ad]=a.map(bd).map(Ld).join(","),t.node.style[Od]=Ld(n.easing||"linear"),t.node.style[Pd]=n.duration/1e3+"s",p=function(e){var n;n=a.indexOf(md(Rd(e.propertyName))),-1!==n&&a.splice(n,1),a.length||(t.node.removeEventListener(Sd,p,!1),s=!0,u())},t.node.addEventListener(Sd,p,!1),setTimeout(function(){for(var r,c,l,f,d,h=a.length,v=[];h--;)f=a[h],r=i+f,Cd&&!Nd[r]&&(t.node.style[bd(f)]=e[f],Dd[r]||(c=t.getStyle(f),Dd[r]=t.getStyle(f)!=e[f],Nd[r]=!Dd[r],Nd[r]&&(t.node.style[bd(f)]=c))),(!Cd||Nd[r])&&(void 0===c&&(c=t.getStyle(f)),l=a.indexOf(f),-1===l?m("Something very strange happened with transitions. Please raise an issue at https://github.com/ractivejs/ractive/issues - thanks!",{node:t.node}):a.splice(l,1),d=/[^\d]*$/.exec(e[f])[0],v.push({name:bd(f),interpolator:qo(parseFloat(c),parseFloat(e[f])),suffix:d}));v.length?new Td({root:t.root,duration:n.duration,easing:md(n.easing||""),step:function(e){var n,a;for(a=v.length;a--;)n=v[a],t.node.style[n.name]=n.interpolator(e)+n.suffix},complete:function(){o=!0,u()}}):o=!0,a.length||(t.node.removeEventListener(Sd,p,!1),s=!0,u())},0)},n.delay||0)}):wd=null;var Fd,Id,Bd,qd,Ud,Gd=wd;if("undefined"!=typeof document){if(Fd="hidden",Ud={},Fd in document)Bd="";else for(qd=ro.length;qd--;)Id=ro[qd],Fd=Id+"Hidden",Fd in document&&(Bd=Id);void 0!==Bd?(document.addEventListener(Bd+"visibilitychange",Ua),Ua()):("onfocusout"in document?(document.addEventListener("focusout",Ga),document.addEventListener("focusin",Va)):(window.addEventListener("pagehide",Ga),window.addEventListener("blur",Ga),window.addEventListener("pageshow",Va),window.addEventListener("focus",Va)),Ud.hidden=!1)}var Vd,zd,Wd,Hd=Ud;Xi?(zd=window.getComputedStyle||Po.getComputedStyle,Vd=function(t,e,n){var a,r=this;if(4===arguments.length)throw Error("t.animateStyle() returns a promise - use .then() instead of passing a callback");if(Hd.hidden)return this.setStyle(t,e),Wd||(Wd=ps.resolve());"string"==typeof t?(a={},a[t]=e):(a=t,n=e),n||(v('The "%s" transition does not supply an options object to `t.animateStyle()`. This will break in a future version of Ractive. For more info see https://github.com/RactiveJS/Ractive/issues/340',this.name),n=this);var i=new ps(function(t){var e,i,o,s,u,p,c;if(!n.duration)return r.setStyle(a),void t();for(e=Object.keys(a),i=[],o=zd(r.node),u={},p=e.length;p--;)c=e[p],s=o[bd(c)],"0px"===s&&(s=0),s!=a[c]&&(i.push(c),r.node.style[bd(c)]=s);return i.length?void Gd(r,a,n,i,t):void t()});return i}):Vd=null;var Kd=Vd,Qd=function(t,e){return"number"==typeof t?t={duration:t}:"string"==typeof t?t="slow"===t?{duration:600}:"fast"===t?{duration:200}:{duration:400}:t||(t={}),r({},t,e)},$d=za,Yd=function(t,e,n){this.init(t,e,n)};Yd.prototype={init:hd,start:$d,getStyle:yd,setStyle:xd,animateStyle:Kd,processParams:Qd};var Jd,Xd,Zd=Yd,th=Ha;Jd=function(){var t=this.node,e=this.fragment.toString(!1);if(window&&window.appearsToBeIELessEqual8&&(t.type="text/css"),t.styleSheet)t.styleSheet.cssText=e;else{for(;t.hasChildNodes();)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(e))}},Xd=function(){this.node.type&&"text/javascript"!==this.node.type||m("Script tag was updated. This does not cause the code to be re-evaluated!",{ractive:this.root}),this.node.text=this.fragment.toString(!1)};var eh=function(){var t,e;return this.template.y?"":(t="<"+this.template.e,t+=this.attributes.map(Xa).join("")+this.conditionalAttributes.map(Xa).join(""),"option"===this.name&&Ya(this)&&(t+=" selected"),"input"===this.name&&Ja(this)&&(t+=" checked"),t+=">","textarea"===this.name&&void 0!==this.getAttribute("value")?t+=Ee(this.getAttribute("value")):void 0!==this.getAttribute("contenteditable")&&(t+=this.getAttribute("value")||""),this.fragment&&(e="script"!==this.name&&"style"!==this.name,t+=this.fragment.toString(e)),ic.test(this.template.e)||(t+=""),t)},nh=Za,ah=tr,rh=function(t){this.init(t)};rh.prototype={bubble:Tl,detach:Ml,find:Rl,findAll:jl,findAllComponents:Ll,findComponent:Dl,findNextNode:Nl,firstNode:Fl,getAttribute:Il,init:fd,rebind:dd,render:th,toString:eh,unbind:nh,unrender:ah};var ih=rh,oh=/^\s*$/,sh=/^\s*/,uh=function(t){var e,n,a,r;return e=t.split("\n"),n=e[0],void 0!==n&&oh.test(n)&&e.shift(),a=D(e),void 0!==a&&oh.test(a)&&e.pop(),r=e.reduce(nr,null),r&&(t=e.map(function(t){return t.replace(r,"")}).join("\n")),t},ph=ar,ch=function(t,e){var n;return e?n=t.split("\n").map(function(t,n){return n?e+t:t}).join("\n"):t},lh='Could not find template for partial "%s"',fh=function(t){var e,n;e=this.parentFragment=t.parentFragment,this.root=e.root,this.type=Ap,this.index=t.index,this.name=t.template.r,this.rendered=!1,this.fragment=this.fragmentToRender=this.fragmentToUnrender=null,Vc.init(this,t),this.keypath||((n=ph(this.root,this.name,e))?(xc.call(this),this.isNamed=!0,this.setTemplate(n)):v(lh,this.name))};fh.prototype={bubble:function(){this.parentFragment.bubble()},detach:function(){return this.fragment.detach()},find:function(t){return this.fragment.find(t)},findAll:function(t,e){return this.fragment.findAll(t,e)},findComponent:function(t){return this.fragment.findComponent(t)},findAllComponents:function(t,e){return this.fragment.findAllComponents(t,e)},firstNode:function(){return this.fragment.firstNode()},findNextNode:function(){return this.parentFragment.findNextNode(this)},getPartialName:function(){return this.isNamed&&this.name?this.name:void 0===this.value?this.name:this.value},getValue:function(){return this.fragment.getValue()},rebind:function(t,e){this.isNamed||Gc.call(this,t,e),this.fragment&&this.fragment.rebind(t,e)},render:function(){return this.docFrag=document.createDocumentFragment(),this.update(),this.rendered=!0,this.docFrag},resolve:Vc.resolve,setValue:function(t){var e;(void 0===t||t!==this.value)&&(void 0!==t&&(e=ph(this.root,""+t,this.parentFragment)),!e&&this.name&&(e=ph(this.root,this.name,this.parentFragment))&&(xc.call(this),this.isNamed=!0),e||v(lh,this.name,{ractive:this.root}),this.value=t,this.setTemplate(e||[]),this.bubble(),this.rendered&&bs.addView(this))},setTemplate:function(t){this.fragment&&(this.fragment.unbind(),this.rendered&&(this.fragmentToUnrender=this.fragment)),this.fragment=new rv({template:t,root:this.root,owner:this,pElement:this.parentFragment.pElement}),this.fragmentToRender=this.fragment},toString:function(t){var e,n,a,r;return e=this.fragment.toString(t),n=this.parentFragment.items[this.index-1],n&&n.type===kp?(a=n.text.split("\n").pop(),(r=/^\s+$/.exec(a))?ch(e,r[0]):e):e},unbind:function(){this.isNamed||xc.call(this),this.fragment&&this.fragment.unbind()},unrender:function(t){this.rendered&&(this.fragment&&this.fragment.unrender(t),this.rendered=!1)},update:function(){var t,e;this.fragmentToUnrender&&(this.fragmentToUnrender.unrender(!0),this.fragmentToUnrender=null),this.fragmentToRender&&(this.docFrag.appendChild(this.fragmentToRender.render()),this.fragmentToRender=null), - this.rendered&&(t=this.parentFragment.getNode(),e=this.parentFragment.findNextNode(this),t.insertBefore(this.docFrag,e))}};var dh,hh,mh,vh=fh,gh=ur,bh=pr,yh=new is("detach"),xh=cr,_h=lr,wh=fr,kh=dr,Eh=hr,Sh=mr,Ch=function(t,e,n,a){var r=t.root,i=t.keypath;a?r.viewmodel.smartUpdate(i,e,a):r.viewmodel.mark(i)},Ph=[],Ah=["pop","push","reverse","shift","sort","splice","unshift"];Ah.forEach(function(t){var e=function(){for(var e=arguments.length,n=Array(e),a=0;e>a;a++)n[a]=arguments[a];var r,i,o,s;for(r=bu(this,t,n),i=Array.prototype[t].apply(this,arguments),bs.start(),this._ractive.setting=!0,s=this._ractive.wrappers.length;s--;)o=this._ractive.wrappers[s],bs.addRactive(o.root),Ch(o,this,t,r);return bs.end(),this._ractive.setting=!1,i};So(Ph,t,{value:e})}),dh={},dh.__proto__?(hh=function(t){t.__proto__=Ph},mh=function(t){t.__proto__=Array.prototype}):(hh=function(t){var e,n;for(e=Ah.length;e--;)n=Ah[e],So(t,n,{value:Ph[n],configurable:!0})},mh=function(t){var e;for(e=Ah.length;e--;)delete t[Ah[e]]}),hh.unpatch=mh;var Oh,Th,Mh,Rh=hh;Oh={filter:function(t){return i(t)&&(!t._ractive||!t._ractive.setting)},wrap:function(t,e,n){return new Th(t,e,n)}},Th=function(t,e,n){this.root=t,this.value=e,this.keypath=E(n),e._ractive||(So(e,"_ractive",{value:{wrappers:[],instances:[],setting:!1},configurable:!0}),Rh(e)),e._ractive.instances[t._guid]||(e._ractive.instances[t._guid]=0,e._ractive.instances.push(t)),e._ractive.instances[t._guid]+=1,e._ractive.wrappers.push(this)},Th.prototype={get:function(){return this.value},teardown:function(){var t,e,n,a,r;if(t=this.value,e=t._ractive,n=e.wrappers,a=e.instances,e.setting)return!1;if(r=n.indexOf(this),-1===r)throw Error(Mh);if(n.splice(r,1),n.length){if(a[this.root._guid]-=1,!a[this.root._guid]){if(r=a.indexOf(this.root),-1===r)throw Error(Mh);a.splice(r,1)}}else delete t._ractive,Rh.unpatch(this.value)}},Mh="Something went wrong in a rather interesting way";var jh,Lh,Dh=Oh,Nh=/^\s*[0-9]+\s*$/,Fh=function(t){return Nh.test(t)?[]:{}};try{Object.defineProperty({},"test",{value:0}),jh={filter:function(t,e,n){var a,r;return e?(e=E(e),(a=n.viewmodel.wrapped[e.parent.str])&&!a.magic?!1:(r=n.viewmodel.get(e.parent),i(r)&&/^[0-9]+$/.test(e.lastKey)?!1:r&&("object"==typeof r||"function"==typeof r))):!1},wrap:function(t,e,n){return new Lh(t,e,n)}},Lh=function(t,e,n){var a,r,i;return n=E(n),this.magic=!0,this.ractive=t,this.keypath=n,this.value=e,this.prop=n.lastKey,a=n.parent,this.obj=a.isRoot?t.viewmodel.data:t.viewmodel.get(a),r=this.originalDescriptor=Object.getOwnPropertyDescriptor(this.obj,this.prop),r&&r.set&&(i=r.set._ractiveWrappers)?void(-1===i.indexOf(this)&&i.push(this)):void vr(this,e,r)},Lh.prototype={get:function(){return this.value},reset:function(t){return this.updating?void 0:(this.updating=!0,this.obj[this.prop]=t,bs.addRactive(this.ractive),this.ractive.viewmodel.mark(this.keypath,{keepExistingWrapper:!0}),this.updating=!1,!0)},set:function(t,e){this.updating||(this.obj[this.prop]||(this.updating=!0,this.obj[this.prop]=Fh(t),this.updating=!1),this.obj[this.prop][t]=e)},teardown:function(){var t,e,n,a,r;return this.updating?!1:(t=Object.getOwnPropertyDescriptor(this.obj,this.prop),e=t&&t.set,void(e&&(a=e._ractiveWrappers,r=a.indexOf(this),-1!==r&&a.splice(r,1),a.length||(n=this.obj[this.prop],Object.defineProperty(this.obj,this.prop,this.originalDescriptor||{writable:!0,enumerable:!0,configurable:!0}),this.obj[this.prop]=n))))}}}catch(Ao){jh=!1}var Ih,Bh,qh=jh;qh&&(Ih={filter:function(t,e,n){return qh.filter(t,e,n)&&Dh.filter(t)},wrap:function(t,e,n){return new Bh(t,e,n)}},Bh=function(t,e,n){this.value=e,this.magic=!0,this.magicWrapper=qh.wrap(t,e,n),this.arrayWrapper=Dh.wrap(t,e,n)},Bh.prototype={get:function(){return this.value},teardown:function(){this.arrayWrapper.teardown(),this.magicWrapper.teardown()},reset:function(t){return this.magicWrapper.reset(t)}});var Uh=Ih,Gh=gr,Vh={},zh=xr,Wh=_r,Hh=Er,Kh=Or,Qh=Tr,$h=function(t,e){this.computation=t,this.viewmodel=t.viewmodel,this.ref=e,this.root=this.viewmodel.ractive,this.parentFragment=this.root.component&&this.root.component.parentFragment};$h.prototype={resolve:function(t){this.computation.softDeps.push(t),this.computation.unresolvedDeps[t.str]=null,this.viewmodel.register(t,this.computation,"computed")}};var Yh=$h,Jh=function(t,e){this.key=t,this.getter=e.getter,this.setter=e.setter,this.hardDeps=e.deps||[],this.softDeps=[],this.unresolvedDeps={},this.depValues={},this._dirty=this._firstRun=!0};Jh.prototype={constructor:Jh,init:function(t){var e,n=this;this.viewmodel=t,this.bypass=!0,e=t.get(this.key),t.clearCache(this.key.str),this.bypass=!1,this.setter&&void 0!==e&&this.set(e),this.hardDeps&&this.hardDeps.forEach(function(e){return t.register(e,n,"computed")})},invalidate:function(){this._dirty=!0},get:function(){var t,e,n=this,a=!1;if(this.getting){var r="The "+this.key.str+" computation indirectly called itself. This probably indicates a bug in the computation. It is commonly caused by `array.sort(...)` - if that's the case, clone the array first with `array.slice().sort(...)`";return h(r),this.value}if(this.getting=!0,this._dirty){if(this._firstRun||!this.hardDeps.length&&!this.softDeps.length?a=!0:[this.hardDeps,this.softDeps].forEach(function(t){var e,r,i;if(!a)for(i=t.length;i--;)if(e=t[i],r=n.viewmodel.get(e),!s(r,n.depValues[e.str]))return n.depValues[e.str]=r,void(a=!0)}),a){this.viewmodel.capture();try{this.value=this.getter()}catch(i){m('Failed to compute "%s"',this.key.str),f(i.stack||i),this.value=void 0}t=this.viewmodel.release(),e=this.updateDependencies(t),e&&[this.hardDeps,this.softDeps].forEach(function(t){t.forEach(function(t){n.depValues[t.str]=n.viewmodel.get(t)})})}this._dirty=!1}return this.getting=this._firstRun=!1,this.value},set:function(t){if(this.setting)return void(this.value=t);if(!this.setter)throw Error("Computed properties without setters are read-only. (This may change in a future version of Ractive!)");this.setter(t)},updateDependencies:function(t){var e,n,a,r,i;for(n=this.softDeps,e=n.length;e--;)a=n[e],-1===t.indexOf(a)&&(r=!0,this.viewmodel.unregister(a,this,"computed"));for(e=t.length;e--;)a=t[e],-1!==n.indexOf(a)||this.hardDeps&&-1!==this.hardDeps.indexOf(a)||(r=!0,Mr(this.viewmodel,a)&&!this.unresolvedDeps[a.str]?(i=new Yh(this,a.str),t.splice(e,1),this.unresolvedDeps[a.str]=i,bs.addUnresolved(i)):this.viewmodel.register(a,this,"computed"));return r&&(this.softDeps=t.slice()),r}};var Xh=Jh,Zh=Rr,tm={FAILED_LOOKUP:!0},em=jr,nm={},am=Dr,rm=Nr,im=function(t,e){this.localKey=t,this.keypath=e.keypath,this.origin=e.origin,this.deps=[],this.unresolved=[],this.resolved=!1};im.prototype={forceResolution:function(){this.keypath=this.localKey,this.setup()},get:function(t,e){return this.resolved?this.origin.get(this.map(t),e):void 0},getValue:function(){return this.keypath?this.origin.get(this.keypath):void 0},initViewmodel:function(t){this.local=t,this.setup()},map:function(t){return void 0===typeof this.keypath?this.localKey:t.replace(this.localKey,this.keypath)},register:function(t,e,n){this.deps.push({keypath:t,dep:e,group:n}),this.resolved&&this.origin.register(this.map(t),e,n)},resolve:function(t){void 0!==this.keypath&&this.unbind(!0),this.keypath=t,this.setup()},set:function(t,e){this.resolved||this.forceResolution(),this.origin.set(this.map(t),e)},setup:function(){var t=this;void 0!==this.keypath&&(this.resolved=!0,this.deps.length&&(this.deps.forEach(function(e){var n=t.map(e.keypath);if(t.origin.register(n,e.dep,e.group),e.dep.setValue)e.dep.setValue(t.origin.get(n));else{if(!e.dep.invalidate)throw Error("An unexpected error occurred. Please raise an issue at https://github.com/ractivejs/ractive/issues - thanks!");e.dep.invalidate()}}),this.origin.mark(this.keypath)))},setValue:function(t){if(!this.keypath)throw Error("Mapping does not have keypath, cannot set value. Please raise an issue at https://github.com/ractivejs/ractive/issues - thanks!");this.origin.set(this.keypath,t)},unbind:function(t){var e=this;t||delete this.local.mappings[this.localKey],this.resolved&&(this.deps.forEach(function(t){e.origin.unregister(e.map(t.keypath),t.dep,t.group)}),this.tracker&&this.origin.unregister(this.keypath,this.tracker))},unregister:function(t,e,n){var a,r;if(this.resolved){for(a=this.deps,r=a.length;r--;)if(a[r].dep===e){a.splice(r,1);break}this.origin.unregister(this.map(t),e,n)}}};var om=Fr,sm=function(t,e){var n,a,r,i;return n={},a=0,r=t.map(function(t,r){var o,s,u;s=a,u=e.length;do{if(o=e.indexOf(t,s),-1===o)return i=!0,-1;s=o+1}while(n[o]&&u>s);return o===a&&(a+=1),o!==r&&(i=!0),n[o]=!0,o})},um=Ir,pm={},cm=Ur,lm=Vr,fm=zr,dm=Wr,hm=Kr,mm={implicit:!0},vm={noCascade:!0},gm=$r,bm=Yr,ym=function(t){var e,n,a=t.adapt,r=t.data,i=t.ractive,o=t.computed,s=t.mappings;this.ractive=i,this.adaptors=a,this.onchange=t.onchange,this.cache={},this.cacheMap=Eo(null),this.deps={computed:Eo(null),"default":Eo(null)},this.depsMap={computed:Eo(null),"default":Eo(null)},this.patternObservers=[],this.specials=Eo(null),this.wrapped=Eo(null),this.computations=Eo(null),this.captureGroups=[],this.unresolvedImplicitDependencies=[],this.changes=[],this.implicitChanges={},this.noCascade={},this.data=r,this.mappings=Eo(null);for(e in s)this.map(E(e),s[e]);if(r)for(e in r)(n=this.mappings[e])&&void 0===n.getValue()&&n.setValue(r[e]);for(e in o)s&&e in s&&l("Cannot map to a computed property ('%s')",e),this.compute(E(e),o[e]);this.ready=!0};ym.prototype={adapt:Gh,applyChanges:Hh,capture:Kh,clearCache:Qh,compute:Zh,get:em,init:am,map:rm,mark:om,merge:um,register:cm,release:lm,reset:fm,set:dm,smartUpdate:hm,teardown:gm,unregister:bm};var xm=ym;Xr.prototype={constructor:Xr,begin:function(t){this.inProcess[t._guid]=!0},end:function(t){var e=t.parent;e&&this.inProcess[e._guid]?Zr(this.queue,e).push(t):ti(this,t),delete this.inProcess[t._guid]}};var _m=Xr,wm=ei,km=/\$\{([^\}]+)\}/g,Em=new is("construct"),Sm=new is("config"),Cm=new _m("init"),Pm=0,Am=["adaptors","components","decorators","easing","events","interpolators","partials","transitions"],Om=ii,Tm=ci;ci.prototype={bubble:function(){this.dirty||(this.dirty=!0,bs.addView(this))},update:function(){this.callback(this.fragment.getValue()),this.dirty=!1},rebind:function(t,e){this.fragment.rebind(t,e)},unbind:function(){this.fragment.unbind()}};var Mm=function(t,e,n,r,o){var s,u,p,c,l,f,d={},h={},v={},g=[];for(u=t.parentFragment,p=t.root,o=o||{},a(d,o),o.content=r||[],d[""]=o.content,e.defaults.el&&m("The <%s/> component has a default `el` property; it has been disregarded",t.name),c=u;c;){if(c.owner.type===Rp){l=c.owner.container;break}c=c.parent}return n&&Object.keys(n).forEach(function(e){var a,r,o=n[e];if("string"==typeof o)a=fc(o),h[e]=a?a.value:o;else if(0===o)h[e]=!0;else{if(!i(o))throw Error("erm wut");fi(o)?(v[e]={origin:t.root.viewmodel,keypath:void 0},r=li(t,o[0],function(t){t.isSpecial?f?s.set(e,t.value):(h[e]=t.value,delete v[e]):f?s.viewmodel.mappings[e].resolve(t):v[e].keypath=t})):r=new Tm(t,o,function(t){f?s.set(e,t):h[e]=t}),g.push(r)}}),s=Eo(e.prototype),Om(s,{el:null,append:!0,data:h,partials:o,magic:p.magic||e.defaults.magic,modifyArrays:p.modifyArrays,adapt:p.adapt},{parent:p,component:t,container:l,mappings:v,inlinePartials:d,cssIds:u.cssIds}),f=!0,t.resolvers=g,s},Rm=di,jm=function(t){var e,n;for(e=t.root;e;)(n=e._liveComponentQueries["_"+t.name])&&n.push(t.instance),e=e.parent},Lm=mi,Dm=vi,Nm=gi,Fm=bi,Im=yi,Bm=new is("teardown"),qm=_i,Um=function(t,e){this.init(t,e)};Um.prototype={detach:bh,find:xh,findAll:_h,findAllComponents:wh,findComponent:kh,findNextNode:Eh,firstNode:Sh,init:Lm,rebind:Dm,render:Nm,toString:Fm,unbind:Im,unrender:qm};var Gm=Um,Vm=function(t){this.type=Op,this.value=t.template.c};Vm.prototype={detach:gc,firstNode:function(){return this.node},render:function(){return this.node||(this.node=document.createComment(this.value)),this.node},toString:function(){return""},unrender:function(t){t&&this.node.parentNode.removeChild(this.node)}};var zm=Vm,Wm=function(t){var e,n;this.type=Rp,this.container=e=t.parentFragment.root,this.component=n=e.component,this.container=e,this.containerFragment=t.parentFragment,this.parentFragment=n.parentFragment;var a=this.name=t.template.n||"",r=e._inlinePartials[a];r||(m('Could not find template for partial "'+a+'"',{ractive:t.root}),r=[]),this.fragment=new rv({owner:this,root:e.parent,template:r,pElement:this.containerFragment.pElement}),i(n.yielders[a])?n.yielders[a].push(this):n.yielders[a]=[this],bs.scheduleTask(function(){if(n.yielders[a].length>1)throw Error("A component template can only have one {{yield"+(a?" "+a:"")+"}} declaration at a time")})};Wm.prototype={detach:function(){return this.fragment.detach()},find:function(t){return this.fragment.find(t)},findAll:function(t,e){return this.fragment.findAll(t,e)},findComponent:function(t){return this.fragment.findComponent(t)},findAllComponents:function(t,e){return this.fragment.findAllComponents(t,e)},findNextNode:function(){return this.containerFragment.findNextNode(this)},firstNode:function(){return this.fragment.firstNode()},getValue:function(t){return this.fragment.getValue(t)},render:function(){return this.fragment.render()},unbind:function(){this.fragment.unbind()},unrender:function(t){this.fragment.unrender(t),N(this.component.yielders[this.name],this)},rebind:function(t,e){this.fragment.rebind(t,e)},toString:function(){return""+this.fragment}};var Hm=Wm,Km=function(t){this.declaration=t.template.a};Km.prototype={init:ko,render:ko,unrender:ko,teardown:ko,toString:function(){return""}};var Qm=Km,$m=wi,Ym=Ei,Jm=Si,Xm=Ci,Zm=Oi,tv=Mi,ev=function(t){this.init(t)};ev.prototype={bubble:cp,detach:lp,find:fp,findAll:dp,findAllComponents:hp,findComponent:mp,findNextNode:vp,firstNode:gp,getArgsList:hc,getNode:mc,getValue:vc,init:$m,rebind:Ym,registerIndexRef:function(t){var e=this.registeredIndexRefs;-1===e.indexOf(t)&&e.push(t)},render:Jm,toString:Xm,unbind:Zm,unregisterIndexRef:function(t){var e=this.registeredIndexRefs;e.splice(e.indexOf(t),1)},unrender:tv};var nv,av,rv=ev,iv=Ri,ov=["template","partials","components","decorators","events"],sv=new is("reset"),uv=function(t,e){function n(e,a,r){r&&r.partials[t]||e.forEach(function(e){e.type===Ap&&e.getPartialName()===t&&a.push(e),e.fragment&&n(e.fragment.items,a,r),i(e.fragments)?n(e.fragments,a,r):i(e.items)?n(e.items,a,r):e.type===Mp&&e.instance&&n(e.instance.fragment.items,a,e.instance),e.type===Pp&&(i(e.attributes)&&n(e.attributes,a,r),i(e.conditionalAttributes)&&n(e.conditionalAttributes,a,r))})}var a,r=[];return n(this.fragment.items,r),this.partials[t]=e,a=bs.start(this,!0),r.forEach(function(e){e.value=void 0,e.setValue(t)}),bs.end(),a},pv=ji,cv=xu("reverse"),lv=Li,fv=xu("shift"),dv=xu("sort"),hv=xu("splice"),mv=Ni,vv=Fi,gv=new is("teardown"),bv=Bi,yv=qi,xv=Ui,_v=new is("unrender"),wv=xu("unshift"),kv=Gi,Ev=new is("update"),Sv=Vi,Cv={add:Zo,animate:Es,detach:Cs,find:As,findAll:Fs,findAllComponents:Is,findComponent:Bs,findContainer:qs,findParent:Us,fire:Ws,get:Hs,insert:Qs,merge:Ys,observe:lu,observeOnce:fu,off:mu,on:vu,once:gu,pop:_u,push:wu,render:Tu,reset:iv,resetPartial:uv,resetTemplate:pv,reverse:cv,set:lv,shift:fv,sort:dv,splice:hv,subtract:mv,teardown:vv,toggle:bv,toHTML:yv,toHtml:yv,unrender:xv,unshift:wv,update:kv,updateModel:Sv},Pv=function(t,e,n){return n||Wi(t,e)?function(){var n,a="_super"in this,r=this._super;return this._super=e,n=t.apply(this,arguments),a&&(this._super=r),n}:t},Av=Hi,Ov=Yi,Tv=function(t){var e,n,a={};return t&&(e=t._ractive)?(a.ractive=e.root,a.keypath=e.keypath.str,a.index={},(n=Oc(e.proxy.parentFragment))&&(a.index=Oc.resolve(n)),a):a};nv=function(t){return this instanceof nv?void Om(this,t):new nv(t)},av={DEBUG:{writable:!0,value:!0},DEBUG_PROMISES:{writable:!0,value:!0},extend:{value:Ov},getNodeInfo:{value:Tv},parse:{value:Hu},Promise:{value:ps},svg:{value:ao},magic:{value:eo},VERSION:{value:"0.7.3"},adaptors:{writable:!0,value:{}},components:{writable:!0,value:{}},decorators:{writable:!0,value:{}},easing:{writable:!0,value:uo},events:{writable:!0,value:{}},interpolators:{writable:!0,value:Go},partials:{writable:!0,value:{}},transitions:{writable:!0,value:{}}},Co(nv,av),nv.prototype=a(Cv,so),nv.prototype.constructor=nv,nv.defaults=nv.prototype;var Mv="function";if(typeof Date.now!==Mv||typeof String.prototype.trim!==Mv||typeof Object.keys!==Mv||typeof Array.prototype.indexOf!==Mv||typeof Array.prototype.forEach!==Mv||typeof Array.prototype.map!==Mv||typeof Array.prototype.filter!==Mv||"undefined"!=typeof window&&typeof window.addEventListener!==Mv)throw Error("It looks like you're attempting to use Ractive.js in an older browser. You'll need to use one of the 'legacy builds' in order to continue - see http://docs.ractivejs.org/latest/legacy-builds for more information.");var Rv=nv;return Rv})},{}],206:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={oninit:function(){var t=this;this.observe("value",function(e,n,a){var r=t.get(),i=r.min,o=r.max,s=Math.clamp(i,o,e);t.animate("percentage",Math.round((s-i)/(o-i)*100))})}}}(r),r.exports.template={v:3,t:[" ",{p:[13,1,305],t:7,e:"div",a:{"class":"bar"},f:[{p:[14,3,326],t:7,e:"div",a:{"class":["barFill ",{t:2,r:"state",p:[14,23,346]}],style:["width: ",{t:2,r:"percentage",p:[14,48,371]},"%"]}}," ",{p:[15,3,398],t:7,e:"span",a:{"class":"barText"},f:[{t:16,p:[15,25,420]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],207:[function(t,e,n){var a=t(205),r={exports:{}};!function(e){"use strict";var n=t(310),a=t(309);e.exports={computed:{clickable:function(){return!this.get("enabled")||this.get("state")&&"toggle"!=this.get("state")?!1:!0},enabled:function(){return this.get("config.status")===n.UI_INTERACTIVE?!0:!1},styles:function(){var t="";if(this.get("class")&&(t+=" "+this.get("class")),this.get("tooltip-side")&&(t=" tooltip-"+this.get("tooltip-side")),this.get("grid")&&(t+=" gridable"),this.get("enabled")){var e=this.get("state"),n=this.get("style");return e?"inactive "+e+" "+t:"active normal "+n+" "+t}return"inactive disabled "+t}},oninit:function(){var t=this;this.on("press",function(e){var n=t.get(),r=n.action,i=n.params;(0,a.act)(t.get("config.ref"),r,i),e.node.blur()})},data:{iconStackToHTML:function(t){var e="",n=t.split(",");if(n.length){e+='';for(var a=n,r=Array.isArray(a),i=0,a=r?a:a[Symbol.iterator]();;){var o;if(r){if(i>=a.length)break;o=a[i++]}else{if(i=a.next(),i.done)break;o=i.value}var s=o,u=/([\w\-]+)\s*(\dx)/g,p=u.exec(s),c=p[1],l=p[2];e+=''}}return e&&(e+=""),e}}}}(r),r.exports.template={v:3,t:[" ",{p:[70,1,2015],t:7,e:"span",a:{"class":["button ",{t:2,r:"styles",p:[70,21,2035]}],unselectable:"on","data-tooltip":[{t:2,r:"tooltip",p:[73,17,2120]}]},m:[{t:4,f:["tabindex='0'"],r:"clickable",p:[72,3,2071]}],v:{"mouseover-mousemove":"hover",mouseleave:"unhover","click-enter":{n:[{t:4,f:["press"],r:"clickable",p:[76,19,2213]}],d:[]}},f:[{t:4,f:[{p:[78,5,2261],t:7,e:"i",a:{"class":["fa fa-",{t:2,r:"icon",p:[78,21,2277]}]}}],n:50,r:"icon",p:[77,3,2243]}," ",{t:4,f:[{t:3,x:{r:["iconStackToHTML","icon_stack"],s:"_0(_1)"},p:[81,6,2331]}],n:50,r:"icon_stack",p:[80,3,2306]}," ",{t:16,p:[83,3,2379]}]}]},e.exports=a.extend(r.exports)},{205:205,309:309,310:310}],208:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"display"},f:[{t:4,f:[{p:[3,5,44],t:7,e:"header",f:[{p:[4,7,60],t:7,e:"h3",f:[{t:2,r:"title",p:[4,11,64]}]}," ",{t:4,f:[{p:[6,9,110],t:7,e:"div",a:{"class":"buttonRight"},f:[{t:16,n:"button",p:[6,34,135]}]}],n:50,r:"button",p:[5,7,86]}]}],n:50,r:"title",p:[2,3,25]}," ",{p:[10,3,202],t:7,e:"article",f:[{t:16,p:[11,5,217]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],209:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={oninit:function(){var t=this;this.on("clear",function(){t.set("value",""),t.find("input").focus()})}}}(r),r.exports.template={v:3,t:[" ",{p:[12,1,170],t:7,e:"input",a:{type:"text",value:[{t:2,r:"value",p:[12,27,196]}],placeholder:[{t:2,r:"placeholder",p:[12,51,220]}]}}," ",{p:[13,1,240],t:7,e:"ui-button",a:{icon:"refresh"},v:{press:"clear"}}]},e.exports=a.extend(r.exports)},{205:205}],210:[function(t,e,n){var a=t(205),r={exports:{}};!function(e){"use strict";e.exports={data:{graph:t(201),xaccessor:function(t){return t.x},yaccessor:function(t){return t.y}},computed:{size:function(){var t=this.get("points");return t[0].length},scale:function(){var t=this.get("points");return Math.max.apply(Math,Array.map(t,function(t){return Math.max.apply(Math,Array.map(t,function(t){return t.y}))}))},xaxis:function(){var t=this.get("xinc"),e=this.get("size");return Array.from(Array(e).keys()).filter(function(e){return e&&e%t==0})},yaxis:function(){var t=this.get("yinc"),e=this.get("scale");return Array.from(Array(t).keys()).map(function(t){return Math.round(e*(++t/100)*10)})}},oninit:function(){var t=this;this.on({enter:function(t){this.set("selected",t.index.count)},exit:function(t){this.set("selected")}}),window.addEventListener("resize",function(e){t.set("width",t.el.clientWidth)})},onrender:function(){this.set("width",this.el.clientWidth)}}}(r),r.exports.template={v:3,t:[" ",{p:[47,1,1269],t:7,e:"svg",a:{"class":"linegraph",width:"100%",height:[{t:2,x:{r:["height"],s:"_0+10"},p:[47,45,1313]}]},f:[{p:[48,3,1334],t:7,e:"g",a:{transform:"translate(0, 5)"},f:[{t:4,f:[{t:4,f:[{p:[51,9,1504],t:7,e:"line",a:{x1:[{t:2,x:{r:["xscale","."],s:"_0(_1)"},p:[51,19,1514]}],x2:[{t:2,x:{r:["xscale","."],s:"_0(_1)"},p:[51,38,1533]}],y1:"0",y2:[{t:2,r:"height",p:[51,64,1559]}],stroke:"darkgray"}}," ",{t:4,f:[{p:[53,11,1635],t:7,e:"text",a:{x:[{t:2,x:{r:["xscale","."],s:"_0(_1)"},p:[53,20,1644]}],y:[{t:2,x:{r:["height"],s:"_0-5"},p:[53,38,1662]}],"text-anchor":"middle",fill:"white"},f:[{t:2,x:{r:["size",".","xfactor"],s:"(_0-_1)*_2"},p:[53,88,1712]}," ",{t:2,r:"xunit",p:[53,113,1737]}]}],n:50,x:{r:["@index"],s:"_0%2==0"},p:[52,9,1600]}],n:52,r:"xaxis",p:[50,7,1479]}," ",{t:4,f:[{p:[57,9,1820],t:7,e:"line",a:{x1:"0",x2:[{t:2,r:"width",p:[57,26,1837]}],y1:[{t:2,x:{r:["yscale","."],s:"_0(_1)"},p:[57,41,1852]}],y2:[{t:2,x:{r:["yscale","."],s:"_0(_1)"},p:[57,60,1871]}],stroke:"darkgray"}}," ",{p:[58,9,1915],t:7,e:"text",a:{x:"0",y:[{t:2,x:{r:["yscale","."],s:"_0(_1)-5"},p:[58,24,1930]}],"text-anchor":"begin",fill:"white"},f:[{t:2,x:{r:[".","yfactor"],s:"_0*_1"},p:[58,76,1982]}," ",{t:2,r:"yunit",p:[58,92,1998]}]}],n:52,r:"yaxis",p:[56,7,1795]}," ",{t:4,f:[{p:[61,9,2071],t:7,e:"path",a:{d:[{t:2,x:{r:["area.path"],s:"_0.print()"},p:[61,18,2080]}],fill:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[61,47,2109]}],opacity:"0.1"}}],n:52,i:"curve",r:"curves",p:[60,7,2039]}," ",{t:4,f:[{p:[64,9,2200],t:7,e:"path",a:{d:[{t:2,x:{r:["line.path"],s:"_0.print()"},p:[64,18,2209]}],stroke:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[64,49,2240]}],fill:"none"}}],n:52,i:"curve",r:"curves",p:[63,7,2168]}," ",{t:4,f:[{t:4,f:[{p:[68,11,2375],t:7,e:"circle",a:{transform:["translate(",{t:2,r:".",p:[68,40,2404]},")"],r:[{t:2,x:{r:["selected","count"],s:"_0==_1?10:4"},p:[68,51,2415]}],fill:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[68,89,2453]}]},v:{mouseenter:"enter",mouseleave:"exit"}}],n:52,i:"count",x:{r:["line.path"],s:"_0.points()"},p:[67,9,2329]}],n:52,i:"curve",r:"curves",p:[66,7,2297]}," ",{t:4,f:[{t:4,f:[{t:4,f:[{p:[74,13,2678],t:7,e:"text",a:{transform:["translate(",{t:2,r:".",p:[74,40,2705]},") ",{t:2,x:{r:["count","size"],s:'_0<=_1/2?"translate(15, 4)":"translate(-15, 4)"'},p:[74,47,2712]}],"text-anchor":[{t:2,x:{r:["count","size"],s:'_0<=_1/2?"start":"end"'},p:[74,126,2791]}],fill:"white"},f:[{t:2,x:{r:["count","item","yfactor"],s:"_1[_0].y*_2"},p:[75,15,2861]}," ",{t:2,r:"yunit",p:[75,43,2889]}," @ ",{t:2,x:{r:["size","count","item","xfactor"],s:"(_0-_2[_1].x)*_3"},p:[75,55,2901]}," ",{t:2,r:"xunit",p:[75,92,2938]}]}],n:50,x:{r:["selected","count"],s:"_0==_1"},p:[73,11,2638]}],n:52,i:"count",x:{r:["line.path"],s:"_0.points()"},p:[72,9,2592]}],n:52,i:"curve",r:"curves",p:[71,7,2560]}," ",{t:4,f:[{p:[81,9,3063],t:7,e:"g",a:{transform:["translate(",{t:2,x:{r:["width","curves.length","@index"],s:"(_0/(_1+1))*(_2+1)"},p:[81,33,3087]},", 10)"]},f:[{p:[82,11,3154],t:7,e:"circle",a:{r:"4",fill:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[82,31,3174]}]}}," ",{p:[83,11,3206],t:7,e:"text",a:{x:"8",y:"4",fill:"white"},f:[{t:2,rx:{r:"legend",m:[{t:30,n:"curve"}]},p:[83,42,3237]}]}]}],n:52,i:"curve",r:"curves",p:[80,7,3031]}],x:{r:["graph","points","xaccessor","yaccessor","width","height"],s:"_0({data:_1,xaccessor:_2,yaccessor:_3,width:_4,height:_5})"},p:[49,5,1371]}]}]}]},e.exports=a.extend(r.exports)},{201:201,205:205}],211:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"notice"},f:[{t:16,p:[2,3,24]}]}]},e.exports=a.extend(r.exports)},{205:205}],212:[function(t,e,n){var a=t(205),r={exports:{}};!function(e){"use strict";var n=t(309),a=t(311);e.exports={oninit:function(){var t=this,e=a.resize.bind(this),r=function(){return t.set({resize:!1,x:null,y:null})};this.observe("config.fancy",function(a,i,o){(0,n.winset)(t.get("config.window"),"can-resize",!a),a?(document.addEventListener("mousemove",e),document.addEventListener("mouseup",r)):(document.removeEventListener("mousemove",e),document.removeEventListener("mouseup",r))}),this.on("resize",function(){return t.toggle("resize")})}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[28,3,766],t:7,e:"div",a:{"class":"resize"},v:{mousedown:"resize"}}],n:50,r:"config.fancy",p:[27,1,742]}]},e.exports=a.extend(r.exports)},{205:205,309:309,311:311}],213:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"section",a:{"class":[{t:4,f:["candystripe"],r:"candystripe",p:[1,17,16]}]},f:[{t:4,f:[{p:[3,5,84],t:7,e:"span",a:{"class":"label",style:[{t:4,f:["color:",{t:2,r:"labelcolor",p:[3,53,132]}],r:"labelcolor",p:[3,32,111]}]},f:[{t:2,r:"label",p:[3,84,163]},":"]}],n:50,r:"label",p:[2,3,65]}," ",{t:4,f:[{t:16,p:[6,5,215]}],n:50,r:"nowrap",p:[5,3,195]},{t:4,n:51,f:[{p:[8,5,242],t:7,e:"div",a:{"class":"content",style:[{t:4,f:["float:right;"],r:"right",p:[8,33,270]}]},f:[{t:16,p:[9,7,312]}]}],r:"nowrap"}]}]},e.exports=a.extend(r.exports)},{205:205}],214:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"subdisplay"},f:[{t:4,f:[{p:[3,5,47],t:7,e:"header",f:[{p:[4,7,63],t:7,e:"h4",f:[{t:2,r:"title",p:[4,11,67]}]}," ",{t:4,f:[{t:16,n:"button",p:[5,21,103]}],n:50,r:"button",p:[5,7,89]}]}],n:50,r:"title",p:[2,3,28]}," ",{p:[8,3,156],t:7,e:"article",f:[{t:16,p:[9,5,171]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],215:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={oninit:function(){var t=this;this.set("active",this.findComponent("tab").get("name")),this.on("switch",function(e){t.set("active",e.node.textContent.trim())}),this.observe("active",function(e,n,a){for(var r=t.findAllComponents("tab"),i=Array.isArray(r),o=0,r=i?r:r[Symbol.iterator]();;){var s;if(i){if(o>=r.length)break;s=r[o++]}else{if(o=r.next(),o.done)break;s=o.value}var u=s;u.set("shown",u.get("name")===e)}})}}}(r),r.exports.template={v:3,t:[" "," ",{p:[20,1,524],t:7,e:"header",f:[{t:4,f:[{p:[22,5,556],t:7,e:"ui-button",a:{pane:[{t:2,r:".",p:[22,22,573]}]},v:{press:"switch"},f:[{t:2,r:".",p:[22,47,598]}]}],n:52,r:"tabs",p:[21,3,536]}]}," ",{p:[25,1,641],t:7,e:"ui-display",f:[{t:8,r:"content",p:[26,3,657]}]}]},r.exports.components=r.exports.components||{};var i={tab:t(216)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,216:216}],216:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{t:16,p:[2,3,17]}],n:50,r:"shown",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],217:[function(t,e,n){var a=t(205),r={exports:{}};!function(e){"use strict";var n=t(310),a=t(309),r=t(311);e.exports={computed:{visualStatus:function(){switch(this.get("config.status")){case n.UI_INTERACTIVE:return"good";case n.UI_UPDATE:return"average";case n.UI_DISABLED:return"bad";default:return"bad"}}},oninit:function(){var t=this,e=r.drag.bind(this),n=function(e){return t.set({drag:!1,x:null,y:null})};this.observe("config.fancy",function(r,i,o){(0,a.winset)(t.get("config.window"),"titlebar",!r&&t.get("config.titlebar")),r?(document.addEventListener("mousemove",e),document.addEventListener("mouseup",n)):(document.removeEventListener("mousemove",e),document.removeEventListener("mouseup",n))}),this.on({drag:function(){this.toggle("drag")},close:function(){(0,a.winset)(this.get("config.window"),"is-visible",!1),window.location.href=(0,a.href)({command:"uiclose "+this.get("config.ref")},"winset")},minimize:function(){(0,a.winset)(this.get("config.window"),"is-minimized",!0)}})}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[50,3,1440],t:7,e:"header",a:{"class":"titlebar"},v:{mousedown:"drag"},f:[{p:[51,5,1491],t:7,e:"i",a:{"class":["statusicon fa fa-eye fa-2x ",{t:2,r:"visualStatus",p:[51,42,1528]}]}}," ",{p:[52,5,1556],t:7,e:"span",a:{"class":"title"},f:[{t:16,p:[52,25,1576]}]}," ",{t:4,f:[{p:[54,7,1626],t:7,e:"i",a:{"class":"minimize fa fa-minus fa-2x"},v:{click:"minimize"}}," ",{p:[55,7,1696],t:7,e:"i",a:{"class":"close fa fa-close fa-2x"},v:{click:"close"}}],n:50,r:"config.fancy",p:[53,5,1598]}]}],n:50,r:"config.titlebar",p:[49,1,1413]}]},e.exports=a.extend(r.exports)},{205:205,309:309,310:310,311:311}],218:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";var e=[11,10,9,8];t.exports={data:{userAgent:navigator.userAgent},computed:{ie:function(){if(document.documentMode)return document.documentMode;for(var t in e){var n=document.createElement("div");if(n.innerHTML="",n.getElementsByTagName("span").length)return t}}},oninit:function(){var t=this;this.on("debug",function(){return t.toggle("debug")})}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[27,3,662],t:7,e:"ui-notice",f:[{p:[28,5,679],t:7,e:"span",f:["You have an old (IE",{t:2,r:"ie",p:[28,30,704]},"), end-of-life (click 'EOL Info' for more information) version of Internet Explorer installed."]},{p:[28,137,811],t:7,e:"br"}," ",{p:[29,5,822],t:7,e:"span",f:["To upgrade, click 'Upgrade IE' to download IE11 from Microsoft."]},{p:[29,81,898],t:7,e:"br"}," ",{p:[30,5,909],t:7,e:"span",f:["If you are unable to upgrade directly, click 'IE VMs' to download a VM with IE11 or Edge from Microsoft."]},{p:[30,122,1026],t:7,e:"br"}," ",{p:[31,5,1037],t:7,e:"span",f:["Otherwise, click 'No Frills' below to disable potentially incompatible features (and this message)."]}," ",{p:[32,5,1155],t:7,e:"hr"}," ",{p:[33,5,1166],t:7,e:"ui-button",a:{icon:"close",action:"tgui:nofrills"},f:["No Frills"]}," ",{p:[34,5,1240],t:7,e:"ui-button",a:{icon:"internet-explorer",action:"tgui:link",params:'{"url": "http://windows.microsoft.com/en-us/internet-explorer/download-ie"}'},f:["Upgrade IE"]}," ",{p:[36,5,1416],t:7,e:"ui-button",a:{icon:"edge",action:"tgui:link",params:'{"url": "https://dev.windows.com/en-us/microsoft-edge/tools/vms"}'},f:["IE VMs"]}," ",{p:[38,5,1565],t:7,e:"ui-button",a:{icon:"info",action:"tgui:link",params:'{"url": "https://support.microsoft.com/en-us/lifecycle#gp/Microsoft-Internet-Explorer"}'},f:["EOL Info"]}," ",{p:[40,5,1738],t:7,e:"ui-button",a:{icon:"bug"},v:{press:"debug"},f:["Debug Info"]}," ",{t:4,f:[{p:[42,7,1826],t:7,e:"hr"}," ",{p:[43,7,1839],t:7,e:"span",f:["Detected: IE",{t:2,r:"ie",p:[43,25,1857]}]},{p:[43,38,1870],t:7,e:"br"}," ",{p:[44,7,1883],t:7,e:"span",f:["User Agent: ",{t:2,r:"userAgent",p:[44,25,1901]}]}],n:50,r:"debug",p:[41,5,1805]}]}],n:50,x:{r:["config.fancy","ie"],s:"_0&&_1&&_1<11"},p:[26,1,621]}]},e.exports=a.extend(r.exports)},{205:205}],219:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" "," "," "," "," ",{p:[7,1,267],t:7,e:"ui-notice",f:[{t:4,f:[{p:[9,5,312],t:7,e:"ui-section",a:{ - label:"Interface Lock"},f:[{p:[10,7,355],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[10,24,372]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[10,75,423]}]}]}],n:50,r:"data.siliconUser",p:[8,3,282]},{t:4,n:51,f:[{p:[13,5,514],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[13,31,540]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[16,1,625],t:7,e:"status"}," ",{t:4,f:[{t:4,f:[{p:[19,7,719],t:7,e:"ui-display",a:{title:"Air Controls"},f:[{p:[20,9,762],t:7,e:"ui-section",f:[{p:[21,11,786],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.atmos_alarm"],s:'_0?"exclamation-triangle":"exclamation"'},p:[21,28,803]}],style:[{t:2,x:{r:["data.atmos_alarm"],s:'_0?"caution":null'},p:[21,98,873]}],action:[{t:2,x:{r:["data.atmos_alarm"],s:'_0?"reset":"alarm"'},p:[22,23,937]}]},f:["Area Atmosphere Alarm"]}]}," ",{p:[24,9,1045],t:7,e:"ui-section",f:[{p:[25,11,1069],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0==3?"exclamation-triangle":"exclamation"'},p:[25,28,1086]}],style:[{t:2,x:{r:["data.mode"],s:'_0==3?"danger":null'},p:[25,96,1154]}],action:"mode",params:['{"mode": ',{t:2,x:{r:["data.mode"],s:"_0==3?1:3"},p:[26,44,1236]},"}"]},f:["Panic Siphon"]}]}," ",{p:[28,9,1322],t:7,e:"br"}," ",{p:[29,9,1337],t:7,e:"ui-section",f:[{p:[30,11,1361],t:7,e:"ui-button",a:{icon:"sign-out",action:"tgui:view",params:'{"screen": "vents"}'},f:["Vent Controls"]}]}," ",{p:[32,9,1494],t:7,e:"ui-section",f:[{p:[33,11,1518],t:7,e:"ui-button",a:{icon:"filter",action:"tgui:view",params:'{"screen": "scrubbers"}'},f:["Scrubber Controls"]}]}," ",{p:[35,9,1657],t:7,e:"ui-section",f:[{p:[36,11,1681],t:7,e:"ui-button",a:{icon:"cog",action:"tgui:view",params:'{"screen": "modes"}'},f:["Operating Mode"]}]}," ",{p:[38,9,1810],t:7,e:"ui-section",f:[{p:[39,11,1834],t:7,e:"ui-button",a:{icon:"bar-chart",action:"tgui:view",params:'{"screen": "thresholds"}'},f:["Alarm Thresholds"]}]}]}],n:50,x:{r:["config.screen"],s:'_0=="home"'},p:[18,3,680]},{t:4,n:51,f:[{t:4,n:50,x:{r:["config.screen"],s:'_0=="vents"'},f:[{p:[43,5,2032],t:7,e:"vents"}]},{t:4,n:50,x:{r:["config.screen"],s:'(!(_0=="vents"))&&(_0=="scrubbers")'},f:[" ",{p:[45,5,2089],t:7,e:"scrubbers"}]},{t:4,n:50,x:{r:["config.screen"],s:'(!(_0=="vents"))&&((!(_0=="scrubbers"))&&(_0=="modes"))'},f:[" ",{p:[47,5,2146],t:7,e:"modes"}]},{t:4,n:50,x:{r:["config.screen"],s:'(!(_0=="vents"))&&((!(_0=="scrubbers"))&&((!(_0=="modes"))&&(_0=="thresholds")))'},f:[" ",{p:[49,5,2204],t:7,e:"thresholds"}]}],x:{r:["config.screen"],s:'_0=="home"'}}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[17,1,636]}]},r.exports.components=r.exports.components||{};var i={vents:t(225),modes:t(221),thresholds:t(224),status:t(223),scrubbers:t(222)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,221:221,222:222,223:223,224:224,225:225}],220:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-button",a:{icon:"arrow-left",action:"tgui:view",params:'{"screen": "home"}'},f:["Back"]}]},e.exports=a.extend(r.exports)},{205:205}],221:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,115],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Operating Modes",button:0},f:[" ",{t:4,f:[{p:[8,5,168],t:7,e:"ui-section",f:[{p:[9,7,188],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["selected"],s:'_0?"check-square-o":"square-o"'},p:[9,24,205]}],state:[{t:2,x:{r:["selected","danger"],s:'_0?_1?"danger":"selected":null'},p:[10,16,267]}],action:"mode",params:['{"mode": ',{t:2,r:"mode",p:[11,40,361]},"}"]},f:[{t:2,r:"name",p:[11,51,372]}]}]}],n:52,r:"data.modes",p:[7,3,142]}]}]},r.exports.components=r.exports.components||{};var i={back:t(220)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,220:220}],222:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,117],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Scrubber Controls",button:0},f:[" ",{t:4,f:[{p:[8,5,174],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"long_name",p:[8,27,196]}]},f:[{p:[9,7,219],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[10,9,255],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["power"],s:'_0?"power-off":"close"'},p:[10,26,272]}],style:[{t:2,x:{r:["power"],s:'_0?"selected":null'},p:[10,68,314]}],action:"power",params:['{"id_tag": "',{t:2,r:"id_tag",p:[11,46,391]},'", "val": ',{t:2,x:{r:["power"],s:"+!_0"},p:[11,66,411]},"}"]},f:[{t:2,x:{r:["power"],s:'_0?"On":"Off"'},p:[11,80,425]}]}]}," ",{p:[13,7,490],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[14,9,525],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["scrubbing"],s:'_0?"filter":"sign-in"'},p:[14,26,542]}],style:[{t:2,x:{r:["scrubbing"],s:'_0?null:"danger"'},p:[14,71,587]}],action:"scrubbing",params:['{"id_tag": "',{t:2,r:"id_tag",p:[15,50,670]},'", "val": ',{t:2,x:{r:["scrubbing"],s:"+!_0"},p:[15,70,690]},"}"]},f:[{t:2,x:{r:["scrubbing"],s:'_0?"Scrubbing":"Siphoning"'},p:[15,88,708]}]}]}," ",{p:[17,7,790],t:7,e:"ui-section",a:{label:"Range"},f:[{p:[18,9,826],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["widenet"],s:'_0?"expand":"compress"'},p:[18,26,843]}],style:[{t:2,x:{r:["widenet"],s:'_0?"selected":null'},p:[18,70,887]}],action:"widenet",params:['{"id_tag": "',{t:2,r:"id_tag",p:[19,48,968]},'", "val": ',{t:2,x:{r:["widenet"],s:"+!_0"},p:[19,68,988]},"}"]},f:[{t:2,x:{r:["widenet"],s:'_0?"Expanded":"Normal"'},p:[19,84,1004]}]}]}," ",{p:[21,7,1080],t:7,e:"ui-section",a:{label:"Filters"},f:[{p:[22,9,1118],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["filter_co2"],s:'_0?"check-square-o":"square-o"'},p:[22,26,1135]}],style:[{t:2,x:{r:["filter_co2"],s:'_0?"selected":null'},p:[22,81,1190]}],action:"co2_scrub",params:['{"id_tag": "',{t:2,r:"id_tag",p:[23,50,1276]},'", "val": ',{t:2,x:{r:["filter_co2"],s:"+!_0"},p:[23,70,1296]},"}"]},f:["CO2"]}," ",{p:[24,9,1340],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["filter_n2o"],s:'_0?"check-square-o":"square-o"'},p:[24,26,1357]}],style:[{t:2,x:{r:["filter_n2o"],s:'_0?"selected":null'},p:[24,81,1412]}],action:"n2o_scrub",params:['{"id_tag": "',{t:2,r:"id_tag",p:[25,50,1498]},'", "val": ',{t:2,x:{r:["filter_n2o"],s:"+!_0"},p:[25,70,1518]},"}"]},f:["N2O"]}," ",{p:[26,9,1562],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["filter_toxins"],s:'_0?"check-square-o":"square-o"'},p:[26,26,1579]}],style:[{t:2,x:{r:["filter_toxins"],s:'_0?"selected":null'},p:[26,84,1637]}],action:"tox_scrub",params:['{"id_tag": "',{t:2,r:"id_tag",p:[27,50,1726]},'", "val": ',{t:2,x:{r:["filter_toxins"],s:"+!_0"},p:[27,70,1746]},"}"]},f:["Plasma"]}," ",{p:[28,3,1790],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["filter_bz"],s:'_0?"check-square-o":"square-o"'},p:[28,20,1807]}],style:[{t:2,x:{r:["filter_bz"],s:'_0?"selected":null'},p:[28,74,1861]}],action:"bz_scrub",params:['{"id_tag": "',{t:2,r:"id_tag",p:[29,43,1939]},'", "val": ',{t:2,x:{r:["filter_bz"],s:"+!_0"},p:[29,63,1959]},"}"]},f:["BZ"]}," ",{p:[30,3,1995],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["filter_freon"],s:'_0?"check-square-o":"square-o"'},p:[30,20,2012]}],style:[{t:2,x:{r:["filter_freon"],s:'_0?"selected":null'},p:[30,77,2069]}],action:"freon_scrub",params:['{"id_tag": "',{t:2,r:"id_tag",p:[31,46,2153]},'", "val": ',{t:2,x:{r:["filter_freon"],s:"+!_0"},p:[31,66,2173]},"}"]},f:["Freon"]}," ",{p:[32,3,2215],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["filter_water_vapor"],s:'_0?"check-square-o":"square-o"'},p:[32,20,2232]}],style:[{t:2,x:{r:["filter_water_vapor"],s:'_0?"selected":null'},p:[32,83,2295]}],action:"water_vapor_scrub",params:['{"id_tag": "',{t:2,r:"id_tag",p:[33,52,2391]},'", "val": ',{t:2,x:{r:["filter_water_vapor"],s:"+!_0"},p:[33,72,2411]},"}"]},f:["Water Vapor"]}]}]}],n:52,r:"data.scrubbers",p:[7,3,144]},{t:4,n:51,f:[{p:[37,5,2522],t:7,e:"span",a:{"class":"bad"},f:["Error: No scrubbers connected."]}],r:"data.scrubbers"}]}]},r.exports.components=r.exports.components||{};var i={back:t(220)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,220:220}],223:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Air Status"},f:[{t:4,f:[{t:4,f:[{p:[4,7,110],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[4,26,129]}]},f:[{p:[5,6,146],t:7,e:"span",a:{"class":[{t:2,x:{r:["danger_level"],s:'_0==2?"bad":_0==1?"average":"good"'},p:[5,19,159]}]},f:[{t:2,x:{r:["value"],s:"Math.fixed(_0,2)"},p:[6,5,237]},{t:2,r:"unit",p:[6,29,261]}]}]}],n:52,r:"adata.environment_data",p:[3,5,70]}," ",{p:[10,5,322],t:7,e:"ui-section",a:{label:"Local Status"},f:[{p:[11,7,363],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.danger_level"],s:'_0==2?"bad bold":_0==1?"average bold":"good"'},p:[11,20,376]}]},f:[{t:2,x:{r:["data.danger_level"],s:'_0==2?"Danger (Internals Required)":_0==1?"Caution":"Optimal"'},p:[12,6,475]}]}]}," ",{p:[15,5,619],t:7,e:"ui-section",a:{label:"Area Status"},f:[{p:[16,7,659],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.atmos_alarm","data.fire_alarm"],s:'_0||_1?"bad bold":"good"'},p:[16,20,672]}]},f:[{t:2,x:{r:["data.atmos_alarm","fire_alarm"],s:'_0?"Atmosphere Alarm":_1?"Fire Alarm":"Nominal"'},p:[17,8,744]}]}]}],n:50,r:"data.environment_data",p:[2,3,35]},{t:4,n:51,f:[{p:[21,5,876],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[22,7,912],t:7,e:"span",a:{"class":"bad bold"},f:["Cannot obtain air sample for analysis."]}]}],r:"data.environment_data"}," ",{t:4,f:[{p:[26,5,1040],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[27,7,1076],t:7,e:"span",a:{"class":"bad bold"},f:["Safety measures offline. Device may exhibit abnormal behavior."]}]}],n:50,r:"data.emagged",p:[25,3,1014]}]}]},e.exports=a.extend(r.exports)},{205:205}],224:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.css=" th, td {\r\n padding-right: 16px;\r\n text-align: left;\r\n }",r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,116],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Alarm Thresholds",button:0},f:[" ",{p:[7,3,143],t:7,e:"table",f:[{p:[8,5,156],t:7,e:"thead",f:[{p:[8,12,163],t:7,e:"tr",f:[{p:[9,7,175],t:7,e:"th"}," ",{p:[10,7,192],t:7,e:"th",f:[{p:[10,11,196],t:7,e:"span",a:{"class":"bad"},f:["min2"]}]}," ",{p:[11,7,238],t:7,e:"th",f:[{p:[11,11,242],t:7,e:"span",a:{"class":"average"},f:["min1"]}]}," ",{p:[12,7,288],t:7,e:"th",f:[{p:[12,11,292],t:7,e:"span",a:{"class":"average"},f:["max1"]}]}," ",{p:[13,7,338],t:7,e:"th",f:[{p:[13,11,342],t:7,e:"span",a:{"class":"bad"},f:["max2"]}]}]}]}," ",{p:[15,5,401],t:7,e:"tbody",f:[{t:4,f:[{p:[16,32,441],t:7,e:"tr",f:[{p:[17,9,455],t:7,e:"th",f:[{t:3,r:"name",p:[17,13,459]}]}," ",{t:4,f:[{p:[18,27,502],t:7,e:"td",f:[{p:[19,11,518],t:7,e:"ui-button",a:{action:"threshold",params:['{"env": "',{t:2,r:"env",p:[19,58,565]},'", "var": "',{t:2,r:"val",p:[19,76,583]},'"}']},f:[{t:2,x:{r:["selected"],s:"Math.fixed(_0,2)"},p:[19,87,594]}]}]}],n:52,r:"settings",p:[18,9,484]}]}],n:52,r:"data.thresholds",p:[16,7,416]}]}," ",{p:[23,3,697],t:7,e:"table",f:[]}]}]}," "]},r.exports.components=r.exports.components||{};var i={back:t(220)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,220:220}],225:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,113],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Vent Controls",button:0},f:[" ",{t:4,f:[{p:[8,5,166],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"long_name",p:[8,27,188]}]},f:[{p:[9,7,211],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[10,9,247],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["power"],s:'_0?"power-off":"close"'},p:[10,26,264]}],style:[{t:2,x:{r:["power"],s:'_0?"selected":null'},p:[10,68,306]}],action:"power",params:['{"id_tag": "',{t:2,r:"id_tag",p:[11,46,383]},'", "val": ',{t:2,x:{r:["power"],s:"+!_0"},p:[11,66,403]},"}"]},f:[{t:2,x:{r:["power"],s:'_0?"On":"Off"'},p:[11,80,417]}]}]}," ",{p:[13,7,482],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[14,9,517],t:7,e:"span",f:[{t:2,x:{r:["direction"],s:'_0=="release"?"Pressurizing":"Siphoning"'},p:[14,15,523]}]}]}," ",{p:[16,7,616],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[17,9,665],t:7,e:"ui-button",a:{icon:"sign-in",style:[{t:2,x:{r:["incheck"],s:'_0?"selected":null'},p:[17,42,698]}],action:"incheck",params:['{"id_tag": "',{t:2,r:"id_tag",p:[18,48,779]},'", "val": ',{t:2,r:"checks",p:[18,68,799]},"}"]},f:["Internal"]}," ",{p:[19,9,842],t:7,e:"ui-button",a:{icon:"sign-out",style:[{t:2,x:{r:["excheck"],s:'_0?"selected":null'},p:[19,43,876]}],action:"excheck",params:['{"id_tag": "',{t:2,r:"id_tag",p:[20,48,957]},'", "val": ',{t:2,r:"checks",p:[20,68,977]},"}"]},f:["External"]}]}," ",{p:[22,7,1039],t:7,e:"ui-section",a:{label:"Target Pressure"},f:[{p:[23,9,1085],t:7,e:"ui-button",a:{icon:"pencil",action:"set_external_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[24,31,1172]},'"}']},f:[{t:2,x:{r:["external"],s:"Math.fixed(_0)"},p:[24,45,1186]}]}," ",{p:[25,9,1232],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["extdefault"],s:'_0?"disabled":null'},p:[25,42,1265]}],action:"reset_external_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[26,31,1365]},'"}']},f:["Reset"]}]}]}],n:52,r:"data.vents",p:[7,3,140]},{t:4,n:51,f:[{p:[30,5,1457],t:7,e:"span",a:{"class":"bad"},f:["Error: No vents connected."]}],r:"data.vents"}]}]},r.exports.components=r.exports.components||{};var i={back:t(220)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,220:220}],226:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.css=" table {\r\n width: 100%;\r\n border-spacing: 2px;\r\n }\r\n th {\r\n text-align: left;\r\n }\r\n td {\r\n vertical-align: top;\r\n }\r\n td .button {\r\n margin-top: 4px\r\n }",r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",f:[{p:[3,5,34],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.oneAccess"],s:'_0?"unlock":"lock"'},p:[3,22,51]}],action:"one_access"},f:[{t:2,x:{r:["data.oneAccess"],s:'_0?"One":"All"'},p:[3,82,111]}," Required"]}," ",{p:[4,5,172],t:7,e:"ui-button",a:{icon:"refresh",action:"clear"},f:["Clear"]}]}," ",{p:[6,3,251],t:7,e:"hr"}," ",{p:[7,3,260],t:7,e:"table",f:[{p:[8,3,271],t:7,e:"thead",f:[{p:[9,4,283],t:7,e:"tr",f:[{t:4,f:[{p:[10,5,315],t:7,e:"th",f:[{p:[10,9,319],t:7,e:"span",a:{"class":"highlight bold"},f:[{t:2,r:"name",p:[10,38,348]}]}]}],n:52,r:"data.regions",p:[9,8,287]}]}]}," ",{p:[13,3,403],t:7,e:"tbody",f:[{p:[14,4,415],t:7,e:"tr",f:[{t:4,f:[{p:[15,5,447],t:7,e:"td",f:[{t:4,f:[{p:[16,11,481],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["req"],s:'_0?"check-square-o":"square-o"'},p:[16,28,498]}],style:[{t:2,x:{r:["req"],s:'_0?"selected":null'},p:[16,76,546]}],action:"set",params:['{"access": "',{t:2,r:"id",p:[17,46,621]},'"}']},f:[{t:2,r:"name",p:[17,56,631]}]}," ",{p:[18,9,661],t:7,e:"br"}],n:52,r:"accesses",p:[15,9,451]}]}],n:52,r:"data.regions",p:[14,8,419]}]}]}]}]}," "]},e.exports=a.extend(r.exports)},{205:205}],227:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{powerState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}}},computed:{malfAction:function(){switch(this.get("data.malfStatus")){case 1:return"hack";case 2:return"occupy";case 3:return"deoccupy"}},malfButton:function(){switch(this.get("data.malfStatus")){case 1:return"Override Programming";case 2:case 4:return"Shunt Core Process";case 3:return"Return to Main Core"}},malfIcon:function(){switch(this.get("data.malfStatus")){case 1:return"terminal";case 2:case 4:return"caret-square-o-down";case 3:return"caret-square-o-left"}},powerCellStatusState:function(){var t=this.get("data.powerCellStatus");return t>50?"good":t>25?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[46,2,1206],t:7,e:"ui-notice",f:[{p:[47,3,1221],t:7,e:"b",f:[{p:[47,6,1224],t:7,e:"h3",f:["SYSTEM FAILURE"]}]}," ",{p:[48,3,1255],t:7,e:"i",f:["I/O regulators malfunction detected! Waiting for system reboot..."]},{p:[48,75,1327],t:7,e:"br"}," Automatic reboot in ",{t:2,r:"data.failTime",p:[49,23,1355]}," seconds... ",{p:[50,3,1387],t:7,e:"ui-button",a:{icon:"refresh",action:"reboot"},f:["Reboot Now"]},{p:[50,67,1451],t:7,e:"br"},{p:[50,71,1455],t:7,e:"br"},{p:[50,75,1459],t:7,e:"br"}]}],n:50,r:"data.failTime",p:[45,1,1182]},{t:4,n:51,f:[{p:[53,2,1491],t:7,e:"ui-notice",f:[{t:4,f:[{p:[55,3,1535],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[56,5,1576],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[56,22,1593]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[56,73,1644]}]}]}],n:50,r:"data.siliconUser",p:[54,4,1507]},{t:4,n:51,f:[{p:[59,3,1732],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[59,29,1758]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[62,2,1846],t:7,e:"ui-display",a:{title:"Power Status"},f:[{p:[63,4,1884],t:7,e:"ui-section",a:{label:"Main Breaker"},f:[{t:4,f:[{p:[65,5,1967],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.isOperating"],s:'_0?"good":"bad"'},p:[65,18,1980]}]},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[65,57,2019]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[64,3,1921]},{t:4,n:51,f:[{p:[67,5,2079],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOperating"],s:'_0?"power-off":"close"'},p:[67,22,2096]}],style:[{t:2,x:{r:["data.isOperating"],s:'_0?"selected":null'},p:[67,75,2149]}],action:"breaker"},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[68,21,2212]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}," ",{p:[71,4,2293],t:7,e:"ui-section",a:{label:"External Power"},f:[{p:[72,3,2332],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.externalPower"],s:"_0(_1)"},p:[72,16,2345]}]},f:[{t:2,x:{r:["data.externalPower"],s:'_0==2?"Good":_0==1?"Low":"None"'},p:[72,52,2381]}]}]}," ",{p:[74,4,2490],t:7,e:"ui-section",a:{label:"Power Cell"},f:[{t:4,f:[{p:[76,5,2567],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.powerCellStatus",p:[76,38,2600]}],state:[{t:2,r:"powerCellStatusState",p:[76,71,2633]}]},f:[{t:2,x:{r:["adata.powerCellStatus"],s:"Math.fixed(_0)"},p:[76,97,2659]},"%"]}],n:50,x:{r:["data.powerCellStatus"],s:"_0!=null"},p:[75,3,2525]},{t:4,n:51,f:[{p:[78,5,2724],t:7,e:"span",a:{"class":"bad"},f:["Removed"]}],x:{r:["data.powerCellStatus"],s:"_0!=null"}}]}," ",{t:4,f:[{p:[82,3,2830],t:7,e:"ui-section",a:{label:"Charge Mode"},f:[{t:4,f:[{p:[84,4,2913],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.chargeMode"],s:'_0?"good":"bad"'},p:[84,17,2926]}]},f:[{t:2,x:{r:["data.chargeMode"],s:'_0?"Auto":"Off"'},p:[84,55,2964]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[83,5,2868]},{t:4,n:51,f:[{p:[86,4,3026],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.chargeMode"],s:'_0?"refresh":"close"'},p:[86,21,3043]}],style:[{t:2,x:{r:["data.chargeMode"],s:'_0?"selected":null'},p:[86,71,3093]}],action:"charge"},f:[{t:2,x:{r:["data.chargeMode"],s:'_0?"Auto":"Off"'},p:[87,22,3156]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}," [",{p:[90,6,3236],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.chargingStatus"],s:"_0(_1)"},p:[90,19,3249]}]},f:[{t:2,x:{r:["data.chargingStatus"],s:'_0==2?"Fully Charged":_0==1?"Charging":"Not Charging"'},p:[90,56,3286]}]},"]"]}],n:50,x:{r:["data.powerCellStatus"],s:"_0!=null"},p:[81,4,2790]}]}," ",{p:[94,2,3445],t:7,e:"ui-display",a:{title:"Power Channels"},f:[{t:4,f:[{p:[96,3,3517],t:7,e:"ui-section",a:{label:[{t:2,r:"title",p:[96,22,3536]}],nowrap:0},f:[{p:[97,5,3560],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.powerChannels"],s:"Math.round(_1[_0].powerLoad)"},p:[97,26,3581]}," W"]}," ",{p:[98,5,3648],t:7,e:"div",a:{"class":"content"},f:[{p:[98,26,3669],t:7,e:"span",a:{"class":[{t:2,x:{r:["status"],s:'_0>=2?"good":"bad"'},p:[98,39,3682]}]},f:[{t:2,x:{r:["status"],s:'_0>=2?"On":"Off"'},p:[98,73,3716]}]}]}," ",{p:[99,5,3765],t:7,e:"div",a:{"class":"content"},f:["[",{p:[99,27,3787],t:7,e:"span",f:[{t:2,x:{r:["status"],s:'_0==1||_0==3?"Auto":"Manual"'},p:[99,33,3793]}]},"]"]}," ",{p:[100,5,3863],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{t:4,f:[{p:[102,6,3956],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["status"],s:'_0==1||_0==3?"selected":null'},p:[102,39,3989]}],action:"channel",params:[{t:2,r:"topicParams.auto",p:[103,30,4071]}]},f:["Auto"]}," ",{p:[104,6,4116],t:7,e:"ui-button",a:{icon:"power-off",state:[{t:2,x:{r:["status"],s:'_0==2?"selected":null'},p:[104,41,4151]}],action:"channel",params:[{t:2,r:"topicParams.on",p:[105,13,4218]}]},f:["On"]}," ",{p:[106,6,4259],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["status"],s:'_0==0?"selected":null'},p:[106,37,4290]}],action:"channel",params:[{t:2,r:"topicParams.off",p:[107,13,4357]}]},f:["Off"]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[101,4,3909]}]}]}],n:52,r:"data.powerChannels",p:[95,4,3485]}," ",{p:[112,4,4453],t:7,e:"ui-section",a:{label:"Total Load"},f:[{p:[113,3,4488],t:7,e:"span",a:{"class":"bold"},f:[{t:2,x:{r:["adata.totalLoad"],s:"Math.round(_0)"},p:[113,22,4507]}," W"]}]}]}," ",{t:4,f:[{p:[117,4,4613],t:7,e:"ui-display",a:{title:"System Overrides"},f:[{p:[118,3,4654],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"overload"},f:["Overload"]}," ",{t:4,f:[{p:[120,5,4755],t:7,e:"ui-button",a:{icon:[{t:2,r:"malfIcon",p:[120,22,4772]}],state:[{t:2,x:{r:["data.malfStatus"],s:'_0==4?"disabled":null'},p:[120,43,4793]}],action:[{t:2,r:"malfAction",p:[120,97,4847]}]},f:[{t:2,r:"malfButton",p:[120,113,4863]}]}],n:50,r:"data.malfStatus",p:[119,3,4726]}]}],n:50,r:"data.siliconUser",p:[116,2,4584]}," ",{p:[124,2,4931],t:7,e:"ui-notice",f:[{p:[125,4,4947],t:7,e:"ui-section",a:{label:"Cover Lock"},f:[{t:4,f:[{p:[127,5,5028],t:7,e:"span",f:[{t:2,x:{r:["data.coverLocked"],s:'_0?"Engaged":"Disengaged"'},p:[127,11,5034]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[126,3,4982]},{t:4,n:51,f:[{p:[129,5,5106],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.coverLocked"],s:'_0?"lock":"unlock"'},p:[129,22,5123]}],action:"cover"},f:[{t:2,x:{r:["data.coverLocked"],s:'_0?"Engaged":"Disengaged"'},p:[129,79,5180]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}]}],r:"data.failTime"}]},e.exports=a.extend(r.exports)},{205:205}],228:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Alarms"},f:[{p:[2,3,31],t:7,e:"ul",f:[{t:4,f:[{p:[4,7,72],t:7,e:"li",f:[{p:[4,11,76],t:7,e:"ui-button",a:{icon:"close",style:"danger",action:"clear",params:['{"zone": "',{t:2,r:".",p:[4,83,148]},'"}']},f:[{t:2,r:".",p:[4,92,157]}]}]}],n:52,r:"data.priority",p:[3,5,41]},{t:4,n:51,f:[{p:[6,7,201],t:7,e:"li",f:[{p:[6,11,205],t:7,e:"span",a:{"class":"good"},f:["No Priority Alerts"]}]}],r:"data.priority"}," ",{t:4,f:[{p:[9,7,303],t:7,e:"li",f:[{p:[9,11,307],t:7,e:"ui-button",a:{icon:"close",style:"caution",action:"clear",params:['{"zone": "',{t:2,r:".",p:[9,84,380]},'"}']},f:[{t:2,r:".",p:[9,93,389]}]}]}],n:52,r:"data.minor",p:[8,5,275]},{t:4,n:51,f:[{p:[11,7,433],t:7,e:"li",f:[{p:[11,11,437],t:7,e:"span",a:{"class":"good"},f:["No Minor Alerts"]}]}],r:"data.minor"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],229:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:[{t:2,x:{r:["data.tank","data.sensors.0.long_name"],s:"_0?_1:null"},p:[1,20,19]}]},f:[{t:4,f:[{p:[3,5,102],t:7,e:"ui-subdisplay",a:{title:[{t:2,x:{r:["data.tank","long_name"],s:"!_0?_1:null"},p:[3,27,124]}]},f:[{p:[4,7,167],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[5,3,200],t:7,e:"span",f:[{t:2,x:{r:["pressure"],s:"Math.fixed(_0,2)"},p:[5,9,206]}," kPa"]}]}," ",{t:4,f:[{p:[8,9,302],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[9,11,346],t:7,e:"span",f:[{t:2,x:{r:["temperature"],s:"Math.fixed(_0,2)"},p:[9,17,352]}," K"]}]}],n:50,r:"temperature",p:[7,7,273]}," ",{t:4,f:[{p:[13,9,462],t:7,e:"ui-section",a:{label:[{t:2,r:"id",p:[13,28,481]}]},f:[{p:[14,5,495],t:7,e:"span",f:[{t:2,x:{r:["."],s:"Math.fixed(_0,2)"},p:[14,11,501]},"%"]}]}],n:52,i:"id",r:"gases",p:[12,4,434]}]}],n:52,r:"adata.sensors",p:[2,3,73]}]}," ",{t:4,f:[{p:{button:[{p:[23,5,704],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect"},f:["Reconnect"]}]},t:7,e:"ui-display",a:{title:"Controls",button:0},f:[" ",{p:[25,5,792],t:7,e:"ui-section",a:{label:"Input Injector"},f:[{p:[26,7,835],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.inputting"],s:'_0?"power-off":"close"'},p:[26,24,852]}],style:[{t:2,x:{r:["data.inputting"],s:'_0?"selected":null'},p:[26,75,903]}],action:"input"},f:[{t:2,x:{r:["data.inputting"],s:'_0?"Injecting":"Off"'},p:[27,9,968]}]}]}," ",{p:[29,5,1044],t:7,e:"ui-section",a:{label:"Input Rate"},f:[{p:[30,7,1083],t:7,e:"span",f:[{t:2,x:{r:["adata.inputRate"],s:"Math.fixed(_0)"},p:[30,13,1089]}," L/s"]}]}," ",{p:[32,5,1156],t:7,e:"ui-section",a:{label:"Output Regulator"},f:[{p:[33,7,1201],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.outputting"],s:'_0?"power-off":"close"'},p:[33,24,1218]}],style:[{t:2,x:{r:["data.outputting"],s:'_0?"selected":null'},p:[33,76,1270]}],action:"output"},f:[{t:2,x:{r:["data.outputting"],s:'_0?"Open":"Closed"'},p:[34,9,1337]}]}]}," ",{p:[36,5,1412],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[37,7,1456],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure"},f:[{t:2,x:{r:["adata.outputPressure"],s:"Math.round(_0)"},p:[37,50,1499]}," kPa"]}]}]}],n:50,r:"data.tank",p:[20,1,618]}]},e.exports=a.extend(r.exports)},{205:205}],230:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,48],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[3,22,65]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[3,66,109]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[4,22,164]}]}]}," ",{p:[6,3,223],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[7,5,265],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[8,5,360],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[8,35,390]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[9,5,518],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[9,11,524]}," kPa"]}]}," ",{p:[11,3,586],t:7,e:"ui-section",a:{label:"Filter"},f:[{p:[12,5,619],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.filter_type"],s:'_0==""?"selected":null'},p:[12,23,637]}],action:"filter",params:'{"mode": ""}'},f:["Nothing"]}," ",{p:[14,5,755],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.filter_type"],s:'_0=="plasma"?"selected":null'},p:[14,23,773]}],action:"filter",params:'{"mode": "plasma"}'},f:["Plasma"]}," ",{p:[16,5,902],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.filter_type"],s:'_0=="o2"?"selected":null'},p:[16,23,920]}],action:"filter",params:'{"mode": "o2"}'},f:["O2"]}," ",{p:[18,5,1037],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.filter_type"],s:'_0=="n2"?"selected":null'},p:[18,23,1055]}],action:"filter",params:'{"mode": "n2"}'},f:["N2"]}," ",{p:[20,5,1172],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.filter_type"],s:'_0=="co2"?"selected":null'},p:[20,23,1190]}],action:"filter",params:'{"mode": "co2"}'},f:["CO2"]}," ",{p:[22,5,1310],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.filter_type"],s:'_0=="n2o"?"selected":null'},p:[22,23,1328]}],action:"filter",params:'{"mode": "n2o"}'},f:["N2O"]}," ",{p:[24,2,1445],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.filter_type"],s:'_0=="bz"?"selected":null'},p:[24,20,1463]}],action:"filter",params:'{"mode": "bz"}'},f:["BZ"]}," ",{p:[26,2,1578],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.filter_type"],s:'_0=="freon"?"selected":null'},p:[26,20,1596]}],action:"filter",params:'{"mode": "freon"}'},f:["Freon"]}," ",{p:[28,2,1720],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.filter_type"],s:'_0=="water_vapor"?"selected":null'},p:[28,20,1738]}],action:"filter",params:'{"mode": "water_vapor"}'},f:["Water Vapor"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],231:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,48],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[3,22,65]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[3,66,109]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[4,22,164]}]}]}," ",{p:[6,3,223],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[7,5,265],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[8,5,360],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.set_pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[8,35,390]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[9,5,522],t:7,e:"span",f:[{t:2,x:{r:["adata.set_pressure"],s:"Math.round(_0)"},p:[9,11,528]}," kPa"]}]}," ",{p:[11,3,594],t:7,e:"ui-section",a:{label:"Node 1"},f:[{p:[12,5,627],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==0?"disabled":null'},p:[12,44,666]}],action:"node1",params:'{"concentration": -0.1}'}}," ",{p:[14,5,783],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==0?"disabled":null'},p:[14,39,817]}],action:"node1",params:'{"concentration": -0.01}'}}," ",{p:[16,5,935],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==100?"disabled":null'},p:[16,38,968]}],action:"node1",params:'{"concentration": 0.01}'}}," ",{p:[18,5,1087],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==100?"disabled":null'},p:[18,43,1125]}],action:"node1",params:'{"concentration": 0.1}'}}," ",{p:[20,5,1243],t:7,e:"span",f:[{t:2,x:{r:["adata.node1_concentration"],s:"Math.round(_0)"},p:[20,11,1249]},"%"]}]}," ",{p:[22,3,1319],t:7,e:"ui-section",a:{label:"Node 2"},f:[{p:[23,5,1352],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==0?"disabled":null'},p:[23,44,1391]}],action:"node2",params:'{"concentration": -0.1}'}}," ",{p:[25,5,1508],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==0?"disabled":null'},p:[25,39,1542]}],action:"node2",params:'{"concentration": -0.01}'}}," ",{p:[27,5,1660],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==100?"disabled":null'},p:[27,38,1693]}],action:"node2",params:'{"concentration": 0.01}'}}," ",{p:[29,5,1812],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==100?"disabled":null'},p:[29,43,1850]}],action:"node2",params:'{"concentration": 0.1}'}}," ",{p:[31,5,1968],t:7,e:"span",f:[{t:2,x:{r:["adata.node2_concentration"],s:"Math.round(_0)"},p:[31,11,1974]},"%"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],232:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,48],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[3,22,65]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[3,66,109]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[4,22,164]}]}]}," ",{t:4,f:[{p:[7,5,250],t:7,e:"ui-section",a:{label:"Transfer Rate"},f:[{p:[8,7,292],t:7,e:"ui-button",a:{icon:"pencil",action:"rate",params:'{"rate": "input"}'},f:["Set"]}," ",{p:[9,7,381],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.rate","data.max_rate"],s:'_0==_1?"disabled":null'},p:[9,37,411]}],action:"rate",params:'{"rate": "max"}'},f:["Max"]}," ",{p:[10,7,525],t:7,e:"span",f:[{t:2,x:{r:["adata.rate"],s:"Math.round(_0)"},p:[10,13,531]}," L/s"]}]}],n:50,r:"data.max_rate",p:[6,3,223]},{t:4,n:51,f:[{ --p:[13,5,605],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[14,7,649],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[15,7,746],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[15,37,776]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[16,7,906],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[16,13,912]}," kPa"]}]}],r:"data.max_rate"}]}]},e.exports=a.extend(r.exports)},{205:205}],233:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{p:[3,5,67],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"selected":null'},p:[3,38,100]}],action:[{t:2,x:{r:["data.timing"],s:'_0?"stop":"start"'},p:[3,83,145]}]},f:[{t:2,x:{r:["data.timing"],s:'_0?"Stop":"Start"'},p:[3,119,181]}]}," ",{p:[4,5,233],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"flash",style:[{t:2,x:{r:["data.flash_charging"],s:'_0?"disabled":null'},p:[4,57,285]}]},f:[{t:2,x:{r:["data.flash_charging"],s:'_0?"Recharging":"Flash"'},p:[4,102,330]}]}]},t:7,e:"ui-display",a:{title:"Cell Timer",button:0},f:[" ",{p:[6,3,410],t:7,e:"ui-section",f:[{p:[7,5,428],t:7,e:"ui-button",a:{icon:"fast-backward",action:"time",params:'{"adjust": -600}'}}," ",{p:[8,5,518],t:7,e:"ui-button",a:{icon:"backward",action:"time",params:'{"adjust": -100}'}}," ",{p:[9,5,603],t:7,e:"span",f:[{t:2,x:{r:["text","data.minutes"],s:"_0.zeroPad(_1,2)"},p:[9,11,609]},":",{t:2,x:{r:["text","data.seconds"],s:"_0.zeroPad(_1,2)"},p:[9,45,643]}]}," ",{p:[10,5,689],t:7,e:"ui-button",a:{icon:"forward",action:"time",params:'{"adjust": 100}'}}," ",{p:[11,5,772],t:7,e:"ui-button",a:{icon:"fast-forward",action:"time",params:'{"adjust": 600}'}}]}," ",{p:[13,3,875],t:7,e:"ui-section",f:[{p:[14,7,895],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "short"}'},f:["Short"]}," ",{p:[15,7,999],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "medium"}'},f:["Medium"]}," ",{p:[16,7,1105],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "long"}'},f:["Long"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],234:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,23],t:7,e:"ui-notice",f:[{t:2,r:"data.notice",p:[3,5,40]}]}],n:50,r:"data.notice",p:[1,1,0]},{p:[6,1,82],t:7,e:"ui-display",a:{title:"Bluespace Artillery Control",button:0},f:[{t:4,f:[{p:[8,3,167],t:7,e:"ui-section",a:{label:"Target"},f:[{p:[9,5,200],t:7,e:"ui-button",a:{icon:"crosshairs",action:"recalibrate"},f:[{t:2,r:"data.target",p:[9,55,250]}]}]}," ",{p:[11,3,298],t:7,e:"ui-section",a:{label:"Controls"},f:[{t:4,f:[{p:[13,3,356],t:7,e:"ui-notice",f:[{p:[14,4,372],t:7,e:"span",f:["Bluespace Artillery firing protocols must be globally unlocked from two keycard authentication devices first!"]}]}],n:50,x:{r:["data.unlocked"],s:"!_0"},p:[12,2,330]},{t:4,n:51,f:[{p:[17,3,525],t:7,e:"ui-button",a:{icon:"warning",state:[{t:2,x:{r:["data.ready"],s:'_0?null:"disabled"'},p:[17,36,558]}],action:"fire"},f:["FIRE!"]}],x:{r:["data.unlocked"],s:"!_0"}}]}],n:50,r:"data.connected",p:[7,3,141]}," ",{t:4,f:[{p:[22,3,694],t:7,e:"ui-section",a:{label:"Maintenance"},f:[{p:[23,7,734],t:7,e:"ui-button",a:{icon:"wrench",action:"build"},f:["Complete Deployment."]}]}],n:50,x:{r:["data.connected"],s:"!_0"},p:[21,3,667]}]}]},e.exports=a.extend(r.exports)},{205:205}],235:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.hasHoldingTank"],s:'_0?"is":"is not"'},p:[2,23,35]}," connected to a tank."]}]}," ",{p:{button:[{p:[6,5,185],t:7,e:"ui-button",a:{icon:"pencil",action:"relabel"},f:["Relabel"]}]},t:7,e:"ui-display",a:{title:"Canister",button:0},f:[" ",{p:[8,3,266],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[9,5,301],t:7,e:"span",f:[{t:2,x:{r:["adata.tankPressure"],s:"Math.round(_0)"},p:[9,11,307]}," kPa"]}]}," ",{p:[11,3,373],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[12,5,404],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.portConnected"],s:'_0?"good":"average"'},p:[12,18,417]}]},f:[{t:2,x:{r:["data.portConnected"],s:'_0?"Connected":"Not Connected"'},p:[12,63,462]}]}]}," ",{t:4,f:[{p:[15,3,573],t:7,e:"ui-section",a:{label:"Access"},f:[{p:[16,7,608],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.restricted"],s:'_0?"lock":"unlock"'},p:[16,24,625]}],style:[{t:2,x:{r:[],s:'"caution"'},p:[17,14,680]}],action:"restricted"},f:[{t:2,x:{r:["data.restricted"],s:'_0?"Restricted to Engineering":"Public"'},p:[18,27,722]}]}]}],n:50,r:"data.isPrototype",p:[14,3,544]}]}," ",{p:[22,1,839],t:7,e:"ui-display",a:{title:"Valve"},f:[{p:[23,3,869],t:7,e:"ui-section",a:{label:"Release Pressure"},f:[{p:[24,5,912],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.minReleasePressure",p:[24,18,925]}],max:[{t:2,r:"data.maxReleasePressure",p:[24,52,959]}],value:[{t:2,r:"data.releasePressure",p:[25,14,1002]}]},f:[{t:2,x:{r:["adata.releasePressure"],s:"Math.round(_0)"},p:[25,40,1028]}," kPa"]}]}," ",{p:[27,3,1099],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[28,5,1144],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.releasePressure","data.defaultReleasePressure"],s:'_0!=_1?null:"disabled"'},p:[28,38,1177]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[30,5,1333],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.releasePressure","data.minReleasePressure"],s:'_0>_1?null:"disabled"'},p:[30,36,1364]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[32,5,1511],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[33,5,1606],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.releasePressure","data.maxReleasePressure"],s:'_0<_1?null:"disabled"'},p:[33,35,1636]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}," ",{p:[36,3,1798],t:7,e:"ui-section",a:{label:"Valve"},f:[{p:[37,5,1830],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.valveOpen"],s:'_0?"unlock":"lock"'},p:[37,22,1847]}],style:[{t:2,x:{r:["data.valveOpen","data.hasHoldingTank"],s:'_0?_1?"caution":"danger":null'},p:[38,14,1901]}],action:"valve"},f:[{t:2,x:{r:["data.valveOpen"],s:'_0?"Open":"Closed"'},p:[39,22,1995]}]}]}]}," ",{t:4,f:[{p:[42,1,2090],t:7,e:"ui-display",a:{title:"Valve Toggle Timer"},f:[{t:4,f:[{p:[44,5,2155],t:7,e:"ui-section",a:{label:"Adjust Timer"},f:[{p:[45,7,2196],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.timer_is_not_default"],s:'_0?null:"disabled"'},p:[45,40,2229]}],action:"timer",params:'{"change": "reset"}'},f:["Reset"]}," ",{p:[47,7,2358],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.timer_is_not_min"],s:'_0?null:"disabled"'},p:[47,38,2389]}],action:"timer",params:'{"change": "decrease"}'},f:["Decrease"]}," ",{p:[49,7,2520],t:7,e:"ui-button",a:{icon:"pencil",state:[{t:2,x:{r:[],s:'"disabled"'},p:[49,39,2552]}],action:"timer",params:'{"change": "input"}'},f:["Set"]}," ",{p:[51,7,2637],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.timer_is_not_max"],s:'_0?null:"disabled"'},p:[51,37,2667]}],action:"timer",params:'{"change": "increase"}'},f:["Increase"]}]}],n:51,r:"data.timing",p:[43,3,2133]}," ",{p:[55,3,2833],t:7,e:"ui-section",a:{label:"Timer"},f:[{p:[56,6,2866],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"danger":"caution"'},p:[56,39,2899]}],action:"toggle_timer"},f:[{t:2,x:{r:["data.timing"],s:'_0?"On":"Off"'},p:[57,30,2969]}]}," ",{p:[59,2,3017],t:7,e:"ui-section",a:{label:"Time until Valve Toggle"},f:[{p:[60,2,3064],t:7,e:"span",f:[{t:2,x:{r:["data.timing","data.time_left","data.timer_set"],s:"_0?_1:_2"},p:[60,8,3070]}]}]}]}]}],n:50,r:"data.isPrototype",p:[41,1,2062]},{p:{button:[{t:4,f:[{p:[69,7,3277],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.valveOpen"],s:'_0?"danger":null'},p:[69,38,3308]}],action:"eject"},f:["Eject"]}],n:50,r:"data.hasHoldingTank",p:[68,5,3242]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[73,3,3442],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holdingTank.name",p:[74,4,3473]}]}," ",{p:[76,3,3519],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holdingTank.tankPressure"],s:"Math.round(_0)"},p:[77,4,3553]}," kPa"]}],n:50,r:"data.hasHoldingTank",p:[72,3,3411]},{t:4,n:51,f:[{p:[80,3,3635],t:7,e:"ui-section",f:[{p:[81,4,3652],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.hasHoldingTank"}]}]},e.exports=a.extend(r.exports)},{205:205}],236:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{tabs:function(){return Object.keys(this.get("data.supplies"))}}}}(r),r.exports.template={v:3,t:[" ",{p:[11,1,158],t:7,e:"ui-display",a:{title:"Cargo"},f:[{p:[12,3,188],t:7,e:"ui-section",a:{label:"Shuttle"},f:[{t:4,f:[{p:[14,7,270],t:7,e:"ui-button",a:{action:"send"},f:[{t:2,r:"data.location",p:[14,32,295]}]}],n:50,x:{r:["data.docked","data.requestonly"],s:"_0&&!_1"},p:[13,5,222]},{t:4,n:51,f:[{p:[16,7,346],t:7,e:"span",f:[{t:2,r:"data.location",p:[16,13,352]}]}],x:{r:["data.docked","data.requestonly"],s:"_0&&!_1"}}]}," ",{p:[19,3,410],t:7,e:"ui-section",a:{label:"Credits"},f:[{p:[20,5,444],t:7,e:"span",f:[{t:2,x:{r:["adata.points"],s:"Math.floor(_0)"},p:[20,11,450]}]}]}," ",{p:[22,3,506],t:7,e:"ui-section",a:{label:"Centcom Message"},f:[{p:[23,7,550],t:7,e:"span",f:[{t:2,r:"data.message",p:[23,13,556]}]}]}," ",{t:4,f:[{p:[26,5,644],t:7,e:"ui-section",a:{label:"Loan"},f:[{t:4,f:[{p:[28,9,716],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.away","data.docked"],s:'_0&&_1?null:"disabled"'},p:[29,17,744]}],action:"loan"},f:["Loan Shuttle"]}],n:50,x:{r:["data.loan_dispatched"],s:"!_0"},p:[27,7,677]},{t:4,n:51,f:[{p:[32,9,868],t:7,e:"span",a:{"class":"bad"},f:["Loaned to Centcom"]}],x:{r:["data.loan_dispatched"],s:"!_0"}}]}],n:50,x:{r:["data.loan","data.requestonly"],s:"_0&&!_1"},p:[25,3,600]}]}," ",{t:4,f:[{p:{button:[{p:[40,7,1066],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.cart.length"],s:'_0?null:"disabled"'},p:[40,38,1097]}],action:"clear"},f:["Clear"]}]},t:7,e:"ui-display",a:{title:"Cart",button:0},f:[" ",{t:4,f:[{p:[43,7,1222],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[44,9,1263],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[44,31,1285]}]}," ",{p:[45,9,1307],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"object",p:[45,30,1328]}]}," ",{p:[46,9,1354],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"cost",p:[46,30,1375]}," Credits"]}," ",{p:[47,9,1407],t:7,e:"div",a:{"class":"content"},f:[{p:[48,11,1440],t:7,e:"ui-button",a:{icon:"minus",action:"remove",params:['{"id": "',{t:2,r:"id",p:[48,67,1496]},'"}']}}]}]}],n:52,r:"data.cart",p:[42,5,1195]},{t:4,n:51,f:[{p:[52,7,1566],t:7,e:"span",f:["Nothing in Cart"]}],r:"data.cart"}]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[37,1,972]},{p:{button:[{t:4,f:[{p:[59,7,1735],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.requests.length"],s:'_0?null:"disabled"'},p:[59,38,1766]}],action:"denyall"},f:["Clear"]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[58,5,1702]}]},t:7,e:"ui-display",a:{title:"Requests",button:0},f:[" ",{t:4,f:[{p:[63,5,1908],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[64,7,1947],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[64,29,1969]}]}," ",{p:[65,7,1989],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"object",p:[65,28,2010]}]}," ",{p:[66,7,2034],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"cost",p:[66,28,2055]}," Credits"]}," ",{p:[67,7,2085],t:7,e:"div",a:{"class":"content"},f:["By ",{t:2,r:"orderer",p:[67,31,2109]}]}," ",{p:[68,7,2134],t:7,e:"div",a:{"class":"content"},f:["Comment: ",{t:2,r:"reason",p:[68,37,2164]}]}," ",{t:4,f:[{p:[70,9,2223],t:7,e:"div",a:{"class":"content"},f:[{p:[71,11,2256],t:7,e:"ui-button",a:{icon:"check",action:"approve",params:['{"id": "',{t:2,r:"id",p:[71,68,2313]},'"}']}}," ",{p:[72,11,2336],t:7,e:"ui-button",a:{icon:"close",action:"deny",params:['{"id": "',{t:2,r:"id",p:[72,65,2390]},'"}']}}]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[69,7,2188]}]}],n:52,r:"data.requests",p:[62,3,1879]},{t:4,n:51,f:[{p:[77,7,2473],t:7,e:"span",f:["No Requests"]}],r:"data.requests"}]}," ",{p:[80,1,2529],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"tabs",p:[80,16,2544]}]},f:[{t:4,f:[{p:[82,5,2587],t:7,e:"tab",a:{name:[{t:2,r:"name",p:[82,16,2598]}]},f:[{t:4,f:[{p:[84,9,2641],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[84,28,2660]}],candystripe:0,right:0},f:[{p:[85,11,2700],t:7,e:"ui-button",a:{action:"add",params:['{"id": "',{t:2,r:"id",p:[85,51,2740]},'"}']},f:[{t:2,r:"cost",p:[85,61,2750]}," Credits"]}]}],n:52,r:"packs",p:[83,7,2616]}]}],n:52,r:"data.supplies",p:[81,3,2558]}]}]},e.exports=a.extend(r.exports)},{205:205}],237:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Cellular Emporium",button:0},f:[{p:[2,3,49],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.can_readapt"],s:'_0?null:"disabled"'},p:[2,36,82]}],action:"readapt"},f:["Readapt"]}," ",{p:[4,3,169],t:7,e:"ui-section",a:{label:"Genetic Points Remaining",right:0},f:[{t:2,r:"data.genetic_points_remaining",p:[5,5,226]}]}]}," ",{p:[8,1,293],t:7,e:"ui-display",f:[{t:4,f:[{p:[10,3,335],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[10,22,354]}],candystripe:0,right:0},f:[{p:[11,5,388],t:7,e:"span",f:[{t:2,r:"desc",p:[11,11,394]}]}," ",{p:[12,5,415],t:7,e:"span",f:[{t:2,r:"helptext",p:[12,11,421]}]}," ",{p:[13,5,446],t:7,e:"span",f:["Cost: ",{t:2,r:"dna_cost",p:[13,17,458]}]}," ",{p:[14,5,483],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["owned","can_purchase"],s:'_0?"selected":_1?null:"disabled"'},p:[15,14,508]}],action:"evolve",params:['{"name": "',{t:2,r:"name",p:[17,25,615]},'"}']},f:[{t:2,x:{r:["owned"],s:'_0?"Evolved":"Evolve"'},p:[18,7,635]}]}]}],n:52,r:"data.abilities",p:[9,1,307]},{t:4,f:[{p:[23,3,738],t:7,e:"span",a:{"class":"warning"},f:["No abilities availible."]}],n:51,r:"data.abilities",p:[22,1,715]}]}]},e.exports=a.extend(r.exports)},{205:205}],238:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,3,31],t:7,e:"ui-section",a:{label:"Energy"},f:[{p:[3,5,64],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.maxEnergy",p:[3,26,85]}],value:[{t:2,r:"data.energy",p:[3,53,112]}]},f:[{t:2,x:{r:["adata.energy"],s:"Math.fixed(_0)"},p:[3,70,129]}," Units"]}]}]}," ",{p:{button:[{t:4,f:[{p:[9,7,315],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.amount","."],s:'_0==_1?"selected":null'},p:[9,37,345]}],action:"amount",params:['{"target": ',{t:2,r:".",p:[9,114,422]},"}"]},f:[{t:2,r:".",p:[9,122,430]}]}],n:52,r:"data.beakerTransferAmounts",p:[8,5,271]}]},t:7,e:"ui-display",a:{title:"Dispense",button:0},f:[" ",{p:[12,3,482],t:7,e:"ui-section",f:[{t:4,f:[{p:[14,7,532],t:7,e:"ui-button",a:{grid:0,icon:"tint",action:"dispense",params:['{"reagent": "',{t:2,r:"id",p:[14,74,599]},'"}']},f:[{t:2,r:"title",p:[14,84,609]}]}],n:52,r:"data.chemicals",p:[13,5,500]}]}]}," ",{p:{button:[{t:4,f:[{p:[21,7,786],t:7,e:"ui-button",a:{icon:"minus",action:"remove",params:['{"amount": ',{t:2,r:".",p:[21,66,845]},"}"]},f:[{t:2,r:".",p:[21,74,853]}]}],n:52,r:"data.beakerTransferAmounts",p:[20,5,742]}," ",{p:[23,5,891],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[23,36,922]}],action:"eject"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[25,3,1019],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[27,7,1089],t:7,e:"span",f:[{t:2,x:{r:["adata.beakerCurrentVolume"],s:"Math.round(_0)"},p:[27,13,1095]},"/",{t:2,r:"data.beakerMaxVolume",p:[27,55,1137]}," Units"]}," ",{p:[28,7,1182],t:7,e:"br"}," ",{t:4,f:[{p:[30,9,1235],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[30,52,1278]}," units of ",{t:2,r:"name",p:[30,87,1313]}]},{p:[30,102,1328],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[29,7,1195]},{t:4,n:51,f:[{p:[32,9,1359],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[26,5,1054]},{t:4,n:51,f:[{p:[35,7,1435],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],239:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Thermostat"},f:[{p:[2,3,35],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,67],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isActive"],s:'_0?"power-off":"close"'},p:[3,22,84]}],style:[{t:2,x:{r:["data.isActive"],s:'_0?"selected":null'},p:[4,10,137]}],state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[5,10,186]}],action:"power"},f:[{t:2,x:{r:["data.isActive"],s:'_0?"On":"Off"'},p:[6,18,249]}]}]}," ",{p:[8,3,314],t:7,e:"ui-section",a:{label:"Target"},f:[{p:[9,4,346],t:7,e:"ui-button",a:{icon:"pencil",action:"temperature",params:'{"target": "input"}'},f:[{t:2,x:{r:["adata.targetTemp"],s:"Math.round(_0)"},p:[9,79,421]}," K"]}]}]}," ",{p:{button:[{p:[14,5,564],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[14,36,595]}],action:"eject"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[16,3,692],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[18,7,762],t:7,e:"span",f:["Temperature: ",{t:2,x:{r:["adata.currentTemp"],s:"Math.round(_0)"},p:[18,26,781]}," K"]}," ",{p:[19,7,831],t:7,e:"br"}," ",{t:4,f:[{p:[21,9,885],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[21,52,928]}," units of ",{t:2,r:"name",p:[21,87,963]}]},{p:[21,102,978],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[20,7,845]},{t:4,n:51,f:[{p:[23,9,1009],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[17,5,727]},{t:4,n:51,f:[{p:[26,7,1085],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],240:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,32],t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[{p:[3,3,70],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"Eject":"close"'},p:[3,20,87]}],style:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"selected":null'},p:[4,11,143]}],state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[5,11,199]}],action:"eject"},f:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"Eject and Clear Buffer":"No beaker"'},p:[7,5,268]}]}," ",{p:[10,3,357],t:7,e:"ui-section",f:[{t:4,f:[{t:4,f:[{p:[13,6,443],t:7,e:"ui-section",a:{label:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[13,25,462]}," units of ",{t:2,r:"name",p:[13,60,497]}],nowrap:0},f:[{p:[14,7,522],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{p:[15,8,572],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[15,61,625]},'", "amount": 1}']},f:["1"]}," ",{p:[16,8,670],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[16,61,723]},'", "amount": 5}']},f:["5"]}," ",{p:[17,8,768],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[17,61,821]},'", "amount": 10}']},f:["10"]}," ",{p:[18,8,868],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[18,61,921]},'", "amount": 1000}']},f:["All"]}," ",{p:[19,8,971],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[19,61,1024]},'", "amount": -1}']},f:["Custom"]}," ",{p:[20,8,1075],t:7,e:"ui-button",a:{action:"analyze",params:['{"id": "',{t:2,r:"id",p:[20,52,1119]},'"}']},f:["Analyze"]}]}]}],n:52,r:"data.beakerContents",p:[12,5,407]},{t:4,n:51,f:[{p:[24,5,1201],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"data.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[11,4,374]},{t:4,n:51,f:[{p:[27,5,1272],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}," ",{p:[32,2,1360],t:7,e:"ui-display",a:{title:"Buffer"},f:[{p:[33,3,1391],t:7,e:"ui-button",a:{action:"toggleMode",state:[{t:2,x:{r:["data.mode"],s:'_0?null:"selected"'},p:[33,41,1429]}]},f:["Destroy"]}," ",{p:[34,3,1487],t:7,e:"ui-button",a:{action:"toggleMode",state:[{t:2,x:{r:["data.mode"],s:'_0?"selected":null'},p:[34,41,1525]}]},f:["Transfer to Beaker"]}," ",{p:[35,3,1594],t:7,e:"ui-section",f:[{t:4,f:[{p:[37,5,1646],t:7,e:"ui-section",a:{label:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[37,24,1665]}," units of ",{t:2,r:"name",p:[37,59,1700]}],nowrap:0},f:[{p:[38,6,1724],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{p:[39,7,1773],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[39,62,1828]},'", "amount": 1}']},f:["1"]}," ",{p:[40,7,1872],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[40,62,1927]},'", "amount": 5}']},f:["5"]}," ",{p:[41,7,1971],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[41,62,2026]},'", "amount": 10}']},f:["10"]}," ",{p:[42,7,2072],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[42,62,2127]},'", "amount": 1000}']},f:["All"]}," ",{p:[43,7,2176],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[43,62,2231]},'", "amount": -1}']},f:["Custom"]}," ",{p:[44,7,2281],t:7,e:"ui-button",a:{action:"analyze",params:['{"id": "',{t:2,r:"id",p:[44,51,2325]},'"}']},f:["Analyze"]}]}]}],n:52,r:"data.bufferContents",p:[36,4,1611]}]}]}," ",{t:4,f:[{p:[52,3,2461],t:7,e:"ui-display",a:{title:"Pills, Bottles and Patches"},f:[{t:4,f:[{p:[54,5,2551],t:7,e:"ui-button",a:{action:"ejectp",state:[{t:2,x:{r:["data.isPillBottleLoaded"],s:'_0?null:"disabled"'},p:[54,39,2585]}]},f:[{t:2,x:{r:["data.isPillBottleLoaded"],s:'_0?"Eject":"No Pill bottle loaded"'},p:[54,88,2634]}]}," ",{p:[55,5,2715],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.pillBotContent",p:[55,27,2737]},"/",{t:2,r:"data.pillBotMaxContent",p:[55,51,2761]}]}],n:50,r:"data.isPillBottleLoaded",p:[53,4,2514]},{t:4,n:51,f:[{p:[57,5,2813],t:7,e:"span",a:{"class":"average"},f:["No Pillbottle"]}],r:"data.isPillBottleLoaded"}," ",{p:[60,4,2877],t:7,e:"br"}," ",{p:[61,4,2887],t:7,e:"br"}," ",{p:[62,4,2897],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[62,63,2956]}]},f:["Create Pill (max 50µ)"]}," ",{p:[63,4,3040],t:7,e:"br"}," ",{p:[64,4,3050],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[64,63,3109]}]},f:["Create Multiple Pills"]}," ",{p:[65,4,3193],t:7,e:"br"}," ",{p:[66,4,3203],t:7,e:"br"}," ",{p:[67,4,3213],t:7,e:"ui-button",a:{action:"createPatch",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[67,64,3273]}]},f:["Create Patch (max 40µ)"]}," ",{p:[68,4,3358],t:7,e:"br"}," ",{p:[69,4,3368],t:7,e:"ui-button",a:{action:"createPatch",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[69,64,3428]}]},f:["Create Multiple Patches"]}," ",{p:[70,4,3514],t:7,e:"br"}," ",{p:[71,4,3524],t:7,e:"br"}," ",{p:[72,4,3534],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[72,65,3595]}]},f:["Create Bottle (max 30µ)"]}," ",{p:[73,4,3681],t:7,e:"br"}," ",{p:[74,4,3691],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[74,65,3752]}]},f:["Dispense Buffer to Bottles"]}]}],n:50,x:{r:["data.condi"],s:"!_0"},p:[51,2,2438]},{t:4,n:51,f:[{p:[79,3,3874],t:7,e:"ui-display",a:{title:"Condiments bottles and packs"},f:[{p:[80,4,3929],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[80,63,3988]}]},f:["Create Pack (max 10µ)"]}," ",{p:[81,4,4072],t:7,e:"br"}," ",{p:[82,4,4082],t:7,e:"br"}," ",{p:[83,4,4092],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[83,65,4153]}]},f:["Create Bottle (max 50µ)"]}]}],x:{r:["data.condi"],s:"!_0"}}],n:50,x:{r:["data.screen"],s:'_0=="home"'},p:[1,1,0]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.screen"],s:'_0=="analyze"'},f:[{p:[87,2,4301],t:7,e:"ui-display",a:{title:[{t:2,r:"data.analyzeVars.name",p:[87,20,4319]}]},f:[{p:[88,3,4350],t:7,e:"span",a:{"class":"highlight"},f:["Description:"]}," ",{p:[89,3,4398],t:7,e:"span",a:{"class":"content",style:"float:center"},f:[{t:2,r:"data.analyzeVars.description",p:[89,46,4441]}]}," ",{p:[90,3,4484],t:7,e:"br"}," ",{p:[91,3,4493],t:7,e:"span",a:{"class":"highlight"},f:["Color:"]}," ",{p:[92,3,4535],t:7,e:"span",a:{style:["color: ",{t:2,r:"data.analyzeVars.color",p:[92,23,4555]},"; background-color: ",{t:2,r:"data.analyzeVars.color",p:[92,69,4601]}]},f:[{t:2,r:"data.analyzeVars.color",p:[92,97,4629]}]}," ",{p:[93,3,4666],t:7,e:"br"}," ",{p:[94,3,4675],t:7,e:"span",a:{"class":"highlight"},f:["State:"]}," ",{p:[95,3,4717],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.state",p:[95,25,4739]}]}," ",{p:[96,3,4776],t:7,e:"br"}," ",{p:[97,3,4785],t:7,e:"span",a:{"class":"highlight"},f:["Metabolization Rate:"]}," ",{p:[98,3,4841],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.metaRate",p:[98,25,4863]},"µ/minute"]}," ",{p:[99,3,4911],t:7,e:"br"}," ",{p:[100,3,4920],t:7,e:"span",a:{"class":"highlight"},f:["Overdose Threshold:"]}," ",{p:[101,3,4975],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.overD",p:[101,25,4997]}]}," ",{p:[102,3,5034],t:7,e:"br"}," ",{p:[103,3,5043],t:7,e:"span",a:{"class":"highlight"},f:["Addiction Threshold:"]}," ",{p:[104,3,5099],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.addicD",p:[104,25,5121]}]}," ",{p:[105,3,5159],t:7,e:"br"}," ",{p:[106,3,5168],t:7,e:"br"}," ",{p:[107,3,5177],t:7,e:"ui-button",a:{action:"goScreen",params:'{"screen": "home"}'},f:["Back"]}]}]}],x:{r:["data.screen"],s:'_0=="home"'}}]},e.exports=a.extend(r.exports)},{205:205}],241:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-button",a:{action:"toggle"},f:[{t:2,x:{r:["data.recollection"],s:'_0?"Recital":"Recollection"'},p:[2,30,43]}]}," ",{p:[3,3,107],t:7,e:"ui-button",a:{action:"component"},f:["Target Component: ",{t:3,r:"data.target_comp",p:[3,51,155]}]}]}," ",{t:4,f:[{p:[6,3,235],t:7,e:"ui-display",f:[{t:3,r:"data.rec_text",p:[7,3,251]}," ",{t:4,f:[{p:[9,4,317],t:7,e:"br"},{p:[9,8,321],t:7,e:"ui-button",a:{action:"rec_category",params:['{"category": "',{t:2,r:"name",p:[9,63,376]},'"}']},f:[{t:3,r:"name",p:[9,75,388]}," - ",{t:3,r:"desc",p:[9,88,401]}]}],n:52,r:"data.recollection_categories",p:[8,3,274]}," ",{t:3,r:"data.rec_section",p:[11,3,440]}," ",{t:3,r:"data.rec_binds",p:[12,3,466]}]}],n:50,r:"data.recollection",p:[5,1,206]},{t:4,n:51,f:[{p:[15,2,517],t:7,e:"ui-display",a:{title:"Components (with Global Cache)",button:0},f:[{p:[16,4,580],t:7,e:"ui-section",f:[{t:3,r:"data.components",p:[17,6,599]}]}]}," ",{p:[20,2,657],t:7,e:"ui-display",f:[{p:[21,3,673],t:7,e:"ui-section",f:[{p:[22,4,690],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Driver"?"selected":null'},p:[22,22,708]}],action:"select",params:'{"category": "Driver"}'},f:["Driver"]}," ",{p:[23,4,831],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Script"?"selected":null'},p:[23,22,849]}],action:"select",params:'{"category": "Script"}'},f:["Scripts"]}," ",{p:[24,4,973],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Application"?"selected":null'},p:[24,22,991]}],action:"select",params:'{"category": "Application"}'},f:["Applications"]}," ",{p:[25,4,1130],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Judgement"?"selected":null'},p:[25,22,1148]}],action:"select",params:'{"category": "Judgement"}'},f:["Judgement"]}," ",{p:[26,4,1279],t:7,e:"br"},{t:3,r:"data.tier_info",p:[26,8,1283]}]},{p:[27,16,1320],t:7,e:"hr"}," ",{p:[28,3,1328],t:7,e:"ui-section",f:[{t:4,f:[{p:[30,4,1373],t:7,e:"div",f:[{p:[30,9,1378],t:7,e:"ui-button",a:{tooltip:[{t:3,r:"tip",p:[30,29,1398]}],"tooltip-side":"right",action:"recite",params:['{"category": "',{t:2,r:"type",p:[30,99,1468]},'"}']},f:["Recite",{t:3,r:"required",p:[30,117,1486]}]}," ",{t:4,f:[{t:4,f:[{p:[33,6,1562],t:7,e:"ui-button",a:{action:"bind",params:['{"category": "',{t:2,r:"type",p:[33,53,1609]},'"}']},f:["Unbind ",{t:3,r:"bound",p:[33,72,1628]}]}],n:50,r:"bound",p:[32,5,1542]},{t:4,n:51,f:[{p:[35,6,1672],t:7,e:"ui-button",a:{action:"bind",params:['{"category": "',{t:2,r:"type",p:[35,53,1719]},'"}']},f:["Quickbind"]}],r:"bound"}],n:50,r:"quickbind",p:[31,6,1519]}," ",{t:3,r:"name",p:[38,6,1786]}," ",{t:3,r:"descname",p:[38,17,1797]}," ",{t:3,r:"invokers",p:[38,32,1812]}]}],n:52,r:"data.scripture",p:[29,3,1344]}]}]}],r:"data.recollection"}]},e.exports=a.extend(r.exports)},{205:205}],242:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Codex Gigas"},f:[{p:[2,2,35],t:7,e:"ui-section",f:[{t:2,r:"data.name",p:[3,3,51]}]}," ",{p:[5,5,86],t:7,e:"ui-section",a:{label:"Prefix"},f:[{p:[6,3,117],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[6,22,136]}],action:"Dark "},f:["Dark"]}," ",{p:[7,3,221],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[7,22,240]}],action:"Hellish "},f:["Hellish"]}," ",{p:[8,3,331],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[8,22,350]}],action:"Fallen "},f:["Fallen"]}," ",{p:[9,3,439],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[9,22,458]}],action:"Fiery "},f:["Fiery"]}," ",{p:[10,3,545],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[10,22,564]}],action:"Sinful "},f:["Sinful"]}," ",{p:[11,3,653],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[11,22,672]}],action:"Blood "},f:["Blood"]}," ",{p:[12,3,759],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[12,22,778]}],action:"Fluffy "},f:["Fluffy"]}]}," ",{p:[14,5,888],t:7,e:"ui-section",a:{label:"Title"},f:[{p:[15,3,918],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[15,22,937]}],action:"Lord "},f:["Lord"]}," ",{p:[16,3,1022],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[16,22,1041]}],action:"Prelate "},f:["Prelate"]}," ",{p:[17,3,1132],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[17,22,1151]}],action:"Count "},f:["Count"]}," ",{p:[18,3,1238],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[18,22,1257]}],action:"Viscount "},f:["Viscount"]}," ",{p:[19,3,1350],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[19,22,1369]}],action:"Vizier "},f:["Vizier"]}," ",{p:[20,3,1458],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[20,22,1477]}],action:"Elder "},f:["Elder"]}," ",{p:[21,3,1564],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[21,22,1583]}],action:"Adept "},f:["Adept"]}]}," ",{p:[23,5,1691],t:7,e:"ui-section",a:{label:"Name"},f:[{p:[24,3,1720],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[24,22,1739]}],action:"hal"},f:["hal"]}," ",{p:[25,3,1821],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[25,22,1840]}],action:"ve" -+p:[13,5,605],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[14,7,649],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[15,7,746],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[15,37,776]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[16,7,906],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[16,13,912]}," kPa"]}]}],r:"data.max_rate"}]}]},e.exports=a.extend(r.exports)},{205:205}],233:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{p:[3,5,67],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"selected":null'},p:[3,38,100]}],action:[{t:2,x:{r:["data.timing"],s:'_0?"stop":"start"'},p:[3,83,145]}]},f:[{t:2,x:{r:["data.timing"],s:'_0?"Stop":"Start"'},p:[3,119,181]}]}," ",{p:[4,5,233],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"flash",style:[{t:2,x:{r:["data.flash_charging"],s:'_0?"disabled":null'},p:[4,57,285]}]},f:[{t:2,x:{r:["data.flash_charging"],s:'_0?"Recharging":"Flash"'},p:[4,102,330]}]}]},t:7,e:"ui-display",a:{title:"Cell Timer",button:0},f:[" ",{p:[6,3,410],t:7,e:"ui-section",f:[{p:[7,5,428],t:7,e:"ui-button",a:{icon:"fast-backward",action:"time",params:'{"adjust": -600}'}}," ",{p:[8,5,518],t:7,e:"ui-button",a:{icon:"backward",action:"time",params:'{"adjust": -100}'}}," ",{p:[9,5,603],t:7,e:"span",f:[{t:2,x:{r:["text","data.minutes"],s:"_0.zeroPad(_1,2)"},p:[9,11,609]},":",{t:2,x:{r:["text","data.seconds"],s:"_0.zeroPad(_1,2)"},p:[9,45,643]}]}," ",{p:[10,5,689],t:7,e:"ui-button",a:{icon:"forward",action:"time",params:'{"adjust": 100}'}}," ",{p:[11,5,772],t:7,e:"ui-button",a:{icon:"fast-forward",action:"time",params:'{"adjust": 600}'}}]}," ",{p:[13,3,875],t:7,e:"ui-section",f:[{p:[14,7,895],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "short"}'},f:["Short"]}," ",{p:[15,7,999],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "medium"}'},f:["Medium"]}," ",{p:[16,7,1105],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "long"}'},f:["Long"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],234:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,23],t:7,e:"ui-notice",f:[{t:2,r:"data.notice",p:[3,5,40]}]}],n:50,r:"data.notice",p:[1,1,0]},{p:[6,1,82],t:7,e:"ui-display",a:{title:"Bluespace Artillery Control",button:0},f:[{t:4,f:[{p:[8,3,167],t:7,e:"ui-section",a:{label:"Target"},f:[{p:[9,5,200],t:7,e:"ui-button",a:{icon:"crosshairs",action:"recalibrate"},f:[{t:2,r:"data.target",p:[9,55,250]}]}]}," ",{p:[11,3,298],t:7,e:"ui-section",a:{label:"Controls"},f:[{t:4,f:[{p:[13,3,356],t:7,e:"ui-notice",f:[{p:[14,4,372],t:7,e:"span",f:["Bluespace Artillery firing protocols must be globally unlocked from two keycard authentication devices first!"]}]}],n:50,x:{r:["data.unlocked"],s:"!_0"},p:[12,2,330]},{t:4,n:51,f:[{p:[17,3,525],t:7,e:"ui-button",a:{icon:"warning",state:[{t:2,x:{r:["data.ready"],s:'_0?null:"disabled"'},p:[17,36,558]}],action:"fire"},f:["FIRE!"]}],x:{r:["data.unlocked"],s:"!_0"}}]}],n:50,r:"data.connected",p:[7,3,141]}," ",{t:4,f:[{p:[22,3,694],t:7,e:"ui-section",a:{label:"Maintenance"},f:[{p:[23,7,734],t:7,e:"ui-button",a:{icon:"wrench",action:"build"},f:["Complete Deployment."]}]}],n:50,x:{r:["data.connected"],s:"!_0"},p:[21,3,667]}]}]},e.exports=a.extend(r.exports)},{205:205}],235:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.hasHoldingTank"],s:'_0?"is":"is not"'},p:[2,23,35]}," connected to a tank."]}]}," ",{p:{button:[{p:[6,5,185],t:7,e:"ui-button",a:{icon:"pencil",action:"relabel"},f:["Relabel"]}]},t:7,e:"ui-display",a:{title:"Canister",button:0},f:[" ",{p:[8,3,266],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[9,5,301],t:7,e:"span",f:[{t:2,x:{r:["adata.tankPressure"],s:"Math.round(_0)"},p:[9,11,307]}," kPa"]}]}," ",{p:[11,3,373],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[12,5,404],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.portConnected"],s:'_0?"good":"average"'},p:[12,18,417]}]},f:[{t:2,x:{r:["data.portConnected"],s:'_0?"Connected":"Not Connected"'},p:[12,63,462]}]}]}," ",{t:4,f:[{p:[15,3,573],t:7,e:"ui-section",a:{label:"Access"},f:[{p:[16,7,608],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.restricted"],s:'_0?"lock":"unlock"'},p:[16,24,625]}],style:[{t:2,x:{r:[],s:'"caution"'},p:[17,14,680]}],action:"restricted"},f:[{t:2,x:{r:["data.restricted"],s:'_0?"Restricted to Engineering":"Public"'},p:[18,27,722]}]}]}],n:50,r:"data.isPrototype",p:[14,3,544]}]}," ",{p:[22,1,839],t:7,e:"ui-display",a:{title:"Valve"},f:[{p:[23,3,869],t:7,e:"ui-section",a:{label:"Release Pressure"},f:[{p:[24,5,912],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.minReleasePressure",p:[24,18,925]}],max:[{t:2,r:"data.maxReleasePressure",p:[24,52,959]}],value:[{t:2,r:"data.releasePressure",p:[25,14,1002]}]},f:[{t:2,x:{r:["adata.releasePressure"],s:"Math.round(_0)"},p:[25,40,1028]}," kPa"]}]}," ",{p:[27,3,1099],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[28,5,1144],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.releasePressure","data.defaultReleasePressure"],s:'_0!=_1?null:"disabled"'},p:[28,38,1177]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[30,5,1333],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.releasePressure","data.minReleasePressure"],s:'_0>_1?null:"disabled"'},p:[30,36,1364]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[32,5,1511],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[33,5,1606],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.releasePressure","data.maxReleasePressure"],s:'_0<_1?null:"disabled"'},p:[33,35,1636]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}," ",{p:[36,3,1798],t:7,e:"ui-section",a:{label:"Valve"},f:[{p:[37,5,1830],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.valveOpen"],s:'_0?"unlock":"lock"'},p:[37,22,1847]}],style:[{t:2,x:{r:["data.valveOpen","data.hasHoldingTank"],s:'_0?_1?"caution":"danger":null'},p:[38,14,1901]}],action:"valve"},f:[{t:2,x:{r:["data.valveOpen"],s:'_0?"Open":"Closed"'},p:[39,22,1995]}]}]}]}," ",{t:4,f:[{p:[42,1,2090],t:7,e:"ui-display",a:{title:"Valve Toggle Timer"},f:[{t:4,f:[{p:[44,5,2155],t:7,e:"ui-section",a:{label:"Adjust Timer"},f:[{p:[45,7,2196],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.timer_is_not_default"],s:'_0?null:"disabled"'},p:[45,40,2229]}],action:"timer",params:'{"change": "reset"}'},f:["Reset"]}," ",{p:[47,7,2358],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.timer_is_not_min"],s:'_0?null:"disabled"'},p:[47,38,2389]}],action:"timer",params:'{"change": "decrease"}'},f:["Decrease"]}," ",{p:[49,7,2520],t:7,e:"ui-button",a:{icon:"pencil",state:[{t:2,x:{r:[],s:'"disabled"'},p:[49,39,2552]}],action:"timer",params:'{"change": "input"}'},f:["Set"]}," ",{p:[51,7,2637],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.timer_is_not_max"],s:'_0?null:"disabled"'},p:[51,37,2667]}],action:"timer",params:'{"change": "increase"}'},f:["Increase"]}]}],n:51,r:"data.timing",p:[43,3,2133]}," ",{p:[55,3,2833],t:7,e:"ui-section",a:{label:"Timer"},f:[{p:[56,6,2866],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"danger":"caution"'},p:[56,39,2899]}],action:"toggle_timer"},f:[{t:2,x:{r:["data.timing"],s:'_0?"On":"Off"'},p:[57,30,2969]}]}," ",{p:[59,2,3017],t:7,e:"ui-section",a:{label:"Time until Valve Toggle"},f:[{p:[60,2,3064],t:7,e:"span",f:[{t:2,x:{r:["data.timing","data.time_left","data.timer_set"],s:"_0?_1:_2"},p:[60,8,3070]}]}]}]}]}],n:50,r:"data.isPrototype",p:[41,1,2062]},{p:{button:[{t:4,f:[{p:[69,7,3277],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.valveOpen"],s:'_0?"danger":null'},p:[69,38,3308]}],action:"eject"},f:["Eject"]}],n:50,r:"data.hasHoldingTank",p:[68,5,3242]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[73,3,3442],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holdingTank.name",p:[74,4,3473]}]}," ",{p:[76,3,3519],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holdingTank.tankPressure"],s:"Math.round(_0)"},p:[77,4,3553]}," kPa"]}],n:50,r:"data.hasHoldingTank",p:[72,3,3411]},{t:4,n:51,f:[{p:[80,3,3635],t:7,e:"ui-section",f:[{p:[81,4,3652],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.hasHoldingTank"}]}]},e.exports=a.extend(r.exports)},{205:205}],236:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{tabs:function(){return Object.keys(this.get("data.supplies"))}}}}(r),r.exports.template={v:3,t:[" ",{p:[11,1,158],t:7,e:"ui-display",a:{title:"Cargo"},f:[{p:[12,3,188],t:7,e:"ui-section",a:{label:"Shuttle"},f:[{t:4,f:[{p:[14,7,270],t:7,e:"ui-button",a:{action:"send"},f:[{t:2,r:"data.location",p:[14,32,295]}]}],n:50,x:{r:["data.docked","data.requestonly"],s:"_0&&!_1"},p:[13,5,222]},{t:4,n:51,f:[{p:[16,7,346],t:7,e:"span",f:[{t:2,r:"data.location",p:[16,13,352]}]}],x:{r:["data.docked","data.requestonly"],s:"_0&&!_1"}}]}," ",{p:[19,3,410],t:7,e:"ui-section",a:{label:"Credits"},f:[{p:[20,5,444],t:7,e:"span",f:[{t:2,x:{r:["adata.points"],s:"Math.floor(_0)"},p:[20,11,450]}]}]}," ",{p:[22,3,506],t:7,e:"ui-section",a:{label:"CentCom Message"},f:[{p:[23,7,550],t:7,e:"span",f:[{t:2,r:"data.message",p:[23,13,556]}]}]}," ",{t:4,f:[{p:[26,5,644],t:7,e:"ui-section",a:{label:"Loan"},f:[{t:4,f:[{p:[28,9,716],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.away","data.docked"],s:'_0&&_1?null:"disabled"'},p:[29,17,744]}],action:"loan"},f:["Loan Shuttle"]}],n:50,x:{r:["data.loan_dispatched"],s:"!_0"},p:[27,7,677]},{t:4,n:51,f:[{p:[32,9,868],t:7,e:"span",a:{"class":"bad"},f:["Loaned to CentCom"]}],x:{r:["data.loan_dispatched"],s:"!_0"}}]}],n:50,x:{r:["data.loan","data.requestonly"],s:"_0&&!_1"},p:[25,3,600]}]}," ",{t:4,f:[{p:{button:[{p:[40,7,1066],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.cart.length"],s:'_0?null:"disabled"'},p:[40,38,1097]}],action:"clear"},f:["Clear"]}]},t:7,e:"ui-display",a:{title:"Cart",button:0},f:[" ",{t:4,f:[{p:[43,7,1222],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[44,9,1263],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[44,31,1285]}]}," ",{p:[45,9,1307],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"object",p:[45,30,1328]}]}," ",{p:[46,9,1354],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"cost",p:[46,30,1375]}," Credits"]}," ",{p:[47,9,1407],t:7,e:"div",a:{"class":"content"},f:[{p:[48,11,1440],t:7,e:"ui-button",a:{icon:"minus",action:"remove",params:['{"id": "',{t:2,r:"id",p:[48,67,1496]},'"}']}}]}]}],n:52,r:"data.cart",p:[42,5,1195]},{t:4,n:51,f:[{p:[52,7,1566],t:7,e:"span",f:["Nothing in Cart"]}],r:"data.cart"}]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[37,1,972]},{p:{button:[{t:4,f:[{p:[59,7,1735],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.requests.length"],s:'_0?null:"disabled"'},p:[59,38,1766]}],action:"denyall"},f:["Clear"]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[58,5,1702]}]},t:7,e:"ui-display",a:{title:"Requests",button:0},f:[" ",{t:4,f:[{p:[63,5,1908],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[64,7,1947],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[64,29,1969]}]}," ",{p:[65,7,1989],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"object",p:[65,28,2010]}]}," ",{p:[66,7,2034],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"cost",p:[66,28,2055]}," Credits"]}," ",{p:[67,7,2085],t:7,e:"div",a:{"class":"content"},f:["By ",{t:2,r:"orderer",p:[67,31,2109]}]}," ",{p:[68,7,2134],t:7,e:"div",a:{"class":"content"},f:["Comment: ",{t:2,r:"reason",p:[68,37,2164]}]}," ",{t:4,f:[{p:[70,9,2223],t:7,e:"div",a:{"class":"content"},f:[{p:[71,11,2256],t:7,e:"ui-button",a:{icon:"check",action:"approve",params:['{"id": "',{t:2,r:"id",p:[71,68,2313]},'"}']}}," ",{p:[72,11,2336],t:7,e:"ui-button",a:{icon:"close",action:"deny",params:['{"id": "',{t:2,r:"id",p:[72,65,2390]},'"}']}}]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[69,7,2188]}]}],n:52,r:"data.requests",p:[62,3,1879]},{t:4,n:51,f:[{p:[77,7,2473],t:7,e:"span",f:["No Requests"]}],r:"data.requests"}]}," ",{p:[80,1,2529],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"tabs",p:[80,16,2544]}]},f:[{t:4,f:[{p:[82,5,2587],t:7,e:"tab",a:{name:[{t:2,r:"name",p:[82,16,2598]}]},f:[{t:4,f:[{p:[84,9,2641],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[84,28,2660]}],candystripe:0,right:0},f:[{p:[85,11,2700],t:7,e:"ui-button",a:{action:"add",params:['{"id": "',{t:2,r:"id",p:[85,51,2740]},'"}']},f:[{t:2,r:"cost",p:[85,61,2750]}," Credits"]}]}],n:52,r:"packs",p:[83,7,2616]}]}],n:52,r:"data.supplies",p:[81,3,2558]}]}]},e.exports=a.extend(r.exports)},{205:205}],237:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Cellular Emporium",button:0},f:[{p:[2,3,49],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.can_readapt"],s:'_0?null:"disabled"'},p:[2,36,82]}],action:"readapt"},f:["Readapt"]}," ",{p:[4,3,169],t:7,e:"ui-section",a:{label:"Genetic Points Remaining",right:0},f:[{t:2,r:"data.genetic_points_remaining",p:[5,5,226]}]}]}," ",{p:[8,1,293],t:7,e:"ui-display",f:[{t:4,f:[{p:[10,3,335],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[10,22,354]}],candystripe:0,right:0},f:[{p:[11,5,388],t:7,e:"span",f:[{t:2,r:"desc",p:[11,11,394]}]}," ",{p:[12,5,415],t:7,e:"span",f:[{t:2,r:"helptext",p:[12,11,421]}]}," ",{p:[13,5,446],t:7,e:"span",f:["Cost: ",{t:2,r:"dna_cost",p:[13,17,458]}]}," ",{p:[14,5,483],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["owned","can_purchase"],s:'_0?"selected":_1?null:"disabled"'},p:[15,14,508]}],action:"evolve",params:['{"name": "',{t:2,r:"name",p:[17,25,615]},'"}']},f:[{t:2,x:{r:["owned"],s:'_0?"Evolved":"Evolve"'},p:[18,7,635]}]}]}],n:52,r:"data.abilities",p:[9,1,307]},{t:4,f:[{p:[23,3,738],t:7,e:"span",a:{"class":"warning"},f:["No abilities availible."]}],n:51,r:"data.abilities",p:[22,1,715]}]}]},e.exports=a.extend(r.exports)},{205:205}],238:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,3,31],t:7,e:"ui-section",a:{label:"Energy"},f:[{p:[3,5,64],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.maxEnergy",p:[3,26,85]}],value:[{t:2,r:"data.energy",p:[3,53,112]}]},f:[{t:2,x:{r:["adata.energy"],s:"Math.fixed(_0)"},p:[3,70,129]}," Units"]}]}]}," ",{p:{button:[{t:4,f:[{p:[9,7,315],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.amount","."],s:'_0==_1?"selected":null'},p:[9,37,345]}],action:"amount",params:['{"target": ',{t:2,r:".",p:[9,114,422]},"}"]},f:[{t:2,r:".",p:[9,122,430]}]}],n:52,r:"data.beakerTransferAmounts",p:[8,5,271]}]},t:7,e:"ui-display",a:{title:"Dispense",button:0},f:[" ",{p:[12,3,482],t:7,e:"ui-section",f:[{t:4,f:[{p:[14,7,532],t:7,e:"ui-button",a:{grid:0,icon:"tint",action:"dispense",params:['{"reagent": "',{t:2,r:"id",p:[14,74,599]},'"}']},f:[{t:2,r:"title",p:[14,84,609]}]}],n:52,r:"data.chemicals",p:[13,5,500]}]}]}," ",{p:{button:[{t:4,f:[{p:[21,7,786],t:7,e:"ui-button",a:{icon:"minus",action:"remove",params:['{"amount": ',{t:2,r:".",p:[21,66,845]},"}"]},f:[{t:2,r:".",p:[21,74,853]}]}],n:52,r:"data.beakerTransferAmounts",p:[20,5,742]}," ",{p:[23,5,891],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[23,36,922]}],action:"eject"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[25,3,1019],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[27,7,1089],t:7,e:"span",f:[{t:2,x:{r:["adata.beakerCurrentVolume"],s:"Math.round(_0)"},p:[27,13,1095]},"/",{t:2,r:"data.beakerMaxVolume",p:[27,55,1137]}," Units"]}," ",{p:[28,7,1182],t:7,e:"br"}," ",{t:4,f:[{p:[30,9,1235],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[30,52,1278]}," units of ",{t:2,r:"name",p:[30,87,1313]}]},{p:[30,102,1328],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[29,7,1195]},{t:4,n:51,f:[{p:[32,9,1359],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[26,5,1054]},{t:4,n:51,f:[{p:[35,7,1435],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],239:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Thermostat"},f:[{p:[2,3,35],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,67],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isActive"],s:'_0?"power-off":"close"'},p:[3,22,84]}],style:[{t:2,x:{r:["data.isActive"],s:'_0?"selected":null'},p:[4,10,137]}],state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[5,10,186]}],action:"power"},f:[{t:2,x:{r:["data.isActive"],s:'_0?"On":"Off"'},p:[6,18,249]}]}]}," ",{p:[8,3,314],t:7,e:"ui-section",a:{label:"Target"},f:[{p:[9,4,346],t:7,e:"ui-button",a:{icon:"pencil",action:"temperature",params:'{"target": "input"}'},f:[{t:2,x:{r:["adata.targetTemp"],s:"Math.round(_0)"},p:[9,79,421]}," K"]}]}]}," ",{p:{button:[{p:[14,5,564],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[14,36,595]}],action:"eject"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[16,3,692],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[18,7,762],t:7,e:"span",f:["Temperature: ",{t:2,x:{r:["adata.currentTemp"],s:"Math.round(_0)"},p:[18,26,781]}," K"]}," ",{p:[19,7,831],t:7,e:"br"}," ",{t:4,f:[{p:[21,9,885],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[21,52,928]}," units of ",{t:2,r:"name",p:[21,87,963]}]},{p:[21,102,978],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[20,7,845]},{t:4,n:51,f:[{p:[23,9,1009],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[17,5,727]},{t:4,n:51,f:[{p:[26,7,1085],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],240:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,32],t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[{p:[3,3,70],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"Eject":"close"'},p:[3,20,87]}],style:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"selected":null'},p:[4,11,143]}],state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[5,11,199]}],action:"eject"},f:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"Eject and Clear Buffer":"No beaker"'},p:[7,5,268]}]}," ",{p:[10,3,357],t:7,e:"ui-section",f:[{t:4,f:[{t:4,f:[{p:[13,6,443],t:7,e:"ui-section",a:{label:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[13,25,462]}," units of ",{t:2,r:"name",p:[13,60,497]}],nowrap:0},f:[{p:[14,7,522],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{p:[15,8,572],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[15,61,625]},'", "amount": 1}']},f:["1"]}," ",{p:[16,8,670],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[16,61,723]},'", "amount": 5}']},f:["5"]}," ",{p:[17,8,768],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[17,61,821]},'", "amount": 10}']},f:["10"]}," ",{p:[18,8,868],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[18,61,921]},'", "amount": 1000}']},f:["All"]}," ",{p:[19,8,971],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[19,61,1024]},'", "amount": -1}']},f:["Custom"]}," ",{p:[20,8,1075],t:7,e:"ui-button",a:{action:"analyze",params:['{"id": "',{t:2,r:"id",p:[20,52,1119]},'"}']},f:["Analyze"]}]}]}],n:52,r:"data.beakerContents",p:[12,5,407]},{t:4,n:51,f:[{p:[24,5,1201],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"data.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[11,4,374]},{t:4,n:51,f:[{p:[27,5,1272],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}," ",{p:[32,2,1360],t:7,e:"ui-display",a:{title:"Buffer"},f:[{p:[33,3,1391],t:7,e:"ui-button",a:{action:"toggleMode",state:[{t:2,x:{r:["data.mode"],s:'_0?null:"selected"'},p:[33,41,1429]}]},f:["Destroy"]}," ",{p:[34,3,1487],t:7,e:"ui-button",a:{action:"toggleMode",state:[{t:2,x:{r:["data.mode"],s:'_0?"selected":null'},p:[34,41,1525]}]},f:["Transfer to Beaker"]}," ",{p:[35,3,1594],t:7,e:"ui-section",f:[{t:4,f:[{p:[37,5,1646],t:7,e:"ui-section",a:{label:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[37,24,1665]}," units of ",{t:2,r:"name",p:[37,59,1700]}],nowrap:0},f:[{p:[38,6,1724],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{p:[39,7,1773],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[39,62,1828]},'", "amount": 1}']},f:["1"]}," ",{p:[40,7,1872],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[40,62,1927]},'", "amount": 5}']},f:["5"]}," ",{p:[41,7,1971],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[41,62,2026]},'", "amount": 10}']},f:["10"]}," ",{p:[42,7,2072],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[42,62,2127]},'", "amount": 1000}']},f:["All"]}," ",{p:[43,7,2176],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[43,62,2231]},'", "amount": -1}']},f:["Custom"]}," ",{p:[44,7,2281],t:7,e:"ui-button",a:{action:"analyze",params:['{"id": "',{t:2,r:"id",p:[44,51,2325]},'"}']},f:["Analyze"]}]}]}],n:52,r:"data.bufferContents",p:[36,4,1611]}]}]}," ",{t:4,f:[{p:[52,3,2461],t:7,e:"ui-display",a:{title:"Pills, Bottles and Patches"},f:[{t:4,f:[{p:[54,5,2551],t:7,e:"ui-button",a:{action:"ejectp",state:[{t:2,x:{r:["data.isPillBottleLoaded"],s:'_0?null:"disabled"'},p:[54,39,2585]}]},f:[{t:2,x:{r:["data.isPillBottleLoaded"],s:'_0?"Eject":"No Pill bottle loaded"'},p:[54,88,2634]}]}," ",{p:[55,5,2715],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.pillBotContent",p:[55,27,2737]},"/",{t:2,r:"data.pillBotMaxContent",p:[55,51,2761]}]}],n:50,r:"data.isPillBottleLoaded",p:[53,4,2514]},{t:4,n:51,f:[{p:[57,5,2813],t:7,e:"span",a:{"class":"average"},f:["No Pillbottle"]}],r:"data.isPillBottleLoaded"}," ",{p:[60,4,2877],t:7,e:"br"}," ",{p:[61,4,2887],t:7,e:"br"}," ",{p:[62,4,2897],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[62,63,2956]}]},f:["Create Pill (max 50µ)"]}," ",{p:[63,4,3040],t:7,e:"br"}," ",{p:[64,4,3050],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[64,63,3109]}]},f:["Create Multiple Pills"]}," ",{p:[65,4,3193],t:7,e:"br"}," ",{p:[66,4,3203],t:7,e:"br"}," ",{p:[67,4,3213],t:7,e:"ui-button",a:{action:"createPatch",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[67,64,3273]}]},f:["Create Patch (max 40µ)"]}," ",{p:[68,4,3358],t:7,e:"br"}," ",{p:[69,4,3368],t:7,e:"ui-button",a:{action:"createPatch",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[69,64,3428]}]},f:["Create Multiple Patches"]}," ",{p:[70,4,3514],t:7,e:"br"}," ",{p:[71,4,3524],t:7,e:"br"}," ",{p:[72,4,3534],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[72,65,3595]}]},f:["Create Bottle (max 30µ)"]}," ",{p:[73,4,3681],t:7,e:"br"}," ",{p:[74,4,3691],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[74,65,3752]}]},f:["Dispense Buffer to Bottles"]}]}],n:50,x:{r:["data.condi"],s:"!_0"},p:[51,2,2438]},{t:4,n:51,f:[{p:[79,3,3874],t:7,e:"ui-display",a:{title:"Condiments bottles and packs"},f:[{p:[80,4,3929],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[80,63,3988]}]},f:["Create Pack (max 10µ)"]}," ",{p:[81,4,4072],t:7,e:"br"}," ",{p:[82,4,4082],t:7,e:"br"}," ",{p:[83,4,4092],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[83,65,4153]}]},f:["Create Bottle (max 50µ)"]}]}],x:{r:["data.condi"],s:"!_0"}}],n:50,x:{r:["data.screen"],s:'_0=="home"'},p:[1,1,0]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.screen"],s:'_0=="analyze"'},f:[{p:[87,2,4301],t:7,e:"ui-display",a:{title:[{t:2,r:"data.analyzeVars.name",p:[87,20,4319]}]},f:[{p:[88,3,4350],t:7,e:"span",a:{"class":"highlight"},f:["Description:"]}," ",{p:[89,3,4398],t:7,e:"span",a:{"class":"content",style:"float:center"},f:[{t:2,r:"data.analyzeVars.description",p:[89,46,4441]}]}," ",{p:[90,3,4484],t:7,e:"br"}," ",{p:[91,3,4493],t:7,e:"span",a:{"class":"highlight"},f:["Color:"]}," ",{p:[92,3,4535],t:7,e:"span",a:{style:["color: ",{t:2,r:"data.analyzeVars.color",p:[92,23,4555]},"; background-color: ",{t:2,r:"data.analyzeVars.color",p:[92,69,4601]}]},f:[{t:2,r:"data.analyzeVars.color",p:[92,97,4629]}]}," ",{p:[93,3,4666],t:7,e:"br"}," ",{p:[94,3,4675],t:7,e:"span",a:{"class":"highlight"},f:["State:"]}," ",{p:[95,3,4717],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.state",p:[95,25,4739]}]}," ",{p:[96,3,4776],t:7,e:"br"}," ",{p:[97,3,4785],t:7,e:"span",a:{"class":"highlight"},f:["Metabolization Rate:"]}," ",{p:[98,3,4841],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.metaRate",p:[98,25,4863]},"µ/minute"]}," ",{p:[99,3,4911],t:7,e:"br"}," ",{p:[100,3,4920],t:7,e:"span",a:{"class":"highlight"},f:["Overdose Threshold:"]}," ",{p:[101,3,4975],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.overD",p:[101,25,4997]}]}," ",{p:[102,3,5034],t:7,e:"br"}," ",{p:[103,3,5043],t:7,e:"span",a:{"class":"highlight"},f:["Addiction Threshold:"]}," ",{p:[104,3,5099],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.addicD",p:[104,25,5121]}]}," ",{p:[105,3,5159],t:7,e:"br"}," ",{p:[106,3,5168],t:7,e:"br"}," ",{p:[107,3,5177],t:7,e:"ui-button",a:{action:"goScreen",params:'{"screen": "home"}'},f:["Back"]}]}]}],x:{r:["data.screen"],s:'_0=="home"'}}]},e.exports=a.extend(r.exports)},{205:205}],241:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-button",a:{action:"toggle"},f:[{t:2,x:{r:["data.recollection"],s:'_0?"Recital":"Recollection"'},p:[2,30,43]}]}," ",{p:[3,3,107],t:7,e:"ui-button",a:{action:"component"},f:["Target Component: ",{t:3,r:"data.target_comp",p:[3,51,155]}]}]}," ",{t:4,f:[{p:[6,3,235],t:7,e:"ui-display",f:[{t:3,r:"data.rec_text",p:[7,3,251]}," ",{t:4,f:[{p:[9,4,317],t:7,e:"br"},{p:[9,8,321],t:7,e:"ui-button",a:{action:"rec_category",params:['{"category": "',{t:2,r:"name",p:[9,63,376]},'"}']},f:[{t:3,r:"name",p:[9,75,388]}," - ",{t:3,r:"desc",p:[9,88,401]}]}],n:52,r:"data.recollection_categories",p:[8,3,274]}," ",{t:3,r:"data.rec_section",p:[11,3,440]}," ",{t:3,r:"data.rec_binds",p:[12,3,466]}]}],n:50,r:"data.recollection",p:[5,1,206]},{t:4,n:51,f:[{p:[15,2,517],t:7,e:"ui-display",a:{title:"Components (with Global Cache)",button:0},f:[{p:[16,4,580],t:7,e:"ui-section",f:[{t:3,r:"data.components",p:[17,6,599]}]}]}," ",{p:[20,2,657],t:7,e:"ui-display",f:[{p:[21,3,673],t:7,e:"ui-section",f:[{p:[22,4,690],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Driver"?"selected":null'},p:[22,22,708]}],action:"select",params:'{"category": "Driver"}'},f:["Driver"]}," ",{p:[23,4,831],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Script"?"selected":null'},p:[23,22,849]}],action:"select",params:'{"category": "Script"}'},f:["Scripts"]}," ",{p:[24,4,973],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Application"?"selected":null'},p:[24,22,991]}],action:"select",params:'{"category": "Application"}'},f:["Applications"]}," ",{p:[25,4,1130],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Judgement"?"selected":null'},p:[25,22,1148]}],action:"select",params:'{"category": "Judgement"}'},f:["Judgement"]}," ",{p:[26,4,1279],t:7,e:"br"},{t:3,r:"data.tier_info",p:[26,8,1283]}]},{p:[27,16,1320],t:7,e:"hr"}," ",{p:[28,3,1328],t:7,e:"ui-section",f:[{t:4,f:[{p:[30,4,1373],t:7,e:"div",f:[{p:[30,9,1378],t:7,e:"ui-button",a:{tooltip:[{t:3,r:"tip",p:[30,29,1398]}],"tooltip-side":"right",action:"recite",params:['{"category": "',{t:2,r:"type",p:[30,99,1468]},'"}']},f:["Recite",{t:3,r:"required",p:[30,117,1486]}]}," ",{t:4,f:[{t:4,f:[{p:[33,6,1562],t:7,e:"ui-button",a:{action:"bind",params:['{"category": "',{t:2,r:"type",p:[33,53,1609]},'"}']},f:["Unbind ",{t:3,r:"bound",p:[33,72,1628]}]}],n:50,r:"bound",p:[32,5,1542]},{t:4,n:51,f:[{p:[35,6,1672],t:7,e:"ui-button",a:{action:"bind",params:['{"category": "',{t:2,r:"type",p:[35,53,1719]},'"}']},f:["Quickbind"]}],r:"bound"}],n:50,r:"quickbind",p:[31,6,1519]}," ",{t:3,r:"name",p:[38,6,1786]}," ",{t:3,r:"descname",p:[38,17,1797]}," ",{t:3,r:"invokers",p:[38,32,1812]}]}],n:52,r:"data.scripture",p:[29,3,1344]}]}]}],r:"data.recollection"}]},e.exports=a.extend(r.exports)},{205:205}],242:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Codex Gigas"},f:[{p:[2,2,35],t:7,e:"ui-section",f:[{t:2,r:"data.name",p:[3,3,51]}]}," ",{p:[5,5,86],t:7,e:"ui-section",a:{label:"Prefix"},f:[{p:[6,3,117],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[6,22,136]}],action:"Dark "},f:["Dark"]}," ",{p:[7,3,221],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[7,22,240]}],action:"Hellish "},f:["Hellish"]}," ",{p:[8,3,331],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[8,22,350]}],action:"Fallen "},f:["Fallen"]}," ",{p:[9,3,439],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[9,22,458]}],action:"Fiery "},f:["Fiery"]}," ",{p:[10,3,545],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[10,22,564]}],action:"Sinful "},f:["Sinful"]}," ",{p:[11,3,653],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[11,22,672]}],action:"Blood "},f:["Blood"]}," ",{p:[12,3,759],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[12,22,778]}],action:"Fluffy "},f:["Fluffy"]}]}," ",{p:[14,5,888],t:7,e:"ui-section",a:{label:"Title"},f:[{p:[15,3,918],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[15,22,937]}],action:"Lord "},f:["Lord"]}," ",{p:[16,3,1022],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[16,22,1041]}],action:"Prelate "},f:["Prelate"]}," ",{p:[17,3,1132],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[17,22,1151]}],action:"Count "},f:["Count"]}," ",{p:[18,3,1238],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[18,22,1257]}],action:"Viscount "},f:["Viscount"]}," ",{p:[19,3,1350],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[19,22,1369]}],action:"Vizier "},f:["Vizier"]}," ",{p:[20,3,1458],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[20,22,1477]}],action:"Elder "},f:["Elder"]}," ",{p:[21,3,1564],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[21,22,1583]}],action:"Adept "},f:["Adept"]}]}," ",{p:[23,5,1691],t:7,e:"ui-section",a:{label:"Name"},f:[{p:[24,3,1720],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[24,22,1739]}],action:"hal"},f:["hal"]}," ",{p:[25,3,1821],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[25,22,1840]}],action:"ve" +@@ -11,6 +11,6 @@ p:[13,5,605],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[14,7,649],t:7 },f:["ve"]}," ",{p:[26,3,1920],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[26,22,1939]}],action:"odr"},f:["odr"]}," ",{p:[27,3,2021],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[27,22,2040]}],action:"neit"},f:["neit"]}," ",{p:[28,3,2124],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[28,22,2143]}],action:"ci"},f:["ci"]}," ",{p:[29,3,2223],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[29,22,2242]}],action:"quon"},f:["quon"]}," ",{p:[30,3,2326],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[30,22,2345]}],action:"mya"},f:["mya"]}," ",{p:[31,3,2427],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[31,22,2446]}],action:"folth"},f:["folth"]}," ",{p:[32,3,2532],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[32,22,2551]}],action:"wren"},f:["wren"]}," ",{p:[33,3,2635],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[33,22,2654]}],action:"geyr"},f:["geyr"]}," ",{p:[34,3,2738],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[34,22,2757]}],action:"hil"},f:["hil"]}," ",{p:[35,3,2839],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[35,22,2858]}],action:"niet"},f:["niet"]}," ",{p:[36,3,2942],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[36,22,2961]}],action:"twou"},f:["twou"]}," ",{p:[37,3,3045],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[37,22,3064]}],action:"phi"},f:["phi"]}," ",{p:[38,3,3146],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[38,22,3165]}],action:"coa"},f:["coa"]}]}," ",{p:[40,5,3268],t:7,e:"ui-section",a:{label:"suffix"},f:[{p:[41,3,3299],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[41,22,3318]}],action:" the Red"},f:["the Red"]}," ",{p:[42,3,3409],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[42,22,3428]}],action:" the Soulless"},f:["the Soulless"]}," ",{p:[43,3,3529],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[43,22,3548]}],action:" the Master"},f:["the Master"]}," ",{p:[44,3,3645],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[44,22,3664]}],action:", the Lord of all things"},f:["the Lord of all things"]}," ",{p:[45,3,3786],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[45,22,3805]}],action:", Jr."},f:["jr"]}]}," ",{p:[47,5,3909],t:7,e:"ui-section",a:{label:"submit"},f:[{p:[48,3,3941],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0>=4?null:"disabled"'},p:[48,21,3959]}],action:"search"},f:["search"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],243:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[2,1,2],t:7,e:"ui-button",a:{icon:"circle",action:"clean_order"},f:["Clear Order"]},{p:[2,70,71],t:7,e:"br"},{p:[2,74,75],t:7,e:"br"}," ",{p:[3,1,81],t:7,e:"i",f:["Your new computer device you always dreamed of is just four steps away..."]},{p:[3,81,161],t:7,e:"hr"}," ",{t:4,f:[" ",{p:[5,1,223],t:7,e:"div",a:{"class":"item"},f:[{p:[6,2,244],t:7,e:"h2",f:["Step 1: Select your device type"]}," ",{p:[7,2,287],t:7,e:"ui-button",a:{icon:"calc",action:"pick_device",params:'{"pick" : "1"}'},f:["Laptop"]}," ",{p:[8,2,377],t:7,e:"ui-button",a:{icon:"calc",action:"pick_device",params:'{"pick" : "2"}'},f:["LTablet"]}]}],n:50,x:{r:["data.state"],s:"_0==0"},p:[4,1,167]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.state"],s:"_0==1"},f:[{p:[11,1,502],t:7,e:"div",a:{"class":"item"},f:[{p:[12,2,523],t:7,e:"h2",f:["Step 2: Personalise your device"]}," ",{p:[13,2,566],t:7,e:"table",f:[{p:[14,3,577],t:7,e:"tr",f:[{p:[15,4,586],t:7,e:"td",f:[{p:[15,8,590],t:7,e:"b",f:["Current Price:"]}]},{p:[16,4,616],t:7,e:"td",f:[{t:2,r:"data.totalprice",p:[16,8,620]},"C"]}]}," ",{p:[18,3,653],t:7,e:"tr",f:[{p:[19,4,663],t:7,e:"td",f:[{p:[19,8,667],t:7,e:"b",f:["Battery:"]}]},{p:[20,4,687],t:7,e:"td",f:[{p:[20,8,691],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "1"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==1?"selected":null'},p:[20,73,756]}]},f:["Standard"]}]},{p:[21,4,827],t:7,e:"td",f:[{p:[21,8,831],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "2"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==2?"selected":null'},p:[21,73,896]}]},f:["Upgraded"]}]},{p:[22,4,967],t:7,e:"td",f:[{p:[22,8,971],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "3"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==3?"selected":null'},p:[22,73,1036]}]},f:["Advanced"]}]}]}," ",{p:[24,3,1115],t:7,e:"tr",f:[{p:[25,4,1124],t:7,e:"td",f:[{p:[25,8,1128],t:7,e:"b",f:["Hard Drive:"]}]},{p:[26,4,1151],t:7,e:"td",f:[{p:[26,8,1155],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "1"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==1?"selected":null'},p:[26,67,1214]}]},f:["Standard"]}]},{p:[27,4,1282],t:7,e:"td",f:[{p:[27,8,1286],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "2"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==2?"selected":null'},p:[27,67,1345]}]},f:["Upgraded"]}]},{p:[28,4,1413],t:7,e:"td",f:[{p:[28,8,1417],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "3"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==3?"selected":null'},p:[28,67,1476]}]},f:["Advanced"]}]}]}," ",{p:[30,3,1552],t:7,e:"tr",f:[{p:[31,4,1561],t:7,e:"td",f:[{p:[31,8,1565],t:7,e:"b",f:["Network Card:"]}]},{p:[32,4,1590],t:7,e:"td",f:[{p:[32,8,1594],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "0"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==0?"selected":null'},p:[32,73,1659]}]},f:["None"]}]},{p:[33,4,1726],t:7,e:"td",f:[{p:[33,8,1730],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "1"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==1?"selected":null'},p:[33,73,1795]}]},f:["Standard"]}]},{p:[34,4,1866],t:7,e:"td",f:[{p:[34,8,1870],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "2"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==2?"selected":null'},p:[34,73,1935]}]},f:["Advanced"]}]}]}," ",{p:[36,3,2014],t:7,e:"tr",f:[{p:[37,4,2023],t:7,e:"td",f:[{p:[37,8,2027],t:7,e:"b",f:["Nano Printer:"]}]},{p:[38,4,2052],t:7,e:"td",f:[{p:[38,8,2056],t:7,e:"ui-button",a:{action:"hw_nanoprint",params:'{"print" : "0"}',state:[{t:2,x:{r:["data.hw_nanoprint"],s:'_0==0?"selected":null'},p:[38,73,2121]}]},f:["None"]}]},{p:[39,4,2190],t:7,e:"td",f:[{p:[39,8,2194],t:7,e:"ui-button",a:{action:"hw_nanoprint",params:'{"print" : "1"}',state:[{t:2,x:{r:["data.hw_nanoprint"],s:'_0==1?"selected":null'},p:[39,73,2259]}]},f:["Standard"]}]}]}," ",{p:[41,3,2340],t:7,e:"tr",f:[{p:[42,4,2349],t:7,e:"td",f:[{p:[42,8,2353],t:7,e:"b",f:["Card Reader:"]}]},{p:[43,4,2377],t:7,e:"td",f:[{p:[43,8,2381],t:7,e:"ui-button",a:{action:"hw_card",params:'{"card" : "0"}',state:[{t:2,x:{r:["data.hw_card"],s:'_0==0?"selected":null'},p:[43,67,2440]}]},f:["None"]}]},{p:[44,4,2504],t:7,e:"td",f:[{p:[44,8,2508],t:7,e:"ui-button",a:{action:"hw_card",params:'{"card" : "1"}',state:[{t:2,x:{r:["data.hw_card"],s:'_0==1?"selected":null'},p:[44,67,2567]}]},f:["Standard"]}]}]}]}," ",{t:4,f:[" ",{p:[49,4,2706],t:7,e:"table",f:[{p:[50,5,2719],t:7,e:"tr",f:[{p:[51,6,2730],t:7,e:"td",f:[{p:[51,10,2734],t:7,e:"b",f:["Processor Unit:"]}]},{p:[52,6,2763],t:7,e:"td",f:[{p:[52,10,2767],t:7,e:"ui-button",a:{action:"hw_cpu",params:'{"cpu" : "1"}',state:[{t:2,x:{r:["data.hw_cpu"],s:'_0==1?"selected":null'},p:[52,67,2824]}]},f:["Standard"]}]},{p:[53,6,2893],t:7,e:"td",f:[{p:[53,10,2897],t:7,e:"ui-button",a:{action:"hw_cpu",params:'{"cpu" : "2"}',state:[{t:2,x:{r:["data.hw_cpu"],s:'_0==2?"selected":null'},p:[53,67,2954]}]},f:["Advanced"]}]}]}," ",{p:[55,5,3033],t:7,e:"tr",f:[{p:[56,6,3044],t:7,e:"td",f:[{p:[56,10,3048],t:7,e:"b",f:["Tesla Relay:"]}]},{p:[57,6,3074],t:7,e:"td",f:[{p:[57,10,3078],t:7,e:"ui-button",a:{action:"hw_tesla",params:'{"tesla" : "0"}',state:[{t:2,x:{r:["data.hw_tesla"],s:'_0==0?"selected":null'},p:[57,71,3139]}]},f:["None"]}]},{p:[58,6,3206],t:7,e:"td",f:[{p:[58,10,3210],t:7,e:"ui-button",a:{action:"hw_tesla",params:'{"tesla" : "1"}',state:[{t:2,x:{r:["data.hw_tesla"],s:'_0==1?"selected":null'},p:[58,71,3271]}]},f:["Standard"]}]}]}]}],n:50,x:{r:["data.devtype"],s:"_0!=2"},p:[48,3,2659]}," ",{p:[62,3,3374],t:7,e:"table",f:[{p:[63,4,3386],t:7,e:"tr",f:[{p:[64,5,3396],t:7,e:"td",f:[{p:[64,9,3400],t:7,e:"b",f:["Confirm Order:"]}]},{p:[65,5,3427],t:7,e:"td",f:[{p:[65,9,3431],t:7,e:"ui-button",a:{action:"confirm_order"},f:["CONFIRM"]}]}]}]}," ",{p:[69,2,3512],t:7,e:"hr"}," ",{p:[70,2,3519],t:7,e:"b",f:["Battery"]}," allows your device to operate without external utility power source. Advanced batteries increase battery life.",{p:[70,127,3644],t:7,e:"br"}," ",{p:[71,2,3651],t:7,e:"b",f:["Hard Drive"]}," stores file on your device. Advanced drives can store more files, but use more power, shortening battery life.",{p:[71,130,3779],t:7,e:"br"}," ",{p:[72,2,3786],t:7,e:"b",f:["Network Card"]}," allows your device to wirelessly connect to stationwide NTNet network. Basic cards are limited to on-station use, while advanced cards can operate anywhere near the station, which includes the asteroid outposts.",{p:[72,233,4017],t:7,e:"br"}," ",{p:[73,2,4024],t:7,e:"b",f:["Processor Unit"]}," is critical for your device's functionality. It allows you to run programs from your hard drive. Advanced CPUs use more power, but allow you to run more programs on background at once.",{p:[73,208,4230],t:7,e:"br"}," ",{p:[74,2,4237],t:7,e:"b",f:["Tesla Relay"]}," is an advanced wireless power relay that allows your device to connect to nearby area power controller to provide alternative power source. This component is currently unavailable on tablet computers due to size restrictions.",{p:[74,246,4481],t:7,e:"br"}," ",{p:[75,2,4488],t:7,e:"b",f:["Nano Printer"]}," is device that allows for various paperwork manipulations, such as, scanning of documents or printing new ones. This device was certified EcoFriendlyPlus and is capable of recycling existing paper for printing purposes.",{p:[75,241,4727],t:7,e:"br"}," ",{p:[76,2,4734],t:7,e:"b",f:["Card Reader"]}," adds a slot that allows you to manipulate RFID cards. Please note that this is not necessary to allow the device to read your identification, it is just necessary to manipulate other cards."]}]},{t:4,n:50,x:{r:["data.state"],s:"(!(_0==1))&&(_0==2)"},f:[" ",{p:[79,2,4981],t:7,e:"h2",f:["Step 3: Payment"]}," ",{p:[80,2,5008],t:7,e:"b",f:["Your device is now ready for fabrication.."]},{p:[80,51,5057],t:7,e:"br"}," ",{p:[81,2,5064],t:7,e:"i",f:["Please ensure the required amount of credits are in the machine, then press purchase."]},{p:[81,94,5156],t:7,e:"br"}," ",{p:[82,2,5163],t:7,e:"i",f:["Current credits: ",{p:[82,22,5183],t:7,e:"b",f:[{t:2,r:"data.credits",p:[82,25,5186]},"C"]}]},{p:[82,50,5211],t:7,e:"br"}," ",{p:[83,2,5218],t:7,e:"i",f:["Total price: ",{p:[83,18,5234],t:7,e:"b",f:[{t:2,r:"data.totalprice",p:[83,21,5237]},"C"]}]},{p:[83,49,5265],t:7,e:"br"},{p:[83,53,5269],t:7,e:"br"}," ",{p:[84,2,5276],t:7,e:"ui-button",a:{action:"purchase",state:[{t:2,x:{r:["data.credits","data.totalprice"],s:'_0>=_1?null:"disabled"'},p:[84,38,5312]}]},f:["PURCHASE"]}]},{t:4,n:50,x:{r:["data.state"],s:"(!(_0==1))&&((!(_0==2))&&(_0==3))"},f:[" ",{p:[87,2,5423],t:7,e:"h2",f:["Step 4: Thank you for your purchase"]},{p:[87,46,5467],t:7,e:"br"}," ",{p:[88,2,5474],t:7,e:"b",f:["Should you experience any issues with your new device, contact your local network admin for assistance."]}]}],x:{r:["data.state"],s:"_0==0"}}]},e.exports=a.extend(r.exports)},{205:205}],244:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,1,22],t:7,e:"ui-display",f:[{p:[3,2,37],t:7,e:"ui-section",a:{label:"Cap"},f:[{p:[4,3,65],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.is_capped"],s:'_0?"power-off":"close"'},p:[4,20,82]}],style:[{t:2,x:{r:["data.is_capped"],s:'_0?null:"selected"'},p:[4,71,133]}],action:"toggle_cap"},f:[{t:2,x:{r:["data.is_capped"],s:'_0?"On":"Off"'},p:[6,4,202]}]}]}]}],n:50,r:"data.has_cap",p:[1,1,0]},{p:[10,1,288],t:7,e:"ui-display",f:[{t:4,f:[{p:[14,2,419],t:7,e:"ui-section",f:[{p:[15,3,435],t:7,e:"ui-button",a:{action:"select_colour"},f:["Select New Colour"]}]}],n:50,r:"data.can_change_colour",p:[13,1,386]}]}," ",{p:[19,1,540],t:7,e:"ui-display",a:{title:"Stencil"},f:[{t:4,f:[{p:[21,2,599],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[21,21,618]}]},f:[{t:4,f:[{p:[23,7,655],t:7,e:"ui-button",a:{action:"select_stencil",params:['{"item":"',{t:2,r:"item",p:[23,59,707]},'"}'],style:[{t:2,x:{r:["item","data.selected_stencil"],s:'_0==_1?"selected":null'},p:[24,12,731]}]},f:[{t:2,r:"item",p:[25,4,791]}]}],n:52,r:"items",p:[22,3,632]}]}],n:52,r:"data.drawables",p:[20,3,572]}]}," ",{p:[31,1,874],t:7,e:"ui-display",a:{title:"Text Mode"},f:[{p:[32,2,907],t:7,e:"ui-section",a:{label:"Current Buffer"},f:[{t:2,r:"text_buffer",p:[32,37,942]}]}," ",{p:[34,2,976],t:7,e:"ui-section",f:[{p:[34,14,988],t:7,e:"ui-button",a:{action:"enter_text"},f:["New Text"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],245:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{temperatureStatus:function(t){return 225>t?"good":273.15>t?"average":"bad"}},computed:{occupantStatState:function(){switch(this.get("data.occupant.stat")){case 0:return"good";case 1:return"average";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[22,1,466],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[23,3,499],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[24,3,532],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[24,9,538]}]}]}," ",{t:4,f:[{p:[27,5,655],t:7,e:"ui-section",a:{label:"State"},f:[{p:[28,7,689],t:7,e:"span",a:{"class":[{t:2,r:"occupantStatState",p:[28,20,702]}]},f:[{t:2,x:{r:["data.occupant.stat"],s:'_0==0?"Conscious":_0==1?"Unconcious":"Dead"'},p:[28,43,725]}]}]}," ",{p:[30,4,846],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[31,6,885],t:7,e:"span",a:{"class":[{t:2,x:{r:["temperatureStatus","adata.occupant.bodyTemperature"],s:"_0(_1)"},p:[31,19,898]}]},f:[{t:2,x:{r:["adata.occupant.bodyTemperature"],s:"Math.round(_0)"},p:[31,74,953]}," K"]}]}," ",{p:[33,5,1032],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[34,7,1067],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[34,20,1080]}],max:[{t:2,r:"data.occupant.maxHealth",p:[34,54,1114]}],value:[{t:2,r:"data.occupant.health",p:[34,90,1150]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[35,16,1192]}]},f:[{t:2,x:{r:["adata.occupant.health"],s:"Math.round(_0)"},p:[35,68,1244]}]}]}," ",{t:4,f:[{p:[38,7,1481],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[38,26,1500]}]},f:[{p:[39,9,1521],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[39,30,1542]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[39,66,1578]}],state:"bad"},f:[{t:2,x:{r:["type","adata.occupant"],s:"Math.round(_1[_0])"},p:[39,103,1615]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[37,5,1315]}],n:50,r:"data.hasOccupant",p:[26,3,625]}]}," ",{p:[44,1,1724],t:7,e:"ui-display",a:{title:"Cell"},f:[{p:[45,3,1753],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[46,5,1785],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOperating"],s:'_0?"power-off":"close"'},p:[46,22,1802]}],style:[{t:2,x:{r:["data.isOperating"],s:'_0?"selected":null'},p:[47,14,1862]}],state:[{t:2,x:{r:["data.isOpen"],s:'_0?"disabled":null'},p:[48,14,1918]}],action:"power"},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[49,22,1977]}]}]}," ",{p:[51,3,2045],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[52,3,2081],t:7,e:"span",a:{"class":[{t:2,x:{r:["temperatureStatus","adata.cellTemperature"],s:"_0(_1)"},p:[52,16,2094]}]},f:[{t:2,x:{r:["adata.cellTemperature"],s:"Math.round(_0)"},p:[52,62,2140]}," K"]}]}," ",{p:[54,2,2205],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[55,5,2236],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOpen"],s:'_0?"unlock":"lock"'},p:[55,22,2253]}],action:"door"},f:[{t:2,x:{r:["data.isOpen"],s:'_0?"Open":"Closed"'},p:[55,73,2304]}]}," ",{p:[56,5,2357],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoEject"],s:'_0?"sign-out":"sign-in"'},p:[56,22,2374]}],action:"autoeject"},f:[{t:2,x:{r:["data.autoEject"],s:'_0?"Auto":"Manual"'},p:[56,86,2438]}]}]}]}," ",{p:{button:[{p:[61,5,2584],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[61,36,2615]}],action:"ejectbeaker"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[63,3,2718],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{t:4,f:[{p:[66,9,2828],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[66,52,2871]}," units of ",{t:2,r:"name",p:[66,87,2906]}]},{p:[66,102,2921],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[65,7,2788]},{t:4,n:51,f:[{p:[68,9,2952],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[64,5,2753]},{t:4,n:51,f:[{p:[71,7,3028],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],246:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,2,15],t:7,e:"ui-section",a:{label:"State"},f:[{t:4,f:[{p:[4,4,76],t:7,e:"span",a:{"class":"good"},f:["Ready"]}],n:50,r:"data.full_pressure",p:[3,3,45]},{t:4,n:51,f:[{t:4,f:[{p:[7,5,153],t:7,e:"span",a:{"class":"bad"},f:["Power Disabled"]}],n:50,r:"data.panel_open",p:[6,4,124]},{t:4,n:51,f:[{t:4,f:[{p:[10,6,248],t:7,e:"span",a:{"class":"average"},f:["Pressurizing"]}],n:50,r:"data.pressure_charging",p:[9,5,211]},{t:4,n:51,f:[{p:[12,6,310],t:7,e:"span",a:{"class":"bad"},f:["Off"]}],r:"data.pressure_charging"}],r:"data.panel_open"}],r:"data.full_pressure"}]}," ",{p:[17,2,393],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[18,3,426],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.per",p:[18,36,459]}],state:"good"},f:[{t:2,r:"data.per",p:[18,63,486]},"%"]}]}," ",{p:[20,5,530],t:7,e:"ui-section",a:{label:"Handle"},f:[{p:[21,9,567],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.flush"],s:'_0?"toggle-on":"toggle-off"'},p:[22,10,589]}],state:[{t:2,x:{r:["data.isai","data.panel_open"],s:'_0||_1?"disabled":null'},p:[23,11,647]}],action:[{t:2,x:{r:["data.flush"],s:'_0?"handle-0":"handle-1"'},p:[24,12,714]}]},f:[{t:2,x:{r:["data.flush"],s:'_0?"Disengage":"Engage"'},p:[25,5,763]}]}]}," ",{p:[27,2,837],t:7,e:"ui-section",a:{label:"Eject"},f:[{p:[28,3,867],t:7,e:"ui-button",a:{icon:"sign-out",state:[{t:2,x:{r:["data.isai"],s:'_0?"disabled":null'},p:[28,37,901]}],action:"eject"},f:["Eject Contents"]},{p:[28,114,978],t:7,e:"br"}]}," ",{p:[30,2,1002],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[31,3,1032],t:7,e:"ui-button",a:{icon:"power-off",state:[{t:2,x:{r:["data.panel_open"],s:'_0?"disabled":null'},p:[31,38,1067]}],action:[{t:2,x:{r:["data.pressure_charging"],s:'_0?"pump-0":"pump-1"'},p:[31,87,1116]}],style:[{t:2,x:{r:["data.pressure_charging"],s:'_0?"selected":null'},p:[31,145,1174]}]}},{p:[31,206,1235],t:7,e:"br"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],247:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"DNA Vault Database"},f:[{p:[2,3,43],t:7,e:"ui-section",a:{label:"Human DNA"},f:[{p:[3,7,81],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.dna_max",p:[3,28,102]}],value:[{t:2,r:"data.dna",p:[3,53,127]}]},f:[{t:2,r:"data.dna",p:[3,67,141]},"/",{t:2,r:"data.dna_max",p:[3,80,154]}," Samples"]}]}," ",{p:[5,3,208],t:7,e:"ui-section",a:{label:"Plant Data"},f:[{p:[6,5,245],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.plants_max",p:[6,26,266]}],value:[{t:2,r:"data.plants",p:[6,54,294]}]},f:[{t:2,r:"data.plants",p:[6,71,311]},"/",{t:2,r:"data.plants_max",p:[6,87,327]}," Samples"]}]}," ",{p:[8,3,384],t:7,e:"ui-section",a:{label:"Animal Data"},f:[{p:[9,5,422],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.animals_max",p:[9,26,443]}],value:[{t:2,r:"data.animals",p:[9,55,472]}]},f:[{t:2,r:"data.animals",p:[9,73,490]},"/",{t:2,r:"data.animals_max",p:[9,90,507]}," Samples"]}]}]}," ",{t:4,f:[{p:[13,1,616],t:7,e:"ui-display",a:{title:"Personal Gene Therapy"},f:[{p:[14,3,663],t:7,e:"ui-section",f:[{p:[15,2,678],t:7,e:"span",f:["Applicable gene therapy treatments:"]}]}," ",{p:[17,3,747],t:7,e:"ui-section",f:[{p:[18,2,762],t:7,e:"ui-button",a:{action:"gene",params:['{"choice": "',{t:2,r:"data.choiceA",p:[18,47,807]},'"}']},f:[{t:2,r:"data.choiceA",p:[18,67,827]}]}," ",{p:[19,2,858],t:7,e:"ui-button",a:{action:"gene",params:['{"choice": "',{t:2,r:"data.choiceB",p:[19,47,903]},'"}']},f:[{t:2,r:"data.choiceB",p:[19,67,923]}]}]}]}],n:50,x:{r:["data.completed","data.used"],s:"_0&&!_1"},p:[12,1,578]}]},e.exports=a.extend(r.exports)},{205:205}],248:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,24],t:7,e:"ui-display",a:{title:[{t:2,r:"data.question",p:[2,21,42]}]},f:[{p:[3,5,66],t:7,e:"ui-section",f:[{t:4,f:[{p:[5,9,118],t:7,e:"ui-button",a:{action:"vote",params:['{"answer": "',{t:2,r:"answer",p:[6,45,174]},'"}'],style:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[7,18,206]}]},f:[{t:2,r:"answer",p:[7,53,241]}," (",{t:2,r:"amount",p:[7,65,253]},")"]}],n:52,r:"data.answers",p:[4,7,86]}]}]}],n:50,r:"data.shaking",p:[1,1,0]},{t:4,n:51,f:[{p:[13,3,353],t:7,e:"ui-notice",f:["The eightball is not currently being shaken."]}],r:"data.shaking"}]},e.exports=a.extend(r.exports)},{205:205}],249:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,5,17],t:7,e:"span",f:["Time Until Launch: ",{t:2,r:"data.timer_str",p:[2,30,42]}]}]}," ",{p:[4,1,83],t:7,e:"ui-notice",f:[{p:[5,3,98],t:7,e:"span",f:["Engines: ",{t:2,x:{r:["data.engines_started"],s:'_0?"Online":"Idle"'},p:[5,18,113]}]}]}," ",{p:[7,1,180],t:7,e:"ui-display",a:{title:"Early Launch"},f:[{p:[8,2,216],t:7,e:"span",f:["Authorizations Remaining: ",{t:2,x:{r:["data.emagged","data.authorizations_remaining"],s:'_0?"ERROR":_1'},p:[9,2,250]}]}," ",{p:[10,2,318],t:7,e:"ui-button",a:{icon:"exclamation-triangle",action:"authorize",style:"danger",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[12,10,404]}]},f:["AUTHORIZE"]}," ",{p:[15,2,473],t:7,e:"ui-button",a:{icon:"minus",action:"repeal",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[16,10,523]}]},f:["Repeal"]}," ",{p:[19,2,589],t:7,e:"ui-button",a:{icon:"close",action:"abort",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[20,10,638]}]},f:["Repeal All"]}]}," ",{p:[24,1,722],t:7,e:"ui-display",a:{title:"Authorizations"},f:[{t:4,f:[{p:[26,3,793],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{t:2,r:"name",p:[26,34,824]}," (",{t:2,r:"job",p:[26,44,834]},")"]}],n:52,r:"data.authorizations",p:[25,2,760]},{t:4,n:51,f:[{p:[28,3,870],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:["No authorizations."]}],r:"data.authorizations"}]}]},e.exports=a.extend(r.exports)},{205:205}],250:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Message"},f:[{t:2,r:"data.hidden_message",p:[3,5,50]}]}," ",{p:[5,3,94],t:7,e:"ui-section",a:{label:"Created On"},f:[{t:2,r:"data.realdate",p:[6,5,131]}]}," ",{p:[8,3,169],t:7,e:"ui-section",a:{label:"Approval"},f:[{p:[9,5,204],t:7,e:"ui-button",a:{icon:"arrow-up",state:[{t:2,x:{r:["data.is_creator","data.has_liked"],s:'_0?"disabled":_1?"selected":null'},p:[11,14,252]}],action:"like"},f:[{t:2,r:"data.num_likes",p:[12,21,344]}]}," ",{p:[13,5,380],t:7,e:"ui-button",a:{icon:"circle",state:[{t:2,x:{r:["data.is_creator","data.has_liked","data.has_disliked"],s:'_0?"disabled":!_1&&!_2?"selected":null'},p:[15,14,426]}],action:"neutral"}}," ",{p:[17,5,562],t:7,e:"ui-button",a:{icon:"arrow-down",state:[{t:2,x:{r:["data.is_creator","data.has_disliked"],s:'_0?"disabled":_1?"selected":null'},p:[19,14,612]}],action:"dislike"},f:[{t:2,r:"data.num_dislikes",p:[20,24,710]}]}]}]}," ",{t:4,f:[{p:[24,3,805],t:7,e:"ui-display",a:{title:"Admin Panel"},f:[{p:[25,5,843],t:7,e:"ui-section",a:{label:"Creator Ckey"},f:[{t:2,r:"data.creator_key",p:[25,38,876]}]}," ",{p:[26,5,915],t:7,e:"ui-section",a:{label:"Creator Character Name"},f:[{t:2,r:"data.creator_name",p:[26,48,958]}]}," ",{p:[27,5,998],t:7,e:"ui-button",a:{icon:"remove",action:"delete",style:"danger"},f:["Delete"]}]}],n:50,r:"data.admin_mode",p:[23,1,778]}]},e.exports=a.extend(r.exports)},{205:205}],251:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The requested interface (",{t:2,r:"config.interface",p:[2,34,46]},") was not found. Does it exist?"]}]}]},e.exports=a.extend(r.exports)},{205:205}],252:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{seclevelState:function(){switch(this.get("data.seclevel")){case"blue":return"average";case"red":return"bad";case"delta":return"bad bold";default:return"good"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[16,1,323],t:7,e:"ui-display",f:[{p:[17,5,341],t:7,e:"ui-section",a:{label:"Alert Level"},f:[{p:[18,9,383],t:7,e:"span",a:{"class":[{t:2,r:"seclevelState",p:[18,22,396]}]},f:[{t:2,x:{r:["text","data.seclevel"],s:"_0.titleCase(_1)"},p:[18,41,415]}]}]}," ",{p:[20,5,480],t:7,e:"ui-section",a:{label:"Controls"},f:[{p:[21,9,519],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.alarm"],s:'_0?"close":"bell-o"'},p:[21,26,536]}],action:[{t:2,x:{r:["data.alarm"],s:'_0?"reset":"alarm"'},p:[21,71,581]}]},f:[{t:2,x:{r:["data.alarm"],s:'_0?"Reset":"Activate"'},p:[22,13,631]}]}]}," ",{t:4,f:[{p:[25,7,733],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[26,9,771],t:7,e:"span",a:{"class":"bad bold"},f:["Safety measures offline. Device may exhibit abnormal behavior."]}]}],n:50,r:"data.emagged",p:[24,5,705]}]}]},e.exports=a.extend(r.exports)},{205:205}],253:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[2,1,31],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,2,60],t:7,e:"ui-button",a:{icon:"power-off",style:[{t:2,x:{r:["data.power"],s:'_0?"selected":"danger"'},p:[3,37,95]}],action:"power"},f:[{t:2,x:{r:["data.power"],s:'_0?"Enabled":"Disabled"'},p:[3,92,150]}]}]}," ",{p:[5,1,218],t:7,e:"ui-section",a:{label:"Tag"},f:[{p:[6,2,245],t:7,e:"ui-button",a:{icon:"pencil",action:"rename"},f:[{t:2,r:"data.tag",p:[6,43,286]}]}]}," ",{p:[8,1,327],t:7,e:"ui-section",a:{label:"Scanning mode"},f:[{p:[9,2,364],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.updating"],s:'_0?"unlock":"lock"'},p:[9,18,380]}],style:[{t:2,x:{r:["data.updating"],s:'_0?null:"danger"'},p:[9,63,425]}],action:"updating",tooltip:"Toggle between automatic scanning or scan only when a button is pressed.","tooltip-side":"right"},f:[{t:2,x:{r:["data.updating"],s:'_0?"AUTO":"MANUAL"'},p:[9,221,583]}]}]}," ",{p:[11,1,649],t:7,e:"ui-section",a:{label:"Detection range"},f:[{p:[12,2,688],t:7,e:"ui-button",a:{icon:"refresh",style:[{t:2,x:{r:["data.globalmode"],s:'_0?null:"selected"'},p:[12,35,721]}],action:"globalmode",tooltip:"Local sector or whole region scanning.","tooltip-side":"right"},f:[{t:2,x:{r:["data.globalmode"],s:'_0?"MAXIMUM":"LOCAL"'},p:[12,165,851]}]}]}]}," ",{t:4,f:[{p:[16,2,957],t:7,e:"ui-display",a:{title:"Current Location"},f:[{p:[17,3,998],t:7,e:"span",f:[{t:2,r:"data.current",p:[17,9,1004]}]}]}," ",{p:[20,2,1048],t:7,e:"ui-display",a:{title:"Detected Signals"},f:[{t:4,f:[{p:[22,3,1114],t:7,e:"ui-section",a:{label:[{t:2,r:"entrytag",p:[22,21,1132]}]},f:[{p:[23,3,1149],t:7,e:"span",f:[{t:2,r:"area",p:[23,9,1155]}," (",{t:2,r:"coord",p:[23,19,1165]},")"]}," ",{t:4,f:[{p:[25,4,1209],t:7,e:"span",f:["Dist: ",{t:2,r:"dist",p:[25,16,1221]},"m Dir: ",{t:2,r:"degrees",p:[25,31,1236]},"° (",{t:2,r:"direction",p:[25,45,1250]},")"]}],n:50,r:"direction",p:[24,3,1187]}]}],n:52,r:"data.signals",p:[21,2,1088]}]}],n:50,r:"data.power",p:[15,1,936]}]},e.exports=a.extend(r.exports)},{205:205}],254:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Labor Camp Teleporter"},f:[{p:[2,2,45],t:7,e:"ui-section",a:{label:"Teleporter Status"},f:[{p:[3,3,87],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.teleporter"],s:'_0?"good":"bad"'},p:[3,16,100]}]},f:[{t:2,x:{r:["data.teleporter"],s:'_0?"Connected":"Not connected"'},p:[3,54,138]}]}]}," ",{t:4,f:[{p:[6,4,244],t:7,e:"ui-section",a:{label:"Location"},f:[{p:[7,5,279],t:7,e:"span",f:[{t:2,r:"data.teleporter_location",p:[7,11,285]}]}]}," ",{p:[9,4,343],t:7,e:"ui-section",a:{label:"Locked status"},f:[{p:[10,5,383],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.teleporter_lock"],s:'_0?"lock":"unlock"'},p:[10,22,400]}],action:"teleporter_lock"},f:[{t:2,x:{r:["data.teleporter_lock"],s:'_0?"Locked":"Unlocked"'},p:[10,93,471]}]}," ",{p:[11,5,537],t:7,e:"ui-button",a:{action:"toggle_open"},f:[{t:2,x:{r:["data.teleporter_state_open"],s:'_0?"Open":"Closed"'},p:[11,37,569]}]}]}],n:50,r:"data.teleporter",p:[5,3,216]},{t:4,n:51,f:[{p:[14,4,666],t:7,e:"span",f:[{p:[14,10,672],t:7,e:"ui-button",a:{action:"scan_teleporter"},f:["Scan Teleporter"]}]}],r:"data.teleporter"}]}," ",{p:[17,1,770],t:7,e:"ui-display",a:{title:"Labor Camp Beacon"},f:[{p:[18,2,811],t:7,e:"ui-section",a:{label:"Beacon Status"},f:[{p:[19,3,849],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.beacon"],s:'_0?"good":"bad"'},p:[19,16,862]}]},f:[{t:2,x:{r:["data.beacon"],s:'_0?"Connected":"Not connected"'},p:[19,50,896]}]}]}," ",{t:4,f:[{p:[22,3,992],t:7,e:"ui-section",a:{label:"Location"},f:[{p:[23,4,1026],t:7,e:"span",f:[{t:2,r:"data.beacon_location",p:[23,10,1032]}]}]}],n:50,r:"data.beacon",p:[21,2,969]},{t:4,n:51,f:[{p:[26,4,1097],t:7,e:"span",f:[{p:[26,10,1103],t:7,e:"ui-button",a:{action:"scan_beacon"},f:["Scan Beacon"]}]}],r:"data.beacon"}]}," ",{p:[29,1,1193],t:7,e:"ui-display",a:{title:"Prisoner details"},f:[{p:[30,2,1233],t:7,e:"ui-section",a:{label:"Prisoner ID"},f:[{p:[31,3,1269],t:7,e:"ui-button",a:{action:"handle_id"},f:[{t:2,x:{r:["data.id","data.id_name"],s:'_0?_1:"-------------"'},p:[31,33,1299]}]}]}," ",{t:4,f:[{p:[34,2,1392],t:7,e:"ui-section",a:{label:"Set ID goal"},f:[{p:[35,4,1429],t:7,e:"ui-button",a:{action:"set_goal"},f:[{t:2,r:"data.goal",p:[35,33,1458]}]}]}],n:50,r:"data.id",p:[33,2,1374]}," ",{p:[38,2,1512],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[39,3,1545],t:7,e:"span",f:[{t:2,x:{r:["data.prisoner.name"],s:'_0?_0:"No Occupant"'},p:[39,9,1551]}]}]}," ",{t:4,f:[{p:[42,3,1661],t:7,e:"ui-section",a:{label:"Criminal Status"},f:[{p:[43,4,1702],t:7,e:"span",f:[{t:2,r:"data.prisoner.crimstat",p:[43,10,1708]}]}]}],n:50,r:"data.prisoner",p:[41,2,1636]}]}," ",{p:[47,1,1785],t:7,e:"ui-display",f:[{p:[48,2,1800],t:7,e:"center",f:[{p:[48,10,1808],t:7,e:"ui-button",a:{action:"teleport",state:[{t:2,x:{r:["data.can_teleport"],s:'_0?null:"disabled"'},p:[48,45,1843]}]},f:["Process Prisoner"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],255:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,2,15],t:7,e:"center",f:[{p:[2,10,23],t:7,e:"ui-button",a:{action:"handle_id"},f:[{t:2,x:{r:["data.id","data.id_name"],s:'_0?_1:"-------------"'},p:[2,40,53]}]}]}]}," ",{p:[4,1,135],t:7,e:"ui-display",a:{title:"Stored Items"},f:[{t:4,f:[{p:[6,3,194],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[6,22,213]}]},f:[{p:[7,4,228],t:7,e:"ui-button",a:{action:"release_items",params:['{"mobref":',{t:2, r:"mob",p:[7,56,280]},"}"],state:[{t:2,x:{r:["data.can_reclaim"],s:'_0?null:"disabled"'},p:[7,72,296]}]},f:["Drop Items"]}]}],n:52,r:"data.mobs",p:[5,2,171]}]}]},e.exports=a.extend(r.exports)},{205:205}],256:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{p:[3,3,70],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.emagged"],s:'_0?"un":null'},p:[3,20,87]},"lock"],state:[{t:2,x:{r:["data.can_toggle_safety"],s:'_0?null:"disabled"'},p:[3,63,130]}],action:"safety"},f:["Safeties: ",{p:[4,14,209],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.emagged"],s:'_0?"bad":"good"'},p:[4,27,222]}]},f:[{t:2,x:{r:["data.emagged"],s:'_0?"OFF":"ON"'},p:[4,62,257]}]}]}]},t:7,e:"ui-display",a:{title:"Default Programs",button:0},f:[" ",{t:4,f:[{p:[8,2,363],t:7,e:"ui-button",a:{action:"load_program",params:['{"type": ',{t:2,r:"type",p:[8,52,413]},"}"],style:[{t:2,x:{r:["data.program","type"],s:'_0==_1?"selected":null'},p:[8,70,431]}]},f:[{t:2,r:"name",p:[9,5,483]}," "]},{p:[10,14,506],t:7,e:"br"}],n:52,r:"data.default_programs",p:[7,2,329]}]}," ",{t:4,f:[{p:[14,2,562],t:7,e:"ui-display",a:{title:"Dangerous Programs"},f:[{t:4,f:[{p:[16,4,638],t:7,e:"ui-button",a:{icon:"warning",action:"load_program",params:['{"type": ',{t:2,r:"type",p:[16,69,703]},"}"],style:[{t:2,x:{r:["data.program","type"],s:'_0==_1?"selected":null'},p:[16,87,721]}]},f:[{t:2,r:"name",p:[17,5,773]}," "]},{p:[18,16,798],t:7,e:"br"}],n:52,r:"data.emag_programs",p:[15,3,605]}]}],n:50,r:"data.emagged",p:[13,1,539]}]},e.exports=a.extend(r.exports)},{205:205}],257:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{occupantStatState:function(){switch(this.get("data.occupant.stat")){case 0:return"good";case 1:return"average";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[15,1,280],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[16,3,313],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[17,3,346],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[17,9,352]}]}]}," ",{t:4,f:[{p:[20,5,466],t:7,e:"ui-section",a:{label:"State"},f:[{p:[21,7,500],t:7,e:"span",a:{"class":[{t:2,r:"occupantStatState",p:[21,20,513]}]},f:[{t:2,x:{r:["data.occupant.stat"],s:'_0==0?"Conscious":_0==1?"Unconcious":"Dead"'},p:[21,43,536]}]}]}],n:50,r:"data.occupied",p:[19,3,439]}]}," ",{p:[25,1,680],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[26,2,712],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[27,5,743],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"unlock":"lock"'},p:[27,22,760]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Open":"Closed"'},p:[27,71,809]}]}]}," ",{p:[29,3,874],t:7,e:"ui-section",a:{label:"Uses"},f:[{t:2,r:"data.ready_implants",p:[30,5,905]}," ",{t:4,f:[{p:[32,7,969],t:7,e:"span",a:{"class":"fa fa-cog fa-spin"}}],n:50,r:"data.replenishing",p:[31,5,936]}]}," ",{p:[35,3,1036],t:7,e:"ui-section",a:{label:"Activate"},f:[{p:[36,7,1073],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.occupied","data.ready_implants","data.ready"],s:'_0&&_1>0&&_2?null:"disabled"'},p:[36,25,1091]}],action:"implant"},f:[{t:2,x:{r:["data.ready","data.special_name"],s:'_0?(_1?_1:"Implant"):"Recharging"'},p:[37,9,1198]}," "]},{p:[38,19,1302],t:7,e:"br"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],258:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{healthState:function(){var t=this.get("data.health");return t>70?"good":t>50?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[15,3,296],t:7,e:"ui-notice",f:[{p:[16,5,313],t:7,e:"span",f:["Wipe in progress!"]}]}],n:50,r:"data.wiping",p:[14,1,273]},{p:{button:[{t:4,f:[{p:[22,7,479],t:7,e:"ui-button",a:{icon:"trash",state:[{t:2,x:{r:["data.isDead"],s:'_0?"disabled":null'},p:[22,38,510]}],action:"wipe"},f:[{t:2,x:{r:["data.wiping"],s:'_0?"Stop Wiping":"Wipe"'},p:[22,89,561]}," AI"]}],n:50,r:"data.name",p:[21,5,454]}]},t:7,e:"ui-display",a:{title:[{t:2,x:{r:["data.name"],s:'_0||"Empty Card"'},p:[19,19,388]}],button:0},f:[" ",{t:4,f:[{p:[26,5,672],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[27,9,709],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.isDead","data.isBraindead"],s:'_0||_1?"bad":"good"'},p:[27,22,722]}]},f:[{t:2,x:{r:["data.isDead","data.isBraindead"],s:'_0||_1?"Offline":"Operational"'},p:[27,76,776]}]}]}," ",{p:[29,5,871],t:7,e:"ui-section",a:{label:"Software Integrity"},f:[{p:[30,7,918],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.health",p:[30,40,951]}],state:[{t:2,r:"healthState",p:[30,64,975]}]},f:[{t:2,x:{r:["adata.health"],s:"Math.round(_0)"},p:[30,81,992]},"%"]}]}," ",{p:[32,5,1055],t:7,e:"ui-section",a:{label:"Laws"},f:[{t:4,f:[{p:[34,9,1117],t:7,e:"span",a:{"class":"highlight"},f:[{t:2,r:".",p:[34,33,1141]}]},{p:[34,45,1153],t:7,e:"br"}],n:52,r:"data.laws",p:[33,7,1088]}]}," ",{p:[37,5,1200],t:7,e:"ui-section",a:{label:"Settings"},f:[{p:[38,7,1237],t:7,e:"ui-button",a:{icon:"signal",style:[{t:2,x:{r:["data.wireless"],s:'_0?"selected":null'},p:[38,39,1269]}],action:"wireless"},f:["Wireless Activity"]}," ",{p:[39,7,1363],t:7,e:"ui-button",a:{icon:"microphone",style:[{t:2,x:{r:["data.radio"],s:'_0?"selected":null'},p:[39,43,1399]}],action:"radio"},f:["Subspace Radio"]}]}],n:50,r:"data.name",p:[25,3,649]}]}]},e.exports=a.extend(r.exports)},{205:205}],259:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,23],t:7,e:"ui-notice",f:[{p:[3,3,38],t:7,e:"span",f:["Waiting for another device to confirm your request..."]}]}],n:50,r:"data.waiting",p:[1,1,0]},{t:4,n:51,f:[{p:[6,2,132],t:7,e:"ui-display",f:[{p:[7,3,148],t:7,e:"ui-section",f:[{t:4,f:[{p:[9,5,197],t:7,e:"ui-button",a:{icon:"check",action:"auth_swipe"},f:["Authorize ",{t:2,r:"data.auth_required",p:[9,59,251]}]}],n:50,r:"data.auth_required",p:[8,4,165]},{t:4,n:51,f:[{p:[11,5,304],t:7,e:"ui-button",a:{icon:"warning",state:[{t:2,x:{r:["data.red_alert"],s:'_0?"disabled":null'},p:[11,38,337]}],action:"red_alert"},f:["Red Alert"]}," ",{p:[12,5,423],t:7,e:"ui-button",a:{icon:"wrench",state:[{t:2,x:{r:["data.emergency_maint"],s:'_0?"disabled":null'},p:[12,37,455]}],action:"emergency_maint"},f:["Emergency Maintenance Access"]}," ",{p:[13,5,572],t:7,e:"ui-button",a:{icon:"warning",state:"null",action:"bsa_unlock"},f:["Bluespace Artillery Unlock"]}],r:"data.auth_required"}]}]}],r:"data.waiting"}]},e.exports=a.extend(r.exports)},{205:205}],260:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Ore values"},f:[{t:4,f:[{p:[3,3,57],t:7,e:"ui-section",a:{label:[{t:2,r:"ore",p:[3,22,76]}]},f:[{p:[4,4,90],t:7,e:"span",f:[{t:2,r:"value",p:[4,10,96]}]}]}],n:52,r:"data.ores",p:[2,2,34]}]}," ",{p:[8,1,158],t:7,e:"ui-display",a:{title:"Points"},f:[{p:[9,2,188],t:7,e:"ui-section",a:{label:"ID"},f:[{p:[10,3,215],t:7,e:"ui-button",a:{action:"handle_id"},f:[{t:2,x:{r:["data.id","data.id_name"],s:'_0?_1:"-------------"'},p:[10,33,245]}]}]}," ",{t:4,f:[{p:[13,3,339],t:7,e:"ui-section",a:{label:"Points collected"},f:[{p:[14,4,381],t:7,e:"span",f:[{t:2,r:"data.points",p:[14,10,387]}]}]}," ",{p:[16,3,430],t:7,e:"ui-section",a:{label:"Goal"},f:[{p:[17,4,460],t:7,e:"span",f:[{t:2,r:"data.goal",p:[17,10,466]}]}]}," ",{p:[19,3,507],t:7,e:"ui-section",a:{label:"Unclaimed points"},f:[{p:[20,4,549],t:7,e:"span",f:[{t:2,r:"data.unclaimed_points",p:[20,10,555]}]}," ",{p:[21,4,592],t:7,e:"ui-button",a:{action:"claim_points",state:[{t:2,x:{r:["data.unclaimed_points"],s:'_0?null:"disabled"'},p:[21,43,631]}]},f:["Claim points"]}]}],n:50,r:"data.id",p:[12,2,320]}]}," ",{p:[25,1,745],t:7,e:"ui-display",f:[{p:[26,2,760],t:7,e:"center",f:[{p:[27,3,772],t:7,e:"ui-button",a:{action:"move_shuttle",state:[{t:2,x:{r:["data.can_go_home"],s:'_0?null:"disabled"'},p:[27,42,811]}]},f:["Move shuttle"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],261:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Known Languages"},f:[{t:4,f:[{p:[3,5,70],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[3,23,88]}]},f:[{p:[4,7,105],t:7,e:"span",f:[{t:2,r:"desc",p:[4,13,111]}]}," ",{p:[5,7,134],t:7,e:"span",f:["Key: ,",{t:2,r:"key",p:[5,19,146]}]}," ",{t:4,f:[{p:[7,9,192],t:7,e:"span",f:["(gained from mob)"]}],n:50,r:"shadow",p:[6,7,168]}," ",{p:[9,7,245],t:7,e:"span",f:[{t:2,x:{r:["can_speak"],s:'_0?"Can Speak":"Cannot Speak"'},p:[9,13,251]}]}," ",{t:4,f:[{p:[11,9,342],t:7,e:"ui-button",a:{action:"select_default",params:['{"language_name":"',{t:2,r:"name",p:[13,37,425]},'"}'],style:[{t:2,x:{r:["is_default","can_speak"],s:'_0?"selected":_1?null:"disabled"'},p:[14,18,455]}]},f:[{t:2,x:{r:["is_default"],s:'_0?"Default Language":"Select as Default"'},p:[15,10,526]}]}],n:50,r:"data.is_living",p:[10,7,310]}," ",{t:4,f:[{t:4,f:[{p:[20,11,685],t:7,e:"ui-button",a:{action:"grant_language",params:['{"language_name":"',{t:2,r:"name",p:[20,72,746]},'"}']},f:["Grant"]}],n:50,r:"shadow",p:[19,9,659]},{t:4,n:51,f:[{p:[22,11,805],t:7,e:"ui-button",a:{action:"remove_language",params:['{"language_name":"',{t:2,r:"name",p:[22,73,867]},'"}']},f:["Remove"]}],r:"shadow"}],n:50,r:"data.admin_mode",p:[18,7,626]}]}],n:52,r:"data.languages",p:[2,3,40]}]}," ",{t:4,f:[{t:4,f:[{p:[30,5,1033],t:7,e:"ui-button",a:{action:"toggle_omnitongue",style:[{t:2,x:{r:["data.omnitongue"],s:'_0?"selected":null'},p:[32,14,1092]}]},f:["Omnitongue ",{t:2,x:{r:["data.omnitongue"],s:'_0?"Enabled":"Disabled"'},p:[33,19,1152]}]}],n:50,r:"data.is_living",p:[29,3,1005]}," ",{p:[36,3,1231],t:7,e:"ui-display",a:{title:"Unknown Languages"},f:[{t:4,f:[{p:[38,7,1315],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[38,25,1333]}]},f:[{p:[39,9,1352],t:7,e:"span",f:[{t:2,r:"desc",p:[39,15,1358]}]}," ",{p:[40,9,1383],t:7,e:"span",f:["Key: ,",{t:2,r:"key",p:[40,21,1395]}]}," ",{p:[41,9,1419],t:7,e:"ui-button",a:{action:"grant_language",params:['{"language_name":"',{t:2,r:"name",p:[43,37,1502]},'"}']},f:["Grant"]}]}],n:52,r:"data.unknown_languages",p:[37,5,1275]}]}],n:50,r:"data.admin_mode",p:[28,1,978]}]},e.exports=a.extend(r.exports)},{205:205}],262:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Controls"},f:[{t:4,f:[{t:4,f:[{p:[4,4,84],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[5,5,118],t:7,e:"span",f:["Launchpad closed."]}]}],n:50,r:"data.pad_closed",p:[3,3,56]},{t:4,n:51,f:[{p:[8,4,183],t:7,e:"ui-section",a:{label:"Launchpad"},f:[{p:[9,4,218],t:7,e:"span",f:[{p:[9,10,224],t:7,e:"b",f:[{t:2,r:"data.pad_name",p:[9,13,227]}]}]},{p:[9,41,255],t:7,e:"br"}," ",{p:[10,4,264],t:7,e:"ui-button",a:{icon:"pencil",action:"rename"},f:["Rename"]}," ",{p:[11,4,328],t:7,e:"ui-button",a:{icon:"remove",style:"danger",action:"remove"},f:["Remove"]}]}," ",{p:[14,4,427],t:7,e:"ui-section",a:{label:"Set Target"},f:[{p:[15,4,463],t:7,e:"table",f:[{p:[16,4,475],t:7,e:"tr",f:[{p:[17,5,485],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[17,38,518],t:7,e:"ui-button",a:{action:"up-left"},f:["↖"]}]}," ",{p:[18,5,570],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[18,57,622],t:7,e:"ui-button",a:{action:"up"},f:["↑"]}]}," ",{p:[19,5,669],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[19,56,720],t:7,e:"ui-button",a:{action:"up-right"},f:["↗"]}]}]}," ",{p:[21,4,782],t:7,e:"tr",f:[{p:[22,5,792],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[22,38,825],t:7,e:"ui-button",a:{action:"left",style:"width:35px!important"},f:["â†"]}]}," ",{p:[23,5,903],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[23,57,955],t:7,e:"ui-button",a:{action:"reset"},f:["R"]}]}," ",{p:[24,5,1005],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[24,56,1056],t:7,e:"ui-button",a:{action:"right"},f:["→"]}]}]}," ",{p:[26,4,1115],t:7,e:"tr",f:[{p:[27,5,1125],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[27,38,1158],t:7,e:"ui-button",a:{action:"down-left"},f:["↙"]}]}," ",{p:[28,5,1212],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[28,57,1264],t:7,e:"ui-button",a:{action:"down"},f:["↓"]}]}," ",{p:[29,5,1313],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[29,56,1364],t:7,e:"ui-button",a:{action:"down-right"},f:["↘"]}]}]}]}]}," ",{p:[33,4,1459],t:7,e:"ui-section",a:{label:"Current Target"},f:[{p:[34,5,1500],t:7,e:"span",f:[{t:2,r:"data.abs_y",p:[34,11,1506]}," ",{t:2,r:"data.north_south",p:[34,26,1521]}]},{p:[34,53,1548],t:7,e:"br"}," ",{p:[35,5,1558],t:7,e:"span",f:[{t:2,r:"data.abs_x",p:[35,11,1564]}," ",{t:2,r:"data.east_west",p:[35,26,1579]}]}]}," ",{p:[37,4,1627],t:7,e:"ui-section",a:{label:"Activate"},f:[{p:[38,5,1662],t:7,e:"ui-button",a:{action:"launch",tooltip:"Teleport everything on the pad to the target.","tooltip-side":"down"},f:["Launch"]}," ",{p:[39,5,1789],t:7,e:"ui-button",a:{action:"pull",tooltip:"Teleport everything from the target to the pad.","tooltip-side":"down"},f:["Pull"]}]}],r:"data.pad_closed"}],n:50,r:"data.has_pad",p:[2,2,32]},{t:4,n:51,f:[{p:[45,3,1956],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[46,4,1989],t:7,e:"span",f:["No launchpad found. Link the remote to a launchpad."]}]}],r:"data.has_pad"}]}]},e.exports=a.extend(r.exports)},{205:205}],263:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{mechChargeState:function(t){var e=this.get("data.recharge_port.mech.cell.maxcharge");return t>=e/1.5?"good":t>=e/3?"average":"bad"},mechHealthState:function(t){var e=this.get("data.recharge_port.mech.maxhealth");return t>e/1.5?"good":t>e/3?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[20,1,545],t:7,e:"ui-display",a:{title:"Mech Status"},f:[{t:4,f:[{t:4,f:[{p:[23,4,646],t:7,e:"ui-section",a:{label:"Integrity"},f:[{p:[24,6,683],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.recharge_port.mech.maxhealth",p:[24,27,704]}],value:[{t:2,r:"adata.recharge_port.mech.health",p:[24,74,751]}],state:[{t:2,x:{r:["mechHealthState","adata.recharge_port.mech.health"],s:"_0(_1)"},p:[24,117,794]}]},f:[{t:2,x:{r:["adata.recharge_port.mech.health"],s:"Math.round(_0)"},p:[24,171,848]},"/",{t:2,r:"adata.recharge_port.mech.maxhealth",p:[24,219,896]}]}]}," ",{t:4,f:[{t:4,f:[{p:[28,5,1061],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[28,31,1087],t:7,e:"span",a:{"class":"bad"},f:["Cell Critical Failure"]}]}],n:50,r:"data.recharge_port.mech.cell.critfail",p:[27,3,1010]},{t:4,n:51,f:[{p:[30,11,1170],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[31,13,1210],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.recharge_port.mech.cell.maxcharge",p:[31,34,1231]}],value:[{t:2,r:"adata.recharge_port.mech.cell.charge",p:[31,86,1283]}],state:[{t:2,x:{r:["mechChargeState","adata.recharge_port.mech.cell.charge"],s:"_0(_1)"},p:[31,134,1331]}]},f:[{t:2,x:{r:["adata.recharge_port.mech.cell.charge"],s:"Math.round(_0)"},p:[31,193,1390]},"/",{t:2,x:{r:["adata.recharge_port.mech.cell.maxcharge"],s:"Math.round(_0)"},p:[31,246,1443]}]}]}],r:"data.recharge_port.mech.cell.critfail"}],n:50,r:"data.recharge_port.mech.cell",p:[26,4,970]},{t:4,n:51,f:[{p:[35,3,1558],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[35,29,1584],t:7,e:"span",a:{"class":"bad"},f:["Cell Missing"]}]}],r:"data.recharge_port.mech.cell"}],n:50,r:"data.recharge_port.mech",p:[22,2,610]},{t:4,n:51,f:[{p:[38,4,1662],t:7,e:"ui-section",f:["Mech Not Found"]}],r:"data.recharge_port.mech"}],n:50,r:"data.recharge_port",p:[21,3,581]},{t:4,n:51,f:[{p:[41,5,1729],t:7,e:"ui-section",f:["Recharging Port Not Found"]}," ",{p:[42,2,1782],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect"},f:["Reconnect"]}],r:"data.recharge_port"}]}]},e.exports=a.extend(r.exports)},{205:205}],264:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{t:4,f:[{p:[3,5,45],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[4,7,88],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[4,24,105]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[4,75,156]}]}]}],n:50,r:"data.siliconUser",p:[2,3,15]},{t:4,n:51,f:[{p:[7,5,247],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[7,31,273]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[10,1,358],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[11,3,389],t:7,e:"ui-section",a:{label:"Power"},f:[{t:4,f:[{p:[13,7,470],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[13,24,487]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[13,68,531]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[13,116,579]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[12,5,421]},{t:4,n:51,f:[{p:[15,7,639],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.on"],s:'_0?"good":"bad"'},p:[15,20,652]}],state:[{t:2,x:{r:["data.cell"],s:'_0?null:"disabled"'},p:[15,57,689]}]},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[15,92,724]}]}],x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"}}]}," ",{p:[18,3,791],t:7,e:"ui-section",a:{label:"Cell"},f:[{p:[19,5,822],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.cell"],s:'_0?null:"bad"'},p:[19,18,835]}]},f:[{t:2,x:{r:["data.cell","data.cellPercent"],s:'_0?_1+"%":"No Cell"'},p:[19,48,865]}]}]}," ",{p:[21,3,943],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[22,5,974],t:7,e:"span",a:{"class":[{t:2,r:"data.modeStatus",p:[22,18,987]}]},f:[{t:2,r:"data.mode",p:[22,39,1008]}]}]}," ",{p:[24,3,1049],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[25,5,1080],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.load"],s:'_0?"good":"average"'},p:[25,18,1093]}]},f:[{t:2,x:{r:["data.load"],s:'_0?_0:"None"'},p:[25,54,1129]}]}]}," ",{p:[27,3,1191],t:7,e:"ui-section",a:{label:"Destination"},f:[{p:[28,5,1229],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.destination"],s:'_0?"good":"average"'},p:[28,18,1242]}]},f:[{t:2,x:{r:["data.destination"],s:'_0?_0:"None"'},p:[28,60,1284]}]}]}]}," ",{t:4,f:[{p:{button:[{t:4,f:[{p:[35,9,1513],t:7,e:"ui-button",a:{icon:"eject",action:"unload"},f:["Unload"]}],n:50,r:"data.load",p:[34,7,1486]}," ",{t:4,f:[{p:[38,9,1623],t:7,e:"ui-button",a:{icon:"eject",action:"ejectpai"},f:["Eject PAI"]}],n:50,r:"data.haspai",p:[37,7,1594]}," ",{p:[40,7,1709],t:7,e:"ui-button",a:{icon:"pencil",action:"setid"},f:["Set ID"]}]},t:7,e:"ui-display",a:{title:"Controls",button:0},f:[" ",{p:[42,5,1791],t:7,e:"ui-section",a:{label:"Destination"},f:[{p:[43,7,1831],t:7,e:"ui-button",a:{icon:"pencil",action:"destination"},f:["Set Destination"]}," ",{p:[44,7,1912],t:7,e:"ui-button",a:{icon:"stop",action:"stop"},f:["Stop"]}," ",{p:[45,7,1973],t:7,e:"ui-button",a:{icon:"play",action:"go"},f:["Go"]}]}," ",{p:[47,5,2047],t:7,e:"ui-section",a:{label:"Home"},f:[{p:[48,7,2080],t:7,e:"ui-button",a:{icon:"home",action:"home"},f:["Go Home"]}," ",{p:[49,7,2144],t:7,e:"ui-button",a:{icon:"pencil",action:"sethome"},f:["Set Home"]}]}," ",{p:[51,5,2231],t:7,e:"ui-section",a:{label:"Settings"},f:[{p:[52,7,2268],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoReturn"],s:'_0?"check-square-o":"square-o"'},p:[52,24,2285]}],style:[{t:2,x:{r:["data.autoReturn"],s:'_0?"selected":null'},p:[52,84,2345]}],action:"autoret"},f:["Auto-Return Home"]}," ",{p:[54,7,2449],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoPickup"],s:'_0?"check-square-o":"square-o"'},p:[54,24,2466]}],style:[{t:2,x:{r:["data.autoPickup"],s:'_0?"selected":null'},p:[54,84,2526]}],action:"autopick"},f:["Auto-Pickup Crate"]}," ",{p:[56,7,2632],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.reportDelivery"],s:'_0?"check-square-o":"square-o"'},p:[56,24,2649]}],style:[{t:2,x:{r:["data.reportDelivery"],s:'_0?"selected":null'},p:[56,88,2713]}],action:"report"},f:["Report Deliveries"]}]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[31,1,1373]}]},e.exports=a.extend(r.exports)},{205:205}],265:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Relay"},f:[{t:4,f:[{p:[3,3,57],t:7,e:"h2",f:["NETWORK BUFFERS OVERLOADED"]}," ",{p:[4,3,96],t:7,e:"h3",f:["Overload Recovery Mode"]}," ",{p:[5,3,131],t:7,e:"i",f:["This system is suffering temporary outage due to overflow of traffic buffers. Until buffered traffic is processed, all further requests will be dropped. Frequent occurences of this error may indicate insufficient hardware capacity of your network. Please contact your network planning department for instructions on how to resolve this issue."]}," ",{p:[6,3,484],t:7,e:"h3",f:["ADMINISTRATIVE OVERRIDE"]}," ",{p:[7,3,520],t:7,e:"b",f:["CAUTION - Data loss may occur"]}," ",{p:[8,3,562],t:7,e:"ui-button",a:{icon:"signal",action:"restart"},f:["Purge buffered traffic"]}],n:50,r:"data.dos_crashed",p:[2,2,29]},{t:4,n:51,f:[{p:[12,3,663],t:7,e:"ui-section",a:{label:"Relay status"},f:[{p:[13,4,701],t:7,e:"ui-button",a:{icon:"power-off",action:"toggle"},f:[{t:2,x:{r:["data.enabled"],s:'_0?"ENABLED":"DISABLED"'},p:[14,6,752]}]}]}," ",{p:[18,3,836],t:7,e:"ui-section",a:{label:"Network buffer status"},f:[{t:2,r:"data.dos_overload",p:[19,4,883]}," / ",{t:2,r:"data.dos_capacity",p:[19,28,907]}," GQ"]}],r:"data.dos_crashed"}]}]},e.exports=a.extend(r.exports)},{205:205}],266:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{healthState:function(){var t=this.get("data.health");return t>70?"good":t>50?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[15,1,320],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[18,3,363],t:7,e:"ui-notice",f:[{p:[19,5,380],t:7,e:"span",f:["Reconstruction in progress!"]}]}],n:50,r:"data.restoring",p:[17,1,337]},{p:[24,1,451],t:7,e:"ui-display",f:[{p:[26,1,467],t:7,e:"div",a:{"class":"item"},f:[{p:[27,3,489],t:7,e:"div",a:{"class":"itemLabel"},f:["Inserted AI:"]}," ",{p:[30,3,541],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[31,2,569],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",state:[{t:2,x:{r:["data.nocard"],s:'_0?"disabled":null'},p:[31,52,619]}]},f:[{t:2,x:{r:["data.name"],s:'_0?_0:"---"'},p:[31,89,656]}]}]}]}," ",{t:4,f:[{p:[36,2,744],t:7,e:"b",f:["ERROR: ",{t:2,r:"data.error",p:[36,12,754]}]}],n:50,r:"data.error",p:[35,1,723]},{t:4,n:51,f:[{p:[38,2,785],t:7,e:"h2",f:["System Status"]}," ",{p:[39,2,810],t:7,e:"div",a:{"class":"item"},f:[{p:[40,3,832],t:7,e:"div",a:{"class":"itemLabel"},f:["Current AI:"]}," ",{p:[43,3,885],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.name",p:[44,4,915]}]}," ",{p:[46,3,942],t:7,e:"div",a:{"class":"itemLabel"},f:["Status:"]}," ",{p:[49,3,991],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["Nonfunctional"],n:50,r:"data.isDead",p:[50,4,1021]},{t:4,n:51,f:["Functional"],r:"data.isDead"}]}," ",{p:[56,3,1114],t:7,e:"div",a:{"class":"itemLabel"},f:["System Integrity:"]}," ",{p:[59,3,1173],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[60,4,1203],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.health",p:[60,37,1236]}],state:[{t:2,r:"healthState",p:[61,11,1264]}]},f:[{t:2,x:{r:["adata.health"],s:"Math.round(_0)"},p:[61,28,1281]},"%"]}]}," ",{p:[63,3,1336],t:7,e:"div",a:{"class":"itemLabel"},f:["Active Laws:"]}," ",{p:[66,3,1390],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[67,4,1420],t:7,e:"table",f:[{t:4,f:[{p:[69,6,1462],t:7,e:"tr",f:[{p:[69,10,1466],t:7,e:"td",f:[{p:[69,14,1470],t:7,e:"span",a:{"class":"highlight"},f:[{t:2,r:".",p:[69,38,1494]}]}]}]}],n:52,r:"data.ai_laws",p:[68,5,1433]}]}]}," ",{p:[73,2,1547],t:7,e:"ui-section",a:{label:"Operations"},f:[{p:[74,3,1582],t:7,e:"ui-button",a:{icon:"plus",style:[{t:2,x:{r:["data.restoring"],s:'_0?"disabled":null'},p:[74,33,1612]}],action:"PRG_beginReconstruction"},f:["Begin Reconstruction"]}]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],267:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[5,1,91],t:7,e:"ui-button",a:{action:"PRG_switchm",icon:"home",params:'{"target" : "mod"}',state:[{t:2,x:{r:["data.mmode"],s:'_0==1?"disabled":null'},p:[5,80,170]}]},f:["Access Modification"]}],n:50,r:"data.have_id_slot",p:[4,1,64]},{p:[7,1,253],t:7,e:"ui-button",a:{action:"PRG_switchm",icon:"folder-open",params:'{"target" : "manage"}',state:[{t:2,x:{r:["data.mmode"],s:'_0==2?"disabled":null'},p:[7,90,342]}]},f:["Job Management"]}," ",{p:[8,1,411],t:7,e:"ui-button",a:{action:"PRG_switchm",icon:"folder-open",params:'{"target" : "manifest"}',state:[{t:2,x:{r:["data.mmode"],s:'!_0?"disabled":null'},p:[8,92,502]}]},f:["Crew Manifest"]}," ",{t:4,f:[{p:[10,1,593],t:7,e:"ui-button",a:{action:"PRG_print",icon:"print",state:[{t:2,x:{r:["data.has_id","data.mmode"],s:'!_1||_0&&_1==1?null:"disabled"'},p:[10,51,643]}]},f:["Print"]}],n:50,r:"data.have_printer",p:[9,1,566]},{t:4,f:[{p:[14,1,766],t:7,e:"div",a:{"class":"item"},f:[{p:[15,3,788],t:7,e:"h2",f:["Crew Manifest"]}," ",{p:[16,3,814],t:7,e:"br"},"Please use security record computer to modify entries.",{p:[16,61,872],t:7,e:"br"},{p:[16,65,876],t:7,e:"br"}]}," ",{t:4,f:[{p:[19,2,916],t:7,e:"div",a:{"class":"item"},f:[{t:2,r:"name",p:[20,2,937]}," - ",{t:2,r:"rank",p:[20,13,948]}]}],n:52,r:"data.manifest",p:[18,1,890]}],n:50,x:{r:["data.mmode"],s:"!_0"},p:[13,1,745]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.mmode"],s:"_0==2"},f:[{p:[25,1,1008],t:7,e:"div",a:{"class":"item"},f:[{p:[26,3,1030],t:7,e:"h2",f:["Job Management"]}]}," ",{p:[28,1,1063],t:7,e:"table",f:[{p:[29,1,1072],t:7,e:"tr",f:[{p:[29,5,1076],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,27,1098],t:7,e:"b",f:["Job"]}]},{p:[29,42,1113],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,64,1135],t:7,e:"b",f:["Slots"]}]},{p:[29,81,1152],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,103,1174],t:7,e:"b",f:["Open job"]}]},{p:[29,123,1194],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,145,1216],t:7,e:"b",f:["Close job"]}]}]}," ",{t:4,f:[{p:[32,2,1269],t:7,e:"tr",f:[{p:[32,6,1273],t:7,e:"td",f:[{t:2,r:"title",p:[32,10,1277]}]},{p:[32,24,1291],t:7,e:"td",f:[{t:2,r:"current",p:[32,28,1295]},"/",{t:2,r:"total",p:[32,40,1307]}]},{p:[32,54,1321],t:7,e:"td",f:[{p:[32,58,1325],t:7,e:"ui-button",a:{action:"PRG_open_job",params:['{"target" : "',{t:2,r:"title",p:[32,112,1379]},'"}'],state:[{t:2,x:{r:["status_open"],s:'_0?null:"disabled"'},p:[32,132,1399]}]},f:[{t:2,r:"desc_open",p:[32,169,1436]}]},{p:[32,194,1461],t:7,e:"br"}]},{p:[32,203,1470],t:7,e:"td",f:[{p:[32,207,1474],t:7,e:"ui-button",a:{action:"PRG_close_job",params:['{"target" : "',{t:2,r:"title",p:[32,262,1529]},'"}'],state:[{t:2,x:{r:["status_close"],s:'_0?null:"disabled"'},p:[32,282,1549]}]},f:[{t:2,r:"desc_close",p:[32,320,1587]}]}]}]}],n:52,r:"data.slots",p:[30,1,1244]}]}]},{t:4,n:50,x:{r:["data.mmode"],s:"!(_0==2)"},f:[" ",{p:[40,1,1665],t:7,e:"div",a:{"class":"item"},f:[{p:[41,3,1687],t:7,e:"h2",f:["Access Modification"]}]}," ",{t:4,f:[{p:[45,3,1751],t:7,e:"span",a:{"class":"alert"},f:[{p:[45,23,1771],t:7,e:"i",f:["Please insert the ID into the terminal to proceed."]}]},{p:[45,87,1835],t:7,e:"br"}],n:50,x:{r:["data.has_id"],s:"!_0"},p:[44,1,1727]},{p:[48,1,1852],t:7,e:"div",a:{"class":"item"},f:[{p:[49,3,1874],t:7,e:"div",a:{"class":"itemLabel"},f:["Target Identity:"]}," ",{p:[52,3,1930],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[53,2,1958],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",params:'{"target" : "id"}'},f:[{t:2,r:"data.id_name",p:[53,72,2028]}]}]}]}," ",{p:[56,1,2076],t:7,e:"div",a:{"class":"item"},f:[{p:[57,3,2098],t:7,e:"div",a:{"class":"itemLabel"},f:["Auth Identity:"]}," ",{p:[60,3,2152],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[61,2,2180],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",params:'{"target" : "auth"}'},f:[{t:2,r:"data.auth_name",p:[61,74,2252]}]}]}]}," ",{p:[64,1,2302],t:7,e:"hr"}," ",{t:4,f:[{t:4,f:[{p:[68,2,2362],t:7,e:"div",a:{"class":"item"},f:[{p:[69,4,2385],t:7,e:"h2",f:["Details"]}]}," ",{t:4,f:[{p:[73,2,2436],t:7,e:"div",a:{"class":"item"},f:[{p:[74,4,2459],t:7,e:"div",a:{"class":"itemLabel"},f:["Registered Name:"]}," ",{p:[77,4,2518],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.id_owner",p:[78,3,2547]}]}]}," ",{p:[81,2,2587],t:7,e:"div",a:{"class":"item"},f:[{p:[82,4,2610],t:7,e:"div",a:{"class":"itemLabel"},f:["Rank:"]}," ",{p:[85,4,2658],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.id_rank",p:[86,3,2687]}]}]}," ",{p:[89,2,2726],t:7,e:"div",a:{"class":"item"},f:[{p:[90,4,2749],t:7,e:"div",a:{"class":"itemLabel"},f:["Demote:"]}," ",{p:[93,4,2799],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[94,3,2828],t:7,e:"ui-button",a:{action:"PRG_terminate",icon:"gear",state:[{t:2,x:{r:["data.id_rank"],s:'_0=="Unassigned"?"disabled":null'},p:[94,56,2881]}]},f:["Demote ",{t:2,r:"data.id_owner",p:[94,117,2942]}]}]}]}],n:50,r:"data.minor",p:[72,2,2415]},{t:4,n:51,f:[{p:[99,2,3007],t:7,e:"div",a:{"class":"item"},f:[{p:[100,4,3030],t:7,e:"div",a:{"class":"itemLabel"},f:["Registered Name:"]}," ",{p:[103,4,3089],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[104,3,3118],t:7,e:"ui-button",a:{action:"PRG_edit",icon:"pencil",params:'{"name" : "1"}'},f:[{t:2,r:"data.id_owner",p:[104,70,3185]}]}]}]}," ",{p:[108,2,3239],t:7,e:"div",a:{"class":"item"},f:[{p:[109,4,3262],t:7,e:"h2",f:["Assignment"]}]}," ",{p:[111,3,3294],t:7,e:"ui-button",a:{action:"PRG_togglea",icon:"gear"},f:[{t:2,x:{r:["data.assignments"],s:'_0?"Hide assignments":"Show assignments"'},p:[111,47,3338]}]}," ",{p:[112,2,3415],t:7,e:"div",a:{"class":"item"},f:[{p:[113,4,3438],t:7,e:"span",a:{id:"allvalue.jobsslot"},f:[]}]}," ",{p:[117,2,3495],t:7,e:"div",a:{"class":"item"},f:[{t:4,f:[{p:[119,4,3547],t:7,e:"div",a:{id:"all-value.jobs"},f:[{p:[120,3,3576],t:7,e:"table",f:[{p:[121,5,3589],t:7,e:"tr",f:[{p:[122,4,3598],t:7,e:"th",f:["Command"]}," ",{p:[123,4,3619],t:7,e:"td",f:[{p:[124,6,3630],t:7,e:"ui-button",a:{action:"PRG_assign",params:'{"assign_target" : "Captain"}',state:[{t:2,x:{r:["data.id_rank"],s:'_0=="Captain"?"selected":null'},p:[124,83,3707]}]},f:["Captain"]}]}]}," ",{p:[127,5,3804],t:7,e:"tr",f:[{p:[128,4,3813],t:7,e:"th",f:["Special"]}," ",{p:[129,4,3834],t:7,e:"td",f:[{p:[130,6,3845],t:7,e:"ui-button",a:{action:"PRG_assign",params:'{"assign_target" : "Custom"}'},f:["Custom"]}]}]}," ",{p:[133,5,3959],t:7,e:"tr",f:[{p:[134,4,3968],t:7,e:"th",a:{style:"color: '#FFA500';"},f:["Engineering"]}," ",{p:[135,4,4019],t:7,e:"td",f:[{t:4,f:[{p:[137,5,4067],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[137,64,4126]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[137,82,4144]}]},f:[{t:2,r:"display_name",p:[137,127,4189]}]}],n:52,r:"data.engineering_jobs",p:[136,6,4030]}]}]}," ",{p:[141,5,4260],t:7,e:"tr",f:[{p:[142,4,4269],t:7,e:"th",a:{style:"color: '#008000';"},f:["Medical"]}," ",{p:[143,4,4316],t:7,e:"td",f:[{t:4,f:[{p:[145,5,4360],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[145,64,4419]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[145,82,4437]}]},f:[{t:2,r:"display_name",p:[145,127,4482]}]}],n:52,r:"data.medical_jobs",p:[144,6,4327]}]}]}," ",{p:[149,5,4553],t:7,e:"tr",f:[{p:[150,4,4562],t:7,e:"th",a:{style:"color: '#800080';"},f:["Science"]}," ",{p:[151,4,4609],t:7,e:"td",f:[{t:4,f:[{p:[153,5,4653],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[153,64,4712]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[153,82,4730]}]},f:[{t:2,r:"display_name",p:[153,127,4775]}]}],n:52,r:"data.science_jobs",p:[152,6,4620]}]}]}," ",{p:[157,5,4846],t:7,e:"tr",f:[{p:[158,4,4855],t:7,e:"th",a:{style:"color: '#DD0000';"},f:["Security"]}," ",{p:[159,4,4903],t:7,e:"td",f:[{t:4,f:[{p:[161,5,4948],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[161,64,5007]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[161,82,5025]}]},f:[{t:2,r:"display_name",p:[161,127,5070]}]}],n:52,r:"data.security_jobs",p:[160,6,4914]}]}]}," ",{p:[165,5,5141],t:7,e:"tr",f:[{p:[166,4,5150],t:7,e:"th",a:{style:"color: '#cc6600';" --},f:["Cargo"]}," ",{p:[167,4,5195],t:7,e:"td",f:[{t:4,f:[{p:[169,5,5237],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[169,64,5296]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[169,82,5314]}]},f:[{t:2,r:"display_name",p:[169,127,5359]}]}],n:52,r:"data.cargo_jobs",p:[168,6,5206]}]}]}," ",{p:[173,5,5430],t:7,e:"tr",f:[{p:[174,4,5439],t:7,e:"th",a:{style:"color: '#808080';"},f:["Civilian"]}," ",{p:[175,4,5487],t:7,e:"td",f:[{t:4,f:[{p:[177,5,5532],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[177,64,5591]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[177,82,5609]}]},f:[{t:2,r:"display_name",p:[177,127,5654]}]}],n:52,r:"data.civilian_jobs",p:[176,6,5498]}]}]}," ",{t:4,f:[{p:[182,4,5757],t:7,e:"tr",f:[{p:[183,6,5768],t:7,e:"th",a:{style:"color: '#A52A2A';"},f:["Centcom"]}," ",{p:[184,6,5817],t:7,e:"td",f:[{t:4,f:[{p:[186,7,5862],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[186,66,5921]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[186,84,5939]}]},f:[{t:2,r:"display_name",p:[186,129,5984]}]}],n:52,r:"data.centcom_jobs",p:[185,5,5827]}]}]}],n:50,r:"data.centcom_access",p:[181,5,5725]}]}]}],n:50,r:"data.assignments",p:[118,4,3518]}]}],r:"data.minor"}," ",{t:4,f:[{p:[198,4,6153],t:7,e:"div",a:{"class":"item"},f:[{p:[199,3,6175],t:7,e:"h2",f:["Central Command"]}]}," ",{p:[201,4,6215],t:7,e:"div",a:{"class":"item",style:"width: 100%"},f:[{t:4,f:[{p:[203,5,6296],t:7,e:"div",a:{"class":"itemContentWide"},f:[{p:[204,5,6331],t:7,e:"ui-button",a:{action:"PRG_access",params:['{"access_target" : "',{t:2,r:"ref",p:[204,64,6390]},'", "allowed" : "',{t:2,r:"allowed",p:[204,87,6413]},'"}'],state:[{t:2,x:{r:["allowed"],s:'_0?"toggle":null'},p:[204,109,6435]}]},f:[{t:2,r:"desc",p:[204,140,6466]}]}]}],n:52,r:"data.all_centcom_access",p:[202,3,6257]}]}],n:50,r:"data.centcom_access",p:[197,2,6121]},{t:4,n:51,f:[{p:[209,4,6538],t:7,e:"div",a:{"class":"item"},f:[{p:[210,3,6560],t:7,e:"h2",f:[{t:2,r:"data.station_name",p:[210,7,6564]}]}]}," ",{p:[212,4,6606],t:7,e:"div",a:{"class":"item",style:"width: 100%"},f:[{t:4,f:[{p:[214,5,6676],t:7,e:"div",a:{style:"float: left; width: 175px; min-height: 250px"},f:[{p:[215,4,6739],t:7,e:"div",a:{"class":"average"},f:[{p:[215,25,6760],t:7,e:"ui-button",a:{action:"PRG_regsel",state:[{t:2,x:{r:["selected"],s:'_0?"toggle":null'},p:[215,63,6798]}],params:['{"region" : "',{t:2,r:"regid",p:[215,116,6851]},'"}']},f:[{p:[215,129,6864],t:7,e:"b",f:[{t:2,r:"name",p:[215,132,6867]}]}]}]}," ",{p:[216,4,6902],t:7,e:"br"}," ",{t:4,f:[{p:[218,6,6938],t:7,e:"div",a:{"class":"itemContentWide"},f:[{p:[219,5,6973],t:7,e:"ui-button",a:{action:"PRG_access",params:['{"access_target" : "',{t:2,r:"ref",p:[219,64,7032]},'", "allowed" : "',{t:2,r:"allowed",p:[219,87,7055]},'"}'],state:[{t:2,x:{r:["allowed"],s:'_0?"toggle":null'},p:[219,109,7077]}]},f:[{t:2,r:"desc",p:[219,140,7108]}]}]}],n:52,r:"accesses",p:[217,6,6913]}]}],n:52,r:"data.regions",p:[213,3,6648]}]}],r:"data.centcom_access"}],n:50,r:"data.has_id",p:[67,3,2340]}],n:50,r:"data.authenticated",p:[66,1,2310]}]}],x:{r:["data.mmode"],s:"!_0"}}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],268:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{chargeState:function(t){var e=this.get("data.battery.max");return t>e/2?"good":t>e/4?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[15,1,311],t:7,e:"ntosheader"}," ",{p:[17,1,328],t:7,e:"ui-display",f:[{p:[18,2,343],t:7,e:"i",f:["Welcome to computer configuration utility. Please consult your system administrator if you have any questions about your device."]},{p:[18,137,478],t:7,e:"hr"}," ",{p:[19,2,485],t:7,e:"ui-display",a:{title:"Power Supply"},f:[{p:[20,3,522],t:7,e:"ui-section",a:{label:"Power Usage"},f:[{t:2,r:"data.power_usage",p:[21,4,559]},"W"]}," ",{t:4,f:[{p:[25,4,630],t:7,e:"ui-section",a:{label:"Battery Status"},f:["Active"]}," ",{p:[28,4,701],t:7,e:"ui-section",a:{label:"Battery Rating"},f:[{t:2,r:"data.battery.max",p:[29,5,742]}]}," ",{p:[31,4,785],t:7,e:"ui-section",a:{label:"Battery Charge"},f:[{p:[32,5,826],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.battery.max",p:[32,26,847]}],value:[{t:2,r:"adata.battery.charge",p:[32,56,877]}],state:[{t:2,x:{r:["chargeState","adata.battery.charge"],s:"_0(_1)"},p:[32,89,910]}]},f:[{t:2,x:{r:["adata.battery.charge"],s:"Math.round(_0)"},p:[32,128,949]},"/",{t:2,r:"adata.battery.max",p:[32,165,986]}]}]}],n:50,r:"data.battery",p:[24,3,605]},{t:4,n:51,f:[{p:[35,4,1051],t:7,e:"ui-section",a:{label:"Battery Status"},f:["Not Available"]}],r:"data.battery"}]}," ",{p:[41,2,1156],t:7,e:"ui-display",a:{title:"File System"},f:[{p:[42,3,1192],t:7,e:"ui-section",a:{label:"Used Capacity"},f:[{p:[43,4,1231],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.disk_size",p:[43,25,1252]}],value:[{t:2,r:"adata.disk_used",p:[43,53,1280]}],state:"good"},f:[{t:2,x:{r:["adata.disk_used"],s:"Math.round(_0)"},p:[43,87,1314]},"GQ / ",{t:2,r:"adata.disk_size",p:[43,123,1350]},"GQ"]}]}]}," ",{p:[47,2,1419],t:7,e:"ui-display",a:{title:"Computer Components"},f:[{t:4,f:[{p:[49,4,1491],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"name",p:[49,26,1513]}]},f:[{p:[50,5,1529],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"desc",p:[50,59,1583]}]}," ",{p:[52,5,1605],t:7,e:"ui-section",a:{label:"State"},f:[{p:[53,6,1638],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["critical"],s:'_0?"disabled":null'},p:[53,24,1656]}],action:"PC_toggle_component",params:['{"name": "',{t:2,r:"name",p:[53,105,1737]},'"}']},f:[{t:2,x:{r:["enabled"],s:'_0?"Enabled":"Disabled"'},p:[54,7,1757]}]}]}," ",{t:4,f:[{p:[59,6,1868],t:7,e:"ui-section",a:{label:"Power Usage"},f:[{t:2,r:"powerusage",p:[60,7,1908]},"W"]}],n:50,r:"powerusage",p:[58,5,1843]}]}," ",{p:[64,4,1985],t:7,e:"br"}],n:52,r:"data.hardware",p:[48,3,1463]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],269:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[7,3,103],t:7,e:"h2",f:["An error has occurred and this program can not continue."]}," Additional information: ",{t:2,r:"data.error",p:[8,27,196]},{p:[8,41,210],t:7,e:"br"}," ",{p:[9,3,218],t:7,e:"i",f:["Please try again. If the problem persists contact your system administrator for assistance."]}," ",{p:[10,3,320],t:7,e:"ui-button",a:{action:"PRG_closefile"},f:["Restart program"]}],n:50,r:"data.error",p:[6,2,81]},{t:4,n:51,f:[{t:4,f:[{p:[13,4,422],t:7,e:"h2",f:["Viewing file ",{t:2,r:"data.filename",p:[13,21,439]}]}," ",{p:[14,4,466],t:7,e:"div",a:{"class":"item"},f:[{p:[15,4,489],t:7,e:"ui-button",a:{action:"PRG_closefile"},f:["CLOSE"]}," ",{p:[16,4,545],t:7,e:"ui-button",a:{action:"PRG_edit"},f:["EDIT"]}," ",{p:[17,4,595],t:7,e:"ui-button",a:{action:"PRG_printfile"},f:["PRINT"]}," "]},{p:[18,10,657],t:7,e:"hr"}," ",{t:3,r:"data.filedata",p:[19,4,666]}],n:50,r:"data.filename",p:[12,3,396]},{t:4,n:51,f:[{p:[21,4,702],t:7,e:"h2",f:["Available files (local):"]}," ",{p:[22,4,740],t:7,e:"table",f:[{p:[23,5,753],t:7,e:"tr",f:[{p:[24,6,764],t:7,e:"th",f:["File name"]}," ",{p:[25,6,789],t:7,e:"th",f:["File type"]}," ",{p:[26,6,814],t:7,e:"th",f:["File size (GQ)"]}," ",{p:[27,6,844],t:7,e:"th",f:["Operations"]}]}," ",{t:4,f:[{p:[30,6,907],t:7,e:"tr",f:[{p:[31,7,919],t:7,e:"td",f:[{t:2,r:"name",p:[31,11,923]}]}," ",{p:[32,7,944],t:7,e:"td",f:[".",{t:2,r:"type",p:[32,12,949]}]}," ",{p:[33,7,970],t:7,e:"td",f:[{t:2,r:"size",p:[33,11,974]},"GQ"]}," ",{p:[34,7,997],t:7,e:"td",f:[{p:[35,8,1010],t:7,e:"ui-button",a:{action:"PRG_openfile",params:['{"name": "',{t:2,r:"name",p:[35,59,1061]},'"}']},f:["VIEW"]}," ",{p:[36,8,1098],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[36,26,1116]}],action:"PRG_deletefile",params:['{"name": "',{t:2,r:"name",p:[36,105,1195]},'"}']},f:["DELETE"]}," ",{p:[37,8,1234],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[37,26,1252]}],action:"PRG_rename",params:['{"name": "',{t:2,r:"name",p:[37,101,1327]},'"}']},f:["RENAME"]}," ",{p:[38,8,1366],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[38,26,1384]}],action:"PRG_clone",params:['{"name": "',{t:2,r:"name",p:[38,100,1458]},'"}']},f:["CLONE"]}," ",{t:4,f:[{p:[40,9,1531],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[40,27,1549]}],action:"PRG_copytousb",params:['{"name": "',{t:2,r:"name",p:[40,105,1627]},'"}']},f:["EXPORT"]}],n:50,r:"data.usbconnected",p:[39,8,1496]}]}]}],n:52,r:"data.files",p:[29,5,880]}]}," ",{t:4,f:[{p:[47,4,1761],t:7,e:"h2",f:["Available files (portable device):"]}," ",{p:[48,4,1809],t:7,e:"table",f:[{p:[49,5,1822],t:7,e:"tr",f:[{p:[50,6,1833],t:7,e:"th",f:["File name"]}," ",{p:[51,6,1858],t:7,e:"th",f:["File type"]}," ",{p:[52,6,1883],t:7,e:"th",f:["File size (GQ)"]}," ",{p:[53,6,1913],t:7,e:"th",f:["Operations"]}]}," ",{t:4,f:[{p:[56,6,1979],t:7,e:"tr",f:[{p:[57,7,1991],t:7,e:"td",f:[{t:2,r:"name",p:[57,11,1995]}]}," ",{p:[58,7,2016],t:7,e:"td",f:[".",{t:2,r:"type",p:[58,12,2021]}]}," ",{p:[59,7,2042],t:7,e:"td",f:[{t:2,r:"size",p:[59,11,2046]},"GQ"]}," ",{p:[60,7,2069],t:7,e:"td",f:[{p:[61,8,2082],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[61,26,2100]}],action:"PRG_usbdeletefile",params:['{"name": "',{t:2,r:"name",p:[61,108,2182]},'"}']},f:["DELETE"]}," ",{t:4,f:[{p:[63,9,2256],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[63,27,2274]}],action:"PRG_copyfromusb",params:['{"name": "',{t:2,r:"name",p:[63,107,2354]},'"}']},f:["IMPORT"]}],n:50,r:"data.usbconnected",p:[62,8,2221]}]}]}],n:52,r:"data.usbfiles",p:[55,5,1949]}]}],n:50,r:"data.usbconnected",p:[46,4,1731]}," ",{p:[70,4,2470],t:7,e:"ui-button",a:{action:"PRG_newtextfile"},f:["NEW DATA FILE"]}],r:"data.filename"}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],270:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"i",f:["No program loaded. Please select program from list below."]}," ",{p:[6,2,146],t:7,e:"table",f:[{t:4,f:[{p:[8,4,185],t:7,e:"tr",f:[{p:[8,8,189],t:7,e:"td",f:[{p:[8,12,193],t:7,e:"ui-button",a:{action:"PC_runprogram",params:['{"name": "',{t:2,r:"name",p:[8,64,245]},'"}']},f:[{t:2,r:"desc",p:[9,5,263]}]}]},{p:[11,4,293],t:7,e:"td",f:[{p:[11,8,297],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["running"],s:'_0?null:"disabled"'},p:[11,26,315]}],icon:"close",action:"PC_killprogram",params:['{"name": "',{t:2,r:"name",p:[11,114,403]},'"}']}}]}]}],n:52,r:"data.programs",p:[7,3,157]}]}," ",{p:[14,2,454],t:7,e:"br"},{p:[14,6,458],t:7,e:"br"}," ",{t:4,f:[{p:[16,3,491],t:7,e:"ui-button",a:{action:"PC_toggle_light",style:[{t:2,x:{r:["data.light_on"],s:'_0?"selected":null'},p:[16,46,534]}]},f:["Toggle Flashlight"]},{p:[16,114,602],t:7,e:"br"}," ",{p:[17,3,610],t:7,e:"ui-button",a:{action:"PC_light_color"},f:["Change Flashlight Color ",{p:[17,62,669],t:7,e:"span",a:{style:["border:1px solid #161616; background-color: ",{t:2,r:"data.comp_light_color",p:[17,119,726]},";"]},f:["   "]}]}],n:50,r:"data.has_light",p:[15,2,465]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],271:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[6,3,105],t:7,e:"h1",f:["ADMINISTRATIVE MODE"]}],n:50,r:"data.adminmode",p:[5,2,79]}," ",{t:4,f:[{p:[10,3,170],t:7,e:"div",a:{"class":"itemLabel"},f:["Current channel:"]}," ",{p:[13,3,229],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.title",p:[14,4,259]}]}," ",{p:[16,3,287],t:7,e:"div",a:{"class":"itemLabel"},f:["Operator access:"]}," ",{p:[19,3,346],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:[{p:[21,5,406],t:7,e:"b",f:["Enabled"]}],n:50,r:"data.is_operator",p:[20,4,376]},{t:4,n:51,f:[{p:[23,5,439],t:7,e:"b",f:["Disabled"]}],r:"data.is_operator"}]}," ",{p:[26,3,480],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[29,3,532],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[30,4,562],t:7,e:"table",f:[{p:[31,5,575],t:7,e:"tr",f:[{p:[31,9,579],t:7,e:"td",f:[{p:[31,13,583],t:7,e:"ui-button",a:{action:"PRG_speak"},f:["Send message"]}]}]},{p:[32,5,643],t:7,e:"tr",f:[{p:[32,9,647],t:7,e:"td",f:[{p:[32,13,651],t:7,e:"ui-button",a:{action:"PRG_changename"},f:["Change nickname"]}]}]},{p:[33,5,719],t:7,e:"tr",f:[{p:[33,9,723],t:7,e:"td",f:[{p:[33,13,727],t:7,e:"ui-button",a:{action:"PRG_toggleadmin"},f:["Toggle administration mode"]}]}]},{p:[34,5,807],t:7,e:"tr",f:[{p:[34,9,811],t:7,e:"td",f:[{p:[34,13,815],t:7,e:"ui-button",a:{action:"PRG_leavechannel"},f:["Leave channel"]}]}]},{p:[35,5,883],t:7,e:"tr",f:[{p:[35,9,887],t:7,e:"td",f:[{p:[35,13,891],t:7,e:"ui-button",a:{action:"PRG_savelog"},f:["Save log to local drive"]}," ",{t:4,f:[{p:[37,6,995],t:7,e:"tr",f:[{p:[37,10,999],t:7,e:"td",f:[{p:[37,14,1003],t:7,e:"ui-button",a:{action:"PRG_renamechannel"},f:["Rename channel"]}]}]},{p:[38,6,1074],t:7,e:"tr",f:[{p:[38,10,1078],t:7,e:"td",f:[{p:[38,14,1082],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}]}]},{p:[39,6,1149],t:7,e:"tr",f:[{p:[39,10,1153],t:7,e:"td",f:[{p:[39,14,1157],t:7,e:"ui-button",a:{action:"PRG_deletechannel"},f:["Delete channel"]}]}]}],n:50,r:"data.is_operator",p:[36,5,964]}]}]}]}]}," ",{p:[43,3,1263],t:7,e:"b",f:["Chat Window"]}," ",{p:[44,4,1286],t:7,e:"div",a:{"class":"statusDisplay",style:"overflow: auto;"},f:[{p:[45,4,1342],t:7,e:"div",a:{"class":"item"},f:[{p:[46,5,1366],t:7,e:"div",a:{"class":"itemContent",style:"width: 100%;"},f:[{t:4,f:[{t:2,r:"msg",p:[48,7,1450]},{p:[48,14,1457],t:7,e:"br"}],n:52,r:"data.messages",p:[47,6,1419]}]}]}]}," ",{p:[53,3,1516],t:7,e:"b",f:["Connected Users"]},{p:[53,25,1538],t:7,e:"br"}," ",{t:4,f:[{t:2,r:"name",p:[55,4,1573]},{p:[55,12,1581],t:7,e:"br"}],n:52,r:"data.clients",p:[54,3,1546]}],n:50,r:"data.title",p:[9,2,148]},{t:4,n:51,f:[{p:[58,3,1613],t:7,e:"b",f:["Controls:"]}," ",{p:[59,3,1633],t:7,e:"table",f:[{p:[60,4,1645],t:7,e:"tr",f:[{p:[60,8,1649],t:7,e:"td",f:[{p:[60,12,1653],t:7,e:"ui-button",a:{action:"PRG_changename"},f:["Change nickname"]}]}]},{p:[61,4,1720],t:7,e:"tr",f:[{p:[61,8,1724],t:7,e:"td",f:[{p:[61,12,1728],t:7,e:"ui-button",a:{action:"PRG_newchannel"},f:["New Channel"]}]}]},{p:[62,4,1791],t:7,e:"tr",f:[{p:[62,8,1795],t:7,e:"td",f:[{p:[62,12,1799],t:7,e:"ui-button",a:{action:"PRG_toggleadmin"},f:["Toggle administration mode"]}]}]}]}," ",{p:[64,3,1889],t:7,e:"b",f:["Available channels:"]}," ",{p:[65,3,1919],t:7,e:"table",f:[{t:4,f:[{p:[67,4,1964],t:7,e:"tr",f:[{p:[67,8,1968],t:7,e:"td",f:[{p:[67,12,1972],t:7,e:"ui-button",a:{action:"PRG_joinchannel",params:['{"id": "',{t:2,r:"id",p:[67,64,2024]},'"}']},f:[{t:2,r:"chan",p:[67,74,2034]}]},{p:[67,94,2054],t:7,e:"br"}]}]}],n:52,r:"data.all_channels",p:[66,3,1930]}]}],r:"data.title"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],272:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:["##SYSTEM ERROR: ",{t:2,r:"data.error",p:[6,19,117]},{p:[6,33,131],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["RESET"]}],n:50,r:"data.error",p:[5,2,79]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.target"],s:"_0"},f:["##DoS traffic generator active. Tx: ",{t:2,r:"data.speed",p:[8,39,243]},"GQ/s",{p:[8,57,261],t:7,e:"br"}," ",{t:4,f:[{t:2,r:"nums",p:[10,4,300]},{p:[10,12,308],t:7,e:"br"}],n:52,r:"data.dos_strings",p:[9,3,269]}," ",{p:[12,3,329],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["ABORT"]}]},{t:4,n:50,x:{r:["data.target"],s:"!(_0)"},f:[" ##DoS traffic generator ready. Select target device.",{p:[14,55,443],t:7,e:"br"}," ",{t:4,f:["Targeted device ID: ",{t:2,r:"data.focus",p:[16,24,494]}],n:50,r:"data.focus",p:[15,3,451]},{t:4,n:51,f:["Targeted device ID: None"],r:"data.focus"}," ",{p:[20,3,564],t:7,e:"ui-button",a:{action:"PRG_execute"},f:["EXECUTE"]},{p:[20,54,615],t:7,e:"div",a:{style:"clear:both"}}," Detected devices on network:",{p:[21,31,677],t:7,e:"br"}," ",{t:4,f:[{p:[23,4,711],t:7,e:"ui-button",a:{action:"PRG_target_relay",params:['{"targid": "',{t:2,r:"id",p:[23,61,768]},'"}']},f:[{t:2,r:"id",p:[23,71,778]}]}],n:52,r:"data.relays",p:[22,3,685]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],273:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"i",f:["Welcome to software download utility. Please select which software you wish to download."]},{p:[5,97,174],t:7,e:"hr"}," ",{t:4,f:[{p:[7,3,203],t:7,e:"ui-display",a:{title:"Download Error"},f:[{p:[8,4,243],t:7,e:"ui-section",a:{label:"Information"},f:[{t:2,r:"data.error",p:[9,5,281]}]}," ",{p:[11,4,318],t:7,e:"ui-section",a:{label:"Reset Program"},f:[{p:[12,5,358],t:7,e:"ui-button",a:{icon:"times",action:"PRG_reseterror"},f:["RESET"]}]}]}],n:50,r:"data.error",p:[6,2,181]},{t:4,n:51,f:[{t:4,f:[{p:[19,4,516],t:7,e:"ui-display",a:{title:"Download Running"},f:[{p:[20,5,559],t:7,e:"i",f:["Please wait..."]}," ",{p:[21,5,586],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"data.downloadname",p:[22,6,623]}]}," ",{p:[24,5,669],t:7,e:"ui-section",a:{label:"File description"},f:[{t:2,r:"data.downloaddesc",p:[25,6,713]}]}," ",{p:[27,5,759],t:7,e:"ui-section",a:{label:"File size"},f:[{t:2,r:"data.downloadsize",p:[28,6,796]},"GQ"]}," ",{p:[30,5,844],t:7,e:"ui-section",a:{label:"Transfer Rate"},f:[{t:2,r:"data.downloadspeed",p:[31,6,885]}," GQ/s"]}," ",{p:[33,5,937],t:7,e:"ui-section",a:{label:"Download progress"},f:[{p:[34,6,982],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.downloadsize",p:[34,27,1003]}],value:[{t:2,r:"adata.downloadcompletion",p:[34,58,1034]}],state:"good"},f:[{t:2,x:{r:["adata.downloadcompletion"],s:"Math.round(_0)"},p:[34,101,1077]},"GQ / ",{t:2,r:"adata.downloadsize",p:[34,146,1122]},"GQ"]}]}]}],n:50,r:"data.downloadname",p:[18,3,486]}],r:"data.error"}," ",{t:4,f:[{t:4,f:[{p:[41,4,1270],t:7,e:"ui-display",a:{title:"File System"},f:[{p:[42,5,1308],t:7,e:"ui-section",a:{label:"Used Capacity"},f:[{p:[43,6,1349],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.disk_size",p:[43,27,1370]}],value:[{t:2,r:"adata.disk_used",p:[43,55,1398]}],state:"good"},f:[{t:2,x:{r:["adata.disk_used"],s:"Math.round(_0)"},p:[43,89,1432]},"GQ / ",{t:2,r:"adata.disk_size",p:[43,125,1468]},"GQ"]}]}]}," ",{p:[47,4,1545],t:7,e:"ui-display",a:{title:"Primary Software Repository"},f:[{t:4,f:[{p:[49,6,1642],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"filedesc",p:[49,28,1664]}]},f:[{p:[50,7,1686],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"fileinfo",p:[50,61,1740]}]}," ",{p:[52,7,1774],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"filename",p:[53,8,1813]}," (",{t:2,r:"size",p:[53,22,1827]}," GQ)"]}," ",{p:[55,7,1868],t:7,e:"ui-section",a:{label:"Compatibility"},f:[{t:2,r:"compatibility",p:[56,8,1911]}]}," ",{p:[58,7,1957],t:7,e:"ui-button",a:{icon:"signal",action:"PRG_downloadfile",params:['{"filename": "',{t:2,r:"filename",p:[58,80,2030]},'"}']},f:["DOWNLOAD"]}]}," ",{p:[62,6,2113],t:7,e:"br"}],n:52,r:"data.downloadable_programs",p:[48,5,1599]}]}," ",{t:4,f:[{p:[67,5,2194],t:7,e:"ui-display",a:{title:"UNKNOWN Software Repository"},f:[{p:[68,6,2249],t:7,e:"i",f:["Please note that Nanotrasen does not recommend download of software from non-official servers."]}," ",{t:4,f:[{p:[70,7,2395],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"filedesc",p:[70,29,2417]}]},f:[{p:[71,8,2440],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"fileinfo",p:[71,62,2494]}]}," ",{p:[73,8,2530],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"filename",p:[74,9,2570]}," (",{t:2,r:"size",p:[74,23,2584]}," GQ)"]}," ",{p:[76,8,2627],t:7,e:"ui-section",a:{label:"Compatibility"},f:[{t:2,r:"compatibility",p:[77,9,2671]}]}," ",{p:[79,8,2719],t:7,e:"ui-button",a:{icon:"signal",action:"PRG_downloadfile",params:['{"filename": "',{t:2,r:"filename",p:[79,81,2792]},'"}']},f:["DOWNLOAD"]}]}," ",{p:[83,7,2879],t:7,e:"br"}],n:52,r:"data.hacked_programs",p:[69,6,2357]}]}],n:50,r:"data.hackedavailable",p:[66,4,2160]}],n:50,x:{r:["data.error"],s:"!_0"},p:[40,3,1246]}],n:50,x:{r:["data.downloadname"],s:"!_0"},p:[39,2,1216]}," ",{p:[89,2,2954],t:7,e:"br"},{p:[89,6,2958],t:7,e:"br"},{p:[89,10,2962],t:7,e:"hr"},{p:[89,14,2966],t:7,e:"i",f:["NTOS v2.0.4b Copyright Nanotrasen 2557 - 2559"]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],274:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[6,2,81],t:7,e:"ui-display",a:{title:"WIRELESS CONNECTIVITY"},f:[{p:[8,3,129],t:7,e:"ui-section",a:{label:"Active NTNetRelays"},f:[{p:[9,4,173],t:7,e:"b",f:[{t:2,r:"data.ntnetrelays",p:[9,7,176]}]}]}," ",{t:4,f:[{p:[12,4,250],t:7,e:"ui-section",a:{label:"System status"},f:[{p:[13,6,291],t:7,e:"b",f:[{t:2,x:{r:["data.ntnetstatus"],s:'_0?"ENABLED":"DISABLED"'},p:[13,9,294]}]}]}," ",{p:[15,4,366],t:7,e:"ui-section",a:{label:"Control"},f:[{p:[17,4,401],t:7,e:"ui-button",a:{icon:"plus",action:"toggleWireless"},f:["TOGGLE"]}]}," ",{p:[21,4,500],t:7,e:"br"},{p:[21,8,504],t:7,e:"br"}," ",{p:[22,4,513],t:7,e:"i",f:["Caution - Disabling wireless transmitters when using wireless device may prevent you from re-enabling them again!"]}],n:50,r:"data.ntnetrelays",p:[11,3,221]},{t:4,n:51,f:[{p:[24,4,650],t:7,e:"br"},{p:[24,8,654],t:7,e:"p",f:["Wireless coverage unavailable, no relays are connected."]}],r:"data.ntnetrelays"}]}," ",{p:[29,2,750],t:7,e:"ui-display",a:{title:"FIREWALL CONFIGURATION"},f:[{p:[31,2,798],t:7,e:"table",f:[{p:[32,3,809],t:7,e:"tr",f:[{p:[33,4,818],t:7,e:"th",f:["PROTOCOL"]},{p:[34,4,835],t:7,e:"th",f:["STATUS"]},{p:[35,4,850],t:7,e:"th",f:["CONTROL"]}]},{p:[36,3,865],t:7,e:"tr",f:[" ",{p:[37,4,874],t:7,e:"td",f:["Software Downloads"]},{p:[38,4,901],t:7,e:"td",f:[{t:2,x:{r:["data.config_softwaredownload"],s:'_0?"ENABLED":"DISABLED"'},p:[38,8,905]}]},{p:[39,4,967],t:7,e:"td",f:[" ",{p:[39,9,972],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "1"}'},f:["TOGGLE"]}]}]},{p:[40,3,1051],t:7,e:"tr",f:[" ",{p:[41,4,1060],t:7,e:"td",f:["Peer to Peer Traffic"]},{p:[42,4,1089],t:7,e:"td",f:[{t:2,x:{r:["data.config_peertopeer"],s:'_0?"ENABLED":"DISABLED"'},p:[42,8,1093]}]},{p:[43,4,1149],t:7,e:"td",f:[{p:[43,8,1153],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "2"}'},f:["TOGGLE"]}]}]},{p:[44,3,1232],t:7,e:"tr",f:[" ",{p:[45,4,1241],t:7,e:"td",f:["Communication Systems"]},{p:[46,4,1271],t:7,e:"td",f:[{t:2,x:{r:["data.config_communication"],s:'_0?"ENABLED":"DISABLED"'},p:[46,8,1275]}]},{p:[47,4,1334],t:7,e:"td",f:[{p:[47,8,1338],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "3"}'},f:["TOGGLE"]}]}]},{p:[48,3,1417],t:7,e:"tr",f:[" ",{p:[49,4,1426],t:7,e:"td",f:["Remote System Control"]},{p:[50,4,1456],t:7,e:"td",f:[{t:2,x:{r:["data.config_systemcontrol"],s:'_0?"ENABLED":"DISABLED"'},p:[50,8,1460]}]},{p:[51,4,1519],t:7,e:"td",f:[{p:[51,8,1523],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "4"}'},f:["TOGGLE"]}]}]}]}]}," ",{p:[55,2,1630],t:7,e:"ui-display",a:{title:"SECURITY SYSTEMS"},f:[{t:4,f:[{p:[58,4,1699],t:7,e:"ui-notice",f:[{p:[59,5,1716],t:7,e:"h1",f:["NETWORK INCURSION DETECTED"]}]}," ",{p:[61,5,1774],t:7,e:"i",f:["An abnormal activity has been detected in the network. Please verify system logs for more information"]}],n:50,r:"data.idsalarm",p:[57,3,1673]}," ",{p:[64,3,1902],t:7,e:"ui-section",a:{label:"Intrusion Detection System"},f:[{p:[65,4,1954],t:7,e:"b",f:[{t:2,x:{r:["data.idsstatus"],s:'_0?"ENABLED":"DISABLED"'},p:[65,7,1957]}]}]}," ",{p:[68,3,2029],t:7,e:"ui-section",a:{label:"Maximal Log Count"},f:[{p:[69,4,2072],t:7,e:"b",f:[{t:2,r:"data.ntnetmaxlogs",p:[69,7,2075]}]}]}," ",{p:[72,3,2125],t:7,e:"ui-section",a:{label:"Controls"},f:[]}," ",{p:[74,4,2176],t:7,e:"table",f:[{p:[75,4,2188],t:7,e:"tr",f:[{p:[75,8,2192],t:7,e:"td",f:[{p:[75,12,2196],t:7,e:"ui-button",a:{action:"resetIDS"},f:["RESET IDS"]}]}]},{p:[76,4,2251],t:7,e:"tr",f:[{p:[76,8,2255],t:7,e:"td",f:[{p:[76,12,2259],t:7,e:"ui-button",a:{action:"toggleIDS"},f:["TOGGLE IDS"]}]}]},{p:[77,4,2316],t:7,e:"tr",f:[{p:[77,8,2320],t:7,e:"td",f:[{p:[77,12,2324],t:7,e:"ui-button",a:{action:"updatemaxlogs"},f:["SET LOG LIMIT"]}]}]},{p:[78,4,2388],t:7,e:"tr",f:[{p:[78,8,2392],t:7,e:"td",f:[{p:[78,12,2396],t:7,e:"ui-button",a:{action:"purgelogs"},f:["PURGE LOGS"]}]}]}]}," ",{p:[81,3,2467],t:7,e:"ui-subdisplay",a:{title:"System Logs"},f:[{p:[82,3,2506],t:7,e:"div",a:{"class":"statusDisplay",style:"overflow: auto;"},f:[{p:[83,3,2561],t:7,e:"div",a:{"class":"item"},f:[{p:[84,4,2584],t:7,e:"div",a:{"class":"itemContent",style:"width: 100%;"},f:[{t:4,f:[{t:2,r:"entry",p:[86,6,2667]},{p:[86,15,2676],t:7,e:"br"}],n:52,r:"data.ntnetlogs",p:[85,5,2636]}]}]}]}]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],275:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[7,2,102],t:7,e:"div",a:{"class":"item"},f:[{p:[8,3,124],t:7,e:"h2",f:["An error has occurred during operation..."]}," ",{p:[9,3,178],t:7,e:"b",f:["Additional information:"]},{t:2,r:"data.error",p:[9,34,209]},{p:[9,48,223],t:7,e:"br"}," ",{p:[10,3,231],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Clear"]}]}],n:50,r:"data.error",p:[6,2,81]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.downloading"],s:"_0"},f:[{p:[13,3,321],t:7,e:"h2",f:["Download in progress..."]}," ",{p:[14,3,357],t:7,e:"div",a:{"class":"itemLabel"},f:["Downloaded file:"]}," ",{p:[17,3,416],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_name",p:[18,4,446]}]}," ",{p:[20,3,483],t:7,e:"div",a:{"class":"itemLabel"},f:["Download progress:"]}," ",{p:[23,3,544],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_progress",p:[24,4,574]}," / ",{t:2,r:"data.download_size",p:[24,33,603]}," GQ"]}," ",{p:[26,3,642],t:7,e:"div",a:{"class":"itemLabel"},f:["Transfer speed:"]}," ",{p:[29,3,700],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_netspeed",p:[30,4,730]},"GQ/s"]}," ",{p:[32,3,774],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[35,3,826],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[36,4,856],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Abort download"]}]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading"],s:"(!(_0))&&(_1)"},f:[" ",{p:[39,3,954],t:7,e:"h2",f:["Server enabled"]}," ",{p:[40,3,981],t:7,e:"div",a:{"class":"itemLabel"},f:["Connected clients:"]}," ",{p:[43,3,1042],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.upload_clients",p:[44,4,1072]}]}," ",{p:[46,3,1109],t:7,e:"div",a:{"class":"itemLabel"},f:["Provided file:"]}," ",{p:[49,3,1166],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.upload_filename",p:[50,4,1196]}]}," ",{p:[52,3,1234],t:7,e:"div",a:{"class":"itemLabel"},f:["Server password:"]}," ",{p:[55,3,1293],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["ENABLED"],n:50,r:"data.upload_haspassword",p:[56,4,1323]},{t:4,n:51,f:["DISABLED"],r:"data.upload_haspassword"}]}," ",{p:[62,3,1420],t:7,e:"div",a:{"class":"itemLabel"},f:["Commands:"]}," ",{p:[65,3,1472],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[66,4,1502],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}," ",{p:[67,4,1567],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Exit server"]}]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading","data.upload_filelist"],s:"(!(_0))&&((!(_1))&&(_2))"},f:[" ",{p:[70,3,1668],t:7,e:"h2",f:["File transfer server ready. Select file to upload:"]}," ",{p:[71,3,1732],t:7,e:"table",f:[{p:[72,3,1743],t:7,e:"tr",f:[{p:[72,7,1747],t:7,e:"th",f:["File name"]},{p:[72,20,1760],t:7,e:"th",f:["File size"]},{p:[72,33,1773],t:7,e:"th",f:["Controls ",{t:4,f:[{p:[74,4,1824],t:7,e:"tr",f:[{p:[74,8,1828],t:7,e:"td",f:[{t:2,r:"filename",p:[74,12,1832]}]},{p:[75,4,1849],t:7,e:"td",f:[{t:2,r:"size",p:[75,8,1853]},"GQ"]},{p:[76,4,1868],t:7,e:"td",f:[{p:[76,8,1872],t:7,e:"ui-button",a:{action:"PRG_uploadfile",params:['{"id": "',{t:2,r:"uid",p:[76,59,1923]},'"}']},f:["Select"]}]}]}],n:52,r:"data.upload_filelist",p:[73,3,1789]}]}]}]}," ",{p:[79,3,1981],t:7,e:"hr"}," ",{p:[80,3,1989],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}," ",{p:[81,3,2053],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Return"]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading","data.upload_filelist"],s:"(!(_0))&&((!(_1))&&(!(_2)))"},f:[" ",{p:[83,3,2116],t:7,e:"h2",f:["Available files:"]}," ",{p:[84,3,2145],t:7,e:"table",a:{border:"1",style:"border-collapse: collapse"},f:[{p:[84,55,2197],t:7,e:"tr",f:[{p:[84,59,2201],t:7,e:"th",f:["Server UID"]},{p:[84,73,2215],t:7,e:"th",f:["File Name"]},{p:[84,86,2228],t:7,e:"th",f:["File Size"]},{p:[84,99,2241],t:7,e:"th",f:["Password Protection"]},{p:[84,122,2264],t:7,e:"th",f:["Operations ",{t:4,f:[{p:[86,5,2311],t:7,e:"tr",f:[{p:[86,9,2315],t:7,e:"td",f:[{t:2,r:"uid",p:[86,13,2319]}]},{p:[87,5,2332],t:7,e:"td",f:[{t:2,r:"filename",p:[87,9,2336]}]},{p:[88,5,2354],t:7,e:"td",f:[{t:2,r:"size",p:[88,9,2358]},"GQ ",{t:4,f:[{p:[90,6,2400],t:7,e:"td",f:["Enabled"]}],n:50,r:"haspassword",p:[89,5,2374]}," ",{t:4,f:[{p:[93,6,2457],t:7,e:"td",f:["Disabled"]}],n:50,x:{r:["haspassword"],s:"!_0"},p:[92,5,2430]}]},{p:[96,5,2494],t:7,e:"td",f:[{p:[96,9,2498],t:7,e:"ui-button",a:{action:"PRG_downloadfile",params:['{"id": "',{t:2,r:"uid",p:[96,62,2551]},'"}']},f:["Download"]}]}]}],n:52,r:"data.servers",p:[85,4,2283]}]}]}]}," ",{p:[99,3,2612],t:7,e:"hr"}," ",{p:[100,3,2620],t:7,e:"ui-button",a:{action:"PRG_uploadmenu"},f:["Send file"]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],276:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{chargingState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},chargingMode:function(t){return 2==t?"Full":1==t?"Charging":"Draining"},channelState:function(t){return t>=2?"good":"bad"},channelPower:function(t){return t>=2?"On":"Off"},channelMode:function(t){return 1==t||3==t?"Auto":"Manual"}},computed:{graphData:function(){var t=this.get("data.history");return Object.keys(t).map(function(e){return t[e].map(function(t,e){return{x:e,y:t}})})}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[43,1,1082],t:7,e:"ntosheader"}," ",{p:[45,1,1099],t:7,e:"ui-display",a:{title:"Network"},f:[{t:4,f:[{p:[47,5,1157],t:7,e:"ui-linegraph",a:{points:[{t:2,r:"graphData", -+},f:["Cargo"]}," ",{p:[167,4,5195],t:7,e:"td",f:[{t:4,f:[{p:[169,5,5237],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[169,64,5296]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[169,82,5314]}]},f:[{t:2,r:"display_name",p:[169,127,5359]}]}],n:52,r:"data.cargo_jobs",p:[168,6,5206]}]}]}," ",{p:[173,5,5430],t:7,e:"tr",f:[{p:[174,4,5439],t:7,e:"th",a:{style:"color: '#808080';"},f:["Civilian"]}," ",{p:[175,4,5487],t:7,e:"td",f:[{t:4,f:[{p:[177,5,5532],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[177,64,5591]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[177,82,5609]}]},f:[{t:2,r:"display_name",p:[177,127,5654]}]}],n:52,r:"data.civilian_jobs",p:[176,6,5498]}]}]}," ",{t:4,f:[{p:[182,4,5757],t:7,e:"tr",f:[{p:[183,6,5768],t:7,e:"th",a:{style:"color: '#A52A2A';"},f:["CentCom"]}," ",{p:[184,6,5817],t:7,e:"td",f:[{t:4,f:[{p:[186,7,5862],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[186,66,5921]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[186,84,5939]}]},f:[{t:2,r:"display_name",p:[186,129,5984]}]}],n:52,r:"data.centcom_jobs",p:[185,5,5827]}]}]}],n:50,r:"data.centcom_access",p:[181,5,5725]}]}]}],n:50,r:"data.assignments",p:[118,4,3518]}]}],r:"data.minor"}," ",{t:4,f:[{p:[198,4,6153],t:7,e:"div",a:{"class":"item"},f:[{p:[199,3,6175],t:7,e:"h2",f:["Central Command"]}]}," ",{p:[201,4,6215],t:7,e:"div",a:{"class":"item",style:"width: 100%"},f:[{t:4,f:[{p:[203,5,6296],t:7,e:"div",a:{"class":"itemContentWide"},f:[{p:[204,5,6331],t:7,e:"ui-button",a:{action:"PRG_access",params:['{"access_target" : "',{t:2,r:"ref",p:[204,64,6390]},'", "allowed" : "',{t:2,r:"allowed",p:[204,87,6413]},'"}'],state:[{t:2,x:{r:["allowed"],s:'_0?"toggle":null'},p:[204,109,6435]}]},f:[{t:2,r:"desc",p:[204,140,6466]}]}]}],n:52,r:"data.all_centcom_access",p:[202,3,6257]}]}],n:50,r:"data.centcom_access",p:[197,2,6121]},{t:4,n:51,f:[{p:[209,4,6538],t:7,e:"div",a:{"class":"item"},f:[{p:[210,3,6560],t:7,e:"h2",f:[{t:2,r:"data.station_name",p:[210,7,6564]}]}]}," ",{p:[212,4,6606],t:7,e:"div",a:{"class":"item",style:"width: 100%"},f:[{t:4,f:[{p:[214,5,6676],t:7,e:"div",a:{style:"float: left; width: 175px; min-height: 250px"},f:[{p:[215,4,6739],t:7,e:"div",a:{"class":"average"},f:[{p:[215,25,6760],t:7,e:"ui-button",a:{action:"PRG_regsel",state:[{t:2,x:{r:["selected"],s:'_0?"toggle":null'},p:[215,63,6798]}],params:['{"region" : "',{t:2,r:"regid",p:[215,116,6851]},'"}']},f:[{p:[215,129,6864],t:7,e:"b",f:[{t:2,r:"name",p:[215,132,6867]}]}]}]}," ",{p:[216,4,6902],t:7,e:"br"}," ",{t:4,f:[{p:[218,6,6938],t:7,e:"div",a:{"class":"itemContentWide"},f:[{p:[219,5,6973],t:7,e:"ui-button",a:{action:"PRG_access",params:['{"access_target" : "',{t:2,r:"ref",p:[219,64,7032]},'", "allowed" : "',{t:2,r:"allowed",p:[219,87,7055]},'"}'],state:[{t:2,x:{r:["allowed"],s:'_0?"toggle":null'},p:[219,109,7077]}]},f:[{t:2,r:"desc",p:[219,140,7108]}]}]}],n:52,r:"accesses",p:[217,6,6913]}]}],n:52,r:"data.regions",p:[213,3,6648]}]}],r:"data.centcom_access"}],n:50,r:"data.has_id",p:[67,3,2340]}],n:50,r:"data.authenticated",p:[66,1,2310]}]}],x:{r:["data.mmode"],s:"!_0"}}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],268:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{chargeState:function(t){var e=this.get("data.battery.max");return t>e/2?"good":t>e/4?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[15,1,311],t:7,e:"ntosheader"}," ",{p:[17,1,328],t:7,e:"ui-display",f:[{p:[18,2,343],t:7,e:"i",f:["Welcome to computer configuration utility. Please consult your system administrator if you have any questions about your device."]},{p:[18,137,478],t:7,e:"hr"}," ",{p:[19,2,485],t:7,e:"ui-display",a:{title:"Power Supply"},f:[{p:[20,3,522],t:7,e:"ui-section",a:{label:"Power Usage"},f:[{t:2,r:"data.power_usage",p:[21,4,559]},"W"]}," ",{t:4,f:[{p:[25,4,630],t:7,e:"ui-section",a:{label:"Battery Status"},f:["Active"]}," ",{p:[28,4,701],t:7,e:"ui-section",a:{label:"Battery Rating"},f:[{t:2,r:"data.battery.max",p:[29,5,742]}]}," ",{p:[31,4,785],t:7,e:"ui-section",a:{label:"Battery Charge"},f:[{p:[32,5,826],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.battery.max",p:[32,26,847]}],value:[{t:2,r:"adata.battery.charge",p:[32,56,877]}],state:[{t:2,x:{r:["chargeState","adata.battery.charge"],s:"_0(_1)"},p:[32,89,910]}]},f:[{t:2,x:{r:["adata.battery.charge"],s:"Math.round(_0)"},p:[32,128,949]},"/",{t:2,r:"adata.battery.max",p:[32,165,986]}]}]}],n:50,r:"data.battery",p:[24,3,605]},{t:4,n:51,f:[{p:[35,4,1051],t:7,e:"ui-section",a:{label:"Battery Status"},f:["Not Available"]}],r:"data.battery"}]}," ",{p:[41,2,1156],t:7,e:"ui-display",a:{title:"File System"},f:[{p:[42,3,1192],t:7,e:"ui-section",a:{label:"Used Capacity"},f:[{p:[43,4,1231],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.disk_size",p:[43,25,1252]}],value:[{t:2,r:"adata.disk_used",p:[43,53,1280]}],state:"good"},f:[{t:2,x:{r:["adata.disk_used"],s:"Math.round(_0)"},p:[43,87,1314]},"GQ / ",{t:2,r:"adata.disk_size",p:[43,123,1350]},"GQ"]}]}]}," ",{p:[47,2,1419],t:7,e:"ui-display",a:{title:"Computer Components"},f:[{t:4,f:[{p:[49,4,1491],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"name",p:[49,26,1513]}]},f:[{p:[50,5,1529],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"desc",p:[50,59,1583]}]}," ",{p:[52,5,1605],t:7,e:"ui-section",a:{label:"State"},f:[{p:[53,6,1638],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["critical"],s:'_0?"disabled":null'},p:[53,24,1656]}],action:"PC_toggle_component",params:['{"name": "',{t:2,r:"name",p:[53,105,1737]},'"}']},f:[{t:2,x:{r:["enabled"],s:'_0?"Enabled":"Disabled"'},p:[54,7,1757]}]}]}," ",{t:4,f:[{p:[59,6,1868],t:7,e:"ui-section",a:{label:"Power Usage"},f:[{t:2,r:"powerusage",p:[60,7,1908]},"W"]}],n:50,r:"powerusage",p:[58,5,1843]}]}," ",{p:[64,4,1985],t:7,e:"br"}],n:52,r:"data.hardware",p:[48,3,1463]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],269:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[7,3,103],t:7,e:"h2",f:["An error has occurred and this program can not continue."]}," Additional information: ",{t:2,r:"data.error",p:[8,27,196]},{p:[8,41,210],t:7,e:"br"}," ",{p:[9,3,218],t:7,e:"i",f:["Please try again. If the problem persists contact your system administrator for assistance."]}," ",{p:[10,3,320],t:7,e:"ui-button",a:{action:"PRG_closefile"},f:["Restart program"]}],n:50,r:"data.error",p:[6,2,81]},{t:4,n:51,f:[{t:4,f:[{p:[13,4,422],t:7,e:"h2",f:["Viewing file ",{t:2,r:"data.filename",p:[13,21,439]}]}," ",{p:[14,4,466],t:7,e:"div",a:{"class":"item"},f:[{p:[15,4,489],t:7,e:"ui-button",a:{action:"PRG_closefile"},f:["CLOSE"]}," ",{p:[16,4,545],t:7,e:"ui-button",a:{action:"PRG_edit"},f:["EDIT"]}," ",{p:[17,4,595],t:7,e:"ui-button",a:{action:"PRG_printfile"},f:["PRINT"]}," "]},{p:[18,10,657],t:7,e:"hr"}," ",{t:3,r:"data.filedata",p:[19,4,666]}],n:50,r:"data.filename",p:[12,3,396]},{t:4,n:51,f:[{p:[21,4,702],t:7,e:"h2",f:["Available files (local):"]}," ",{p:[22,4,740],t:7,e:"table",f:[{p:[23,5,753],t:7,e:"tr",f:[{p:[24,6,764],t:7,e:"th",f:["File name"]}," ",{p:[25,6,789],t:7,e:"th",f:["File type"]}," ",{p:[26,6,814],t:7,e:"th",f:["File size (GQ)"]}," ",{p:[27,6,844],t:7,e:"th",f:["Operations"]}]}," ",{t:4,f:[{p:[30,6,907],t:7,e:"tr",f:[{p:[31,7,919],t:7,e:"td",f:[{t:2,r:"name",p:[31,11,923]}]}," ",{p:[32,7,944],t:7,e:"td",f:[".",{t:2,r:"type",p:[32,12,949]}]}," ",{p:[33,7,970],t:7,e:"td",f:[{t:2,r:"size",p:[33,11,974]},"GQ"]}," ",{p:[34,7,997],t:7,e:"td",f:[{p:[35,8,1010],t:7,e:"ui-button",a:{action:"PRG_openfile",params:['{"name": "',{t:2,r:"name",p:[35,59,1061]},'"}']},f:["VIEW"]}," ",{p:[36,8,1098],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[36,26,1116]}],action:"PRG_deletefile",params:['{"name": "',{t:2,r:"name",p:[36,105,1195]},'"}']},f:["DELETE"]}," ",{p:[37,8,1234],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[37,26,1252]}],action:"PRG_rename",params:['{"name": "',{t:2,r:"name",p:[37,101,1327]},'"}']},f:["RENAME"]}," ",{p:[38,8,1366],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[38,26,1384]}],action:"PRG_clone",params:['{"name": "',{t:2,r:"name",p:[38,100,1458]},'"}']},f:["CLONE"]}," ",{t:4,f:[{p:[40,9,1531],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[40,27,1549]}],action:"PRG_copytousb",params:['{"name": "',{t:2,r:"name",p:[40,105,1627]},'"}']},f:["EXPORT"]}],n:50,r:"data.usbconnected",p:[39,8,1496]}]}]}],n:52,r:"data.files",p:[29,5,880]}]}," ",{t:4,f:[{p:[47,4,1761],t:7,e:"h2",f:["Available files (portable device):"]}," ",{p:[48,4,1809],t:7,e:"table",f:[{p:[49,5,1822],t:7,e:"tr",f:[{p:[50,6,1833],t:7,e:"th",f:["File name"]}," ",{p:[51,6,1858],t:7,e:"th",f:["File type"]}," ",{p:[52,6,1883],t:7,e:"th",f:["File size (GQ)"]}," ",{p:[53,6,1913],t:7,e:"th",f:["Operations"]}]}," ",{t:4,f:[{p:[56,6,1979],t:7,e:"tr",f:[{p:[57,7,1991],t:7,e:"td",f:[{t:2,r:"name",p:[57,11,1995]}]}," ",{p:[58,7,2016],t:7,e:"td",f:[".",{t:2,r:"type",p:[58,12,2021]}]}," ",{p:[59,7,2042],t:7,e:"td",f:[{t:2,r:"size",p:[59,11,2046]},"GQ"]}," ",{p:[60,7,2069],t:7,e:"td",f:[{p:[61,8,2082],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[61,26,2100]}],action:"PRG_usbdeletefile",params:['{"name": "',{t:2,r:"name",p:[61,108,2182]},'"}']},f:["DELETE"]}," ",{t:4,f:[{p:[63,9,2256],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[63,27,2274]}],action:"PRG_copyfromusb",params:['{"name": "',{t:2,r:"name",p:[63,107,2354]},'"}']},f:["IMPORT"]}],n:50,r:"data.usbconnected",p:[62,8,2221]}]}]}],n:52,r:"data.usbfiles",p:[55,5,1949]}]}],n:50,r:"data.usbconnected",p:[46,4,1731]}," ",{p:[70,4,2470],t:7,e:"ui-button",a:{action:"PRG_newtextfile"},f:["NEW DATA FILE"]}],r:"data.filename"}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],270:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"i",f:["No program loaded. Please select program from list below."]}," ",{p:[6,2,146],t:7,e:"table",f:[{t:4,f:[{p:[8,4,185],t:7,e:"tr",f:[{p:[8,8,189],t:7,e:"td",f:[{p:[8,12,193],t:7,e:"ui-button",a:{action:"PC_runprogram",params:['{"name": "',{t:2,r:"name",p:[8,64,245]},'"}']},f:[{t:2,r:"desc",p:[9,5,263]}]}]},{p:[11,4,293],t:7,e:"td",f:[{p:[11,8,297],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["running"],s:'_0?null:"disabled"'},p:[11,26,315]}],icon:"close",action:"PC_killprogram",params:['{"name": "',{t:2,r:"name",p:[11,114,403]},'"}']}}]}]}],n:52,r:"data.programs",p:[7,3,157]}]}," ",{p:[14,2,454],t:7,e:"br"},{p:[14,6,458],t:7,e:"br"}," ",{t:4,f:[{p:[16,3,491],t:7,e:"ui-button",a:{action:"PC_toggle_light",style:[{t:2,x:{r:["data.light_on"],s:'_0?"selected":null'},p:[16,46,534]}]},f:["Toggle Flashlight"]},{p:[16,114,602],t:7,e:"br"}," ",{p:[17,3,610],t:7,e:"ui-button",a:{action:"PC_light_color"},f:["Change Flashlight Color ",{p:[17,62,669],t:7,e:"span",a:{style:["border:1px solid #161616; background-color: ",{t:2,r:"data.comp_light_color",p:[17,119,726]},";"]},f:["   "]}]}],n:50,r:"data.has_light",p:[15,2,465]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],271:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[6,3,105],t:7,e:"h1",f:["ADMINISTRATIVE MODE"]}],n:50,r:"data.adminmode",p:[5,2,79]}," ",{t:4,f:[{p:[10,3,170],t:7,e:"div",a:{"class":"itemLabel"},f:["Current channel:"]}," ",{p:[13,3,229],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.title",p:[14,4,259]}]}," ",{p:[16,3,287],t:7,e:"div",a:{"class":"itemLabel"},f:["Operator access:"]}," ",{p:[19,3,346],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:[{p:[21,5,406],t:7,e:"b",f:["Enabled"]}],n:50,r:"data.is_operator",p:[20,4,376]},{t:4,n:51,f:[{p:[23,5,439],t:7,e:"b",f:["Disabled"]}],r:"data.is_operator"}]}," ",{p:[26,3,480],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[29,3,532],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[30,4,562],t:7,e:"table",f:[{p:[31,5,575],t:7,e:"tr",f:[{p:[31,9,579],t:7,e:"td",f:[{p:[31,13,583],t:7,e:"ui-button",a:{action:"PRG_speak"},f:["Send message"]}]}]},{p:[32,5,643],t:7,e:"tr",f:[{p:[32,9,647],t:7,e:"td",f:[{p:[32,13,651],t:7,e:"ui-button",a:{action:"PRG_changename"},f:["Change nickname"]}]}]},{p:[33,5,719],t:7,e:"tr",f:[{p:[33,9,723],t:7,e:"td",f:[{p:[33,13,727],t:7,e:"ui-button",a:{action:"PRG_toggleadmin"},f:["Toggle administration mode"]}]}]},{p:[34,5,807],t:7,e:"tr",f:[{p:[34,9,811],t:7,e:"td",f:[{p:[34,13,815],t:7,e:"ui-button",a:{action:"PRG_leavechannel"},f:["Leave channel"]}]}]},{p:[35,5,883],t:7,e:"tr",f:[{p:[35,9,887],t:7,e:"td",f:[{p:[35,13,891],t:7,e:"ui-button",a:{action:"PRG_savelog"},f:["Save log to local drive"]}," ",{t:4,f:[{p:[37,6,995],t:7,e:"tr",f:[{p:[37,10,999],t:7,e:"td",f:[{p:[37,14,1003],t:7,e:"ui-button",a:{action:"PRG_renamechannel"},f:["Rename channel"]}]}]},{p:[38,6,1074],t:7,e:"tr",f:[{p:[38,10,1078],t:7,e:"td",f:[{p:[38,14,1082],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}]}]},{p:[39,6,1149],t:7,e:"tr",f:[{p:[39,10,1153],t:7,e:"td",f:[{p:[39,14,1157],t:7,e:"ui-button",a:{action:"PRG_deletechannel"},f:["Delete channel"]}]}]}],n:50,r:"data.is_operator",p:[36,5,964]}]}]}]}]}," ",{p:[43,3,1263],t:7,e:"b",f:["Chat Window"]}," ",{p:[44,4,1286],t:7,e:"div",a:{"class":"statusDisplay",style:"overflow: auto;"},f:[{p:[45,4,1342],t:7,e:"div",a:{"class":"item"},f:[{p:[46,5,1366],t:7,e:"div",a:{"class":"itemContent",style:"width: 100%;"},f:[{t:4,f:[{t:2,r:"msg",p:[48,7,1450]},{p:[48,14,1457],t:7,e:"br"}],n:52,r:"data.messages",p:[47,6,1419]}]}]}]}," ",{p:[53,3,1516],t:7,e:"b",f:["Connected Users"]},{p:[53,25,1538],t:7,e:"br"}," ",{t:4,f:[{t:2,r:"name",p:[55,4,1573]},{p:[55,12,1581],t:7,e:"br"}],n:52,r:"data.clients",p:[54,3,1546]}],n:50,r:"data.title",p:[9,2,148]},{t:4,n:51,f:[{p:[58,3,1613],t:7,e:"b",f:["Controls:"]}," ",{p:[59,3,1633],t:7,e:"table",f:[{p:[60,4,1645],t:7,e:"tr",f:[{p:[60,8,1649],t:7,e:"td",f:[{p:[60,12,1653],t:7,e:"ui-button",a:{action:"PRG_changename"},f:["Change nickname"]}]}]},{p:[61,4,1720],t:7,e:"tr",f:[{p:[61,8,1724],t:7,e:"td",f:[{p:[61,12,1728],t:7,e:"ui-button",a:{action:"PRG_newchannel"},f:["New Channel"]}]}]},{p:[62,4,1791],t:7,e:"tr",f:[{p:[62,8,1795],t:7,e:"td",f:[{p:[62,12,1799],t:7,e:"ui-button",a:{action:"PRG_toggleadmin"},f:["Toggle administration mode"]}]}]}]}," ",{p:[64,3,1889],t:7,e:"b",f:["Available channels:"]}," ",{p:[65,3,1919],t:7,e:"table",f:[{t:4,f:[{p:[67,4,1964],t:7,e:"tr",f:[{p:[67,8,1968],t:7,e:"td",f:[{p:[67,12,1972],t:7,e:"ui-button",a:{action:"PRG_joinchannel",params:['{"id": "',{t:2,r:"id",p:[67,64,2024]},'"}']},f:[{t:2,r:"chan",p:[67,74,2034]}]},{p:[67,94,2054],t:7,e:"br"}]}]}],n:52,r:"data.all_channels",p:[66,3,1930]}]}],r:"data.title"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],272:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:["##SYSTEM ERROR: ",{t:2,r:"data.error",p:[6,19,117]},{p:[6,33,131],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["RESET"]}],n:50,r:"data.error",p:[5,2,79]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.target"],s:"_0"},f:["##DoS traffic generator active. Tx: ",{t:2,r:"data.speed",p:[8,39,243]},"GQ/s",{p:[8,57,261],t:7,e:"br"}," ",{t:4,f:[{t:2,r:"nums",p:[10,4,300]},{p:[10,12,308],t:7,e:"br"}],n:52,r:"data.dos_strings",p:[9,3,269]}," ",{p:[12,3,329],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["ABORT"]}]},{t:4,n:50,x:{r:["data.target"],s:"!(_0)"},f:[" ##DoS traffic generator ready. Select target device.",{p:[14,55,443],t:7,e:"br"}," ",{t:4,f:["Targeted device ID: ",{t:2,r:"data.focus",p:[16,24,494]}],n:50,r:"data.focus",p:[15,3,451]},{t:4,n:51,f:["Targeted device ID: None"],r:"data.focus"}," ",{p:[20,3,564],t:7,e:"ui-button",a:{action:"PRG_execute"},f:["EXECUTE"]},{p:[20,54,615],t:7,e:"div",a:{style:"clear:both"}}," Detected devices on network:",{p:[21,31,677],t:7,e:"br"}," ",{t:4,f:[{p:[23,4,711],t:7,e:"ui-button",a:{action:"PRG_target_relay",params:['{"targid": "',{t:2,r:"id",p:[23,61,768]},'"}']},f:[{t:2,r:"id",p:[23,71,778]}]}],n:52,r:"data.relays",p:[22,3,685]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],273:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"i",f:["Welcome to software download utility. Please select which software you wish to download."]},{p:[5,97,174],t:7,e:"hr"}," ",{t:4,f:[{p:[7,3,203],t:7,e:"ui-display",a:{title:"Download Error"},f:[{p:[8,4,243],t:7,e:"ui-section",a:{label:"Information"},f:[{t:2,r:"data.error",p:[9,5,281]}]}," ",{p:[11,4,318],t:7,e:"ui-section",a:{label:"Reset Program"},f:[{p:[12,5,358],t:7,e:"ui-button",a:{icon:"times",action:"PRG_reseterror"},f:["RESET"]}]}]}],n:50,r:"data.error",p:[6,2,181]},{t:4,n:51,f:[{t:4,f:[{p:[19,4,516],t:7,e:"ui-display",a:{title:"Download Running"},f:[{p:[20,5,559],t:7,e:"i",f:["Please wait..."]}," ",{p:[21,5,586],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"data.downloadname",p:[22,6,623]}]}," ",{p:[24,5,669],t:7,e:"ui-section",a:{label:"File description"},f:[{t:2,r:"data.downloaddesc",p:[25,6,713]}]}," ",{p:[27,5,759],t:7,e:"ui-section",a:{label:"File size"},f:[{t:2,r:"data.downloadsize",p:[28,6,796]},"GQ"]}," ",{p:[30,5,844],t:7,e:"ui-section",a:{label:"Transfer Rate"},f:[{t:2,r:"data.downloadspeed",p:[31,6,885]}," GQ/s"]}," ",{p:[33,5,937],t:7,e:"ui-section",a:{label:"Download progress"},f:[{p:[34,6,982],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.downloadsize",p:[34,27,1003]}],value:[{t:2,r:"adata.downloadcompletion",p:[34,58,1034]}],state:"good"},f:[{t:2,x:{r:["adata.downloadcompletion"],s:"Math.round(_0)"},p:[34,101,1077]},"GQ / ",{t:2,r:"adata.downloadsize",p:[34,146,1122]},"GQ"]}]}]}],n:50,r:"data.downloadname",p:[18,3,486]}],r:"data.error"}," ",{t:4,f:[{t:4,f:[{p:[41,4,1270],t:7,e:"ui-display",a:{title:"File System"},f:[{p:[42,5,1308],t:7,e:"ui-section",a:{label:"Used Capacity"},f:[{p:[43,6,1349],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.disk_size",p:[43,27,1370]}],value:[{t:2,r:"adata.disk_used",p:[43,55,1398]}],state:"good"},f:[{t:2,x:{r:["adata.disk_used"],s:"Math.round(_0)"},p:[43,89,1432]},"GQ / ",{t:2,r:"adata.disk_size",p:[43,125,1468]},"GQ"]}]}]}," ",{p:[47,4,1545],t:7,e:"ui-display",a:{title:"Primary Software Repository"},f:[{t:4,f:[{p:[49,6,1642],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"filedesc",p:[49,28,1664]}]},f:[{p:[50,7,1686],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"fileinfo",p:[50,61,1740]}]}," ",{p:[52,7,1774],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"filename",p:[53,8,1813]}," (",{t:2,r:"size",p:[53,22,1827]}," GQ)"]}," ",{p:[55,7,1868],t:7,e:"ui-section",a:{label:"Compatibility"},f:[{t:2,r:"compatibility",p:[56,8,1911]}]}," ",{p:[58,7,1957],t:7,e:"ui-button",a:{icon:"signal",action:"PRG_downloadfile",params:['{"filename": "',{t:2,r:"filename",p:[58,80,2030]},'"}']},f:["DOWNLOAD"]}]}," ",{p:[62,6,2113],t:7,e:"br"}],n:52,r:"data.downloadable_programs",p:[48,5,1599]}]}," ",{t:4,f:[{p:[67,5,2194],t:7,e:"ui-display",a:{title:"UNKNOWN Software Repository"},f:[{p:[68,6,2249],t:7,e:"i",f:["Please note that Nanotrasen does not recommend download of software from non-official servers."]}," ",{t:4,f:[{p:[70,7,2395],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"filedesc",p:[70,29,2417]}]},f:[{p:[71,8,2440],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"fileinfo",p:[71,62,2494]}]}," ",{p:[73,8,2530],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"filename",p:[74,9,2570]}," (",{t:2,r:"size",p:[74,23,2584]}," GQ)"]}," ",{p:[76,8,2627],t:7,e:"ui-section",a:{label:"Compatibility"},f:[{t:2,r:"compatibility",p:[77,9,2671]}]}," ",{p:[79,8,2719],t:7,e:"ui-button",a:{icon:"signal",action:"PRG_downloadfile",params:['{"filename": "',{t:2,r:"filename",p:[79,81,2792]},'"}']},f:["DOWNLOAD"]}]}," ",{p:[83,7,2879],t:7,e:"br"}],n:52,r:"data.hacked_programs",p:[69,6,2357]}]}],n:50,r:"data.hackedavailable",p:[66,4,2160]}],n:50,x:{r:["data.error"],s:"!_0"},p:[40,3,1246]}],n:50,x:{r:["data.downloadname"],s:"!_0"},p:[39,2,1216]}," ",{p:[89,2,2954],t:7,e:"br"},{p:[89,6,2958],t:7,e:"br"},{p:[89,10,2962],t:7,e:"hr"},{p:[89,14,2966],t:7,e:"i",f:["NTOS v2.0.4b Copyright Nanotrasen 2557 - 2559"]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],274:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[6,2,81],t:7,e:"ui-display",a:{title:"WIRELESS CONNECTIVITY"},f:[{p:[8,3,129],t:7,e:"ui-section",a:{label:"Active NTNetRelays"},f:[{p:[9,4,173],t:7,e:"b",f:[{t:2,r:"data.ntnetrelays",p:[9,7,176]}]}]}," ",{t:4,f:[{p:[12,4,250],t:7,e:"ui-section",a:{label:"System status"},f:[{p:[13,6,291],t:7,e:"b",f:[{t:2,x:{r:["data.ntnetstatus"],s:'_0?"ENABLED":"DISABLED"'},p:[13,9,294]}]}]}," ",{p:[15,4,366],t:7,e:"ui-section",a:{label:"Control"},f:[{p:[17,4,401],t:7,e:"ui-button",a:{icon:"plus",action:"toggleWireless"},f:["TOGGLE"]}]}," ",{p:[21,4,500],t:7,e:"br"},{p:[21,8,504],t:7,e:"br"}," ",{p:[22,4,513],t:7,e:"i",f:["Caution - Disabling wireless transmitters when using wireless device may prevent you from re-enabling them again!"]}],n:50,r:"data.ntnetrelays",p:[11,3,221]},{t:4,n:51,f:[{p:[24,4,650],t:7,e:"br"},{p:[24,8,654],t:7,e:"p",f:["Wireless coverage unavailable, no relays are connected."]}],r:"data.ntnetrelays"}]}," ",{p:[29,2,750],t:7,e:"ui-display",a:{title:"FIREWALL CONFIGURATION"},f:[{p:[31,2,798],t:7,e:"table",f:[{p:[32,3,809],t:7,e:"tr",f:[{p:[33,4,818],t:7,e:"th",f:["PROTOCOL"]},{p:[34,4,835],t:7,e:"th",f:["STATUS"]},{p:[35,4,850],t:7,e:"th",f:["CONTROL"]}]},{p:[36,3,865],t:7,e:"tr",f:[" ",{p:[37,4,874],t:7,e:"td",f:["Software Downloads"]},{p:[38,4,901],t:7,e:"td",f:[{t:2,x:{r:["data.config_softwaredownload"],s:'_0?"ENABLED":"DISABLED"'},p:[38,8,905]}]},{p:[39,4,967],t:7,e:"td",f:[" ",{p:[39,9,972],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "1"}'},f:["TOGGLE"]}]}]},{p:[40,3,1051],t:7,e:"tr",f:[" ",{p:[41,4,1060],t:7,e:"td",f:["Peer to Peer Traffic"]},{p:[42,4,1089],t:7,e:"td",f:[{t:2,x:{r:["data.config_peertopeer"],s:'_0?"ENABLED":"DISABLED"'},p:[42,8,1093]}]},{p:[43,4,1149],t:7,e:"td",f:[{p:[43,8,1153],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "2"}'},f:["TOGGLE"]}]}]},{p:[44,3,1232],t:7,e:"tr",f:[" ",{p:[45,4,1241],t:7,e:"td",f:["Communication Systems"]},{p:[46,4,1271],t:7,e:"td",f:[{t:2,x:{r:["data.config_communication"],s:'_0?"ENABLED":"DISABLED"'},p:[46,8,1275]}]},{p:[47,4,1334],t:7,e:"td",f:[{p:[47,8,1338],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "3"}'},f:["TOGGLE"]}]}]},{p:[48,3,1417],t:7,e:"tr",f:[" ",{p:[49,4,1426],t:7,e:"td",f:["Remote System Control"]},{p:[50,4,1456],t:7,e:"td",f:[{t:2,x:{r:["data.config_systemcontrol"],s:'_0?"ENABLED":"DISABLED"'},p:[50,8,1460]}]},{p:[51,4,1519],t:7,e:"td",f:[{p:[51,8,1523],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "4"}'},f:["TOGGLE"]}]}]}]}]}," ",{p:[55,2,1630],t:7,e:"ui-display",a:{title:"SECURITY SYSTEMS"},f:[{t:4,f:[{p:[58,4,1699],t:7,e:"ui-notice",f:[{p:[59,5,1716],t:7,e:"h1",f:["NETWORK INCURSION DETECTED"]}]}," ",{p:[61,5,1774],t:7,e:"i",f:["An abnormal activity has been detected in the network. Please verify system logs for more information"]}],n:50,r:"data.idsalarm",p:[57,3,1673]}," ",{p:[64,3,1902],t:7,e:"ui-section",a:{label:"Intrusion Detection System"},f:[{p:[65,4,1954],t:7,e:"b",f:[{t:2,x:{r:["data.idsstatus"],s:'_0?"ENABLED":"DISABLED"'},p:[65,7,1957]}]}]}," ",{p:[68,3,2029],t:7,e:"ui-section",a:{label:"Maximal Log Count"},f:[{p:[69,4,2072],t:7,e:"b",f:[{t:2,r:"data.ntnetmaxlogs",p:[69,7,2075]}]}]}," ",{p:[72,3,2125],t:7,e:"ui-section",a:{label:"Controls"},f:[]}," ",{p:[74,4,2176],t:7,e:"table",f:[{p:[75,4,2188],t:7,e:"tr",f:[{p:[75,8,2192],t:7,e:"td",f:[{p:[75,12,2196],t:7,e:"ui-button",a:{action:"resetIDS"},f:["RESET IDS"]}]}]},{p:[76,4,2251],t:7,e:"tr",f:[{p:[76,8,2255],t:7,e:"td",f:[{p:[76,12,2259],t:7,e:"ui-button",a:{action:"toggleIDS"},f:["TOGGLE IDS"]}]}]},{p:[77,4,2316],t:7,e:"tr",f:[{p:[77,8,2320],t:7,e:"td",f:[{p:[77,12,2324],t:7,e:"ui-button",a:{action:"updatemaxlogs"},f:["SET LOG LIMIT"]}]}]},{p:[78,4,2388],t:7,e:"tr",f:[{p:[78,8,2392],t:7,e:"td",f:[{p:[78,12,2396],t:7,e:"ui-button",a:{action:"purgelogs"},f:["PURGE LOGS"]}]}]}]}," ",{p:[81,3,2467],t:7,e:"ui-subdisplay",a:{title:"System Logs"},f:[{p:[82,3,2506],t:7,e:"div",a:{"class":"statusDisplay",style:"overflow: auto;"},f:[{p:[83,3,2561],t:7,e:"div",a:{"class":"item"},f:[{p:[84,4,2584],t:7,e:"div",a:{"class":"itemContent",style:"width: 100%;"},f:[{t:4,f:[{t:2,r:"entry",p:[86,6,2667]},{p:[86,15,2676],t:7,e:"br"}],n:52,r:"data.ntnetlogs",p:[85,5,2636]}]}]}]}]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],275:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[7,2,102],t:7,e:"div",a:{"class":"item"},f:[{p:[8,3,124],t:7,e:"h2",f:["An error has occurred during operation..."]}," ",{p:[9,3,178],t:7,e:"b",f:["Additional information:"]},{t:2,r:"data.error",p:[9,34,209]},{p:[9,48,223],t:7,e:"br"}," ",{p:[10,3,231],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Clear"]}]}],n:50,r:"data.error",p:[6,2,81]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.downloading"],s:"_0"},f:[{p:[13,3,321],t:7,e:"h2",f:["Download in progress..."]}," ",{p:[14,3,357],t:7,e:"div",a:{"class":"itemLabel"},f:["Downloaded file:"]}," ",{p:[17,3,416],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_name",p:[18,4,446]}]}," ",{p:[20,3,483],t:7,e:"div",a:{"class":"itemLabel"},f:["Download progress:"]}," ",{p:[23,3,544],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_progress",p:[24,4,574]}," / ",{t:2,r:"data.download_size",p:[24,33,603]}," GQ"]}," ",{p:[26,3,642],t:7,e:"div",a:{"class":"itemLabel"},f:["Transfer speed:"]}," ",{p:[29,3,700],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_netspeed",p:[30,4,730]},"GQ/s"]}," ",{p:[32,3,774],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[35,3,826],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[36,4,856],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Abort download"]}]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading"],s:"(!(_0))&&(_1)"},f:[" ",{p:[39,3,954],t:7,e:"h2",f:["Server enabled"]}," ",{p:[40,3,981],t:7,e:"div",a:{"class":"itemLabel"},f:["Connected clients:"]}," ",{p:[43,3,1042],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.upload_clients",p:[44,4,1072]}]}," ",{p:[46,3,1109],t:7,e:"div",a:{"class":"itemLabel"},f:["Provided file:"]}," ",{p:[49,3,1166],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.upload_filename",p:[50,4,1196]}]}," ",{p:[52,3,1234],t:7,e:"div",a:{"class":"itemLabel"},f:["Server password:"]}," ",{p:[55,3,1293],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["ENABLED"],n:50,r:"data.upload_haspassword",p:[56,4,1323]},{t:4,n:51,f:["DISABLED"],r:"data.upload_haspassword"}]}," ",{p:[62,3,1420],t:7,e:"div",a:{"class":"itemLabel"},f:["Commands:"]}," ",{p:[65,3,1472],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[66,4,1502],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}," ",{p:[67,4,1567],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Exit server"]}]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading","data.upload_filelist"],s:"(!(_0))&&((!(_1))&&(_2))"},f:[" ",{p:[70,3,1668],t:7,e:"h2",f:["File transfer server ready. Select file to upload:"]}," ",{p:[71,3,1732],t:7,e:"table",f:[{p:[72,3,1743],t:7,e:"tr",f:[{p:[72,7,1747],t:7,e:"th",f:["File name"]},{p:[72,20,1760],t:7,e:"th",f:["File size"]},{p:[72,33,1773],t:7,e:"th",f:["Controls ",{t:4,f:[{p:[74,4,1824],t:7,e:"tr",f:[{p:[74,8,1828],t:7,e:"td",f:[{t:2,r:"filename",p:[74,12,1832]}]},{p:[75,4,1849],t:7,e:"td",f:[{t:2,r:"size",p:[75,8,1853]},"GQ"]},{p:[76,4,1868],t:7,e:"td",f:[{p:[76,8,1872],t:7,e:"ui-button",a:{action:"PRG_uploadfile",params:['{"id": "',{t:2,r:"uid",p:[76,59,1923]},'"}']},f:["Select"]}]}]}],n:52,r:"data.upload_filelist",p:[73,3,1789]}]}]}]}," ",{p:[79,3,1981],t:7,e:"hr"}," ",{p:[80,3,1989],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}," ",{p:[81,3,2053],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Return"]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading","data.upload_filelist"],s:"(!(_0))&&((!(_1))&&(!(_2)))"},f:[" ",{p:[83,3,2116],t:7,e:"h2",f:["Available files:"]}," ",{p:[84,3,2145],t:7,e:"table",a:{border:"1",style:"border-collapse: collapse"},f:[{p:[84,55,2197],t:7,e:"tr",f:[{p:[84,59,2201],t:7,e:"th",f:["Server UID"]},{p:[84,73,2215],t:7,e:"th",f:["File Name"]},{p:[84,86,2228],t:7,e:"th",f:["File Size"]},{p:[84,99,2241],t:7,e:"th",f:["Password Protection"]},{p:[84,122,2264],t:7,e:"th",f:["Operations ",{t:4,f:[{p:[86,5,2311],t:7,e:"tr",f:[{p:[86,9,2315],t:7,e:"td",f:[{t:2,r:"uid",p:[86,13,2319]}]},{p:[87,5,2332],t:7,e:"td",f:[{t:2,r:"filename",p:[87,9,2336]}]},{p:[88,5,2354],t:7,e:"td",f:[{t:2,r:"size",p:[88,9,2358]},"GQ ",{t:4,f:[{p:[90,6,2400],t:7,e:"td",f:["Enabled"]}],n:50,r:"haspassword",p:[89,5,2374]}," ",{t:4,f:[{p:[93,6,2457],t:7,e:"td",f:["Disabled"]}],n:50,x:{r:["haspassword"],s:"!_0"},p:[92,5,2430]}]},{p:[96,5,2494],t:7,e:"td",f:[{p:[96,9,2498],t:7,e:"ui-button",a:{action:"PRG_downloadfile",params:['{"id": "',{t:2,r:"uid",p:[96,62,2551]},'"}']},f:["Download"]}]}]}],n:52,r:"data.servers",p:[85,4,2283]}]}]}]}," ",{p:[99,3,2612],t:7,e:"hr"}," ",{p:[100,3,2620],t:7,e:"ui-button",a:{action:"PRG_uploadmenu"},f:["Send file"]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],276:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{chargingState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},chargingMode:function(t){return 2==t?"Full":1==t?"Charging":"Draining"},channelState:function(t){return t>=2?"good":"bad"},channelPower:function(t){return t>=2?"On":"Off"},channelMode:function(t){return 1==t||3==t?"Auto":"Manual"}},computed:{graphData:function(){var t=this.get("data.history");return Object.keys(t).map(function(e){return t[e].map(function(t,e){return{x:e,y:t}})})}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[43,1,1082],t:7,e:"ntosheader"}," ",{p:[45,1,1099],t:7,e:"ui-display",a:{title:"Network"},f:[{t:4,f:[{p:[47,5,1157],t:7,e:"ui-linegraph",a:{points:[{t:2,r:"graphData", - p:[47,27,1179]}],height:"500",legend:'["Available", "Load"]',colors:'["rgb(0, 102, 0)", "rgb(153, 0, 0)"]',xunit:"seconds ago",xfactor:[{t:2,r:"data.interval",p:[49,38,1331]}],yunit:"W",yfactor:"1",xinc:[{t:2,x:{r:["data.stored"],s:"_0/10"},p:[50,15,1387]}],yinc:"9"}}],n:50,r:"config.fancy",p:[46,3,1131]},{t:4,n:51,f:[{p:[52,5,1437],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[53,7,1475],t:7,e:"span",f:[{t:2,r:"data.supply",p:[53,13,1481]}," W"]}]}," ",{p:[55,5,1530],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[56,9,1565],t:7,e:"span",f:[{t:2,r:"data.demand",p:[56,15,1571]}," W"]}]}],r:"config.fancy"}]}," ",{p:[60,1,1642],t:7,e:"ui-display",a:{title:"Areas"},f:[{p:[61,3,1672],t:7,e:"ui-section",a:{nowrap:0},f:[{p:[62,5,1697],t:7,e:"div",a:{"class":"content"},f:["Area"]}," ",{p:[63,5,1734],t:7,e:"div",a:{"class":"content"},f:["Charge"]}," ",{p:[64,5,1773],t:7,e:"div",a:{"class":"content"},f:["Load"]}," ",{p:[65,5,1810],t:7,e:"div",a:{"class":"content"},f:["Status"]}," ",{p:[66,5,1849],t:7,e:"div",a:{"class":"content"},f:["Equipment"]}," ",{p:[67,5,1891],t:7,e:"div",a:{"class":"content"},f:["Lighting"]}," ",{p:[68,5,1932],t:7,e:"div",a:{"class":"content"},f:["Environment"]}]}," ",{t:4,f:[{p:[71,5,2017],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[71,24,2036]}],nowrap:0},f:[{p:[72,7,2061],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].charge)"},p:[72,28,2082]}," %"]}," ",{p:[73,7,2140],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].load)"},p:[73,28,2161]}," W"]}," ",{p:[74,7,2217],t:7,e:"div",a:{"class":"content"},f:[{p:[74,28,2238],t:7,e:"span",a:{"class":[{t:2,x:{r:["chargingState","charging"],s:"_0(_1)"},p:[74,41,2251]}]},f:[{t:2,x:{r:["chargingMode","charging"],s:"_0(_1)"},p:[74,70,2280]}]}]}," ",{p:[75,7,2327],t:7,e:"div",a:{"class":"content"},f:[{p:[75,28,2348],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","eqp"],s:"_0(_1)"},p:[75,41,2361]}]},f:[{t:2,x:{r:["channelPower","eqp"],s:"_0(_1)"},p:[75,64,2384]}," [",{p:[75,87,2407],t:7,e:"span",f:[{t:2,x:{r:["channelMode","eqp"],s:"_0(_1)"},p:[75,93,2413]}]},"]"]}]}," ",{p:[76,7,2462],t:7,e:"div",a:{"class":"content"},f:[{p:[76,28,2483],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","lgt"],s:"_0(_1)"},p:[76,41,2496]}]},f:[{t:2,x:{r:["channelPower","lgt"],s:"_0(_1)"},p:[76,64,2519]}," [",{p:[76,87,2542],t:7,e:"span",f:[{t:2,x:{r:["channelMode","lgt"],s:"_0(_1)"},p:[76,93,2548]}]},"]"]}]}," ",{p:[77,7,2597],t:7,e:"div",a:{"class":"content"},f:[{p:[77,28,2618],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","env"],s:"_0(_1)"},p:[77,41,2631]}]},f:[{t:2,x:{r:["channelPower","env"],s:"_0(_1)"},p:[77,64,2654]}," [",{p:[77,87,2677],t:7,e:"span",f:[{t:2,x:{r:["channelMode","env"],s:"_0(_1)"},p:[77,93,2683]}]},"]"]}]}]}],n:52,r:"data.areas",p:[70,3,1991]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],277:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"div",a:{"class":"item"},f:[{p:[6,3,101],t:7,e:"div",a:{"class":"itemLabel"},f:["Payload status:"]}," ",{p:[9,3,158],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["ARMED"],n:50,r:"data.armed",p:[10,4,188]},{t:4,n:51,f:["DISARMED"],r:"data.armed"}]}," ",{p:[16,3,270],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[19,3,321],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[20,4,351],t:7,e:"table",f:[{p:[21,4,363],t:7,e:"tr",f:[{p:[21,8,367],t:7,e:"td",f:[{p:[21,12,371],t:7,e:"ui-button",a:{action:"PRG_obfuscate"},f:["OBFUSCATE PROGRAM NAME"]}]}]},{p:[22,4,444],t:7,e:"tr",f:[{p:[22,8,448],t:7,e:"td",f:[{p:[22,12,452],t:7,e:"ui-button",a:{action:"PRG_arm",state:[{t:2,x:{r:["data.armed"],s:'_0?"danger":null'},p:[22,47,487]}]},f:[{t:2,x:{r:["data.armed"],s:'_0?"DISARM":"ARM"'},p:[22,81,521]}]}," ",{p:[23,4,571],t:7,e:"ui-button",a:{icon:"radiation",state:[{t:2,x:{r:["data.armed"],s:'_0?null:"disabled"'},p:[23,39,606]}],action:"PRG_activate"},f:["ACTIVATE"]}]}]}]}]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],278:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[5,3,95],t:7,e:"ui-display",a:{title:[{t:2,r:"class",p:[5,22,114]}," Alarms"]},f:[{p:[6,5,138],t:7,e:"ul",f:[{t:4,f:[{p:[8,9,171],t:7,e:"li",f:[{t:2,r:".",p:[8,13,175]}]}],n:52,r:".",p:[7,7,150]},{t:4,n:51,f:[{p:[10,9,211],t:7,e:"li",f:["System Nominal"]}],r:"."}]}]}],n:52,i:"class",r:"data.alarms",p:[4,1,64]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],279:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{integState:function(t){var e=100;return t==e?"good":t>e/2?"average":"bad"},bigState:function(t,e,n){return charge>n?"bad":t>e?"average":"good"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[23,1,421],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[27,2,462],t:7,e:"ui-button",a:{action:"PRG_clear"},f:["Back to Menu"]},{p:[27,56,516],t:7,e:"br"}," ",{p:[28,3,524],t:7,e:"ui-display",a:{title:"Supermatter Status:"},f:[{p:[29,3,568],t:7,e:"ui-section",a:{label:"Core Integrity"},f:[{p:[30,5,609],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"adata.SM_integrity",p:[30,38,642]}],state:[{t:2,x:{r:["integState","adata.SM_integrity"],s:"_0(_1)"},p:[30,69,673]}]},f:[{t:2,r:"data.SM_integrity",p:[30,105,709]},"%"]}]}," ",{p:[32,3,761],t:7,e:"ui-section",a:{label:"Relative EER"},f:[{p:[33,5,800],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_power"],s:"_0(_1,150,300)"},p:[33,18,813]}]},f:[{t:2,r:"data.SM_power",p:[33,55,850]}," MeV/cm3"]}]}," ",{p:[35,3,903],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[36,5,941],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_ambienttemp"],s:"_0(_1,4000,5000)"},p:[36,18,954]}]},f:[{t:2,r:"data.SM_ambienttemp",p:[36,63,999]}," K"]}]}," ",{p:[38,3,1052],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[39,5,1087],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_ambientpressure"],s:"_0(_1,5000,10000)"},p:[39,18,1100]}]},f:[{t:2,r:"data.SM_ambientpressure",p:[39,68,1150]}," kPa"]}]}]}," ",{p:[42,3,1227],t:7,e:"hr"},{p:[42,7,1231],t:7,e:"br"}," ",{p:[43,3,1239],t:7,e:"ui-display",a:{title:"Gas Composition:"},f:[{t:4,f:[{p:[45,5,1307],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[45,24,1326]}]},f:[{t:2,r:"amount",p:[46,6,1343]}," %"]}],n:52,r:"data.gases",p:[44,4,1281]}]}],n:50,r:"data.active",p:[26,1,440]},{t:4,n:51,f:[{p:[51,2,1418],t:7,e:"ui-button",a:{action:"PRG_refresh"},f:["Refresh"]},{p:[51,53,1469],t:7,e:"br"}," ",{p:[52,2,1476],t:7,e:"ui-display",a:{title:"Detected Supermatters"},f:[{t:4,f:[{p:[54,3,1552],t:7,e:"ui-section",a:{label:"Area"},f:[{t:2,r:"area_name",p:[55,5,1583]}," - (#",{t:2,r:"uid",p:[55,23,1601]},")"]}," ",{p:[57,3,1630],t:7,e:"ui-section",a:{label:"Integrity"},f:[{t:2,r:"integrity",p:[58,5,1666]}," %"]}," ",{p:[60,3,1702],t:7,e:"ui-section",a:{label:"Options"},f:[{p:[61,5,1736],t:7,e:"ui-button",a:{action:"PRG_set",params:['{"target" : "',{t:2,r:"uid",p:[61,54,1785]},'"}']},f:["View Details"]}]}],n:52,r:"data.supermatters",p:[53,2,1521]}]}],r:"data.active"}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],280:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"item",style:"float: left"},f:[{p:[2,2,41],t:7,e:"table",f:[{p:[2,9,48],t:7,e:"tr",f:[{t:4,f:[{p:[4,3,113],t:7,e:"td",f:[{p:[4,7,117],t:7,e:"img",a:{src:[{t:2,r:"data.PC_batteryicon",p:[4,17,127]}]}}]}],n:50,x:{r:["data.PC_batteryicon","data.PC_showbatteryicon"],s:"_0&&_1"},p:[3,2,55]}," ",{t:4,f:[{p:[7,3,226],t:7,e:"td",f:[{p:[7,7,230],t:7,e:"b",f:[{t:2,r:"data.PC_batterypercent",p:[7,10,233]}]}]}],n:50,x:{r:["data.PC_batterypercent","data.PC_showbatteryicon"],s:"_0&&_1"},p:[6,2,165]}," ",{t:4,f:[{p:[10,3,305],t:7,e:"td",f:[{p:[10,7,309],t:7,e:"img",a:{src:[{t:2,r:"data.PC_ntneticon",p:[10,17,319]}]}}]}],n:50,r:"data.PC_ntneticon",p:[9,2,276]}," ",{t:4,f:[{p:[13,3,386],t:7,e:"td",f:[{p:[13,7,390],t:7,e:"img",a:{src:[{t:2,r:"data.PC_apclinkicon",p:[13,17,400]}]}}]}],n:50,r:"data.PC_apclinkicon",p:[12,2,355]}," ",{t:4,f:[{p:[16,3,469],t:7,e:"td",f:[{p:[16,7,473],t:7,e:"b",f:[{t:2,r:"data.PC_stationtime",p:[16,10,476]}]}]}],n:50,r:"data.PC_stationtime",p:[15,2,438]}," ",{t:4,f:[{p:[19,3,552],t:7,e:"td",f:[{p:[19,7,556],t:7,e:"img",a:{src:[{t:2,r:"icon",p:[19,17,566]}]}}]}],n:52,r:"data.PC_programheaders",p:[18,2,516]}]}]}]}," ",{p:[23,1,609],t:7,e:"div",a:{style:"float: right; margin-top: 5px"},f:[{p:[24,2,655],t:7,e:"ui-button",a:{action:"PC_shutdown"},f:["Shutdown"]}," ",{t:4,f:[{p:[26,3,745],t:7,e:"ui-button",a:{action:"PC_exit"},f:["EXIT PROGRAM"]}," ",{p:[27,3,801],t:7,e:"ui-button",a:{action:"PC_minimize"},f:["Minimize Program"]}],n:50,r:"data.PC_showexitprogram",p:[25,2,710]}]}," ",{p:[30,1,881],t:7,e:"div",a:{style:"clear: both"}}]},e.exports=a.extend(r.exports)},{205:205}],281:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Auth. Disk:"},f:[{t:4,f:[{p:[3,7,69],t:7,e:"ui-button",a:{icon:"eject",style:"selected",action:"eject_disk"},f:["++++++++++"]}],n:50,r:"data.disk_present",p:[2,3,36]},{t:4,n:51,f:[{p:[5,7,172],t:7,e:"ui-button",a:{icon:"plus",action:"insert_disk"},f:["----------"]}],r:"data.disk_present"}]}," ",{p:[8,1,266],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[9,3,297],t:7,e:"span",f:[{t:2,r:"data.status1",p:[9,9,303]},"-",{t:2,r:"data.status2",p:[9,26,320]}]}]}," ",{p:[11,1,360],t:7,e:"ui-display",a:{title:"Timer"},f:[{p:[12,3,390],t:7,e:"ui-section",a:{label:"Time to Detonation"},f:[{p:[13,5,435],t:7,e:"span",f:[{t:2,x:{r:["data.timing","data.time_left","data.timer_set"],s:"_0?_1:_2"},p:[13,11,441]}]}]}," ",{t:4,f:[{p:[16,5,540],t:7,e:"ui-section",a:{label:"Adjust Timer"},f:[{p:[17,7,581],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_default"],s:'_0&&_1&&_2?null:"disabled"'},p:[17,40,614]}],action:"timer",params:'{"change": "reset"}'},f:["Reset"]}," ",{p:[19,7,786],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_min"],s:'_0&&_1&&_2?null:"disabled"'},p:[19,38,817]}],action:"timer",params:'{"change": "decrease"}'},f:["Decrease"]}," ",{p:[21,7,991],t:7,e:"ui-button",a:{icon:"pencil",state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[21,39,1023]}],action:"timer",params:'{"change": "input"}'},f:["Set"]}," ",{p:[22,7,1155],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_max"],s:'_0&&_1&&_2?null:"disabled"'},p:[22,37,1185]}],action:"timer",params:'{"change": "increase"}'},f:["Increase"]}]}],n:51,r:"data.timing",p:[15,3,518]}," ",{p:[26,3,1394],t:7,e:"ui-section",a:{label:"Timer"},f:[{p:[27,5,1426],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"danger":"caution"'},p:[27,38,1459]}],action:"toggle_timer",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.safety"],s:'_0&&_1&&!_2?null:"disabled"'},p:[29,14,1542]}]},f:[{t:2,x:{r:["data.timing"],s:'_0?"On":"Off"'},p:[30,7,1631]}]}]}]}," ",{p:[34,1,1713],t:7,e:"ui-display",a:{title:"Anchoring"},f:[{p:[35,3,1747],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[36,12,1770]}],icon:[{t:2,x:{r:["data.anchored"],s:'_0?"lock":"unlock"'},p:[37,11,1846]}],style:[{t:2,x:{r:["data.anchored"],s:'_0?null:"caution"'},p:[38,12,1897]}],action:"anchor"},f:[{t:2,x:{r:["data.anchored"],s:'_0?"Engaged":"Off"'},p:[39,21,1956]}]}]}," ",{p:[41,1,2022],t:7,e:"ui-display",a:{title:"Safety"},f:[{p:[42,3,2053],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[43,12,2076]}],icon:[{t:2,x:{r:["data.safety"],s:'_0?"lock":"unlock"'},p:[44,11,2152]}],action:"safety",style:[{t:2,x:{r:["data.safety"],s:'_0?"caution":"danger"'},p:[45,12,2217]}]},f:[{p:[46,7,2265],t:7,e:"span",f:[{t:2,x:{r:["data.safety"],s:'_0?"On":"Off"'},p:[46,13,2271]}]}]}]}," ",{p:[49,1,2341],t:7,e:"ui-display",a:{title:"Code"},f:[{p:[50,3,2370],t:7,e:"ui-section",a:{label:"Message"},f:[{t:2,r:"data.message",p:[50,31,2398]}]}," ",{p:[51,3,2431],t:7,e:"ui-section",a:{label:"Keypad"},f:[{p:[52,5,2464],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[52,39,2498]}],params:'{"digit":"1"}'},f:["1"]}," ",{p:[53,5,2583],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[53,39,2617]}],params:'{"digit":"2"}'},f:["2"]}," ",{p:[54,5,2702],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[54,39,2736]}],params:'{"digit":"3"}'},f:["3"]}," ",{p:[55,5,2821],t:7,e:"br"}," ",{p:[56,5,2831],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[56,39,2865]}],params:'{"digit":"4"}'},f:["4"]}," ",{p:[57,5,2950],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[57,39,2984]}],params:'{"digit":"5"}'},f:["5"]}," ",{p:[58,5,3069],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[58,39,3103]}],params:'{"digit":"6"}'},f:["6"]}," ",{p:[59,5,3188],t:7,e:"br"}," ",{p:[60,5,3198],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[60,39,3232]}],params:'{"digit":"7"}'},f:["7"]}," ",{p:[61,5,3317],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[61,39,3351]}],params:'{"digit":"8"}'},f:["8"]}," ",{p:[62,5,3436],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[62,39,3470]}],params:'{"digit":"9"}'},f:["9"]}," ",{p:[63,5,3555],t:7,e:"br"}," ",{p:[64,5,3565],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[64,39,3599]}],params:'{"digit":"R"}'},f:["R"]}," ",{p:[65,5,3684],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[65,39,3718]}],params:'{"digit":"0"}'},f:["0"]}," ",{p:[66,5,3803],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[66,39,3837]}],params:'{"digit":"E"}'},f:["E"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],282:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,2,15],t:7,e:"ui-section",f:["This machine only accepts ore. Gibtonite and Slag are not accepted."]}," ",{p:[5,2,117],t:7,e:"ui-section",f:["Current unclaimed points: ",{t:2,r:"data.unclaimedPoints",p:[6,29,159]}," ",{t:4,f:[{p:[8,4,220],t:7,e:"ui-button",a:{action:"Claim"},f:["Claim Points"]}],n:50,r:"data.unclaimedPoints",p:[7,3,187]}]}," ",{p:[13,2,311],t:7,e:"ui-section",f:[{t:4,f:[{p:[15,4,350],t:7,e:"ui-button",a:{action:"Eject"},f:["Eject ID"]}," You have ",{t:2,r:"data.claimedPoints",p:[18,13,421]}," mining points collected."],n:50,r:"data.hasID",p:[14,3,327]},{t:4,n:51,f:[{p:[20,4,485],t:7,e:"ui-button",a:{action:"Insert"},f:["Insert ID"]}],r:"data.hasID"}]}]}," ",{p:[26,1,588],t:7,e:"ui-display",f:[{t:4,f:[{p:[28,3,627],t:7,e:"ui-section",f:[{p:[29,4,644],t:7,e:"ui-button",a:{action:"diskEject",icon:"eject"},f:["Eject Disk"]}]}," ",{t:4,f:[{p:[34,4,772],t:7,e:"ui-section",a:{"class":"candystripe"},f:[{p:[35,5,808],t:7,e:"ui-button",a:{action:"diskUpload",state:[{t:2,x:{r:["canupload"],s:'(_0)?null:"disabled"'},p:[35,42,845]}],icon:"upload",align:"right",params:['{ "design" : "',{t:2,r:"index",p:[35,129,932]},'" }']},f:["Upload"]}," File ",{t:2,r:"index",p:[38,10,988]},": ",{t:2,r:"name",p:[38,21,999]}]}],n:52,r:"data.diskDesigns",p:[33,3,741]}],n:50,r:"data.hasDisk",p:[27,2,603]},{t:4,n:51,f:[{p:[42,3,1053],t:7,e:"ui-section",f:[{p:[43,4,1070],t:7,e:"ui-button",a:{action:"diskInsert",icon:"floppy-o"},f:["Insert Disk"]}]}],r:"data.hasDisk"}]}," ",{p:[49,1,1195],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[50,2,1227],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[51,4,1261],t:7,e:"section",a:{"class":"cell"},f:["Mineral"]}," ",{p:[54,4,1316],t:7,e:"section",a:{"class":"cell"},f:["Sheets"]}," ",{p:[57,4,1370],t:7,e:"section",a:{"class":"cell"},f:[]}," ",{p:[59,4,1412],t:7,e:"section",a:{"class":"cell"},f:[{p:[60,5,1440],t:7,e:"ui-button",a:{"class":"center mineral",grid:0,action:"Release",params:'{"id" : "all"}'},f:["Release All"]}]}," ",{p:[64,4,1576],t:7,e:"section",a:{"class":"cell"},f:["Ore Value"]}]}," ",{t:4,f:[{p:[69,3,1673],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[70,4,1707],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[71,5,1735]}]}," ",{p:[73,4,1763],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[74,5,1805]}]}," ",{p:[76,4,1835],t:7,e:"section",a:{"class":"cell"},f:[{p:[77,5,1863],t:7,e:"input",a:{value:[{t:2,r:"sheets",p:[77,18,1876]}],placeholder:"###","class":"number"}}]}," ",{p:[79,4,1941],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[80,5,1983],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[80,59,2037]}],params:['{ "id" : ',{t:2,r:"id",p:[80,114,2092]},', "sheets" : ',{t:2,r:"sheets",p:[80,133,2111]}," }"]},f:["Release"]}]}," ",{p:[84,4,2178],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"value",p:[85,5,2220]}]}]}],n:52,r:"data.materials",p:[68,2,1645]}," ",{t:4,f:[{p:[90,3,2298],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[91,4,2332],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[92,5,2360]}]}," ",{p:[94,4,2388],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[95,5,2430]}]}," ",{p:[97,4,2460],t:7,e:"section",a:{"class":"cell"},f:[{p:[98,5,2488],t:7,e:"input",a:{value:[{t:2,r:"sheets",p:[98,18,2501]}],placeholder:"###","class":"number"}}]}," ",{p:[100,4,2566],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[101,5,2608],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"Smelt",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[101,57,2660]}],params:['{ "id" : ',{t:2,r:"id",p:[101,113,2716]},', "sheets" : ',{t:2,r:"sheets",p:[101,132,2735]}," }"]},f:["Smelt"]}]}," ",{p:[105,4,2799],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[106,5,2841],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"SmeltAll",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[106,60,2896]}],params:['{ "id" : ',{t:2,r:"id",p:[106,116,2952]}," }"]},f:["Smelt All"]}]}]}],n:52,r:"data.alloys",p:[89,2,2273]}]}]},e.exports=a.extend(r.exports)},{205:205}],283:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{p:[3,3,60],t:7,e:"ui-button",a:{icon:"remove",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[3,35,92]}],action:"empty_eject_beaker"},f:["Empty and eject"]}," ",{p:[6,3,201],t:7,e:"ui-button",a:{icon:"trash",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[6,34,232]}],action:"empty_beaker"},f:["Empty"]}," ",{p:[9,3,325],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[9,34,356]}],action:"eject_beaker"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{t:4,f:[{p:[14,3,490],t:7,e:"ui-section",f:[{t:4,f:[{p:[16,5,538],t:7,e:"span",a:{"class":"bad"},f:["The beaker is empty!"]}],n:50,r:"data.beaker_empty",p:[15,4,507]},{t:4,n:51,f:[{p:[18,5,602],t:7,e:"ui-subdisplay",a:{title:"Blood"},f:[{t:4,f:[{p:[20,7,668],t:7,e:"ui-section",a:{label:"Blood DNA"},f:[{t:2,r:"data.blood.dna",p:[20,37,698]}]}," ",{p:[21,7,737],t:7,e:"ui-section",a:{label:"Blood type"},f:[{t:2,r:"data.blood.type",p:[21,38,768]}]}],n:50,r:"data.has_blood",p:[19,6,638]},{t:4,n:51,f:[{p:[23,7,823],t:7,e:"ui-section",f:[{p:[24,8,844],t:7,e:"span",a:{"class":"average"},f:["No blood sample detected."]}]}],r:"data.has_blood"}]}],r:"data.beaker_empty"}]}],n:50,r:"data.has_beaker",p:[13,2,463]},{t:4,n:51,f:[{p:[31,3,999],t:7,e:"ui-section",f:[{p:[32,4,1016],t:7,e:"span",a:{"class":"bad"},f:["No beaker loaded."]}]}],r:"data.has_beaker"}]}," ",{t:4,f:[{p:[37,2,1127],t:7,e:"ui-display",a:{title:"Diseases"},f:[{t:4,f:[{p:{button:[{t:4,f:[{p:[42,7,1277],t:7,e:"ui-button",a:{icon:"pencil",action:"rename_disease",state:[{t:2,x:{r:["can_rename"],s:'_0?"":"disabled"'},p:[42,63,1333]}],params:['{"index": ',{t:2,r:"index",p:[42,115,1385]},"}"]},f:["Name advanced disease"]}],n:50,r:"is_adv",p:[41,6,1255]}," ",{p:[46,6,1468],t:7,e:"ui-button",a:{icon:"flask",action:"create_culture_bottle",state:[{t:2,x:{r:["data.is_ready"],s:'_0?"":"disabled"'},p:[46,68,1530]}],params:['{"index": ',{t:2,r:"index",p:[46,123,1585]},"}"]},f:["Create virus culture bottle"]}]},t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[39,23,1206]}],button:0},f:[" ",{p:[50,5,1675],t:7,e:"ui-section",a:{label:"Disease agent"},f:[{t:2,r:"agent",p:[50,39,1709]}]}," ",{p:[51,5,1737],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"description",p:[51,37,1769]}]}," ",{p:[52,5,1803],t:7,e:"ui-section",a:{label:"Spread"},f:[{t:2,r:"spread",p:[52,32,1830]}]}," ",{p:[53,5,1859],t:7,e:"ui-section",a:{label:"Possible cure"},f:[{t:2,r:"cure",p:[53,39,1893]}]}," ",{t:4,f:[{p:[55,6,1942],t:7,e:"ui-section",a:{label:"Resistance"},f:[{t:2,r:"resistance",p:[55,37,1973]}]}," ",{p:[56,6,2007],t:7,e:"ui-section",a:{label:"Stealth"},f:[{t:2,r:"stealth",p:[56,34,2035]}]}," ",{p:[57,6,2066],t:7,e:"ui-section",a:{label:"Stage speed"},f:[{t:2,r:"stage_speed",p:[57,38,2098]}]}," ",{p:[58,6,2133],t:7,e:"ui-section",a:{label:"Symptoms"},f:[{t:4,f:[{p:[60,8,2197],t:7,e:"span",f:[{t:2,r:"name",p:[60,14,2203]}]},{p:[60,29,2218],t:7,e:"br"}],n:52,r:"symptoms",p:[59,7,2170]}]}],n:50,r:"is_adv",p:[54,5,1921]}]}],n:52,r:"data.viruses",p:[38,3,1160]},{t:4,n:51,f:[{p:[66,4,2309],t:7,e:"ui-section",f:[{p:[67,5,2327],t:7,e:"span",a:{"class":"average"},f:["No detectable virus in the blood sample."]}]}],r:"data.viruses"}]}," ",{p:[71,2,2446],t:7,e:"ui-display",a:{title:"Antibodies"},f:[{t:4,f:[{p:[73,4,2512],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[73,23,2531]}]},f:[{p:[74,6,2548],t:7,e:"ui-button",a:{icon:"eyedropper",state:[{t:2,x:{r:["data.is_ready"],s:'_0?"":"disabled"'},p:[74,42,2584]}],action:"create_vaccine_bottle",params:['{"index": ',{t:2,r:"id",p:[74,128,2670]},"}"]},f:["Create vaccine bottle"]}]}],n:52,r:"data.resistances",p:[72,3,2481]},{t:4,n:51,f:[{p:[79,4,2762],t:7,e:"ui-section",f:[{p:[80,5,2780],t:7,e:"span",a:{"class":"average"},f:["No antibodies detected in the blood sample."]}]}],r:"data.resistances"}]}],n:50,r:"data.has_blood",p:[36,1,1102]}]},e.exports=a.extend(r.exports)},{205:205}],284:[function(t,e,n){var a=t(205),r={exports:{}};!function(e){"use strict";var n=t(312);e.exports={data:{filter:"",tooltiptext:function(t,e,n){var a="";return t&&(a+="REQUIREMENTS: "+t+" "),e&&(a+="CATALYSTS: "+e+" "),n&&(a+="TOOLS: "+n),a}},oninit:function(){var t=this;this.on({hover:function(t){this.set("hovered",t.context.params)},unhover:function(t){this.set("hovered")}}),this.observe("filter",function(e,a,r){var i=null;i=t.get("data.display_compact")?t.findAll(".section"):t.findAll(".display:not(:first-child)"),(0,n.filterMulti)(i,t.get("filter").toLowerCase())},{init:!1})}}}(r),r.exports.template={v:3,t:[" ",{p:[48,1,1342],t:7,e:"ui-display",a:{title:[{t:2,r:"data.category",p:[48,20,1361]},{t:4,f:[" : ",{t:2,r:"data.subcategory",p:[48,64,1405]}],n:50,r:"data.subcategory",p:[48,37,1378]}]},f:[{t:4,f:[{p:[50,3,1459],t:7,e:"ui-section",f:["Crafting... ",{p:[51,16,1488],t:7,e:"i",a:{"class":"fa-spin fa fa-spinner"}}]}],n:50,r:"data.busy",p:[49,2,1438]},{t:4,n:51,f:[{p:[54,3,1557],t:7,e:"ui-section",f:[{p:[55,4,1574],t:7,e:"table",a:{style:"width:100%"},f:[{p:[56,5,1606],t:7,e:"tr",f:[{p:[57,6,1617],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[58,7,1659],t:7,e:"ui-button",a:{icon:"arrow-left",action:"backwardCat"},f:[{t:2,r:"data.prev_cat",p:[59,8,1718]}]}]}," ",{p:[62,6,1774],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[63,7,1816],t:7,e:"ui-button",a:{icon:"arrow-right",action:"forwardCat"},f:[{t:2,r:"data.next_cat",p:[64,7,1874]}]}]}," ",{p:[67,6,1930],t:7,e:"td",a:{style:"float:right!important"},f:[{t:4,f:[{p:[69,7,2014],t:7,e:"ui-button",a:{icon:"lock",action:"toggle_recipes"},f:["Showing Craftable Recipes"]}],n:50,r:"data.display_craftable_only",p:[68,6,1971]},{t:4,n:51,f:[{p:[73,7,2138],t:7,e:"ui-button",a:{icon:"unlock",action:"toggle_recipes"},f:["Showing All Recipes"]}],r:"data.display_craftable_only"}]}," ",{p:[78,6,2268],t:7,e:"td",a:{style:"float:right!important"},f:[{p:[79,7,2310],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.display_compact"],s:'_0?"check-square-o":"square-o"'},p:[79,24,2327]}],action:"toggle_compact"},f:["Compact"]}]}]}," ",{p:[84,5,2474],t:7,e:"tr",f:[{t:4,f:[{p:[86,6,2515],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[87,7,2557],t:7,e:"ui-button",a:{icon:"arrow-left",action:"backwardSubCat"},f:[{t:2,r:"data.prev_subcat",p:[88,8,2619]}]}]}," ",{p:[91,6,2678],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[92,7,2720],t:7,e:"ui-button",a:{icon:"arrow-right",action:"forwardSubCat"},f:[{t:2,r:"data.next_subcat",p:[93,8,2782]}]}]}],n:50,r:"data.subcategory",p:[85,5,2484]}]}]}," ",{t:4,f:[{t:4,f:[" ",{p:[101,6,2992],t:7,e:"ui-input",a:{value:[{t:2,r:"filter",p:[101,23,3009]}],placeholder:"Filter.."}}],n:51,r:"data.display_compact",p:[100,5,2902]}],n:50,r:"config.fancy",p:[99,4,2876]}]}," ",{t:4,f:[{p:[106,5,3144],t:7,e:"ui-display",f:[{t:4,f:[{p:[108,6,3193],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[108,25,3212]}]},f:[{p:[109,7,3230],t:7,e:"ui-button",a:{tooltip:[{t:2,x:{r:["tooltiptext","req_text","catalyst_text","tool_text"],s:"_0(_1,_2,_3)"},p:[109,27,3250]}],"tooltip-side":"right",action:"make",params:['{"recipe": "',{t:2,r:"ref",p:[109,135,3358]},'"}'],icon:"gears"},v:{hover:"hover",unhover:"unhover"},f:["Craft"]}]}],n:52,r:"data.can_craft",p:[107,5,3162]}," ",{t:4,f:[{t:4,f:[{p:[116,7,3567],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[116,26,3586]}]},f:[{p:[117,8,3605],t:7,e:"ui-button",a:{tooltip:[{t:2,x:{r:["tooltiptext","req_text","catalyst_text","tool_text"],s:"_0(_1,_2,_3)"},p:[117,28,3625]}],"tooltip-side":"right",state:"disabled",icon:"gears"},v:{hover:"hover",unhover:"unhover"},f:["Craft"]}]}],n:52,r:"data.cant_craft",p:[115,6,3534]}],n:51,r:"data.display_craftable_only",p:[114,5,3495]}]}],n:50,r:"data.display_compact",p:[105,4,3110]},{t:4,n:51,f:[{t:4,f:[{p:[126,6,3947],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[126,25,3966]}]},f:[{t:4,f:[{p:[128,8,4009],t:7,e:"ui-section",a:{label:"Requirements"},f:[{t:2,r:"req_text",p:[129,9,4052]}]}],n:50,r:"req_text",p:[127,7,3984]}," ",{t:4,f:[{p:[133,8,4139],t:7,e:"ui-section",a:{label:"Catalysts"},f:[{t:2,r:"catalyst_text",p:[134,9,4179]}]}],n:50,r:"catalyst_text",p:[132,7,4109]}," ",{t:4,f:[{p:[138,8,4267],t:7,e:"ui-section",a:{label:"Tools"},f:[{t:2,r:"tool_text",p:[139,9,4303]}]}],n:50,r:"tool_text",p:[137,7,4241]}," ",{p:[142,7,4361],t:7,e:"ui-section",f:[{p:[143,8,4382],t:7,e:"ui-button",a:{icon:"gears",action:"make",params:['{"recipe": "',{t:2,r:"ref",p:[143,66,4440]},'"}']},f:["Craft"]}]}]}],n:52,r:"data.can_craft",p:[125,5,3916]}," ",{t:4,f:[{t:4,f:[{p:[151,7,4621],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[151,26,4640]}]},f:[{t:4,f:[{p:[153,9,4685],t:7,e:"ui-section",a:{label:"Requirements"},f:[{t:2,r:"req_text",p:[154,10,4729]}]}],n:50,r:"req_text",p:[152,8,4659]}," ",{t:4,f:[{p:[158,9,4820],t:7,e:"ui-section",a:{label:"Catalysts"},f:[{t:2,r:"catalyst_text",p:[159,10,4861]}]}],n:50,r:"catalyst_text",p:[157,8,4789]}," ",{t:4,f:[{p:[163,9,4953],t:7,e:"ui-section",a:{label:"Tools"},f:[{t:2,r:"tool_text",p:[164,10,4990]}]}],n:50,r:"tool_text",p:[162,8,4926]}]}],n:52,r:"data.cant_craft",p:[150,6,4588]}],n:51,r:"data.display_craftable_only",p:[149,5,4549]}],r:"data.display_compact"}],r:"data.busy"}]}]},e.exports=a.extend(r.exports)},{205:205,312:312}],285:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.holding"],s:'_0?"is":"is not"'},p:[2,23,35]}," connected to a tank."]}]}," ",{p:[4,1,113],t:7,e:"ui-display",a:{title:"Status",button:0},f:[{p:[5,3,151],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,5,186],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[6,11,192]}," kPa"]}]}," ",{p:[8,3,254],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[9,5,285],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected"],s:'_0?"good":"average"'},p:[9,18,298]}]},f:[{t:2,x:{r:["data.connected"],s:'_0?"Connected":"Not Connected"'},p:[9,59,339]}]}]}]}," ",{p:[12,1,430],t:7,e:"ui-display",a:{title:"Pump"},f:[{p:[13,3,459],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,5,491],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[14,22,508]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":"null"'},p:[15,14,559]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[16,22,616]}]}]}," ",{p:[18,3,675],t:7,e:"ui-section",a:{label:"Direction"},f:[{p:[19,5,711],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.direction"],s:'_0=="out"?"sign-out":"sign-in"'},p:[19,22,728]}],action:"direction"},f:[{t:2,x:{r:["data.direction"],s:'_0=="out"?"Out":"In"'},p:[20,26,808]}]}]}," ",{p:[22,3,883],t:7,e:"ui-section",a:{label:"Target Pressure"},f:[{p:[23,5,925],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.min_pressure",p:[23,18,938]}],max:[{t:2,r:"data.max_pressure",p:[23,46,966]}],value:[{t:2,r:"data.target_pressure",p:[24,14,1003]}]},f:[{t:2,x:{r:["adata.target_pressure"],s:"Math.round(_0)"},p:[24,40,1029]}," kPa"]}]}," ",{p:[26,3,1100],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[27,5,1145],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.target_pressure","data.default_pressure"],s:'_0!=_1?null:"disabled"'},p:[27,38,1178]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[29,5,1328],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.target_pressure","data.min_pressure"],s:'_0>_1?null:"disabled"'},p:[29,36,1359]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[31,5,1500],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[32,5,1595],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.target_pressure","data.max_pressure"],s:'_0<_1?null:"disabled"'},p:[32,35,1625]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}]}," ",{p:{button:[{t:4,f:[{p:[39,7,1891],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.on"],s:'_0?"danger":null'},p:[39,38,1922]}],action:"eject"},f:["Eject"]}],n:50,r:"data.holding",p:[38,5,1863]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[43,3,2042],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holding.name",p:[44,4,2073]}]}," ",{p:[46,3,2115],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holding.pressure"],s:"Math.round(_0)"},p:[47,4,2149]}," kPa"]}],n:50,r:"data.holding",p:[42,3,2018]},{t:4,n:51,f:[{p:[50,3,2223],t:7,e:"ui-section",f:[{p:[51,4,2240],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.holding"}]}]},e.exports=a.extend(r.exports)},{205:205}],286:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0], - t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.holding"],s:'_0?"is":"is not"'},p:[2,23,35]}," connected to a tank."]}]}," ",{p:[4,1,113],t:7,e:"ui-display",a:{title:"Status",button:0},f:[{p:[5,3,151],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,5,186],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[6,11,192]}," kPa"]}]}," ",{p:[8,3,254],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[9,5,285],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected"],s:'_0?"good":"average"'},p:[9,18,298]}]},f:[{t:2,x:{r:["data.connected"],s:'_0?"Connected":"Not Connected"'},p:[9,59,339]}]}]}]}," ",{p:[12,1,430],t:7,e:"ui-display",a:{title:"Filter"},f:[{p:[13,3,461],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,5,493],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[14,22,510]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":"null"'},p:[15,14,561]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[16,22,618]}]}]}]}," ",{p:{button:[{t:4,f:[{p:[22,7,787],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.on"],s:'_0?"danger":null'},p:[22,38,818]}],action:"eject"},f:["Eject"]}],n:50,r:"data.holding",p:[21,5,759]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[26,3,938],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holding.name",p:[27,4,969]}]}," ",{p:[29,3,1011],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holding.pressure"],s:"Math.round(_0)"},p:[30,4,1045]}," kPa"]}],n:50,r:"data.holding",p:[25,3,914]},{t:4,n:51,f:[{p:[33,3,1119],t:7,e:"ui-section",f:[{p:[34,4,1136],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.holding"}]}]},e.exports=a.extend(r.exports)},{205:205}],287:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{chargingState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},chargingMode:function(t){return 2==t?"Full":1==t?"Charging":"Draining"},channelState:function(t){return t>=2?"good":"bad"},channelPower:function(t){return t>=2?"On":"Off"},channelMode:function(t){return 1==t||3==t?"Auto":"Manual"}},computed:{graphData:function(){var t=this.get("data.history");return Object.keys(t).map(function(e){return t[e].map(function(t,e){return{x:e,y:t}})})}}}}(r),r.exports.template={v:3,t:[" ",{p:[42,1,1035],t:7,e:"ui-display",a:{title:"Network"},f:[{t:4,f:[{p:[44,5,1093],t:7,e:"ui-linegraph",a:{points:[{t:2,r:"graphData",p:[44,27,1115]}],height:"500",legend:'["Available", "Load"]',colors:'["rgb(0, 102, 0)", "rgb(153, 0, 0)"]',xunit:"seconds ago",xfactor:[{t:2,r:"data.interval",p:[46,38,1267]}],yunit:"W",yfactor:"1",xinc:[{t:2,x:{r:["data.stored"],s:"_0/10"},p:[47,15,1323]}],yinc:"9"}}],n:50,r:"config.fancy",p:[43,3,1067]},{t:4,n:51,f:[{p:[49,5,1373],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[50,7,1411],t:7,e:"span",f:[{t:2,r:"data.supply",p:[50,13,1417]}," W"]}]}," ",{p:[52,5,1466],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[53,9,1501],t:7,e:"span",f:[{t:2,r:"data.demand",p:[53,15,1507]}," W"]}]}],r:"config.fancy"}]}," ",{p:[57,1,1578],t:7,e:"ui-display",a:{title:"Areas"},f:[{p:[58,3,1608],t:7,e:"ui-section",a:{nowrap:0},f:[{p:[59,5,1633],t:7,e:"div",a:{"class":"content"},f:["Area"]}," ",{p:[60,5,1670],t:7,e:"div",a:{"class":"content"},f:["Charge"]}," ",{p:[61,5,1709],t:7,e:"div",a:{"class":"content"},f:["Load"]}," ",{p:[62,5,1746],t:7,e:"div",a:{"class":"content"},f:["Status"]}," ",{p:[63,5,1785],t:7,e:"div",a:{"class":"content"},f:["Equipment"]}," ",{p:[64,5,1827],t:7,e:"div",a:{"class":"content"},f:["Lighting"]}," ",{p:[65,5,1868],t:7,e:"div",a:{"class":"content"},f:["Environment"]}]}," ",{t:4,f:[{p:[68,5,1953],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[68,24,1972]}],nowrap:0},f:[{p:[69,7,1997],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].charge)"},p:[69,28,2018]}," %"]}," ",{p:[70,7,2076],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].load)"},p:[70,28,2097]}," W"]}," ",{p:[71,7,2153],t:7,e:"div",a:{"class":"content"},f:[{p:[71,28,2174],t:7,e:"span",a:{"class":[{t:2,x:{r:["chargingState","charging"],s:"_0(_1)"},p:[71,41,2187]}]},f:[{t:2,x:{r:["chargingMode","charging"],s:"_0(_1)"},p:[71,70,2216]}]}]}," ",{p:[72,7,2263],t:7,e:"div",a:{"class":"content"},f:[{p:[72,28,2284],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","eqp"],s:"_0(_1)"},p:[72,41,2297]}]},f:[{t:2,x:{r:["channelPower","eqp"],s:"_0(_1)"},p:[72,64,2320]}," [",{p:[72,87,2343],t:7,e:"span",f:[{t:2,x:{r:["channelMode","eqp"],s:"_0(_1)"},p:[72,93,2349]}]},"]"]}]}," ",{p:[73,7,2398],t:7,e:"div",a:{"class":"content"},f:[{p:[73,28,2419],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","lgt"],s:"_0(_1)"},p:[73,41,2432]}]},f:[{t:2,x:{r:["channelPower","lgt"],s:"_0(_1)"},p:[73,64,2455]}," [",{p:[73,87,2478],t:7,e:"span",f:[{t:2,x:{r:["channelMode","lgt"],s:"_0(_1)"},p:[73,93,2484]}]},"]"]}]}," ",{p:[74,7,2533],t:7,e:"div",a:{"class":"content"},f:[{p:[74,28,2554],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","env"],s:"_0(_1)"},p:[74,41,2567]}]},f:[{t:2,x:{r:["channelPower","env"],s:"_0(_1)"},p:[74,64,2590]}," [",{p:[74,87,2613],t:7,e:"span",f:[{t:2,x:{r:["channelMode","env"],s:"_0(_1)"},p:[74,93,2619]}]},"]"]}]}]}],n:52,r:"data.areas",p:[67,3,1927]}]}]},e.exports=a.extend(r.exports)},{205:205}],288:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{readableFrequency:function(){return Math.round(this.get("adata.frequency"))/10}}}}(r),r.exports.template={v:3,t:[" ",{p:[11,1,177],t:7,e:"ui-display",a:{title:"Settings"},f:[{t:4,f:[{p:[13,5,236],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,7,270],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.listening"],s:'_0?"power-off":"close"'},p:[14,24,287]}],style:[{t:2,x:{r:["data.listening"],s:'_0?"selected":null'},p:[14,75,338]}],action:"listen"},f:[{t:2,x:{r:["data.listening"],s:'_0?"On":"Off"'},p:[16,9,413]}]}]}],n:50,r:"data.headset",p:[12,3,210]},{t:4,n:51,f:[{p:[19,5,494],t:7,e:"ui-section",a:{label:"Microphone"},f:[{p:[20,7,533],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.broadcasting"],s:'_0?"power-off":"close"'},p:[20,24,550]}],style:[{t:2,x:{r:["data.broadcasting"],s:'_0?"selected":null'},p:[20,78,604]}],action:"broadcast"},f:[{t:2,x:{r:["data.broadcasting"],s:'_0?"Engaged":"Disengaged"'},p:[22,9,685]}]}]}," ",{p:[24,5,769],t:7,e:"ui-section",a:{label:"Speaker"},f:[{p:[25,7,805],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.listening"],s:'_0?"power-off":"close"'},p:[25,24,822]}],style:[{t:2,x:{r:["data.listening"],s:'_0?"selected":null'},p:[25,75,873]}],action:"listen"},f:[{t:2,x:{r:["data.listening"],s:'_0?"Engaged":"Disengaged"'},p:[27,9,948]}]}]}],r:"data.headset"}," ",{t:4,f:[{p:[31,5,1064],t:7,e:"ui-section",a:{label:"High Volume"},f:[{p:[32,7,1104],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.useCommand"],s:'_0?"power-off":"close"'},p:[32,24,1121]}],style:[{t:2,x:{r:["data.useCommand"],s:'_0?"selected":null'},p:[32,76,1173]}],action:"command"},f:[{t:2,x:{r:["data.useCommand"],s:'_0?"On":"Off"'},p:[34,9,1250]}]}]}],n:50,r:"data.command",p:[30,3,1038]}]}," ",{p:[38,1,1342],t:7,e:"ui-display",a:{title:"Channel"},f:[{p:[39,3,1374],t:7,e:"ui-section",a:{label:"Frequency"},f:[{t:4,f:[{p:[41,7,1439],t:7,e:"span",f:[{t:2,r:"readableFrequency",p:[41,13,1445]}]}],n:50,r:"data.freqlock",p:[40,5,1410]},{t:4,n:51,f:[{p:[43,7,1495],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.frequency","data.minFrequency"],s:'_0==_1?"disabled":null'},p:[43,46,1534]}],action:"frequency",params:'{"adjust": -1}'}}," ",{p:[44,7,1646],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.frequency","data.minFrequency"],s:'_0==_1?"disabled":null'},p:[44,41,1680]}],action:"frequency",params:'{"adjust": -.2}'}}," ",{p:[45,7,1793],t:7,e:"ui-button",a:{icon:"pencil",action:"frequency",params:'{"tune": "input"}'},f:[{t:2,r:"readableFrequency",p:[45,78,1864]}]}," ",{p:[46,7,1905],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.frequency","data.maxFrequency"],s:'_0==_1?"disabled":null'},p:[46,40,1938]}],action:"frequency",params:'{"adjust": .2}'}}," ",{p:[47,7,2050],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.frequency","data.maxFrequency"],s:'_0==_1?"disabled":null'},p:[47,45,2088]}],action:"frequency",params:'{"adjust": 1}'}}],r:"data.freqlock"}]}," ",{t:4,f:[{p:[51,5,2262],t:7,e:"ui-section",a:{label:"Subspace Transmission"},f:[{p:[52,7,2312],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.subspace"],s:'_0?"power-off":"close"'},p:[52,24,2329]}],style:[{t:2,x:{r:["data.subspace"],s:'_0?"selected":null'},p:[52,74,2379]}],action:"subspace"},f:[{t:2,x:{r:["data.subspace"],s:'_0?"Active":"Inactive"'},p:[53,29,2447]}]}]}],n:50,r:"data.subspaceSwitchable",p:[50,3,2225]}," ",{t:4,f:[{p:[57,5,2578],t:7,e:"ui-section",a:{label:"Channels"},f:[{t:4,f:[{p:[59,9,2656],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["."],s:'_0?"check-square-o":"square-o"'},p:[59,26,2673]}],style:[{t:2,x:{r:["."],s:'_0?"selected":null'},p:[60,18,2730]}],action:"channel",params:['{"channel": "',{t:2,r:"channel",p:[61,49,2806]},'"}']},f:[{t:2,r:"channel",p:[62,11,2833]}]},{p:[62,34,2856],t:7,e:"br"}],n:52,i:"channel",r:"data.channels",p:[58,7,2615]}]}],n:50,x:{r:["data.subspace","data.channels"],s:"_0&&_1"},p:[56,3,2534]}]}]},e.exports=a.extend(r.exports)},{205:205}],289:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,23],t:7,e:"ui-notice",f:[{t:2,r:"data.notice",p:[3,5,40]}]}],n:50,r:"data.notice",p:[1,1,0]},{p:[6,1,82],t:7,e:"ui-display",a:{title:"Satellite Network Control",button:0},f:[{t:4,f:[{p:[8,4,168],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[9,9,209],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[9,31,231]}]}," ",{p:[10,9,253],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"mode",p:[10,30,274]}]}," ",{p:[11,9,298],t:7,e:"div",a:{"class":"content"},f:[{p:[12,11,331],t:7,e:"ui-button",a:{action:"toggle",params:['{"id": "',{t:2,r:"id",p:[12,54,374]},'"}']},f:[{t:2,x:{r:["active"],s:'_0?"Deactivate":"Activate"'},p:[12,64,384]}]}]}]}],n:52,r:"data.satellites",p:[7,2,138]}]}," ",{t:4,f:[{p:[18,1,528],t:7,e:"ui-display",a:{title:"Station Shield Coverage"},f:[{p:[19,3,576],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.meteor_shield_coverage_max",p:[19,24,597]}],value:[{t:2,r:"data.meteor_shield_coverage",p:[19,68,641]}]},f:[{t:2,x:{r:["data.meteor_shield_coverage","data.meteor_shield_coverage_max"],s:"100*_0/_1"},p:[19,101,674]}," %"]}," ",{p:[20,1,758],t:7,e:"ui-display",f:[]}]}],n:50,r:"data.meteor_shield",p:[17,1,500]}]},e.exports=a.extend(r.exports)},{205:205}],290:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" "," "," ",{p:[5,1,200],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.tabs",p:[5,16,215]}]},f:[{p:[6,2,233],t:7,e:"tab",a:{name:"Status"},f:[{p:[7,3,256],t:7,e:"status"}]}," ",{p:[9,2,277],t:7,e:"tab",a:{name:"Templates"},f:[{p:[10,3,303],t:7,e:"templates"}]}," ",{p:[12,2,327],t:7,e:"tab",a:{name:"Modification"},f:[{t:4,f:[{p:[14,3,381],t:7,e:"modification"}],n:50,r:"data.selected",p:[13,3,356]}," ",{t:4,f:[{p:[17,3,437],t:7,e:"span",a:{"class":"bad"},f:["No shuttle selected."]}],n:50,x:{r:["data.selected"],s:"!_0"},p:[16,3,411]}]}]}]},r.exports.components=r.exports.components||{};var i={modification:t(291),templates:t(293),status:t(292)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,291:291,292:292,293:293}],291:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:["Selected: ",{t:2,r:"data.selected.name",p:[1,30,29]}]},f:[{t:4,f:[{p:[3,5,96],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.selected.description",p:[3,37,128]}]}],n:50,r:"data.selected.description",p:[2,3,57]}," ",{t:4,f:[{p:[6,5,224],t:7,e:"ui-section",a:{label:"Admin Notes"},f:[{t:2,r:"data.selected.admin_notes",p:[6,37,256]}]}],n:50,r:"data.selected.admin_notes",p:[5,3,185]}]}," ",{t:4,f:[{p:[11,3,361],t:7,e:"ui-display",a:{title:["Existing Shuttle: ",{t:2,r:"data.existing_shuttle.name",p:[11,40,398]}]},f:["Status: ",{t:2,r:"data.existing_shuttle.status",p:[12,13,444]}," ",{t:4,f:["(",{t:2,r:"data.existing_shuttle.timeleft",p:[14,8,526]},")"],n:50,r:"data.existing_shuttle.timer",p:[13,5,482]}," ",{p:[16,5,580],t:7,e:"ui-button",a:{action:"jump_to",params:['{"type": "mobile", "id": "',{t:2,r:"data.existing_shuttle.id",p:[17,41,649]},'"}']},f:["Jump To"]}]}],n:50,r:"data.existing_shuttle",p:[10,1,328]},{t:4,f:[{p:[24,3,778],t:7,e:"ui-display",a:{title:"Existing Shuttle: None"}}],n:50,x:{r:["data.existing_shuttle"],s:"!_0"},p:[23,1,744]},{p:[27,1,847],t:7,e:"ui-button",a:{action:"preview",params:['{"shuttle_id": "',{t:2,r:"data.selected.shuttle_id",p:[28,27,902]},'"}']},f:["Preview"]}," ",{p:[31,1,961],t:7,e:"ui-button",a:{action:"load",params:['{"shuttle_id": "',{t:2,r:"data.selected.shuttle_id",p:[32,27,1013]},'"}'],style:"danger"},f:["Load"]}," ",{p:[37,1,1089],t:7,e:"ui-display",a:{title:"Status"},f:[]}]},e.exports=a.extend(r.exports)},{205:205}],292:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,27],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[2,22,46]}," (",{t:2,r:"id",p:[2,32,56]},")"]},f:[{t:2,r:"status",p:[3,5,71]}," ",{t:4,f:["(",{t:2,r:"timeleft",p:[5,8,109]},")"],n:50,r:"timer",p:[4,5,87]}," ",{p:[7,5,141],t:7,e:"ui-button",a:{action:"jump_to",params:['{"type": "mobile", "id": "',{t:2,r:"id",p:[7,67,203]},'"}']},f:["Jump To"]}," ",{p:[10,5,252],t:7,e:"ui-button",a:{action:"fast_travel",params:['{"id": "',{t:2,r:"id",p:[10,53,300]},'"}'],state:[{t:2,x:{r:["can_fast_travel"],s:'_0?null:"disabled"'},p:[10,70,317]}]},f:["Fast Travel"]}]}],n:52,r:"data.shuttles",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],293:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.templates_tabs",p:[1,16,15]}]},f:[{t:4,f:[{p:[3,5,74],t:7,e:"tab",a:{name:[{t:2,r:"port_id",p:[3,16,85]}]},f:[{t:4,f:[{p:[5,9,135],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[5,28,154]}]},f:[{t:4,f:[{p:[7,13,209],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"description",p:[7,45,241]}]}],n:50,r:"description",p:[6,11,176]}," ",{t:4,f:[{p:[10,13,333],t:7,e:"ui-section",a:{label:"Admin Notes"},f:[{t:2,r:"admin_notes",p:[10,45,365]}]}],n:50,r:"admin_notes",p:[9,11,300]}," ",{p:[13,11,426],t:7,e:"ui-button",a:{action:"select_template",params:['{"shuttle_id": "',{t:2,r:"shuttle_id",p:[14,37,499]},'"}'],state:[{t:2,x:{r:["data.selected.shuttle_id","shuttle_id"],s:'_0==_1?"selected":null'},p:[15,20,537]}]},f:[{t:2,x:{r:["data.selected.shuttle_id","shuttle_id"],s:'_0==_1?"Selected":"Select"'},p:[17,13,630]}]}]}],n:52,r:"templates",p:[4,7,106]}]}],n:52,r:"data.templates",p:[2,3,44]}]}]},e.exports=a.extend(r.exports)},{205:205}],294:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{occupantStatState:function(){switch(this.get("data.occupant.stat")){case 0:return"good";case 1:return"average";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[15,1,280],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[16,3,313],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[17,3,346],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[17,9,352]}]}]}," ",{t:4,f:[{p:[20,5,466],t:7,e:"ui-section",a:{label:"State"},f:[{p:[21,7,500],t:7,e:"span",a:{"class":[{t:2,r:"occupantStatState",p:[21,20,513]}]},f:[{t:2,x:{r:["data.occupant.stat"],s:'_0==0?"Conscious":_0==1?"Unconcious":"Dead"'},p:[21,43,536]}]}]}," ",{p:[23,5,658],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[24,7,693],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[24,20,706]}],max:[{t:2,r:"data.occupant.maxHealth",p:[24,54,740]}],value:[{t:2,r:"data.occupant.health",p:[24,90,776]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[25,16,818]}]},f:[{t:2,x:{r:["adata.occupant.health"],s:"Math.round(_0)"},p:[25,68,870]}]}]}," ",{t:4,f:[{p:[28,7,1107],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[28,26,1126]}]},f:[{p:[29,9,1147],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[29,30,1168]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[29,66,1204]}],state:"bad"},f:[{t:2,x:{r:["type","adata.occupant"],s:"Math.round(_1[_0])"},p:[29,103,1241]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[27,5,941]}," ",{p:[32,5,1328],t:7,e:"ui-section",a:{label:"Cells"},f:[{p:[33,9,1364],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"bad":"good"'},p:[33,22,1377]}]},f:[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"Damaged":"Healthy"'},p:[33,68,1423]}]}]}," ",{p:[35,5,1506],t:7,e:"ui-section",a:{label:"Brain"},f:[{p:[36,9,1542],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"bad":"good"'},p:[36,22,1555]}]},f:[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"Abnormal":"Healthy"'},p:[36,68,1601]}]}]}," ",{p:[38,5,1685],t:7,e:"ui-section",a:{label:"Bloodstream"},f:[{t:4,f:[{p:[40,11,1772],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,1)"},p:[40,54,1815]}," units of ",{t:2,r:"name",p:[40,89,1850]}]},{p:[40,104,1865],t:7,e:"br"}],n:52,r:"adata.occupant.reagents",p:[39,9,1727]},{t:4,n:51,f:[{p:[42,11,1900],t:7,e:"span",a:{"class":"good"},f:["Pure"]}],r:"adata.occupant.reagents"}]}],n:50,r:"data.occupied",p:[19,3,439]}]}," ",{p:[47,1,1996],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[48,2,2028],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[49,5,2059],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"unlock":"lock"'},p:[49,22,2076]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Open":"Closed"'},p:[49,71,2125]}]}]}," ",{p:[51,3,2190],t:7,e:"ui-section",a:{label:"Inject"},f:[{t:4,f:[{p:[53,7,2251],t:7,e:"ui-button",a:{icon:"flask",state:[{t:2,x:{r:["data.occupied","allowed"],s:'_0&&_1?null:"disabled"'},p:[53,38,2282]}],action:"inject",params:['{"chem": "',{t:2,r:"id",p:[53,122,2366]},'"}']},f:[{t:2,r:"name",p:[53,132,2376]}]},{p:[53,152,2396],t:7,e:"br"}],n:52,r:"data.chems",p:[52,5,2223]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],295:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,25],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[2,22,44]}],labelcolor:[{t:2,r:"htmlcolor",p:[2,44,66]}],candystripe:0,right:0},f:[{p:[3,5,105],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[3,32,132],t:7,e:"span",a:{"class":[{t:2,x:{r:["status"],s:'_0=="Dead"?"bad bold":_0=="Unconscious"?"average bold":"good"'},p:[3,45,145]}]},f:[{t:2,r:"status",p:[3,132,232]}]}]}," ",{p:[4,5,268],t:7,e:"ui-section",a:{label:"Jelly"},f:[{t:2,r:"exoticblood",p:[4,31,294]}]}," ",{p:[5,5,328],t:7,e:"ui-section",a:{label:"Location"},f:[{t:2,r:"area",p:[5,34,357]}]}," ",{p:[7,5,386],t:7,e:"ui-button",a:{state:[{t:2,r:"swap_button_state",p:[8,14,411]}],action:"swap",params:['{"ref": "',{t:2,r:"ref",p:[9,38,472]},'"}']},f:[{t:2,x:{r:["is_current"],s:'_0?"You Are Here":"Swap"'},p:[10,7,491]}]}]}],n:52,r:"data.bodies",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],296:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{capacityPercentState:function(){var t=this.get("data.capacityPercent");return t>50?"good":t>15?"average":"bad"},inputState:function(){return this.get("data.capacityPercent")>=100?"good":this.get("data.inputting")?"average":"bad"},outputState:function(){return this.get("data.outputting")?"good":this.get("data.charge")>0?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[24,1,663],t:7,e:"ui-display",a:{title:"Storage"},f:[{p:[25,3,695],t:7,e:"ui-section",a:{label:"Stored Energy"},f:[{p:[26,5,735],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.capacityPercent",p:[26,38,768]}],state:[{t:2,r:"capacityPercentState",p:[26,71,801]}]},f:[{t:2,x:{r:["adata.capacityPercent"],s:"Math.fixed(_0)"},p:[26,97,827]},"%"]}]}]}," ",{p:[29,1,908],t:7,e:"ui-display",a:{title:"Input"},f:[{p:[30,3,938],t:7,e:"ui-section",a:{label:"Charge Mode"},f:[{p:[31,5,976],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"refresh":"close"'},p:[31,22,993]}],style:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"selected":null'},p:[31,74,1045]}],action:"tryinput"},f:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"Auto":"Off"'},p:[32,25,1113]}]},"   [",{p:[34,6,1182],t:7,e:"span",a:{"class":[{t:2,r:"inputState",p:[34,19,1195]}]},f:[{t:2,x:{r:["data.capacityPercent","data.inputting"],s:'_0>=100?"Fully Charged":_1?"Charging":"Not Charging"'},p:[34,35,1211]}]},"]"]}," ",{p:[36,3,1335],t:7,e:"ui-section",a:{label:"Target Input"},f:[{p:[37,5,1374],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.inputLevelMax",p:[37,26,1395]}],value:[{t:2,r:"data.inputLevel",p:[37,57,1426]}]},f:[{t:2,x:{r:["adata.inputLevel"],s:"Math.round(_0)"},p:[37,78,1447]},"W"]}]}," ",{p:[39,3,1509],t:7,e:"ui-section",a:{label:"Adjust Input"},f:[{p:[40,5,1548],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.inputLevel"],s:'_0==0?"disabled":null'},p:[40,44,1587]}],action:"input",params:'{"target": "min"}'}}," ",{p:[41,5,1682],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.inputLevel"],s:'_0==0?"disabled":null'},p:[41,39,1716]}],action:"input",params:'{"adjust": -10000}'}}," ",{p:[42,5,1812],t:7,e:"ui-button",a:{icon:"pencil",action:"input",params:'{"target": "input"}'},f:["Set"]}," ",{p:[43,5,1902],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.inputLevel","data.inputLevelMax"],s:'_0==_1?"disabled":null'},p:[43,38,1935]}],action:"input",params:'{"adjust": 10000}'}}," ",{p:[44,5,2047],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.inputLevel","data.inputLevelMax"],s:'_0==_1?"disabled":null'},p:[44,43,2085]}],action:"input",params:'{"target": "max"}'}}]}," ",{p:[46,3,2212],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[47,3,2246],t:7,e:"span",f:[{t:2,x:{r:["adata.inputAvailable"],s:"Math.round(_0)"},p:[47,9,2252]},"W"]}]}]}," ",{p:[50,1,2329],t:7,e:"ui-display",a:{title:"Output"},f:[{p:[51,3,2360],t:7,e:"ui-section",a:{label:"Output Mode"},f:[{p:[52,5,2398],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"power-off":"close"'},p:[52,22,2415]}],style:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"selected":null'},p:[52,77,2470]}],action:"tryoutput"},f:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"On":"Off"'},p:[53,26,2540]}]},"   [",{p:[55,6,2608],t:7,e:"span",a:{"class":[{t:2,r:"outputState",p:[55,19,2621]}]},f:[{t:2,x:{r:["data.outputting","data.charge"],s:'_0?"Sending":_1>0?"Not Sending":"No Charge"'},p:[55,36,2638]}]},"]"]}," ",{p:[57,3,2745],t:7,e:"ui-section",a:{label:"Target Output"},f:[{p:[58,5,2785],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.outputLevelMax",p:[58,26,2806]}],value:[{t:2,r:"data.outputLevel",p:[58,58,2838]}]},f:[{t:2,x:{r:["adata.outputLevel"],s:"Math.round(_0)"},p:[58,80,2860]},"W"]}]}," ",{p:[60,3,2923],t:7,e:"ui-section",a:{label:"Adjust Output"},f:[{p:[61,5,2963],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.outputLevel"],s:'_0==0?"disabled":null'},p:[61,44,3002]}],action:"output",params:'{"target": "min"}'}}," ",{p:[62,5,3099],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.outputLevel"],s:'_0==0?"disabled":null'},p:[62,39,3133]}],action:"output",params:'{"adjust": -10000}'}}," ",{p:[63,5,3231],t:7,e:"ui-button",a:{icon:"pencil",action:"output",params:'{"target": "input"}'},f:["Set"]}," ",{p:[64,5,3322],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.outputLevel","data.outputLevelMax"],s:'_0==_1?"disabled":null'},p:[64,38,3355]}],action:"output",params:'{"adjust": 10000}'}}," ",{p:[65,5,3470],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.outputLevel","data.outputLevelMax"],s:'_0==_1?"disabled":null'},p:[65,43,3508]}],action:"output",params:'{"target": "max"}'}}]}," ",{p:[67,3,3638],t:7,e:"ui-section",a:{label:"Outputting"},f:[{p:[68,3,3673],t:7,e:"span",f:[{t:2,x:{r:["adata.outputUsed"],s:"Math.round(_0)"},p:[68,9,3679]},"W"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],297:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,3,31],t:7,e:"ui-section",a:{label:"Generated Power"},f:[{t:2,x:{r:["adata.generated"],s:"Math.round(_0)"},p:[3,5,73]},"W"]}," ",{p:[5,3,126],t:7,e:"ui-section",a:{label:"Orientation"},f:[{p:[6,5,164],t:7,e:"span",f:[{t:2,x:{r:["adata.angle"],s:"Math.round(_0)"},p:[6,11,170]},"° (",{t:2,r:"data.direction",p:[6,45,204]},")"]}]}," ",{p:[8,3,251],t:7,e:"ui-section",a:{label:"Adjust Angle"},f:[{p:[9,5,290],t:7,e:"ui-button",a:{icon:"step-backward",action:"angle",params:'{"adjust": -15}'},f:["15°"]}," ",{p:[10,5,387],t:7,e:"ui-button",a:{icon:"backward",action:"angle",params:'{"adjust": -5}'},f:["5°"]}," ",{p:[11,5,477],t:7,e:"ui-button",a:{icon:"forward",action:"angle",params:'{"adjust": 5}'},f:["5°"]}," ",{p:[12,5,565],t:7,e:"ui-button",a:{icon:"step-forward",action:"angle",params:'{"adjust": 15}'},f:["15°"]}]}]}," ",{p:[15,1,687],t:7,e:"ui-display",a:{title:"Tracking"},f:[{p:[16,3,720],t:7,e:"ui-section",a:{label:"Tracker Mode"},f:[{p:[17,5,759],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.tracking_state"],s:'_0==0?"selected":null'},p:[17,36,790]}],action:"tracking",params:'{"mode": 0}'},f:["Off"]}," ",{p:[19,5,907],t:7,e:"ui-button",a:{icon:"clock-o",state:[{t:2,x:{r:["data.tracking_state"],s:'_0==1?"selected":null'},p:[19,38,940]}],action:"tracking",params:'{"mode": 1}'},f:["Timed"]}," ",{p:[21,5,1059],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.connected_tracker","data.tracking_state"],s:'_0?_1==2?"selected":null:"disabled"'},p:[21,38,1092]}],action:"tracking",params:'{"mode": 2}'},f:["Auto"]}]}," ",{p:[24,3,1262],t:7,e:"ui-section",a:{label:"Tracking Rate"},f:[{p:[25,3,1300],t:7,e:"span",f:[{t:2,x:{r:["adata.tracking_rate"],s:"Math.round(_0)"},p:[25,9,1306]},"°/h (",{t:2,r:"data.rotating_way",p:[25,53,1350]},")"]}]}," ",{p:[27,3,1399],t:7,e:"ui-section",a:{label:"Adjust Rate"},f:[{p:[28,5,1437],t:7,e:"ui-button",a:{icon:"fast-backward",action:"rate",params:'{"adjust": -180}'},f:["180°"]}," ",{p:[29,5,1535],t:7,e:"ui-button",a:{icon:"step-backward",action:"rate",params:'{"adjust": -30}'},f:["30°"]}," ",{p:[30,5,1631],t:7,e:"ui-button",a:{icon:"backward",action:"rate",params:'{"adjust": -5}'},f:["5°"]}," ",{p:[31,5,1720],t:7,e:"ui-button",a:{icon:"forward",action:"rate",params:'{"adjust": 5}'},f:["5°"]}," ",{p:[32,5,1807],t:7,e:"ui-button",a:{icon:"step-forward",action:"rate",params:'{"adjust": 30}'},f:["30°"]}," ",{p:[33,5,1901],t:7,e:"ui-button",a:{icon:"fast-forward",action:"rate",params:'{"adjust": 180}'},f:["180°"]}]}]}," ",{p:{button:[{p:[38,5,2088],t:7,e:"ui-button",a:{icon:"refresh",action:"refresh"},f:["Refresh"]}]},t:7,e:"ui-display",a:{title:"Devices",button:0},f:[" ",{p:[40,2,2169],t:7,e:"ui-section",a:{label:"Solar Tracker"},f:[{p:[41,5,2209],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected_tracker"],s:'_0?"good":"bad"'},p:[41,18,2222]}]},f:[{t:2,x:{r:["data.connected_tracker"],s:'_0?"":"Not "'},p:[41,63,2267]},"Found"]}]}," ",{p:[43,2,2338],t:7,e:"ui-section",a:{label:"Solar Panels"},f:[{p:[44,3,2375],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected_panels"],s:'_0?"good":"bad"'},p:[44,16,2388]}]},f:[{t:2,x:{r:["adata.connected_panels"],s:"Math.round(_0)"},p:[44,60,2432]}," Panels Connected"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],298:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{t:4,f:[{p:[4,7,87],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.hasPowercell"],s:'_0?null:"disabled"'},p:[4,38,118]}],action:"eject"},f:["Eject"]}],n:50,r:"data.open",p:[3,5,62]}]},t:7,e:"ui-display",a:{title:"Power",button:0},f:[" ",{p:[7,3,226],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[8,5,258],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[8,22,275]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[9,14,326]}],state:[{t:2,x:{r:["data.hasPowercell"],s:'_0?null:"disabled"'},p:[9,54,366]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[10,22,431]}]}]}," ",{p:[12,3,490],t:7,e:"ui-section",a:{label:"Cell"},f:[{t:4,f:[{p:[14,7,554],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.powerLevel",p:[14,40,587]}]},f:[{t:2,x:{r:["adata.powerLevel"],s:"Math.fixed(_0)"},p:[14,61,608]},"%"]}],n:50,r:"data.hasPowercell",p:[13,5,521]},{t:4,n:51,f:[{p:[16,4,667],t:7,e:"span",a:{"class":"bad"},f:["No Cell"]}],r:"data.hasPowercell"}]}]}," ",{p:[20,1,744],t:7,e:"ui-display",a:{title:"Thermostat"},f:[{p:[21,3,779],t:7,e:"ui-section",a:{label:"Current Temperature"},f:[{p:[22,3,823],t:7,e:"span",f:[{t:2,x:{r:["adata.currentTemp"],s:"Math.round(_0)"},p:[22,9,829]},"°C"]}]}," ",{p:[24,2,894],t:7,e:"ui-section",a:{label:"Target Temperature"},f:[{p:[25,3,937],t:7,e:"span",f:[{t:2,x:{r:["adata.targetTemp"],s:"Math.round(_0)"},p:[25,9,943]},"°C"]}]}," ",{t:4,f:[{p:[28,5,1031],t:7,e:"ui-section",a:{label:"Adjust Target"},f:[{p:[29,7,1073],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.targetTemp","data.minTemp"],s:'_0>_1?null:"disabled"'},p:[29,46,1112]}],action:"target",params:'{"adjust": -20}'}}," ",{p:[30,7,1218],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.targetTemp","data.minTemp"],s:'_0>_1?null:"disabled"'},p:[30,41,1252]}],action:"target",params:'{"adjust": -5}'}}," ",{p:[31,7,1357],t:7,e:"ui-button",a:{icon:"pencil",action:"target",params:'{"target": "input"}'},f:["Set"]}," ",{p:[32,7,1450],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.targetTemp","data.maxTemp"],s:'_0<_1?null:"disabled"'},p:[32,40,1483]}],action:"target",params:'{"adjust": 5}'}}," ",{p:[33,7,1587],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.targetTemp","data.maxTemp"],s:'_0<_1?null:"disabled"'},p:[33,45,1625]}],action:"target",params:'{"adjust": 20}'}}]}],n:50,r:"data.open",p:[27,3,1008]}," ",{p:[36,3,1754],t:7,e:"ui-section",a:{label:"Mode"},f:[{t:4,f:[{p:[38,7,1808],t:7,e:"ui-button",a:{icon:"long-arrow-up",state:[{t:2,x:{r:["data.mode"],s:'_0=="heat"?"selected":null'},p:[38,46,1847]}],action:"mode",params:'{"mode": "heat"}'},f:["Heat"]}," ",{p:[39,7,1956],t:7,e:"ui-button",a:{icon:"long-arrow-down",state:[{t:2,x:{r:["data.mode"],s:'_0=="cool"?"selected":null'},p:[39,48,1997]}],action:"mode",params:'{"mode": "cool"}'},f:["Cool"]}," ",{p:[40,7,2106],t:7,e:"ui-button",a:{icon:"arrows-v",state:[{t:2,x:{r:["data.mode"],s:'_0=="auto"?"selected":null'},p:[40,41,2140]}],action:"mode",params:'{"mode": "auto"}'},f:["Auto"]}],n:50,r:"data.open",p:[37,3,1783]},{t:4,n:51,f:[{p:[42,4,2258],t:7,e:"span",f:[{t:2,x:{r:["text","data.mode"],s:"_0.titleCase(_1)"},p:[42,10,2264]}]}],r:"data.open"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],299:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,31],t:7,e:"ui-display",a:{title:[{t:2,r:"class",p:[2,22,50]}," Alarms"]},f:[{p:[3,5,74],t:7,e:"ul",f:[{t:4,f:[{p:[5,9,107],t:7,e:"li",f:[{t:2,r:".",p:[5,13,111]}]}],n:52,r:".",p:[4,7,86]},{t:4,n:51,f:[{p:[7,9,147],t:7,e:"li",f:["System Nominal"]}],r:"."}]}]}],n:52,i:"class",r:"data.alarms",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],300:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,42],t:7,e:"ui-notice",f:[{p:[3,5,59],t:7,e:"span",f:["Biological entity detected in contents. Please remove."]}]}],n:50,x:{r:["data.occupied","data.safeties"],s:"_0&&_1"},p:[1,1,0]},{t:4,f:[{p:[7,3,179],t:7,e:"ui-notice",f:[{p:[8,5,196],t:7,e:"span",f:["Contents are being disinfected. Please wait."]}]}],n:50,r:"data.uv_active",p:[6,1,153]},{t:4,n:51,f:[{p:{button:[{t:4,f:[{p:[13,25,369],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[13,42,386] - }],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Unlock":"Lock"'},p:[13,93,437]}]}],n:50,x:{r:["data.open"],s:"!_0"},p:[13,7,351]}," ",{t:4,f:[{p:[14,27,519],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"sign-out":"sign-in"'},p:[14,44,536]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Close":"Open"'},p:[14,98,590]}]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[14,7,499]}]},t:7,e:"ui-display",a:{title:"Storage",button:0},f:[" ",{t:4,f:[{p:[17,7,692],t:7,e:"ui-notice",f:[{p:[18,9,713],t:7,e:"span",f:["Unit Locked"]}]}],n:50,r:"data.locked",p:[16,5,665]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.open"],s:"_0"},f:[{p:[21,9,793],t:7,e:"ui-section",a:{label:"Helmet"},f:[{p:[22,11,832],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.helmet"],s:'_0?"square":"square-o"'},p:[22,28,849]}],state:[{t:2,x:{r:["data.helmet"],s:'_0?null:"disabled"'},p:[22,75,896]}],action:"dispense",params:'{"item": "helmet"}'},f:[{t:2,x:{r:["data.helmet"],s:'_0||"Empty"'},p:[23,59,992]}]}]}," ",{p:[25,9,1063],t:7,e:"ui-section",a:{label:"Suit"},f:[{p:[26,11,1100],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.suit"],s:'_0?"square":"square-o"'},p:[26,28,1117]}],state:[{t:2,x:{r:["data.suit"],s:'_0?null:"disabled"'},p:[26,74,1163]}],action:"dispense",params:'{"item": "suit"}'},f:[{t:2,x:{r:["data.suit"],s:'_0||"Empty"'},p:[27,57,1255]}]}]}," ",{p:[29,9,1324],t:7,e:"ui-section",a:{label:"Mask"},f:[{p:[30,11,1361],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mask"],s:'_0?"square":"square-o"'},p:[30,28,1378]}],state:[{t:2,x:{r:["data.mask"],s:'_0?null:"disabled"'},p:[30,74,1424]}],action:"dispense",params:'{"item": "mask"}'},f:[{t:2,x:{r:["data.mask"],s:'_0||"Empty"'},p:[31,57,1516]}]}]}," ",{p:[33,9,1585],t:7,e:"ui-section",a:{label:"Storage"},f:[{p:[34,11,1625],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.storage"],s:'_0?"square":"square-o"'},p:[34,28,1642]}],state:[{t:2,x:{r:["data.storage"],s:'_0?null:"disabled"'},p:[34,77,1691]}],action:"dispense",params:'{"item": "storage"}'},f:[{t:2,x:{r:["data.storage"],s:'_0||"Empty"'},p:[35,60,1789]}]}]}]},{t:4,n:50,x:{r:["data.open"],s:"!(_0)"},f:[" ",{p:[38,7,1873],t:7,e:"ui-button",a:{icon:"recycle",state:[{t:2,x:{r:["data.occupied","data.safeties"],s:'_0&&_1?"disabled":null'},p:[38,40,1906]}],action:"uv"},f:["Disinfect"]}]}],r:"data.locked"}]}],r:"data.uv_active"}]},e.exports=a.extend(r.exports)},{205:205}],301:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,5,18],t:7,e:"ui-section",a:{label:"Dispense"},f:[{p:[3,9,57],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.plasma"],s:'_0?"square":"square-o"'},p:[3,26,74]}],state:[{t:2,x:{r:["data.plasma"],s:'_0?null:"disabled"'},p:[3,74,122]}],action:"plasma"},f:["Plasma (",{t:2,x:{r:["adata.plasma"],s:"Math.round(_0)"},p:[4,37,196]},")"]}," ",{p:[5,9,247],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.oxygen"],s:'_0?"square":"square-o"'},p:[5,26,264]}],state:[{t:2,x:{r:["data.oxygen"],s:'_0?null:"disabled"'},p:[5,74,312]}],action:"oxygen"},f:["Oxygen (",{t:2,x:{r:["adata.oxygen"],s:"Math.round(_0)"},p:[6,37,386]},")"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],302:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{tankPressureState:function(){var t=this.get("data.tankPressure");return t>=200?"good":t>=100?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[14,1,295],t:7,e:"ui-notice",f:[{p:[15,3,310],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.connected"],s:'_0?"is":"is not"'},p:[15,23,330]}," connected to a mask."]}]}," ",{p:[17,1,409],t:7,e:"ui-display",f:[{p:[18,3,425],t:7,e:"ui-section",a:{label:"Tank Pressure"},f:[{p:[19,7,467],t:7,e:"ui-bar",a:{min:"0",max:"1013",value:[{t:2,r:"data.tankPressure",p:[19,41,501]}],state:[{t:2,r:"tankPressureState",p:[20,16,540]}]},f:[{t:2,x:{r:["adata.tankPressure"],s:"Math.round(_0)"},p:[20,39,563]}," kPa"]}]}," ",{p:[22,3,631],t:7,e:"ui-section",a:{label:"Release Pressure"},f:[{p:[23,5,674],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.minReleasePressure",p:[23,18,687]}],max:[{t:2,r:"data.maxReleasePressure",p:[23,52,721]}],value:[{t:2,r:"data.releasePressure",p:[24,14,764]}]},f:[{t:2,x:{r:["adata.releasePressure"],s:"Math.round(_0)"},p:[24,40,790]}," kPa"]}]}," ",{p:[26,3,861],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[27,5,906],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.releasePressure","data.defaultReleasePressure"],s:'_0!=_1?null:"disabled"'},p:[27,38,939]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[29,5,1095],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.releasePressure","data.minReleasePressure"],s:'_0>_1?null:"disabled"'},p:[29,36,1126]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[31,5,1273],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[32,5,1368],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.releasePressure","data.maxReleasePressure"],s:'_0<_1?null:"disabled"'},p:[32,35,1398]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],303:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,5,33],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[3,9,75],t:7,e:"span",f:[{t:2,x:{r:["adata.temperature"],s:"Math.fixed(_0,2)"},p:[3,15,81]}," K"]}]}," ",{p:[5,5,151],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,9,190],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.fixed(_0,2)"},p:[6,15,196]}," kPa"]}]}]}," ",{p:[9,1,276],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[10,5,311],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[11,9,347],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[11,26,364]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[11,70,408]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[12,28,469]}]}]}," ",{p:[14,5,531],t:7,e:"ui-section",a:{label:"Target Temperature"},f:[{p:[15,9,580],t:7,e:"ui-button",a:{icon:"fast-backward",style:[{t:2,x:{r:["data.target","data.min"],s:'_0==_1?"disabled":null'},p:[15,48,619]}],action:"target",params:'{"adjust": -20}'}}," ",{p:[17,9,733],t:7,e:"ui-button",a:{icon:"backward",style:[{t:2,x:{r:["data.target","data.min"],s:'_0==_1?"disabled":null'},p:[17,43,767]}],action:"target",params:'{"adjust": -5}'}}," ",{p:[19,9,880],t:7,e:"ui-button",a:{icon:"pencil",action:"target",params:'{"target": "input"}'},f:[{t:2,x:{r:["adata.target"],s:"Math.fixed(_0,2)"},p:[19,79,950]}]}," ",{p:[20,9,1003],t:7,e:"ui-button",a:{icon:"forward",style:[{t:2,x:{r:["data.target","data.max"],s:'_0==_1?"disabled":null'},p:[20,42,1036]}],action:"target",params:'{"adjust": 5}'}}," ",{p:[22,9,1148],t:7,e:"ui-button",a:{icon:"fast-forward",style:[{t:2,x:{r:["data.target","data.max"],s:'_0==_1?"disabled":null'},p:[22,47,1186]}],action:"target",params:'{"adjust": 20}'}}]}]}]},e.exports=a.extend(r.exports)},{205:205}],304:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{},oninit:function(){this.on({hover:function(t){var e=this.get("data.telecrystals");e>=t.context.params.cost&&this.set("hovered",t.context.params)},unhover:function(t){this.set("hovered")}})}}}(r),r.exports.template={v:3,t:[" ",{p:{button:[{t:4,f:[{p:[23,7,482],t:7,e:"ui-button",a:{icon:"lock",action:"lock"},f:["Lock"]}],n:50,r:"data.lockable",p:[22,5,453]}]},t:7,e:"ui-display",a:{title:"Uplink",button:0},f:[" ",{p:[26,3,568],t:7,e:"ui-section",a:{label:"Telecrystals",right:0},f:[{p:[27,5,613],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.telecrystals"],s:'_0>0?"good":"bad"'},p:[27,18,626]}]},f:[{t:2,r:"data.telecrystals",p:[27,62,670]}," TC"]}]}]}," ",{t:4,f:[{p:[31,3,764],t:7,e:"ui-display",f:[{p:[32,2,779],t:7,e:"ui-button",a:{action:"select",params:['{"category": "',{t:2,r:"name",p:[32,51,828]},'"}']},f:[{t:2,r:"name",p:[32,63,840]}]}," ",{t:4,f:[{p:[34,4,883],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[34,23,902]}],candystripe:0,right:0},f:[{p:[35,3,934],t:7,e:"ui-button",a:{tooltip:[{t:2,r:"name",p:[35,23,954]},": ",{t:2,r:"desc",p:[35,33,964]}],"tooltip-side":"left",state:[{t:2,x:{r:["data.telecrystals","hovered.cost","cost","hovered.item","name"],s:'_0<_2||(_0-_1<_2&&_3!=_4)?"disabled":null'},p:[36,12,1006]}],action:"buy",params:['{"category": "',{t:2,r:"category",p:[37,40,1165]},'", "item": ',{t:2,r:"name",p:[37,63,1188]},', "cost": ',{t:2,r:"cost",p:[37,81,1206]},"}"]},v:{hover:"hover",unhover:"unhover"},f:[{t:2,r:"cost",p:[38,43,1260]}," TC"]}]}],n:52,r:"items",p:[33,2,863]}]}],n:52,r:"data.categories",p:[30,1,735]}]},e.exports=a.extend(r.exports)},{205:205}],305:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{healthState:function(t){var e=this.get("data.vr_avatar.maxhealth");return t>e/1.5?"good":t>e/3?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[14,1,292],t:7,e:"ui-display",f:[{t:4,f:[{p:[16,3,333],t:7,e:"ui-display",a:{title:"Virtual Avatar"},f:[{p:[17,4,373],t:7,e:"ui-section",a:{label:"Name"},f:[{t:2,r:"data.vr_avatar.name",p:[18,5,404]}]}," ",{p:[20,4,450],t:7,e:"ui-section",a:{label:"Status"},f:[{t:2,r:"data.vr_avatar.status",p:[21,5,483]}]}," ",{p:[23,4,531],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[24,5,564],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.vr_avatar.maxhealth",p:[24,26,585]}],value:[{t:2,r:"adata.vr_avatar.health",p:[24,64,623]}],state:[{t:2,x:{r:["healthState","adata.vr_avatar.health"],s:"_0(_1)"},p:[24,99,658]}]},f:[{t:2,x:{r:["adata.vr_avatar.health"],s:"Math.round(_0)"},p:[24,140,699]},"/",{t:2,r:"adata.vr_avatar.maxhealth",p:[24,179,738]}]}]}]}],n:50,r:"data.vr_avatar",p:[15,2,307]},{t:4,n:51,f:[{p:[28,3,826],t:7,e:"ui-display",a:{title:"Virtual Avatar"},f:["No Virtual Avatar detected"]}],r:"data.vr_avatar"}," ",{p:[32,2,922],t:7,e:"ui-display",a:{title:"VR Commands"},f:[{p:[33,3,958],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.toggle_open"],s:'_0?"times":"plus"'},p:[33,20,975]}],action:"toggle_open"},f:[{t:2,x:{r:["data.toggle_open"],s:'_0?"Close":"Open"'},p:[34,4,1042]}," the VR Sleeper"]}," ",{t:4,f:[{p:[37,4,1144],t:7,e:"ui-button",a:{icon:"signal",action:"vr_connect"},f:["Connect to VR"]}],n:50,r:"data.isoccupant",p:[36,3,1116]}," ",{t:4,f:[{p:[42,4,1267],t:7,e:"ui-button",a:{icon:"ban",action:"delete_avatar"},f:["Delete Virtual Avatar"]}],n:50,r:"data.vr_avatar",p:[41,3,1240]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],306:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{t:4,f:[{p:[3,5,42],t:7,e:"ui-section",a:{label:[{t:2,r:"color",p:[3,24,61]},{t:2,x:{r:["wire"],s:'_0?" ("+_0+")":""'},p:[3,33,70]}],labelcolor:[{t:2,r:"color",p:[3,80,117]}],candystripe:0,right:0},f:[{p:[4,7,154],t:7,e:"ui-button",a:{action:"cut",params:['{"wire":"',{t:2,r:"color",p:[4,48,195]},'"}']},f:[{t:2,x:{r:["cut"],s:'_0?"Mend":"Cut"'},p:[4,61,208]}]}," ",{p:[5,7,252],t:7,e:"ui-button",a:{action:"pulse",params:['{"wire":"',{t:2,r:"color",p:[5,50,295]},'"}']},f:["Pulse"]}," ",{p:[6,7,333],t:7,e:"ui-button",a:{action:"attach",params:['{"wire":"',{t:2,r:"color",p:[6,51,377]},'"}']},f:[{t:2,x:{r:["attached"],s:'_0?"Detach":"Attach"'},p:[6,64,390]}]}]}],n:52,r:"data.wires",p:[2,3,16]}]}," ",{t:4,f:[{p:[11,3,508],t:7,e:"ui-display",f:[{t:4,f:[{p:[13,7,555],t:7,e:"ui-section",f:[{t:2,r:".",p:[13,19,567]}]}],n:52,r:"data.status",p:[12,5,526]}]}],n:50,r:"data.status",p:[10,1,485]}]},e.exports=a.extend(r.exports)},{205:205}],307:[function(t,e,n){(function(e){"use strict";var n=t(205),a=e.interopRequireDefault(n);t(194),t(1),t(190),t(193);var r=t(308),i=e.interopRequireDefault(r),o=t(309),s=t(191),u=t(192),p=e.interopRequireDefault(u);a["default"].DEBUG=/minified/.test(function(){}),Object.assign(Math,t(313)),window.initialize=function(e){window.tgui||(window.tgui=new i["default"]({el:"#container",data:function(){var n=JSON.parse(e);return{constants:t(310),text:t(314),config:n.config,data:n.data,adata:n.data}}}))};var c=document.getElementById("data"),l=c.textContent,f=c.getAttribute("data-ref");"{}"!==l&&(window.initialize(l),c.remove()),(0,o.act)(f,"tgui:initialize"),(0,s.loadCSS)("font-awesome.min.css");var d=new p["default"]("FontAwesome");d.check("").then(function(){return document.body.classList.add("icons")})["catch"](function(){return document.body.classList.add("no-icons")})}).call(this,t("babel/external-helpers"))},{1:1,190:190,191:191,192:192,193:193,194:194,205:205,308:308,309:309,310:310,313:313,314:314,"babel/external-helpers":"babel/external-helpers"}],308:[function(t,e,n){var a=t(205),r={exports:{}};!function(e){"use strict";var n=t(309),a=t(311);e.exports={components:{"ui-bar":t(206),"ui-button":t(207),"ui-display":t(208),"ui-input":t(209),"ui-linegraph":t(210),"ui-notice":t(211),"ui-section":t(213),"ui-subdisplay":t(214),"ui-tabs":t(215)},events:{enter:t(203).enter,space:t(203).space},transitions:{fade:t(204)},onconfig:function(){var e=this.get("config.interface"),n={airalarm:t(219),"airalarm/back":t(220),"airalarm/modes":t(221),"airalarm/scrubbers":t(222),"airalarm/status":t(223),"airalarm/thresholds":t(224),"airalarm/vents":t(225),airlock_electronics:t(226),apc:t(227),atmos_alert:t(228),atmos_control:t(229),atmos_filter:t(230),atmos_mixer:t(231),atmos_pump:t(232),brig_timer:t(233),bsa:t(234),canister:t(235),cargo:t(236),cellular_emporium:t(237),chem_dispenser:t(238),chem_heater:t(239),chem_master:t(240),clockwork_slab:t(241),codex_gigas:t(242),computer_fabricator:t(243),crayon:t(244),cryo:t(245),disposal_unit:t(246),dna_vault:t(247),eightball:t(248),emergency_shuttle_console:t(249),engraved_message:t(250),error:t(251),firealarm:t(252),gps:t(253),gulag_console:t(254),gulag_item_reclaimer:t(255),holodeck:t(256),implantchair:t(257),intellicard:t(258),keycard_auth:t(259),labor_claim_console:t(260),language_menu:t(261),launchpad_remote:t(262),mech_bay_power_console:t(263),mulebot:t(264),ntnet_relay:t(265),ntos_ai_restorer:t(266),ntos_card:t(267),ntos_configuration:t(268),ntos_file_manager:t(269),ntos_main:t(270),ntos_net_chat:t(271),ntos_net_dos:t(272),ntos_net_downloader:t(273),ntos_net_monitor:t(274),ntos_net_transfer:t(275),ntos_power_monitor:t(276),ntos_revelation:t(277),ntos_station_alert:t(278),ntos_supermatter_monitor:t(279),ntosheader:t(280),nuclear_bomb:t(281),ore_redemption_machine:t(282),pandemic:t(283),personal_crafting:t(284),portable_pump:t(285),portable_scrubber:t(286),power_monitor:t(287),radio:t(288),sat_control:t(289),shuttle_manipulator:t(290),"shuttle_manipulator/modification":t(291),"shuttle_manipulator/status":t(292),"shuttle_manipulator/templates":t(293),sleeper:t(294),slime_swap_body:t(295),smes:t(296),solar_control:t(297),space_heater:t(298),station_alert:t(299),suit_storage_unit:t(300),tank_dispenser:t(301),tanks:t(302),thermomachine:t(303),uplink:t(304),vr_sleeper:t(305),wires:t(306)};e in n?this.components["interface"]=n[e]:this.components["interface"]=n.error},oninit:function(){this.observe("config.style",function(t,e,n){t&&document.body.classList.add(t),e&&document.body.classList.remove(e)})},oncomplete:function(){if(this.get("config.locked")){var t=(0,a.lock)(window.screenLeft,window.screenTop),e=t.x,r=t.y;(0,n.winset)(this.get("config.window"),"pos",e+","+r)}(0,n.winset)("mapwindow.map","focus",!0)}}}(r),r.exports.template={v:3,t:[" "," "," "," ",{p:[56,1,1874],t:7,e:"titlebar",f:[{t:3,r:"config.title",p:[56,11,1884]}]}," ",{p:[57,1,1915],t:7,e:"main",f:[{p:[58,3,1925],t:7,e:"warnings"}," ",{p:[59,3,1940],t:7,e:"interface"}]}," ",{t:4,f:[{p:[62,3,1990],t:7,e:"resize"}],n:50,r:"config.titlebar",p:[61,1,1963]}]},r.exports.components=r.exports.components||{};var i={warnings:t(218),titlebar:t(217),resize:t(212)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{203:203,204:204,205:205,206:206,207:207,208:208,209:209,210:210,211:211,212:212,213:213,214:214,215:215,217:217,218:218,219:219,220:220,221:221,222:222,223:223,224:224,225:225,226:226,227:227,228:228,229:229,230:230,231:231,232:232,233:233,234:234,235:235,236:236,237:237,238:238,239:239,240:240,241:241,242:242,243:243,244:244,245:245,246:246,247:247,248:248,249:249,250:250,251:251,252:252,253:253,254:254,255:255,256:256,257:257,258:258,259:259,260:260,261:261,262:262,263:263,264:264,265:265,266:266,267:267,268:268,269:269,270:270,271:271,272:272,273:273,274:274,275:275,276:276,277:277,278:278,279:279,280:280,281:281,282:282,283:283,284:284,285:285,286:286,287:287,288:288,289:289,290:290,291:291,292:292,293:293,294:294,295:295,296:296,297:297,298:298,299:299,300:300,301:301,302:302,303:303,304:304,305:305,306:306,309:309,311:311}],309:[function(t,e,n){"use strict";function a(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return"byond://"+e+"?"+Object.keys(t).map(function(e){return o(e)+"="+o(t[e])}).join("&")}function r(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};window.location.href=a(Object.assign({src:t,action:e},n))}function i(t,e,n){var r;window.location.href=a((r={},r[t+"."+e]=n,r),"winset")}n.__esModule=!0,n.href=a,n.act=r,n.winset=i;var o=encodeURIComponent},{}],310:[function(t,e,n){"use strict";n.__esModule=!0;n.UI_INTERACTIVE=2,n.UI_UPDATE=1,n.UI_DISABLED=0,n.UI_CLOSE=-1},{}],311:[function(t,e,n){"use strict";function a(t,e){return 0>t?t=0:t+window.innerWidth>window.screen.availWidth&&(t=window.screen.availWidth-window.innerWidth),0>e?e=0:e+window.innerHeight>window.screen.availHeight&&(e=window.screen.availHeight-window.innerHeight),{x:t,y:e}}function r(t){if(t.preventDefault(),this.get("drag")){if(this.get("x")){var e=t.screenX-this.get("x")+window.screenLeft,n=t.screenY-this.get("y")+window.screenTop;if(this.get("config.locked")){var r=a(e,n);e=r.x,n=r.y}(0,s.winset)(this.get("config.window"),"pos",e+","+n)}this.set({x:t.screenX,y:t.screenY})}}function i(t,e){return t=Math.clamp(100,window.screen.width,t),e=Math.clamp(100,window.screen.height,e),{x:t,y:e}}function o(t){if(t.preventDefault(),this.get("resize")){if(this.get("x")){var e=t.screenX-this.get("x")+window.innerWidth,n=t.screenY-this.get("y")+window.innerHeight,a=i(e,n);e=a.x,n=a.y,(0,s.winset)(this.get("config.window"),"size",e+","+n)}this.set({x:t.screenX,y:t.screenY})}}n.__esModule=!0,n.lock=a,n.drag=r,n.sane=i,n.resize=o;var s=t(309)},{309:309}],312:[function(t,e,n){"use strict";function a(t,e){for(var n=t,a=Array.isArray(n),i=0,n=a?n:n[Symbol.iterator]();;){var o;if(a){if(i>=n.length)break;o=n[i++]}else{if(i=n.next(),i.done)break;o=i.value}var s=o;s.textContent.toLowerCase().includes(e)?(s.style.display="",r(s,e)):s.style.display="none"}}function r(t,e){for(var n=t.queryAll("section"),a=t.query("header").textContent.toLowerCase().includes(e),r=n,i=Array.isArray(r),o=0,r=i?r:r[Symbol.iterator]();;){var s;if(i){if(o>=r.length)break;s=r[o++]}else{if(o=r.next(),o.done)break;s=o.value}var u=s;a||u.textContent.toLowerCase().includes(e)?u.style.display="":u.style.display="none"}}n.__esModule=!0,n.filterMulti=a,n.filter=r},{}],313:[function(t,e,n){"use strict";function a(t,e,n){return Math.max(t,Math.min(n,e))}function r(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return+(Math.round(t+"e"+e)+"e-"+e)}n.__esModule=!0,n.clamp=a,n.fixed=r},{}],314:[function(t,e,n){"use strict";function a(t){return t[0].toUpperCase()+t.slice(1).toLowerCase()}function r(t){return t.replace(/\w\S*/g,a)}function i(t,e){for(t=""+t;t.length1){for(var u=Array(o),p=0;o>p;p++)u[p]=arguments[p+3];n.children=u}return{$$typeof:t,type:e,key:void 0===a?null:""+a,ref:null,props:n,_owner:null}}}(),e.asyncIterator=function(t){if("function"==typeof Symbol){if(Symbol.asyncIterator){var e=t[Symbol.asyncIterator];if(null!=e)return e.call(t)}if(Symbol.iterator)return t[Symbol.iterator]()}throw new TypeError("Object is not async iterable")},e.asyncGenerator=function(){function t(t){this.value=t}function e(e){function n(t,e){return new Promise(function(n,r){var s={key:t,arg:e,resolve:n,reject:r,next:null};o?o=o.next=s:(i=o=s,a(t,e))})}function a(n,i){try{var o=e[n](i),s=o.value;s instanceof t?Promise.resolve(s.value).then(function(t){a("next",t)},function(t){a("throw",t)}):r(o.done?"return":"normal",o.value)}catch(u){r("throw",u)}}function r(t,e){switch(t){case"return":i.resolve({value:e,done:!0});break;case"throw":i.reject(e);break;default:i.resolve({value:e,done:!1})}i=i.next,i?a(i.key,i.arg):o=null}var i,o;this._invoke=n,"function"!=typeof e["return"]&&(this["return"]=void 0)}return"function"==typeof Symbol&&Symbol.asyncIterator&&(e.prototype[Symbol.asyncIterator]=function(){return this}),e.prototype.next=function(t){return this._invoke("next",t)},e.prototype["throw"]=function(t){return this._invoke("throw",t)},e.prototype["return"]=function(t){return this._invoke("return",t)},{wrap:function(t){return function(){return new e(t.apply(this,arguments))}},await:function(e){return new t(e)}}}(),e.asyncGeneratorDelegate=function(t,e){function n(n,a){return r=!0,a=new Promise(function(e){e(t[n](a))}),{done:!1,value:e(a)}}var a={},r=!1;return"function"==typeof Symbol&&Symbol.iterator&&(a[Symbol.iterator]=function(){return this}),a.next=function(t){return r?(r=!1,t):n("next",t)},"function"==typeof t["throw"]&&(a["throw"]=function(t){if(r)throw r=!1,t;return n("throw",t)}),"function"==typeof t["return"]&&(a["return"]=function(t){return n("return",t)}),a},e.asyncToGenerator=function(t){return function(){var e=t.apply(this,arguments);return new Promise(function(t,n){function a(r,i){try{var o=e[r](i),s=o.value}catch(u){return void n(u)}return o.done?void t(s):Promise.resolve(s).then(function(t){a("next",t)},function(t){a("throw",t)})}return a("next")})}},e.classCallCheck=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},e.createClass=function(){function t(t,e){for(var n=0;n=0||Object.prototype.hasOwnProperty.call(t,a)&&(n[a]=t[a]);return n},e.possibleConstructorReturn=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},e.selfGlobal=void 0===t?self:t,e.set=function a(t,e,n,r){var i=Object.getOwnPropertyDescriptor(t,e);if(void 0===i){var o=Object.getPrototypeOf(t);null!==o&&a(o,e,n,r)}else if("value"in i&&i.writable)i.value=n;else{var s=i.set;void 0!==s&&s.call(r,n)}return n},e.slicedToArray=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),e.slicedToArrayLoose=function(t,e){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t)){for(var n,a=[],r=t[Symbol.iterator]();!(n=r.next()).done&&(a.push(n.value),!e||a.length!==e););return a}throw new TypeError("Invalid attempt to destructure non-iterable instance")},e.taggedTemplateLiteral=function(t,e){return Object.freeze(Object.defineProperties(t,{raw:{value:Object.freeze(e)}}))},e.taggedTemplateLiteralLoose=function(t,e){return t.raw=e,t},e.temporalRef=function(t,e,n){if(t===n)throw new ReferenceError(e+" is not defined - temporal dead zone");return t},e.temporalUndefined={},e.toArray=function(t){return Array.isArray(t)?t:Array.from(t)},e.toConsumableArray=function(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);ee/2?"good":t>e/4?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[15,1,311],t:7,e:"ntosheader"}," ",{p:[17,1,328],t:7,e:"ui-display",f:[{p:[18,2,343],t:7,e:"i",f:["Welcome to computer configuration utility. Please consult your system administrator if you have any questions about your device."]},{p:[18,137,478],t:7,e:"hr"}," ",{p:[19,2,485],t:7,e:"ui-display",a:{title:"Power Supply"},f:[{p:[20,3,522],t:7,e:"ui-section",a:{label:"Power Usage"},f:[{t:2,r:"data.power_usage",p:[21,4,559]},"W"]}," ",{t:4,f:[{p:[25,4,630],t:7,e:"ui-section",a:{label:"Battery Status"},f:["Active"]}," ",{p:[28,4,701],t:7,e:"ui-section",a:{label:"Battery Rating"},f:[{t:2,r:"data.battery.max",p:[29,5,742]}]}," ",{p:[31,4,785],t:7,e:"ui-section",a:{label:"Battery Charge"},f:[{p:[32,5,826],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.battery.max",p:[32,26,847]}],value:[{t:2,r:"adata.battery.charge",p:[32,56,877]}],state:[{t:2,x:{r:["chargeState","adata.battery.charge"],s:"_0(_1)"},p:[32,89,910]}]},f:[{t:2,x:{r:["adata.battery.charge"],s:"Math.round(_0)"},p:[32,128,949]},"/",{t:2,r:"adata.battery.max",p:[32,165,986]}]}]}],n:50,r:"data.battery",p:[24,3,605]},{t:4,n:51,f:[{p:[35,4,1051],t:7,e:"ui-section",a:{label:"Battery Status"},f:["Not Available"]}],r:"data.battery"}]}," ",{p:[41,2,1156],t:7,e:"ui-display",a:{title:"File System"},f:[{p:[42,3,1192],t:7,e:"ui-section",a:{label:"Used Capacity"},f:[{p:[43,4,1231],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.disk_size",p:[43,25,1252]}],value:[{t:2,r:"adata.disk_used",p:[43,53,1280]}],state:"good"},f:[{t:2,x:{r:["adata.disk_used"],s:"Math.round(_0)"},p:[43,87,1314]},"GQ / ",{t:2,r:"adata.disk_size",p:[43,123,1350]},"GQ"]}]}]}," ",{p:[47,2,1419],t:7,e:"ui-display",a:{title:"Computer Components"},f:[{t:4,f:[{p:[49,4,1491],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"name",p:[49,26,1513]}]},f:[{p:[50,5,1529],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"desc",p:[50,59,1583]}]}," ",{p:[52,5,1605],t:7,e:"ui-section",a:{label:"State"},f:[{p:[53,6,1638],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["critical"],s:'_0?"disabled":null'},p:[53,24,1656]}],action:"PC_toggle_component",params:['{"name": "',{t:2,r:"name",p:[53,105,1737]},'"}']},f:[{t:2,x:{r:["enabled"],s:'_0?"Enabled":"Disabled"'},p:[54,7,1757]}]}]}," ",{t:4,f:[{p:[59,6,1868],t:7,e:"ui-section",a:{label:"Power Usage"},f:[{t:2,r:"powerusage",p:[60,7,1908]},"W"]}],n:50,r:"powerusage",p:[58,5,1843]}]}," ",{p:[64,4,1985],t:7,e:"br"}],n:52,r:"data.hardware",p:[48,3,1463]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],269:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[7,3,103],t:7,e:"h2",f:["An error has occurred and this program can not continue."]}," Additional information: ",{t:2,r:"data.error",p:[8,27,196]},{p:[8,41,210],t:7,e:"br"}," ",{p:[9,3,218],t:7,e:"i",f:["Please try again. If the problem persists contact your system administrator for assistance."]}," ",{p:[10,3,320],t:7,e:"ui-button",a:{action:"PRG_closefile"},f:["Restart program"]}],n:50,r:"data.error",p:[6,2,81]},{t:4,n:51,f:[{t:4,f:[{p:[13,4,422],t:7,e:"h2",f:["Viewing file ",{t:2,r:"data.filename",p:[13,21,439]}]}," ",{p:[14,4,466],t:7,e:"div",a:{"class":"item"},f:[{p:[15,4,489],t:7,e:"ui-button",a:{action:"PRG_closefile"},f:["CLOSE"]}," ",{p:[16,4,545],t:7,e:"ui-button",a:{action:"PRG_edit"},f:["EDIT"]}," ",{p:[17,4,595],t:7,e:"ui-button",a:{action:"PRG_printfile"},f:["PRINT"]}," "]},{p:[18,10,657],t:7,e:"hr"}," ",{t:3,r:"data.filedata",p:[19,4,666]}],n:50,r:"data.filename",p:[12,3,396]},{t:4,n:51,f:[{p:[21,4,702],t:7,e:"h2",f:["Available files (local):"]}," ",{p:[22,4,740],t:7,e:"table",f:[{p:[23,5,753],t:7,e:"tr",f:[{p:[24,6,764],t:7,e:"th",f:["File name"]}," ",{p:[25,6,789],t:7,e:"th",f:["File type"]}," ",{p:[26,6,814],t:7,e:"th",f:["File size (GQ)"]}," ",{p:[27,6,844],t:7,e:"th",f:["Operations"]}]}," ",{t:4,f:[{p:[30,6,907],t:7,e:"tr",f:[{p:[31,7,919],t:7,e:"td",f:[{t:2,r:"name",p:[31,11,923]}]}," ",{p:[32,7,944],t:7,e:"td",f:[".",{t:2,r:"type",p:[32,12,949]}]}," ",{p:[33,7,970],t:7,e:"td",f:[{t:2,r:"size",p:[33,11,974]},"GQ"]}," ",{p:[34,7,997],t:7,e:"td",f:[{p:[35,8,1010],t:7,e:"ui-button",a:{action:"PRG_openfile",params:['{"name": "',{t:2,r:"name",p:[35,59,1061]},'"}']},f:["VIEW"]}," ",{p:[36,8,1098],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[36,26,1116]}],action:"PRG_deletefile",params:['{"name": "',{t:2,r:"name",p:[36,105,1195]},'"}']},f:["DELETE"]}," ",{p:[37,8,1234],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[37,26,1252]}],action:"PRG_rename",params:['{"name": "',{t:2,r:"name",p:[37,101,1327]},'"}']},f:["RENAME"]}," ",{p:[38,8,1366],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[38,26,1384]}],action:"PRG_clone",params:['{"name": "',{t:2,r:"name",p:[38,100,1458]},'"}']},f:["CLONE"]}," ",{t:4,f:[{p:[40,9,1531],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[40,27,1549]}],action:"PRG_copytousb",params:['{"name": "',{t:2,r:"name",p:[40,105,1627]},'"}']},f:["EXPORT"]}],n:50,r:"data.usbconnected",p:[39,8,1496]}]}]}],n:52,r:"data.files",p:[29,5,880]}]}," ",{t:4,f:[{p:[47,4,1761],t:7,e:"h2",f:["Available files (portable device):"]}," ",{p:[48,4,1809],t:7,e:"table",f:[{p:[49,5,1822],t:7,e:"tr",f:[{p:[50,6,1833],t:7,e:"th",f:["File name"]}," ",{p:[51,6,1858],t:7,e:"th",f:["File type"]}," ",{p:[52,6,1883],t:7,e:"th",f:["File size (GQ)"]}," ",{p:[53,6,1913],t:7,e:"th",f:["Operations"]}]}," ",{t:4,f:[{p:[56,6,1979],t:7,e:"tr",f:[{p:[57,7,1991],t:7,e:"td",f:[{t:2,r:"name",p:[57,11,1995]}]}," ",{p:[58,7,2016],t:7,e:"td",f:[".",{t:2,r:"type",p:[58,12,2021]}]}," ",{p:[59,7,2042],t:7,e:"td",f:[{t:2,r:"size",p:[59,11,2046]},"GQ"]}," ",{p:[60,7,2069],t:7,e:"td",f:[{p:[61,8,2082],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[61,26,2100]}],action:"PRG_usbdeletefile",params:['{"name": "',{t:2,r:"name",p:[61,108,2182]},'"}']},f:["DELETE"]}," ",{t:4,f:[{p:[63,9,2256],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[63,27,2274]}],action:"PRG_copyfromusb",params:['{"name": "',{t:2,r:"name",p:[63,107,2354]},'"}']},f:["IMPORT"]}],n:50,r:"data.usbconnected",p:[62,8,2221]}]}]}],n:52,r:"data.usbfiles",p:[55,5,1949]}]}],n:50,r:"data.usbconnected",p:[46,4,1731]}," ",{p:[70,4,2470],t:7,e:"ui-button",a:{action:"PRG_newtextfile"},f:["NEW DATA FILE"]}],r:"data.filename"}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],270:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"i",f:["No program loaded. Please select program from list below."]}," ",{p:[6,2,146],t:7,e:"table",f:[{t:4,f:[{p:[8,4,185],t:7,e:"tr",f:[{p:[8,8,189],t:7,e:"td",f:[{p:[8,12,193],t:7,e:"ui-button",a:{action:"PC_runprogram",params:['{"name": "',{t:2,r:"name",p:[8,64,245]},'"}']},f:[{t:2,r:"desc",p:[9,5,263]}]}]},{p:[11,4,293],t:7,e:"td",f:[{p:[11,8,297],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["running"],s:'_0?null:"disabled"'},p:[11,26,315]}],icon:"close",action:"PC_killprogram",params:['{"name": "',{t:2,r:"name",p:[11,114,403]},'"}']}}]}]}],n:52,r:"data.programs",p:[7,3,157]}]}," ",{p:[14,2,454],t:7,e:"br"},{p:[14,6,458],t:7,e:"br"}," ",{t:4,f:[{p:[16,3,491],t:7,e:"ui-button",a:{action:"PC_toggle_light",style:[{t:2,x:{r:["data.light_on"],s:'_0?"selected":null'},p:[16,46,534]}]},f:["Toggle Flashlight"]},{p:[16,114,602],t:7,e:"br"}," ",{p:[17,3,610],t:7,e:"ui-button",a:{action:"PC_light_color"},f:["Change Flashlight Color ",{p:[17,62,669],t:7,e:"span",a:{style:["border:1px solid #161616; background-color: ",{t:2,r:"data.comp_light_color",p:[17,119,726]},";"]},f:["   "]}]}],n:50,r:"data.has_light",p:[15,2,465]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],271:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[6,3,105],t:7,e:"h1",f:["ADMINISTRATIVE MODE"]}],n:50,r:"data.adminmode",p:[5,2,79]}," ",{t:4,f:[{p:[10,3,170],t:7,e:"div",a:{"class":"itemLabel"},f:["Current channel:"]}," ",{p:[13,3,229],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.title",p:[14,4,259]}]}," ",{p:[16,3,287],t:7,e:"div",a:{"class":"itemLabel"},f:["Operator access:"]}," ",{p:[19,3,346],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:[{p:[21,5,406],t:7,e:"b",f:["Enabled"]}],n:50,r:"data.is_operator",p:[20,4,376]},{t:4,n:51,f:[{p:[23,5,439],t:7,e:"b",f:["Disabled"]}],r:"data.is_operator"}]}," ",{p:[26,3,480],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[29,3,532],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[30,4,562],t:7,e:"table",f:[{p:[31,5,575],t:7,e:"tr",f:[{p:[31,9,579],t:7,e:"td",f:[{p:[31,13,583],t:7,e:"ui-button",a:{action:"PRG_speak"},f:["Send message"]}]}]},{p:[32,5,643],t:7,e:"tr",f:[{p:[32,9,647],t:7,e:"td",f:[{p:[32,13,651],t:7,e:"ui-button",a:{action:"PRG_changename"},f:["Change nickname"]}]}]},{p:[33,5,719],t:7,e:"tr",f:[{p:[33,9,723],t:7,e:"td",f:[{p:[33,13,727],t:7,e:"ui-button",a:{action:"PRG_toggleadmin"},f:["Toggle administration mode"]}]}]},{p:[34,5,807],t:7,e:"tr",f:[{p:[34,9,811],t:7,e:"td",f:[{p:[34,13,815],t:7,e:"ui-button",a:{action:"PRG_leavechannel"},f:["Leave channel"]}]}]},{p:[35,5,883],t:7,e:"tr",f:[{p:[35,9,887],t:7,e:"td",f:[{p:[35,13,891],t:7,e:"ui-button",a:{action:"PRG_savelog"},f:["Save log to local drive"]}," ",{t:4,f:[{p:[37,6,995],t:7,e:"tr",f:[{p:[37,10,999],t:7,e:"td",f:[{p:[37,14,1003],t:7,e:"ui-button",a:{action:"PRG_renamechannel"},f:["Rename channel"]}]}]},{p:[38,6,1074],t:7,e:"tr",f:[{p:[38,10,1078],t:7,e:"td",f:[{p:[38,14,1082],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}]}]},{p:[39,6,1149],t:7,e:"tr",f:[{p:[39,10,1153],t:7,e:"td",f:[{p:[39,14,1157],t:7,e:"ui-button",a:{action:"PRG_deletechannel"},f:["Delete channel"]}]}]}],n:50,r:"data.is_operator",p:[36,5,964]}]}]}]}]}," ",{p:[43,3,1263],t:7,e:"b",f:["Chat Window"]}," ",{p:[44,4,1286],t:7,e:"div",a:{"class":"statusDisplay",style:"overflow: auto;"},f:[{p:[45,4,1342],t:7,e:"div",a:{"class":"item"},f:[{p:[46,5,1366],t:7,e:"div",a:{"class":"itemContent",style:"width: 100%;"},f:[{t:4,f:[{t:2,r:"msg",p:[48,7,1450]},{p:[48,14,1457],t:7,e:"br"}],n:52,r:"data.messages",p:[47,6,1419]}]}]}]}," ",{p:[53,3,1516],t:7,e:"b",f:["Connected Users"]},{p:[53,25,1538],t:7,e:"br"}," ",{t:4,f:[{t:2,r:"name",p:[55,4,1573]},{p:[55,12,1581],t:7,e:"br"}],n:52,r:"data.clients",p:[54,3,1546]}],n:50,r:"data.title",p:[9,2,148]},{t:4,n:51,f:[{p:[58,3,1613],t:7,e:"b",f:["Controls:"]}," ",{p:[59,3,1633],t:7,e:"table",f:[{p:[60,4,1645],t:7,e:"tr",f:[{p:[60,8,1649],t:7,e:"td",f:[{p:[60,12,1653],t:7,e:"ui-button",a:{action:"PRG_changename"},f:["Change nickname"]}]}]},{p:[61,4,1720],t:7,e:"tr",f:[{p:[61,8,1724],t:7,e:"td",f:[{p:[61,12,1728],t:7,e:"ui-button",a:{action:"PRG_newchannel"},f:["New Channel"]}]}]},{p:[62,4,1791],t:7,e:"tr",f:[{p:[62,8,1795],t:7,e:"td",f:[{p:[62,12,1799],t:7,e:"ui-button",a:{action:"PRG_toggleadmin"},f:["Toggle administration mode"]}]}]}]}," ",{p:[64,3,1889],t:7,e:"b",f:["Available channels:"]}," ",{p:[65,3,1919],t:7,e:"table",f:[{t:4,f:[{p:[67,4,1964],t:7,e:"tr",f:[{p:[67,8,1968],t:7,e:"td",f:[{p:[67,12,1972],t:7,e:"ui-button",a:{action:"PRG_joinchannel",params:['{"id": "',{t:2,r:"id",p:[67,64,2024]},'"}']},f:[{t:2,r:"chan",p:[67,74,2034]}]},{p:[67,94,2054],t:7,e:"br"}]}]}],n:52,r:"data.all_channels",p:[66,3,1930]}]}],r:"data.title"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],272:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:["##SYSTEM ERROR: ",{t:2,r:"data.error",p:[6,19,117]},{p:[6,33,131],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["RESET"]}],n:50,r:"data.error",p:[5,2,79]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.target"],s:"_0"},f:["##DoS traffic generator active. Tx: ",{t:2,r:"data.speed",p:[8,39,243]},"GQ/s",{p:[8,57,261],t:7,e:"br"}," ",{t:4,f:[{t:2,r:"nums",p:[10,4,300]},{p:[10,12,308],t:7,e:"br"}],n:52,r:"data.dos_strings",p:[9,3,269]}," ",{p:[12,3,329],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["ABORT"]}]},{t:4,n:50,x:{r:["data.target"],s:"!(_0)"},f:[" ##DoS traffic generator ready. Select target device.",{p:[14,55,443],t:7,e:"br"}," ",{t:4,f:["Targeted device ID: ",{t:2,r:"data.focus",p:[16,24,494]}],n:50,r:"data.focus",p:[15,3,451]},{t:4,n:51,f:["Targeted device ID: None"],r:"data.focus"}," ",{p:[20,3,564],t:7,e:"ui-button",a:{action:"PRG_execute"},f:["EXECUTE"]},{p:[20,54,615],t:7,e:"div",a:{style:"clear:both"}}," Detected devices on network:",{p:[21,31,677],t:7,e:"br"}," ",{t:4,f:[{p:[23,4,711],t:7,e:"ui-button",a:{action:"PRG_target_relay",params:['{"targid": "',{t:2,r:"id",p:[23,61,768]},'"}']},f:[{t:2,r:"id",p:[23,71,778]}]}],n:52,r:"data.relays",p:[22,3,685]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],273:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"i",f:["Welcome to software download utility. Please select which software you wish to download."]},{p:[5,97,174],t:7,e:"hr"}," ",{t:4,f:[{p:[7,3,203],t:7,e:"ui-display",a:{title:"Download Error"},f:[{p:[8,4,243],t:7,e:"ui-section",a:{label:"Information"},f:[{t:2,r:"data.error",p:[9,5,281]}]}," ",{p:[11,4,318],t:7,e:"ui-section",a:{label:"Reset Program"},f:[{p:[12,5,358],t:7,e:"ui-button",a:{icon:"times",action:"PRG_reseterror"},f:["RESET"]}]}]}],n:50,r:"data.error",p:[6,2,181]},{t:4,n:51,f:[{t:4,f:[{p:[19,4,516],t:7,e:"ui-display",a:{title:"Download Running"},f:[{p:[20,5,559],t:7,e:"i",f:["Please wait..."]}," ",{p:[21,5,586],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"data.downloadname",p:[22,6,623]}]}," ",{p:[24,5,669],t:7,e:"ui-section",a:{label:"File description"},f:[{t:2,r:"data.downloaddesc",p:[25,6,713]}]}," ",{p:[27,5,759],t:7,e:"ui-section",a:{label:"File size"},f:[{t:2,r:"data.downloadsize",p:[28,6,796]},"GQ"]}," ",{p:[30,5,844],t:7,e:"ui-section",a:{label:"Transfer Rate"},f:[{t:2,r:"data.downloadspeed",p:[31,6,885]}," GQ/s"]}," ",{p:[33,5,937],t:7,e:"ui-section",a:{label:"Download progress"},f:[{p:[34,6,982],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.downloadsize",p:[34,27,1003]}],value:[{t:2,r:"adata.downloadcompletion",p:[34,58,1034]}],state:"good"},f:[{t:2,x:{r:["adata.downloadcompletion"],s:"Math.round(_0)"},p:[34,101,1077]},"GQ / ",{t:2,r:"adata.downloadsize",p:[34,146,1122]},"GQ"]}]}]}],n:50,r:"data.downloadname",p:[18,3,486]}],r:"data.error"}," ",{t:4,f:[{t:4,f:[{p:[41,4,1270],t:7,e:"ui-display",a:{title:"File System"},f:[{p:[42,5,1308],t:7,e:"ui-section",a:{label:"Used Capacity"},f:[{p:[43,6,1349],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.disk_size",p:[43,27,1370]}],value:[{t:2,r:"adata.disk_used",p:[43,55,1398]}],state:"good"},f:[{t:2,x:{r:["adata.disk_used"],s:"Math.round(_0)"},p:[43,89,1432]},"GQ / ",{t:2,r:"adata.disk_size",p:[43,125,1468]},"GQ"]}]}]}," ",{p:[47,4,1545],t:7,e:"ui-display",a:{title:"Primary Software Repository"},f:[{t:4,f:[{p:[49,6,1642],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"filedesc",p:[49,28,1664]}]},f:[{p:[50,7,1686],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"fileinfo",p:[50,61,1740]}]}," ",{p:[52,7,1774],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"filename",p:[53,8,1813]}," (",{t:2,r:"size",p:[53,22,1827]}," GQ)"]}," ",{p:[55,7,1868],t:7,e:"ui-section",a:{label:"Compatibility"},f:[{t:2,r:"compatibility",p:[56,8,1911]}]}," ",{p:[58,7,1957],t:7,e:"ui-button",a:{icon:"signal",action:"PRG_downloadfile",params:['{"filename": "',{t:2,r:"filename",p:[58,80,2030]},'"}']},f:["DOWNLOAD"]}]}," ",{p:[62,6,2113],t:7,e:"br"}],n:52,r:"data.downloadable_programs",p:[48,5,1599]}]}," ",{t:4,f:[{p:[67,5,2194],t:7,e:"ui-display",a:{title:"UNKNOWN Software Repository"},f:[{p:[68,6,2249],t:7,e:"i",f:["Please note that Nanotrasen does not recommend download of software from non-official servers."]}," ",{t:4,f:[{p:[70,7,2395],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"filedesc",p:[70,29,2417]}]},f:[{p:[71,8,2440],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"fileinfo",p:[71,62,2494]}]}," ",{p:[73,8,2530],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"filename",p:[74,9,2570]}," (",{t:2,r:"size",p:[74,23,2584]}," GQ)"]}," ",{p:[76,8,2627],t:7,e:"ui-section",a:{label:"Compatibility"},f:[{t:2,r:"compatibility",p:[77,9,2671]}]}," ",{p:[79,8,2719],t:7,e:"ui-button",a:{icon:"signal",action:"PRG_downloadfile",params:['{"filename": "',{t:2,r:"filename",p:[79,81,2792]},'"}']},f:["DOWNLOAD"]}]}," ",{p:[83,7,2879],t:7,e:"br"}],n:52,r:"data.hacked_programs",p:[69,6,2357]}]}],n:50,r:"data.hackedavailable",p:[66,4,2160]}],n:50,x:{r:["data.error"],s:"!_0"},p:[40,3,1246]}],n:50,x:{r:["data.downloadname"],s:"!_0"},p:[39,2,1216]}," ",{p:[89,2,2954],t:7,e:"br"},{p:[89,6,2958],t:7,e:"br"},{p:[89,10,2962],t:7,e:"hr"},{p:[89,14,2966],t:7,e:"i",f:["NTOS v2.0.4b Copyright Nanotrasen 2557 - 2559"]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],274:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[6,2,81],t:7,e:"ui-display",a:{title:"WIRELESS CONNECTIVITY"},f:[{p:[8,3,129],t:7,e:"ui-section",a:{label:"Active NTNetRelays"},f:[{p:[9,4,173],t:7,e:"b",f:[{t:2,r:"data.ntnetrelays",p:[9,7,176]}]}]}," ",{t:4,f:[{p:[12,4,250],t:7,e:"ui-section",a:{label:"System status"},f:[{p:[13,6,291],t:7,e:"b",f:[{t:2,x:{r:["data.ntnetstatus"],s:'_0?"ENABLED":"DISABLED"'},p:[13,9,294]}]}]}," ",{p:[15,4,366],t:7,e:"ui-section",a:{label:"Control"},f:[{p:[17,4,401],t:7,e:"ui-button",a:{icon:"plus",action:"toggleWireless"},f:["TOGGLE"]}]}," ",{p:[21,4,500],t:7,e:"br"},{p:[21,8,504],t:7,e:"br"}," ",{p:[22,4,513],t:7,e:"i",f:["Caution - Disabling wireless transmitters when using wireless device may prevent you from re-enabling them again!"]}],n:50,r:"data.ntnetrelays",p:[11,3,221]},{t:4,n:51,f:[{p:[24,4,650],t:7,e:"br"},{p:[24,8,654],t:7,e:"p",f:["Wireless coverage unavailable, no relays are connected."]}],r:"data.ntnetrelays"}]}," ",{p:[29,2,750],t:7,e:"ui-display",a:{title:"FIREWALL CONFIGURATION"},f:[{p:[31,2,798],t:7,e:"table",f:[{p:[32,3,809],t:7,e:"tr",f:[{p:[33,4,818],t:7,e:"th",f:["PROTOCOL"]},{p:[34,4,835],t:7,e:"th",f:["STATUS"]},{p:[35,4,850],t:7,e:"th",f:["CONTROL"]}]},{p:[36,3,865],t:7,e:"tr",f:[" ",{p:[37,4,874],t:7,e:"td",f:["Software Downloads"]},{p:[38,4,901],t:7,e:"td",f:[{t:2,x:{r:["data.config_softwaredownload"],s:'_0?"ENABLED":"DISABLED"'},p:[38,8,905]}]},{p:[39,4,967],t:7,e:"td",f:[" ",{p:[39,9,972],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "1"}'},f:["TOGGLE"]}]}]},{p:[40,3,1051],t:7,e:"tr",f:[" ",{p:[41,4,1060],t:7,e:"td",f:["Peer to Peer Traffic"]},{p:[42,4,1089],t:7,e:"td",f:[{t:2,x:{r:["data.config_peertopeer"],s:'_0?"ENABLED":"DISABLED"'},p:[42,8,1093]}]},{p:[43,4,1149],t:7,e:"td",f:[{p:[43,8,1153],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "2"}'},f:["TOGGLE"]}]}]},{p:[44,3,1232],t:7,e:"tr",f:[" ",{p:[45,4,1241],t:7,e:"td",f:["Communication Systems"]},{p:[46,4,1271],t:7,e:"td",f:[{t:2,x:{r:["data.config_communication"],s:'_0?"ENABLED":"DISABLED"'},p:[46,8,1275]}]},{p:[47,4,1334],t:7,e:"td",f:[{p:[47,8,1338],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "3"}'},f:["TOGGLE"]}]}]},{p:[48,3,1417],t:7,e:"tr",f:[" ",{p:[49,4,1426],t:7,e:"td",f:["Remote System Control"]},{p:[50,4,1456],t:7,e:"td",f:[{t:2,x:{r:["data.config_systemcontrol"],s:'_0?"ENABLED":"DISABLED"'},p:[50,8,1460]}]},{p:[51,4,1519],t:7,e:"td",f:[{p:[51,8,1523],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "4"}'},f:["TOGGLE"]}]}]}]}]}," ",{p:[55,2,1630],t:7,e:"ui-display",a:{title:"SECURITY SYSTEMS"},f:[{t:4,f:[{p:[58,4,1699],t:7,e:"ui-notice",f:[{p:[59,5,1716],t:7,e:"h1",f:["NETWORK INCURSION DETECTED"]}]}," ",{p:[61,5,1774],t:7,e:"i",f:["An abnormal activity has been detected in the network. Please verify system logs for more information"]}],n:50,r:"data.idsalarm",p:[57,3,1673]}," ",{p:[64,3,1902],t:7,e:"ui-section",a:{label:"Intrusion Detection System"},f:[{p:[65,4,1954],t:7,e:"b",f:[{t:2,x:{r:["data.idsstatus"],s:'_0?"ENABLED":"DISABLED"'},p:[65,7,1957]}]}]}," ",{p:[68,3,2029],t:7,e:"ui-section",a:{label:"Maximal Log Count"},f:[{p:[69,4,2072],t:7,e:"b",f:[{t:2,r:"data.ntnetmaxlogs",p:[69,7,2075]}]}]}," ",{p:[72,3,2125],t:7,e:"ui-section",a:{label:"Controls"},f:[]}," ",{p:[74,4,2176],t:7,e:"table",f:[{p:[75,4,2188],t:7,e:"tr",f:[{p:[75,8,2192],t:7,e:"td",f:[{p:[75,12,2196],t:7,e:"ui-button",a:{action:"resetIDS"},f:["RESET IDS"]}]}]},{p:[76,4,2251],t:7,e:"tr",f:[{p:[76,8,2255],t:7,e:"td",f:[{p:[76,12,2259],t:7,e:"ui-button",a:{action:"toggleIDS"},f:["TOGGLE IDS"]}]}]},{p:[77,4,2316],t:7,e:"tr",f:[{p:[77,8,2320],t:7,e:"td",f:[{p:[77,12,2324],t:7,e:"ui-button",a:{action:"updatemaxlogs"},f:["SET LOG LIMIT"]}]}]},{p:[78,4,2388],t:7,e:"tr",f:[{p:[78,8,2392],t:7,e:"td",f:[{p:[78,12,2396],t:7,e:"ui-button",a:{action:"purgelogs"},f:["PURGE LOGS"]}]}]}]}," ",{p:[81,3,2467],t:7,e:"ui-subdisplay",a:{title:"System Logs"},f:[{p:[82,3,2506],t:7,e:"div",a:{"class":"statusDisplay",style:"overflow: auto;"},f:[{p:[83,3,2561],t:7,e:"div",a:{"class":"item"},f:[{p:[84,4,2584],t:7,e:"div",a:{"class":"itemContent",style:"width: 100%;"},f:[{t:4,f:[{t:2,r:"entry",p:[86,6,2667]},{p:[86,15,2676],t:7,e:"br"}],n:52,r:"data.ntnetlogs",p:[85,5,2636]}]}]}]}]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],275:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[7,2,102],t:7,e:"div",a:{"class":"item"},f:[{p:[8,3,124],t:7,e:"h2",f:["An error has occurred during operation..."]}," ",{p:[9,3,178],t:7,e:"b",f:["Additional information:"]},{t:2,r:"data.error",p:[9,34,209]},{p:[9,48,223],t:7,e:"br"}," ",{p:[10,3,231],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Clear"]}]}],n:50,r:"data.error",p:[6,2,81]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.downloading"],s:"_0"},f:[{p:[13,3,321],t:7,e:"h2",f:["Download in progress..."]}," ",{p:[14,3,357],t:7,e:"div",a:{"class":"itemLabel"},f:["Downloaded file:"]}," ",{p:[17,3,416],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_name",p:[18,4,446]}]}," ",{p:[20,3,483],t:7,e:"div",a:{"class":"itemLabel"},f:["Download progress:"]}," ",{p:[23,3,544],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_progress",p:[24,4,574]}," / ",{t:2,r:"data.download_size",p:[24,33,603]}," GQ"]}," ",{p:[26,3,642],t:7,e:"div",a:{"class":"itemLabel"},f:["Transfer speed:"]}," ",{p:[29,3,700],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_netspeed",p:[30,4,730]},"GQ/s"]}," ",{p:[32,3,774],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[35,3,826],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[36,4,856],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Abort download"]}]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading"],s:"(!(_0))&&(_1)"},f:[" ",{p:[39,3,954],t:7,e:"h2",f:["Server enabled"]}," ",{p:[40,3,981],t:7,e:"div",a:{"class":"itemLabel"},f:["Connected clients:"]}," ",{p:[43,3,1042],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.upload_clients",p:[44,4,1072]}]}," ",{p:[46,3,1109],t:7,e:"div",a:{"class":"itemLabel"},f:["Provided file:"]}," ",{p:[49,3,1166],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.upload_filename",p:[50,4,1196]}]}," ",{p:[52,3,1234],t:7,e:"div",a:{"class":"itemLabel"},f:["Server password:"]}," ",{p:[55,3,1293],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["ENABLED"],n:50,r:"data.upload_haspassword",p:[56,4,1323]},{t:4,n:51,f:["DISABLED"],r:"data.upload_haspassword"}]}," ",{p:[62,3,1420],t:7,e:"div",a:{"class":"itemLabel"},f:["Commands:"]}," ",{p:[65,3,1472],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[66,4,1502],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}," ",{p:[67,4,1567],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Exit server"]}]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading","data.upload_filelist"],s:"(!(_0))&&((!(_1))&&(_2))"},f:[" ",{p:[70,3,1668],t:7,e:"h2",f:["File transfer server ready. Select file to upload:"]}," ",{p:[71,3,1732],t:7,e:"table",f:[{p:[72,3,1743],t:7,e:"tr",f:[{p:[72,7,1747],t:7,e:"th",f:["File name"]},{p:[72,20,1760],t:7,e:"th",f:["File size"]},{p:[72,33,1773],t:7,e:"th",f:["Controls ",{t:4,f:[{p:[74,4,1824],t:7,e:"tr",f:[{p:[74,8,1828],t:7,e:"td",f:[{t:2,r:"filename",p:[74,12,1832]}]},{p:[75,4,1849],t:7,e:"td",f:[{t:2,r:"size",p:[75,8,1853]},"GQ"]},{p:[76,4,1868],t:7,e:"td",f:[{p:[76,8,1872],t:7,e:"ui-button",a:{action:"PRG_uploadfile",params:['{"id": "',{t:2,r:"uid",p:[76,59,1923]},'"}']},f:["Select"]}]}]}],n:52,r:"data.upload_filelist",p:[73,3,1789]}]}]}]}," ",{p:[79,3,1981],t:7,e:"hr"}," ",{p:[80,3,1989],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}," ",{p:[81,3,2053],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Return"]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading","data.upload_filelist"],s:"(!(_0))&&((!(_1))&&(!(_2)))"},f:[" ",{p:[83,3,2116],t:7,e:"h2",f:["Available files:"]}," ",{p:[84,3,2145],t:7,e:"table",a:{border:"1",style:"border-collapse: collapse"},f:[{p:[84,55,2197],t:7,e:"tr",f:[{p:[84,59,2201],t:7,e:"th",f:["Server UID"]},{p:[84,73,2215],t:7,e:"th",f:["File Name"]},{p:[84,86,2228],t:7,e:"th",f:["File Size"]},{p:[84,99,2241],t:7,e:"th",f:["Password Protection"]},{p:[84,122,2264],t:7,e:"th",f:["Operations ",{t:4,f:[{p:[86,5,2311],t:7,e:"tr",f:[{p:[86,9,2315],t:7,e:"td",f:[{t:2,r:"uid",p:[86,13,2319]}]},{p:[87,5,2332],t:7,e:"td",f:[{t:2,r:"filename",p:[87,9,2336]}]},{p:[88,5,2354],t:7,e:"td",f:[{t:2,r:"size",p:[88,9,2358]},"GQ ",{t:4,f:[{p:[90,6,2400],t:7,e:"td",f:["Enabled"]}],n:50,r:"haspassword",p:[89,5,2374]}," ",{t:4,f:[{p:[93,6,2457],t:7,e:"td",f:["Disabled"]}],n:50,x:{r:["haspassword"],s:"!_0"},p:[92,5,2430]}]},{p:[96,5,2494],t:7,e:"td",f:[{p:[96,9,2498],t:7,e:"ui-button",a:{action:"PRG_downloadfile",params:['{"id": "',{t:2,r:"uid",p:[96,62,2551]},'"}']},f:["Download"]}]}]}],n:52,r:"data.servers",p:[85,4,2283]}]}]}]}," ",{p:[99,3,2612],t:7,e:"hr"}," ",{p:[100,3,2620],t:7,e:"ui-button",a:{action:"PRG_uploadmenu"},f:["Send file"]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],276:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{chargingState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},chargingMode:function(t){return 2==t?"Full":1==t?"Charging":"Draining"},channelState:function(t){return t>=2?"good":"bad"},channelPower:function(t){return t>=2?"On":"Off"},channelMode:function(t){return 1==t||3==t?"Auto":"Manual"}},computed:{graphData:function(){var t=this.get("data.history");return Object.keys(t).map(function(e){return t[e].map(function(t,e){return{x:e,y:t}})})}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[43,1,1082],t:7,e:"ntosheader"}," ",{p:[45,1,1099],t:7,e:"ui-display",a:{title:"Network"},f:[{t:4,f:[{p:[47,5,1157],t:7,e:"ui-linegraph",a:{points:[{t:2,r:"graphData", +-p:[47,27,1179]}],height:"500",legend:'["Available", "Load"]',colors:'["rgb(0, 102, 0)", "rgb(153, 0, 0)"]',xunit:"seconds ago",xfactor:[{t:2,r:"data.interval",p:[49,38,1331]}],yunit:"W",yfactor:"1",xinc:[{t:2,x:{r:["data.stored"],s:"_0/10"},p:[50,15,1387]}],yinc:"9"}}],n:50,r:"config.fancy",p:[46,3,1131]},{t:4,n:51,f:[{p:[52,5,1437],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[53,7,1475],t:7,e:"span",f:[{t:2,r:"data.supply",p:[53,13,1481]}," W"]}]}," ",{p:[55,5,1530],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[56,9,1565],t:7,e:"span",f:[{t:2,r:"data.demand",p:[56,15,1571]}," W"]}]}],r:"config.fancy"}]}," ",{p:[60,1,1642],t:7,e:"ui-display",a:{title:"Areas"},f:[{p:[61,3,1672],t:7,e:"ui-section",a:{nowrap:0},f:[{p:[62,5,1697],t:7,e:"div",a:{"class":"content"},f:["Area"]}," ",{p:[63,5,1734],t:7,e:"div",a:{"class":"content"},f:["Charge"]}," ",{p:[64,5,1773],t:7,e:"div",a:{"class":"content"},f:["Load"]}," ",{p:[65,5,1810],t:7,e:"div",a:{"class":"content"},f:["Status"]}," ",{p:[66,5,1849],t:7,e:"div",a:{"class":"content"},f:["Equipment"]}," ",{p:[67,5,1891],t:7,e:"div",a:{"class":"content"},f:["Lighting"]}," ",{p:[68,5,1932],t:7,e:"div",a:{"class":"content"},f:["Environment"]}]}," ",{t:4,f:[{p:[71,5,2017],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[71,24,2036]}],nowrap:0},f:[{p:[72,7,2061],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].charge)"},p:[72,28,2082]}," %"]}," ",{p:[73,7,2140],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].load)"},p:[73,28,2161]}," W"]}," ",{p:[74,7,2217],t:7,e:"div",a:{"class":"content"},f:[{p:[74,28,2238],t:7,e:"span",a:{"class":[{t:2,x:{r:["chargingState","charging"],s:"_0(_1)"},p:[74,41,2251]}]},f:[{t:2,x:{r:["chargingMode","charging"],s:"_0(_1)"},p:[74,70,2280]}]}]}," ",{p:[75,7,2327],t:7,e:"div",a:{"class":"content"},f:[{p:[75,28,2348],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","eqp"],s:"_0(_1)"},p:[75,41,2361]}]},f:[{t:2,x:{r:["channelPower","eqp"],s:"_0(_1)"},p:[75,64,2384]}," [",{p:[75,87,2407],t:7,e:"span",f:[{t:2,x:{r:["channelMode","eqp"],s:"_0(_1)"},p:[75,93,2413]}]},"]"]}]}," ",{p:[76,7,2462],t:7,e:"div",a:{"class":"content"},f:[{p:[76,28,2483],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","lgt"],s:"_0(_1)"},p:[76,41,2496]}]},f:[{t:2,x:{r:["channelPower","lgt"],s:"_0(_1)"},p:[76,64,2519]}," [",{p:[76,87,2542],t:7,e:"span",f:[{t:2,x:{r:["channelMode","lgt"],s:"_0(_1)"},p:[76,93,2548]}]},"]"]}]}," ",{p:[77,7,2597],t:7,e:"div",a:{"class":"content"},f:[{p:[77,28,2618],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","env"],s:"_0(_1)"},p:[77,41,2631]}]},f:[{t:2,x:{r:["channelPower","env"],s:"_0(_1)"},p:[77,64,2654]}," [",{p:[77,87,2677],t:7,e:"span",f:[{t:2,x:{r:["channelMode","env"],s:"_0(_1)"},p:[77,93,2683]}]},"]"]}]}]}],n:52,r:"data.areas",p:[70,3,1991]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],277:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"div",a:{"class":"item"},f:[{p:[6,3,101],t:7,e:"div",a:{"class":"itemLabel"},f:["Payload status:"]}," ",{p:[9,3,158],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["ARMED"],n:50,r:"data.armed",p:[10,4,188]},{t:4,n:51,f:["DISARMED"],r:"data.armed"}]}," ",{p:[16,3,270],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[19,3,321],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[20,4,351],t:7,e:"table",f:[{p:[21,4,363],t:7,e:"tr",f:[{p:[21,8,367],t:7,e:"td",f:[{p:[21,12,371],t:7,e:"ui-button",a:{action:"PRG_obfuscate"},f:["OBFUSCATE PROGRAM NAME"]}]}]},{p:[22,4,444],t:7,e:"tr",f:[{p:[22,8,448],t:7,e:"td",f:[{p:[22,12,452],t:7,e:"ui-button",a:{action:"PRG_arm",state:[{t:2,x:{r:["data.armed"],s:'_0?"danger":null'},p:[22,47,487]}]},f:[{t:2,x:{r:["data.armed"],s:'_0?"DISARM":"ARM"'},p:[22,81,521]}]}," ",{p:[23,4,571],t:7,e:"ui-button",a:{icon:"radiation",state:[{t:2,x:{r:["data.armed"],s:'_0?null:"disabled"'},p:[23,39,606]}],action:"PRG_activate"},f:["ACTIVATE"]}]}]}]}]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],278:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[5,3,95],t:7,e:"ui-display",a:{title:[{t:2,r:"class",p:[5,22,114]}," Alarms"]},f:[{p:[6,5,138],t:7,e:"ul",f:[{t:4,f:[{p:[8,9,171],t:7,e:"li",f:[{t:2,r:".",p:[8,13,175]}]}],n:52,r:".",p:[7,7,150]},{t:4,n:51,f:[{p:[10,9,211],t:7,e:"li",f:["System Nominal"]}],r:"."}]}]}],n:52,i:"class",r:"data.alarms",p:[4,1,64]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],279:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{integState:function(t){var e=100;return t==e?"good":t>e/2?"average":"bad"},bigState:function(t,e,n){return charge>n?"bad":t>e?"average":"good"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[23,1,421],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[27,2,462],t:7,e:"ui-button",a:{action:"PRG_clear"},f:["Back to Menu"]},{p:[27,56,516],t:7,e:"br"}," ",{p:[28,3,524],t:7,e:"ui-display",a:{title:"Supermatter Status:"},f:[{p:[29,3,568],t:7,e:"ui-section",a:{label:"Core Integrity"},f:[{p:[30,5,609],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"adata.SM_integrity",p:[30,38,642]}],state:[{t:2,x:{r:["integState","adata.SM_integrity"],s:"_0(_1)"},p:[30,69,673]}]},f:[{t:2,r:"data.SM_integrity",p:[30,105,709]},"%"]}]}," ",{p:[32,3,761],t:7,e:"ui-section",a:{label:"Relative EER"},f:[{p:[33,5,800],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_power"],s:"_0(_1,150,300)"},p:[33,18,813]}]},f:[{t:2,r:"data.SM_power",p:[33,55,850]}," MeV/cm3"]}]}," ",{p:[35,3,903],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[36,5,941],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_ambienttemp"],s:"_0(_1,4000,5000)"},p:[36,18,954]}]},f:[{t:2,r:"data.SM_ambienttemp",p:[36,63,999]}," K"]}]}," ",{p:[38,3,1052],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[39,5,1087],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_ambientpressure"],s:"_0(_1,5000,10000)"},p:[39,18,1100]}]},f:[{t:2,r:"data.SM_ambientpressure",p:[39,68,1150]}," kPa"]}]}]}," ",{p:[42,3,1227],t:7,e:"hr"},{p:[42,7,1231],t:7,e:"br"}," ",{p:[43,3,1239],t:7,e:"ui-display",a:{title:"Gas Composition:"},f:[{t:4,f:[{p:[45,5,1307],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[45,24,1326]}]},f:[{t:2,r:"amount",p:[46,6,1343]}," %"]}],n:52,r:"data.gases",p:[44,4,1281]}]}],n:50,r:"data.active",p:[26,1,440]},{t:4,n:51,f:[{p:[51,2,1418],t:7,e:"ui-button",a:{action:"PRG_refresh"},f:["Refresh"]},{p:[51,53,1469],t:7,e:"br"}," ",{p:[52,2,1476],t:7,e:"ui-display",a:{title:"Detected Supermatters"},f:[{t:4,f:[{p:[54,3,1552],t:7,e:"ui-section",a:{label:"Area"},f:[{t:2,r:"area_name",p:[55,5,1583]}," - (#",{t:2,r:"uid",p:[55,23,1601]},")"]}," ",{p:[57,3,1630],t:7,e:"ui-section",a:{label:"Integrity"},f:[{t:2,r:"integrity",p:[58,5,1666]}," %"]}," ",{p:[60,3,1702],t:7,e:"ui-section",a:{label:"Options"},f:[{p:[61,5,1736],t:7,e:"ui-button",a:{action:"PRG_set",params:['{"target" : "',{t:2,r:"uid",p:[61,54,1785]},'"}']},f:["View Details"]}]}],n:52,r:"data.supermatters",p:[53,2,1521]}]}],r:"data.active"}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],280:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"item",style:"float: left"},f:[{p:[2,2,41],t:7,e:"table",f:[{p:[2,9,48],t:7,e:"tr",f:[{t:4,f:[{p:[4,3,113],t:7,e:"td",f:[{p:[4,7,117],t:7,e:"img",a:{src:[{t:2,r:"data.PC_batteryicon",p:[4,17,127]}]}}]}],n:50,x:{r:["data.PC_batteryicon","data.PC_showbatteryicon"],s:"_0&&_1"},p:[3,2,55]}," ",{t:4,f:[{p:[7,3,226],t:7,e:"td",f:[{p:[7,7,230],t:7,e:"b",f:[{t:2,r:"data.PC_batterypercent",p:[7,10,233]}]}]}],n:50,x:{r:["data.PC_batterypercent","data.PC_showbatteryicon"],s:"_0&&_1"},p:[6,2,165]}," ",{t:4,f:[{p:[10,3,305],t:7,e:"td",f:[{p:[10,7,309],t:7,e:"img",a:{src:[{t:2,r:"data.PC_ntneticon",p:[10,17,319]}]}}]}],n:50,r:"data.PC_ntneticon",p:[9,2,276]}," ",{t:4,f:[{p:[13,3,386],t:7,e:"td",f:[{p:[13,7,390],t:7,e:"img",a:{src:[{t:2,r:"data.PC_apclinkicon",p:[13,17,400]}]}}]}],n:50,r:"data.PC_apclinkicon",p:[12,2,355]}," ",{t:4,f:[{p:[16,3,469],t:7,e:"td",f:[{p:[16,7,473],t:7,e:"b",f:[{t:2,r:"data.PC_stationtime",p:[16,10,476]}]}]}],n:50,r:"data.PC_stationtime",p:[15,2,438]}," ",{t:4,f:[{p:[19,3,552],t:7,e:"td",f:[{p:[19,7,556],t:7,e:"img",a:{src:[{t:2,r:"icon",p:[19,17,566]}]}}]}],n:52,r:"data.PC_programheaders",p:[18,2,516]}]}]}]}," ",{p:[23,1,609],t:7,e:"div",a:{style:"float: right; margin-top: 5px"},f:[{p:[24,2,655],t:7,e:"ui-button",a:{action:"PC_shutdown"},f:["Shutdown"]}," ",{t:4,f:[{p:[26,3,745],t:7,e:"ui-button",a:{action:"PC_exit"},f:["EXIT PROGRAM"]}," ",{p:[27,3,801],t:7,e:"ui-button",a:{action:"PC_minimize"},f:["Minimize Program"]}],n:50,r:"data.PC_showexitprogram",p:[25,2,710]}]}," ",{p:[30,1,881],t:7,e:"div",a:{style:"clear: both"}}]},e.exports=a.extend(r.exports)},{205:205}],281:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Auth. Disk:"},f:[{t:4,f:[{p:[3,7,69],t:7,e:"ui-button",a:{icon:"eject",style:"selected",action:"eject_disk"},f:["++++++++++"]}],n:50,r:"data.disk_present",p:[2,3,36]},{t:4,n:51,f:[{p:[5,7,172],t:7,e:"ui-button",a:{icon:"plus",action:"insert_disk"},f:["----------"]}],r:"data.disk_present"}]}," ",{p:[8,1,266],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[9,3,297],t:7,e:"span",f:[{t:2,r:"data.status1",p:[9,9,303]},"-",{t:2,r:"data.status2",p:[9,26,320]}]}]}," ",{p:[11,1,360],t:7,e:"ui-display",a:{title:"Timer"},f:[{p:[12,3,390],t:7,e:"ui-section",a:{label:"Time to Detonation"},f:[{p:[13,5,435],t:7,e:"span",f:[{t:2,x:{r:["data.timing","data.time_left","data.timer_set"],s:"_0?_1:_2"},p:[13,11,441]}]}]}," ",{t:4,f:[{p:[16,5,540],t:7,e:"ui-section",a:{label:"Adjust Timer"},f:[{p:[17,7,581],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_default"],s:'_0&&_1&&_2?null:"disabled"'},p:[17,40,614]}],action:"timer",params:'{"change": "reset"}'},f:["Reset"]}," ",{p:[19,7,786],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_min"],s:'_0&&_1&&_2?null:"disabled"'},p:[19,38,817]}],action:"timer",params:'{"change": "decrease"}'},f:["Decrease"]}," ",{p:[21,7,991],t:7,e:"ui-button",a:{icon:"pencil",state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[21,39,1023]}],action:"timer",params:'{"change": "input"}'},f:["Set"]}," ",{p:[22,7,1155],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_max"],s:'_0&&_1&&_2?null:"disabled"'},p:[22,37,1185]}],action:"timer",params:'{"change": "increase"}'},f:["Increase"]}]}],n:51,r:"data.timing",p:[15,3,518]}," ",{p:[26,3,1394],t:7,e:"ui-section",a:{label:"Timer"},f:[{p:[27,5,1426],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"danger":"caution"'},p:[27,38,1459]}],action:"toggle_timer",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.safety"],s:'_0&&_1&&!_2?null:"disabled"'},p:[29,14,1542]}]},f:[{t:2,x:{r:["data.timing"],s:'_0?"On":"Off"'},p:[30,7,1631]}]}]}]}," ",{p:[34,1,1713],t:7,e:"ui-display",a:{title:"Anchoring"},f:[{p:[35,3,1747],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[36,12,1770]}],icon:[{t:2,x:{r:["data.anchored"],s:'_0?"lock":"unlock"'},p:[37,11,1846]}],style:[{t:2,x:{r:["data.anchored"],s:'_0?null:"caution"'},p:[38,12,1897]}],action:"anchor"},f:[{t:2,x:{r:["data.anchored"],s:'_0?"Engaged":"Off"'},p:[39,21,1956]}]}]}," ",{p:[41,1,2022],t:7,e:"ui-display",a:{title:"Safety"},f:[{p:[42,3,2053],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[43,12,2076]}],icon:[{t:2,x:{r:["data.safety"],s:'_0?"lock":"unlock"'},p:[44,11,2152]}],action:"safety",style:[{t:2,x:{r:["data.safety"],s:'_0?"caution":"danger"'},p:[45,12,2217]}]},f:[{p:[46,7,2265],t:7,e:"span",f:[{t:2,x:{r:["data.safety"],s:'_0?"On":"Off"'},p:[46,13,2271]}]}]}]}," ",{p:[49,1,2341],t:7,e:"ui-display",a:{title:"Code"},f:[{p:[50,3,2370],t:7,e:"ui-section",a:{label:"Message"},f:[{t:2,r:"data.message",p:[50,31,2398]}]}," ",{p:[51,3,2431],t:7,e:"ui-section",a:{label:"Keypad"},f:[{p:[52,5,2464],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[52,39,2498]}],params:'{"digit":"1"}'},f:["1"]}," ",{p:[53,5,2583],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[53,39,2617]}],params:'{"digit":"2"}'},f:["2"]}," ",{p:[54,5,2702],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[54,39,2736]}],params:'{"digit":"3"}'},f:["3"]}," ",{p:[55,5,2821],t:7,e:"br"}," ",{p:[56,5,2831],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[56,39,2865]}],params:'{"digit":"4"}'},f:["4"]}," ",{p:[57,5,2950],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[57,39,2984]}],params:'{"digit":"5"}'},f:["5"]}," ",{p:[58,5,3069],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[58,39,3103]}],params:'{"digit":"6"}'},f:["6"]}," ",{p:[59,5,3188],t:7,e:"br"}," ",{p:[60,5,3198],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[60,39,3232]}],params:'{"digit":"7"}'},f:["7"]}," ",{p:[61,5,3317],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[61,39,3351]}],params:'{"digit":"8"}'},f:["8"]}," ",{p:[62,5,3436],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[62,39,3470]}],params:'{"digit":"9"}'},f:["9"]}," ",{p:[63,5,3555],t:7,e:"br"}," ",{p:[64,5,3565],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[64,39,3599]}],params:'{"digit":"R"}'},f:["R"]}," ",{p:[65,5,3684],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[65,39,3718]}],params:'{"digit":"0"}'},f:["0"]}," ",{p:[66,5,3803],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[66,39,3837]}],params:'{"digit":"E"}'},f:["E"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],282:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,2,15],t:7,e:"ui-section",f:["This machine only accepts ore. Gibtonite and Slag are not accepted."]}," ",{p:[5,2,117],t:7,e:"ui-section",f:["Current unclaimed points: ",{t:2,r:"data.unclaimedPoints",p:[6,29,159]}," ",{t:4,f:[{p:[8,4,220],t:7,e:"ui-button",a:{action:"Claim"},f:["Claim Points"]}],n:50,r:"data.unclaimedPoints",p:[7,3,187]}]}," ",{p:[13,2,311],t:7,e:"ui-section",f:[{t:4,f:[{p:[15,4,350],t:7,e:"ui-button",a:{action:"Eject"},f:["Eject ID"]}," You have ",{t:2,r:"data.claimedPoints",p:[18,13,421]}," mining points collected."],n:50,r:"data.hasID",p:[14,3,327]},{t:4,n:51,f:[{p:[20,4,485],t:7,e:"ui-button",a:{action:"Insert"},f:["Insert ID"]}],r:"data.hasID"}]}]}," ",{p:[26,1,588],t:7,e:"ui-display",f:[{t:4,f:[{p:[28,3,627],t:7,e:"ui-section",f:[{p:[29,4,644],t:7,e:"ui-button",a:{action:"diskEject",icon:"eject"},f:["Eject Disk"]}]}," ",{t:4,f:[{p:[34,4,772],t:7,e:"ui-section",a:{"class":"candystripe"},f:[{p:[35,5,808],t:7,e:"ui-button",a:{action:"diskUpload",state:[{t:2,x:{r:["canupload"],s:'(_0)?null:"disabled"'},p:[35,42,845]}],icon:"upload",align:"right",params:['{ "design" : "',{t:2,r:"index",p:[35,129,932]},'" }']},f:["Upload"]}," File ",{t:2,r:"index",p:[38,10,988]},": ",{t:2,r:"name",p:[38,21,999]}]}],n:52,r:"data.diskDesigns",p:[33,3,741]}],n:50,r:"data.hasDisk",p:[27,2,603]},{t:4,n:51,f:[{p:[42,3,1053],t:7,e:"ui-section",f:[{p:[43,4,1070],t:7,e:"ui-button",a:{action:"diskInsert",icon:"floppy-o"},f:["Insert Disk"]}]}],r:"data.hasDisk"}]}," ",{p:[49,1,1195],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[50,2,1227],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[51,4,1261],t:7,e:"section",a:{"class":"cell"},f:["Mineral"]}," ",{p:[54,4,1316],t:7,e:"section",a:{"class":"cell"},f:["Sheets"]}," ",{p:[57,4,1370],t:7,e:"section",a:{"class":"cell"},f:[]}," ",{p:[59,4,1412],t:7,e:"section",a:{"class":"cell"},f:[{p:[60,5,1440],t:7,e:"ui-button",a:{"class":"center mineral",grid:0,action:"Release",params:'{"id" : "all"}'},f:["Release All"]}]}," ",{p:[64,4,1576],t:7,e:"section",a:{"class":"cell"},f:["Ore Value"]}]}," ",{t:4,f:[{p:[69,3,1673],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[70,4,1707],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[71,5,1735]}]}," ",{p:[73,4,1763],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[74,5,1805]}]}," ",{p:[76,4,1835],t:7,e:"section",a:{"class":"cell"},f:[{p:[77,5,1863],t:7,e:"input",a:{value:[{t:2,r:"sheets",p:[77,18,1876]}],placeholder:"###","class":"number"}}]}," ",{p:[79,4,1941],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[80,5,1983],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[80,59,2037]}],params:['{ "id" : ',{t:2,r:"id",p:[80,114,2092]},', "sheets" : ',{t:2,r:"sheets",p:[80,133,2111]}," }"]},f:["Release"]}]}," ",{p:[84,4,2178],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"value",p:[85,5,2220]}]}]}],n:52,r:"data.materials",p:[68,2,1645]}," ",{t:4,f:[{p:[90,3,2298],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[91,4,2332],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[92,5,2360]}]}," ",{p:[94,4,2388],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[95,5,2430]}]}," ",{p:[97,4,2460],t:7,e:"section",a:{"class":"cell"},f:[{p:[98,5,2488],t:7,e:"input",a:{value:[{t:2,r:"sheets",p:[98,18,2501]}],placeholder:"###","class":"number"}}]}," ",{p:[100,4,2566],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[101,5,2608],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"Smelt",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[101,57,2660]}],params:['{ "id" : ',{t:2,r:"id",p:[101,113,2716]},', "sheets" : ',{t:2,r:"sheets",p:[101,132,2735]}," }"]},f:["Smelt"]}]}," ",{p:[105,4,2799],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[106,5,2841],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"SmeltAll",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[106,60,2896]}],params:['{ "id" : ',{t:2,r:"id",p:[106,116,2952]}," }"]},f:["Smelt All"]}]}]}],n:52,r:"data.alloys",p:[89,2,2273]}]}]},e.exports=a.extend(r.exports)},{205:205}],283:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:{button:[{p:[4,4,87],t:7,e:"ui-button",a:{icon:"remove",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[4,36,119]}],action:"empty_eject_beaker"},f:["Empty and eject"]}," ",{p:[7,4,231],t:7,e:"ui-button",a:{icon:"trash",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[7,35,262]}],action:"empty_beaker"},f:["Empty"]}," ",{p:[10,4,358],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[10,35,389]}],action:"eject_beaker"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{t:4,f:[{p:[15,4,528],t:7,e:"ui-section",f:[{t:4,f:[{p:[17,6,578],t:7,e:"span",a:{"class":"bad"},f:["The beaker is empty!"]}],n:50,r:"data.beaker_empty",p:[16,5,546]},{t:4,n:51,f:[{p:[19,6,644],t:7,e:"ui-subdisplay",a:{title:"Blood"},f:[{t:4,f:[{p:[21,8,712],t:7,e:"ui-section",a:{label:"Blood DNA"},f:[{t:2,r:"data.blood.dna",p:[21,38,742]}]}," ",{p:[22,8,782],t:7,e:"ui-section",a:{label:"Blood type"},f:[{t:2,r:"data.blood.type",p:[22,39,813]}]}],n:50,r:"data.has_blood",p:[20,7,681]},{t:4,n:51,f:[{p:[24,8,870],t:7,e:"ui-section",f:[{p:[25,9,892],t:7,e:"span",a:{"class":"average"},f:["No blood sample detected."]}]}],r:"data.has_blood"}]}],r:"data.beaker_empty"}]}],n:50,r:"data.has_beaker",p:[14,3,500]},{t:4,n:51,f:[{p:[32,4,1054],t:7,e:"ui-section",f:[{p:[33,5,1072],t:7,e:"span",a:{"class":"bad"},f:["No beaker loaded."]}]}],r:"data.has_beaker"}]}," ",{t:4,f:[{p:[38,3,1188],t:7,e:"ui-display",a:{title:"Diseases"},f:[{t:4,f:[{p:{button:[{t:4,f:[{p:[43,8,1343],t:7,e:"ui-button",a:{icon:"pencil",action:"rename_disease",state:[{t:2,x:{r:["can_rename"],s:'_0?"":"disabled"'},p:[43,64,1399]}],params:['{"index": ',{t:2,r:"index",p:[43,116,1451]},"}"]},f:["Name advanced disease"]}],n:50,r:"is_adv",p:[42,7,1320]}," ",{p:[47,7,1538],t:7,e:"ui-button",a:{icon:"flask",action:"create_culture_bottle",state:[{t:2,x:{r:["data.is_ready"],s:'_0?"":"disabled"'},p:[47,69,1600]}],params:['{"index": ',{t:2,r:"index",p:[47,124,1655]},"}"]},f:["Create virus culture bottle"]}]},t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[40,24,1269]}],button:0},f:[" ",{p:[51,6,1749],t:7,e:"ui-section",a:{label:"Disease agent"},f:[{t:2,r:"agent",p:[51,40,1783]}]}," ",{p:[52,6,1812],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"description",p:[52,38,1844]}]}," ",{p:[53,6,1879],t:7,e:"ui-section",a:{label:"Spread"},f:[{t:2,r:"spread",p:[53,33,1906]}]}," ",{p:[54,6,1936],t:7,e:"ui-section",a:{label:"Possible cure"},f:[{t:2,r:"cure",p:[54,40,1970]}]}," ",{t:4,f:[{p:[56,7,2021],t:7,e:"ui-section",a:{label:"Symptoms"},f:[{t:4,f:[{p:[58,9,2087],t:7,e:"ui-button",a:{action:"symptom_details",state:"",params:['{"picked_symptom": ',{t:2,r:"sym_index",p:[58,81,2159]},', "index": ',{t:2,r:"index",p:[58,105,2183]},"}"]},f:[{t:2,r:"name",p:[59,10,2206]}," "]},{p:[60,21,2236],t:7,e:"br"}],n:52,r:"symptoms",p:[57,8,2059]}]}," ",{p:[63,7,2289],t:7,e:"ui-section",a:{label:"Resistance"},f:[{t:2,r:"resistance",p:[63,38,2320]}]}," ",{p:[64,7,2355],t:7,e:"ui-section",a:{label:"Stealth"},f:[{t:2,r:"stealth",p:[64,35,2383]}]}," ",{p:[65,7,2415],t:7,e:"ui-section",a:{label:"Stage speed"},f:[{t:2,r:"stage_speed",p:[65,39,2447]}]}," ",{p:[66,7,2483],t:7,e:"ui-section",a:{label:"Transmittability"},f:[{t:2,r:"transmission",p:[66,44,2520]}]}],n:50,r:"is_adv",p:[55,6,1999]}]}],n:52,r:"data.viruses",p:[39,4,1222]},{t:4,n:51,f:[{p:[70,5,2601],t:7,e:"ui-section",f:[{p:[71,6,2620],t:7,e:"span",a:{"class":"average"},f:["No detectable virus in the blood sample."]}]}],r:"data.viruses"}]}," ",{p:[75,3,2743],t:7,e:"ui-display",a:{title:"Antibodies"},f:[{t:4,f:[{p:[77,5,2811],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[77,24,2830]}]},f:[{p:[78,7,2848],t:7,e:"ui-button",a:{icon:"eyedropper",state:[{t:2,x:{r:["data.is_ready"],s:'_0?"":"disabled"'},p:[78,43,2884]}],action:"create_vaccine_bottle",params:['{"index": ',{t:2,r:"id",p:[78,129,2970]},"}"]},f:["Create vaccine bottle"]}]}],n:52,r:"data.resistances",p:[76,4,2779]},{t:4,n:51,f:[{p:[83,5,3067],t:7,e:"ui-section",f:[{p:[84,6,3086],t:7,e:"span",a:{"class":"average"},f:["No antibodies detected in the blood sample."]}]}],r:"data.resistances"}]}],n:50,r:"data.has_blood",p:[37,2,1162]}],n:50,x:{r:["data.mode"],s:"_0==1"},p:[1,1,0]},{t:4,n:51,f:[{p:[90,2,3231],t:7,e:"ui-button",a:{icon:"undo",state:"",action:"back"},f:["Back"]}," ",{t:4,f:[{p:[94,4,3330],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[94,23,3349]}]},f:[{p:[95,4,3364],t:7,e:"ui-section",f:[{t:2,r:"desc",p:[96,5,3382]}," ",{t:4,f:[{p:[98,5,3417],t:7,e:"br"}," ",{p:[99,5,3428],t:7,e:"b",f:["This symptom has been neutered, and has no effect. It will still affect the virus' statistics."]}],n:50,r:"neutered",p:[97,4,3395]}]}," ",{p:[102,4,3564],t:7,e:"ui-section",f:[{p:[103,5,3582],t:7,e:"ui-section",a:{label:"Level"},f:[{t:2,r:"level",p:[103,31,3608]}]}," ",{p:[104,5,3636],t:7,e:"ui-section",a:{label:"Resistance"},f:[{t:2,r:"resistance",p:[104,36,3667]}]}," ",{p:[105,5,3700],t:7,e:"ui-section",a:{label:"Stealth"},f:[{t:2,r:"stealth",p:[105,33,3728]}]}," ",{p:[106,5,3758],t:7,e:"ui-section",a:{label:"Stage speed"},f:[{t:2,r:"stage_speed",p:[106,37,3790]}]}," ",{p:[107,5,3824],t:7,e:"ui-section",a:{label:"Transmittability"},f:[{t:2,r:"transmission",p:[107,42,3861]}]}]}]}],n:53,r:"data.symptom",p:[93,2,3303]}],x:{r:["data.mode"],s:"_0==1"}}]},e.exports=a.extend(r.exports)},{205:205}],284:[function(t,e,n){var a=t(205),r={exports:{}};!function(e){"use strict";var n=t(312);e.exports={data:{filter:"",tooltiptext:function(t,e,n){var a="";return t&&(a+="REQUIREMENTS: "+t+" "),e&&(a+="CATALYSTS: "+e+" "),n&&(a+="TOOLS: "+n),a}},oninit:function(){var t=this;this.on({hover:function(t){this.set("hovered",t.context.params)},unhover:function(t){this.set("hovered")}}),this.observe("filter",function(e,a,r){var i=null;i=t.get("data.display_compact")?t.findAll(".section"):t.findAll(".display:not(:first-child)"),(0,n.filterMulti)(i,t.get("filter").toLowerCase())},{init:!1})}}}(r),r.exports.template={v:3,t:[" ",{p:[48,1,1342],t:7,e:"ui-display",a:{title:[{t:2,r:"data.category",p:[48,20,1361]},{t:4,f:[" : ",{t:2,r:"data.subcategory",p:[48,64,1405]}],n:50,r:"data.subcategory",p:[48,37,1378]}]},f:[{t:4,f:[{p:[50,3,1459],t:7,e:"ui-section",f:["Crafting... ",{p:[51,16,1488],t:7,e:"i",a:{"class":"fa-spin fa fa-spinner"}}]}],n:50,r:"data.busy",p:[49,2,1438]},{t:4,n:51,f:[{p:[54,3,1557],t:7,e:"ui-section",f:[{p:[55,4,1574],t:7,e:"table",a:{style:"width:100%"},f:[{p:[56,5,1606],t:7,e:"tr",f:[{p:[57,6,1617],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[58,7,1659],t:7,e:"ui-button",a:{icon:"arrow-left",action:"backwardCat"},f:[{t:2,r:"data.prev_cat",p:[59,8,1718]}]}]}," ",{p:[62,6,1774],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[63,7,1816],t:7,e:"ui-button",a:{icon:"arrow-right",action:"forwardCat"},f:[{t:2,r:"data.next_cat",p:[64,7,1874]}]}]}," ",{p:[67,6,1930],t:7,e:"td",a:{style:"float:right!important"},f:[{t:4,f:[{p:[69,7,2014],t:7,e:"ui-button",a:{icon:"lock",action:"toggle_recipes"},f:["Showing Craftable Recipes"]}],n:50,r:"data.display_craftable_only",p:[68,6,1971]},{t:4,n:51,f:[{p:[73,7,2138],t:7,e:"ui-button",a:{icon:"unlock",action:"toggle_recipes"},f:["Showing All Recipes"]}],r:"data.display_craftable_only"}]}," ",{p:[78,6,2268],t:7,e:"td",a:{style:"float:right!important"},f:[{p:[79,7,2310],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.display_compact"],s:'_0?"check-square-o":"square-o"'},p:[79,24,2327]}],action:"toggle_compact"},f:["Compact"]}]}]}," ",{p:[84,5,2474],t:7,e:"tr",f:[{t:4,f:[{p:[86,6,2515],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[87,7,2557],t:7,e:"ui-button",a:{icon:"arrow-left",action:"backwardSubCat"},f:[{t:2,r:"data.prev_subcat",p:[88,8,2619]}]}]}," ",{p:[91,6,2678],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[92,7,2720],t:7,e:"ui-button",a:{icon:"arrow-right",action:"forwardSubCat"},f:[{t:2,r:"data.next_subcat",p:[93,8,2782]}]}]}],n:50,r:"data.subcategory",p:[85,5,2484]}]}]}," ",{t:4,f:[{t:4,f:[" ",{p:[101,6,2992],t:7,e:"ui-input",a:{value:[{t:2,r:"filter",p:[101,23,3009]}],placeholder:"Filter.."}}],n:51,r:"data.display_compact",p:[100,5,2902]}],n:50,r:"config.fancy",p:[99,4,2876]}]}," ",{t:4,f:[{p:[106,5,3144],t:7,e:"ui-display",f:[{t:4,f:[{p:[108,6,3193],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[108,25,3212]}]},f:[{p:[109,7,3230],t:7,e:"ui-button",a:{tooltip:[{t:2,x:{r:["tooltiptext","req_text","catalyst_text","tool_text"],s:"_0(_1,_2,_3)"},p:[109,27,3250]}],"tooltip-side":"right",action:"make",params:['{"recipe": "',{t:2,r:"ref",p:[109,135,3358]},'"}'],icon:"gears"},v:{hover:"hover",unhover:"unhover"},f:["Craft"]}]}],n:52,r:"data.can_craft",p:[107,5,3162]}," ",{t:4,f:[{t:4,f:[{p:[116,7,3567],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[116,26,3586]}]},f:[{p:[117,8,3605],t:7,e:"ui-button",a:{tooltip:[{t:2,x:{r:["tooltiptext","req_text","catalyst_text","tool_text"],s:"_0(_1,_2,_3)"},p:[117,28,3625]}],"tooltip-side":"right",state:"disabled",icon:"gears"},v:{hover:"hover",unhover:"unhover"},f:["Craft"]}]}],n:52,r:"data.cant_craft",p:[115,6,3534]}],n:51,r:"data.display_craftable_only",p:[114,5,3495]}]}],n:50,r:"data.display_compact",p:[105,4,3110]},{t:4,n:51,f:[{t:4,f:[{p:[126,6,3947],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[126,25,3966]}]},f:[{t:4,f:[{p:[128,8,4009],t:7,e:"ui-section",a:{label:"Requirements"},f:[{t:2,r:"req_text",p:[129,9,4052]}]}],n:50,r:"req_text",p:[127,7,3984]}," ",{t:4,f:[{p:[133,8,4139],t:7,e:"ui-section",a:{label:"Catalysts"},f:[{t:2,r:"catalyst_text",p:[134,9,4179]}]}],n:50,r:"catalyst_text",p:[132,7,4109]}," ",{t:4,f:[{p:[138,8,4267],t:7,e:"ui-section",a:{label:"Tools"},f:[{t:2,r:"tool_text",p:[139,9,4303]}]}],n:50,r:"tool_text",p:[137,7,4241]}," ",{p:[142,7,4361],t:7,e:"ui-section",f:[{p:[143,8,4382],t:7,e:"ui-button",a:{icon:"gears",action:"make",params:['{"recipe": "',{t:2,r:"ref",p:[143,66,4440]},'"}']},f:["Craft"]}]}]}],n:52,r:"data.can_craft",p:[125,5,3916]}," ",{t:4,f:[{t:4,f:[{p:[151,7,4621],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[151,26,4640]}]},f:[{t:4,f:[{p:[153,9,4685],t:7,e:"ui-section",a:{label:"Requirements"},f:[{t:2,r:"req_text",p:[154,10,4729]}]}],n:50,r:"req_text",p:[152,8,4659]}," ",{t:4,f:[{p:[158,9,4820],t:7,e:"ui-section",a:{label:"Catalysts"},f:[{t:2,r:"catalyst_text",p:[159,10,4861]}]}],n:50,r:"catalyst_text",p:[157,8,4789]}," ",{t:4,f:[{p:[163,9,4953],t:7,e:"ui-section",a:{label:"Tools"},f:[{t:2,r:"tool_text",p:[164,10,4990]}]}],n:50,r:"tool_text",p:[162,8,4926]}]}],n:52,r:"data.cant_craft",p:[150,6,4588]}],n:51,r:"data.display_craftable_only",p:[149,5,4549]}],r:"data.display_compact"}],r:"data.busy"}]}]},e.exports=a.extend(r.exports)},{205:205,312:312}],285:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.holding"],s:'_0?"is":"is not"'},p:[2,23,35]}," connected to a tank."]}]}," ",{p:[4,1,113],t:7,e:"ui-display",a:{title:"Status",button:0},f:[{p:[5,3,151],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,5,186],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[6,11,192]}," kPa"]}]}," ",{p:[8,3,254],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[9,5,285],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected"],s:'_0?"good":"average"'},p:[9,18,298]}]},f:[{t:2,x:{r:["data.connected"],s:'_0?"Connected":"Not Connected"'},p:[9,59,339]}]}]}]}," ",{p:[12,1,430],t:7,e:"ui-display",a:{title:"Pump"},f:[{p:[13,3,459],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,5,491],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[14,22,508]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":"null"'},p:[15,14,559]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[16,22,616]}]}]}," ",{p:[18,3,675],t:7,e:"ui-section",a:{label:"Direction"},f:[{p:[19,5,711],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.direction"],s:'_0=="out"?"sign-out":"sign-in"'},p:[19,22,728]}],action:"direction"},f:[{t:2,x:{r:["data.direction"],s:'_0=="out"?"Out":"In"'},p:[20,26,808]}]}]}," ",{p:[22,3,883],t:7,e:"ui-section",a:{label:"Target Pressure"},f:[{p:[23,5,925],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.min_pressure",p:[23,18,938]}],max:[{t:2,r:"data.max_pressure",p:[23,46,966]}],value:[{t:2,r:"data.target_pressure",p:[24,14,1003]}]},f:[{t:2,x:{r:["adata.target_pressure"],s:"Math.round(_0)"},p:[24,40,1029]}," kPa"]}]}," ",{p:[26,3,1100],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[27,5,1145],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.target_pressure","data.default_pressure"],s:'_0!=_1?null:"disabled"'},p:[27,38,1178]}],action:"pressure",params:'{"pressure": "reset"}' +-},f:["Reset"]}," ",{p:[29,5,1328],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.target_pressure","data.min_pressure"],s:'_0>_1?null:"disabled"'},p:[29,36,1359]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[31,5,1500],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[32,5,1595],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.target_pressure","data.max_pressure"],s:'_0<_1?null:"disabled"'},p:[32,35,1625]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}]}," ",{p:{button:[{t:4,f:[{p:[39,7,1891],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.on"],s:'_0?"danger":null'},p:[39,38,1922]}],action:"eject"},f:["Eject"]}],n:50,r:"data.holding",p:[38,5,1863]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[43,3,2042],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holding.name",p:[44,4,2073]}]}," ",{p:[46,3,2115],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holding.pressure"],s:"Math.round(_0)"},p:[47,4,2149]}," kPa"]}],n:50,r:"data.holding",p:[42,3,2018]},{t:4,n:51,f:[{p:[50,3,2223],t:7,e:"ui-section",f:[{p:[51,4,2240],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.holding"}]}]},e.exports=a.extend(r.exports)},{205:205}],286:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.holding"],s:'_0?"is":"is not"'},p:[2,23,35]}," connected to a tank."]}]}," ",{p:[4,1,113],t:7,e:"ui-display",a:{title:"Status",button:0},f:[{p:[5,3,151],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,5,186],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[6,11,192]}," kPa"]}]}," ",{p:[8,3,254],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[9,5,285],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected"],s:'_0?"good":"average"'},p:[9,18,298]}]},f:[{t:2,x:{r:["data.connected"],s:'_0?"Connected":"Not Connected"'},p:[9,59,339]}]}]}]}," ",{p:[12,1,430],t:7,e:"ui-display",a:{title:"Filter"},f:[{p:[13,3,461],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,5,493],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[14,22,510]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":"null"'},p:[15,14,561]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[16,22,618]}]}]}]}," ",{p:{button:[{t:4,f:[{p:[22,7,787],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.on"],s:'_0?"danger":null'},p:[22,38,818]}],action:"eject"},f:["Eject"]}],n:50,r:"data.holding",p:[21,5,759]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[26,3,938],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holding.name",p:[27,4,969]}]}," ",{p:[29,3,1011],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holding.pressure"],s:"Math.round(_0)"},p:[30,4,1045]}," kPa"]}],n:50,r:"data.holding",p:[25,3,914]},{t:4,n:51,f:[{p:[33,3,1119],t:7,e:"ui-section",f:[{p:[34,4,1136],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.holding"}]}]},e.exports=a.extend(r.exports)},{205:205}],287:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{chargingState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},chargingMode:function(t){return 2==t?"Full":1==t?"Charging":"Draining"},channelState:function(t){return t>=2?"good":"bad"},channelPower:function(t){return t>=2?"On":"Off"},channelMode:function(t){return 1==t||3==t?"Auto":"Manual"}},computed:{graphData:function(){var t=this.get("data.history");return Object.keys(t).map(function(e){return t[e].map(function(t,e){return{x:e,y:t}})})}}}}(r),r.exports.template={v:3,t:[" ",{p:[42,1,1035],t:7,e:"ui-display",a:{title:"Network"},f:[{t:4,f:[{p:[44,5,1093],t:7,e:"ui-linegraph",a:{points:[{t:2,r:"graphData",p:[44,27,1115]}],height:"500",legend:'["Available", "Load"]',colors:'["rgb(0, 102, 0)", "rgb(153, 0, 0)"]',xunit:"seconds ago",xfactor:[{t:2,r:"data.interval",p:[46,38,1267]}],yunit:"W",yfactor:"1",xinc:[{t:2,x:{r:["data.stored"],s:"_0/10"},p:[47,15,1323]}],yinc:"9"}}],n:50,r:"config.fancy",p:[43,3,1067]},{t:4,n:51,f:[{p:[49,5,1373],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[50,7,1411],t:7,e:"span",f:[{t:2,r:"data.supply",p:[50,13,1417]}," W"]}]}," ",{p:[52,5,1466],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[53,9,1501],t:7,e:"span",f:[{t:2,r:"data.demand",p:[53,15,1507]}," W"]}]}],r:"config.fancy"}]}," ",{p:[57,1,1578],t:7,e:"ui-display",a:{title:"Areas"},f:[{p:[58,3,1608],t:7,e:"ui-section",a:{nowrap:0},f:[{p:[59,5,1633],t:7,e:"div",a:{"class":"content"},f:["Area"]}," ",{p:[60,5,1670],t:7,e:"div",a:{"class":"content"},f:["Charge"]}," ",{p:[61,5,1709],t:7,e:"div",a:{"class":"content"},f:["Load"]}," ",{p:[62,5,1746],t:7,e:"div",a:{"class":"content"},f:["Status"]}," ",{p:[63,5,1785],t:7,e:"div",a:{"class":"content"},f:["Equipment"]}," ",{p:[64,5,1827],t:7,e:"div",a:{"class":"content"},f:["Lighting"]}," ",{p:[65,5,1868],t:7,e:"div",a:{"class":"content"},f:["Environment"]}]}," ",{t:4,f:[{p:[68,5,1953],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[68,24,1972]}],nowrap:0},f:[{p:[69,7,1997],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].charge)"},p:[69,28,2018]}," %"]}," ",{p:[70,7,2076],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].load)"},p:[70,28,2097]}," W"]}," ",{p:[71,7,2153],t:7,e:"div",a:{"class":"content"},f:[{p:[71,28,2174],t:7,e:"span",a:{"class":[{t:2,x:{r:["chargingState","charging"],s:"_0(_1)"},p:[71,41,2187]}]},f:[{t:2,x:{r:["chargingMode","charging"],s:"_0(_1)"},p:[71,70,2216]}]}]}," ",{p:[72,7,2263],t:7,e:"div",a:{"class":"content"},f:[{p:[72,28,2284],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","eqp"],s:"_0(_1)"},p:[72,41,2297]}]},f:[{t:2,x:{r:["channelPower","eqp"],s:"_0(_1)"},p:[72,64,2320]}," [",{p:[72,87,2343],t:7,e:"span",f:[{t:2,x:{r:["channelMode","eqp"],s:"_0(_1)"},p:[72,93,2349]}]},"]"]}]}," ",{p:[73,7,2398],t:7,e:"div",a:{"class":"content"},f:[{p:[73,28,2419],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","lgt"],s:"_0(_1)"},p:[73,41,2432]}]},f:[{t:2,x:{r:["channelPower","lgt"],s:"_0(_1)"},p:[73,64,2455]}," [",{p:[73,87,2478],t:7,e:"span",f:[{t:2,x:{r:["channelMode","lgt"],s:"_0(_1)"},p:[73,93,2484]}]},"]"]}]}," ",{p:[74,7,2533],t:7,e:"div",a:{"class":"content"},f:[{p:[74,28,2554],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","env"],s:"_0(_1)"},p:[74,41,2567]}]},f:[{t:2,x:{r:["channelPower","env"],s:"_0(_1)"},p:[74,64,2590]}," [",{p:[74,87,2613],t:7,e:"span",f:[{t:2,x:{r:["channelMode","env"],s:"_0(_1)"},p:[74,93,2619]}]},"]"]}]}]}],n:52,r:"data.areas",p:[67,3,1927]}]}]},e.exports=a.extend(r.exports)},{205:205}],288:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{readableFrequency:function(){return Math.round(this.get("adata.frequency"))/10}}}}(r),r.exports.template={v:3,t:[" ",{p:[11,1,177],t:7,e:"ui-display",a:{title:"Settings"},f:[{t:4,f:[{p:[13,5,236],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,7,270],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.listening"],s:'_0?"power-off":"close"'},p:[14,24,287]}],style:[{t:2,x:{r:["data.listening"],s:'_0?"selected":null'},p:[14,75,338]}],action:"listen"},f:[{t:2,x:{r:["data.listening"],s:'_0?"On":"Off"'},p:[16,9,413]}]}]}],n:50,r:"data.headset",p:[12,3,210]},{t:4,n:51,f:[{p:[19,5,494],t:7,e:"ui-section",a:{label:"Microphone"},f:[{p:[20,7,533],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.broadcasting"],s:'_0?"power-off":"close"'},p:[20,24,550]}],style:[{t:2,x:{r:["data.broadcasting"],s:'_0?"selected":null'},p:[20,78,604]}],action:"broadcast"},f:[{t:2,x:{r:["data.broadcasting"],s:'_0?"Engaged":"Disengaged"'},p:[22,9,685]}]}]}," ",{p:[24,5,769],t:7,e:"ui-section",a:{label:"Speaker"},f:[{p:[25,7,805],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.listening"],s:'_0?"power-off":"close"'},p:[25,24,822]}],style:[{t:2,x:{r:["data.listening"],s:'_0?"selected":null'},p:[25,75,873]}],action:"listen"},f:[{t:2,x:{r:["data.listening"],s:'_0?"Engaged":"Disengaged"'},p:[27,9,948]}]}]}],r:"data.headset"}," ",{t:4,f:[{p:[31,5,1064],t:7,e:"ui-section",a:{label:"High Volume"},f:[{p:[32,7,1104],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.useCommand"],s:'_0?"power-off":"close"'},p:[32,24,1121]}],style:[{t:2,x:{r:["data.useCommand"],s:'_0?"selected":null'},p:[32,76,1173]}],action:"command"},f:[{t:2,x:{r:["data.useCommand"],s:'_0?"On":"Off"'},p:[34,9,1250]}]}]}],n:50,r:"data.command",p:[30,3,1038]}]}," ",{p:[38,1,1342],t:7,e:"ui-display",a:{title:"Channel"},f:[{p:[39,3,1374],t:7,e:"ui-section",a:{label:"Frequency"},f:[{t:4,f:[{p:[41,7,1439],t:7,e:"span",f:[{t:2,r:"readableFrequency",p:[41,13,1445]}]}],n:50,r:"data.freqlock",p:[40,5,1410]},{t:4,n:51,f:[{p:[43,7,1495],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.frequency","data.minFrequency"],s:'_0==_1?"disabled":null'},p:[43,46,1534]}],action:"frequency",params:'{"adjust": -1}'}}," ",{p:[44,7,1646],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.frequency","data.minFrequency"],s:'_0==_1?"disabled":null'},p:[44,41,1680]}],action:"frequency",params:'{"adjust": -.2}'}}," ",{p:[45,7,1793],t:7,e:"ui-button",a:{icon:"pencil",action:"frequency",params:'{"tune": "input"}'},f:[{t:2,r:"readableFrequency",p:[45,78,1864]}]}," ",{p:[46,7,1905],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.frequency","data.maxFrequency"],s:'_0==_1?"disabled":null'},p:[46,40,1938]}],action:"frequency",params:'{"adjust": .2}'}}," ",{p:[47,7,2050],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.frequency","data.maxFrequency"],s:'_0==_1?"disabled":null'},p:[47,45,2088]}],action:"frequency",params:'{"adjust": 1}'}}],r:"data.freqlock"}]}," ",{t:4,f:[{p:[51,5,2262],t:7,e:"ui-section",a:{label:"Subspace Transmission"},f:[{p:[52,7,2312],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.subspace"],s:'_0?"power-off":"close"'},p:[52,24,2329]}],style:[{t:2,x:{r:["data.subspace"],s:'_0?"selected":null'},p:[52,74,2379]}],action:"subspace"},f:[{t:2,x:{r:["data.subspace"],s:'_0?"Active":"Inactive"'},p:[53,29,2447]}]}]}],n:50,r:"data.subspaceSwitchable",p:[50,3,2225]}," ",{t:4,f:[{p:[57,5,2578],t:7,e:"ui-section",a:{label:"Channels"},f:[{t:4,f:[{p:[59,9,2656],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["."],s:'_0?"check-square-o":"square-o"'},p:[59,26,2673]}],style:[{t:2,x:{r:["."],s:'_0?"selected":null'},p:[60,18,2730]}],action:"channel",params:['{"channel": "',{t:2,r:"channel",p:[61,49,2806]},'"}']},f:[{t:2,r:"channel",p:[62,11,2833]}]},{p:[62,34,2856],t:7,e:"br"}],n:52,i:"channel",r:"data.channels",p:[58,7,2615]}]}],n:50,x:{r:["data.subspace","data.channels"],s:"_0&&_1"},p:[56,3,2534]}]}]},e.exports=a.extend(r.exports)},{205:205}],289:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,23],t:7,e:"ui-notice",f:[{t:2,r:"data.notice",p:[3,5,40]}]}],n:50,r:"data.notice",p:[1,1,0]},{p:[6,1,82],t:7,e:"ui-display",a:{title:"Satellite Network Control",button:0},f:[{t:4,f:[{p:[8,4,168],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[9,9,209],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[9,31,231]}]}," ",{p:[10,9,253],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"mode",p:[10,30,274]}]}," ",{p:[11,9,298],t:7,e:"div",a:{"class":"content"},f:[{p:[12,11,331],t:7,e:"ui-button",a:{action:"toggle",params:['{"id": "',{t:2,r:"id",p:[12,54,374]},'"}']},f:[{t:2,x:{r:["active"],s:'_0?"Deactivate":"Activate"'},p:[12,64,384]}]}]}]}],n:52,r:"data.satellites",p:[7,2,138]}]}," ",{t:4,f:[{p:[18,1,528],t:7,e:"ui-display",a:{title:"Station Shield Coverage"},f:[{p:[19,3,576],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.meteor_shield_coverage_max",p:[19,24,597]}],value:[{t:2,r:"data.meteor_shield_coverage",p:[19,68,641]}]},f:[{t:2,x:{r:["data.meteor_shield_coverage","data.meteor_shield_coverage_max"],s:"100*_0/_1"},p:[19,101,674]}," %"]}," ",{p:[20,1,758],t:7,e:"ui-display",f:[]}]}],n:50,r:"data.meteor_shield",p:[17,1,500]}]},e.exports=a.extend(r.exports)},{205:205}],290:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" "," "," ",{p:[5,1,200],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.tabs",p:[5,16,215]}]},f:[{p:[6,2,233],t:7,e:"tab",a:{name:"Status"},f:[{p:[7,3,256],t:7,e:"status"}]}," ",{p:[9,2,277],t:7,e:"tab",a:{name:"Templates"},f:[{p:[10,3,303],t:7,e:"templates"}]}," ",{p:[12,2,327],t:7,e:"tab",a:{name:"Modification"},f:[{t:4,f:[{p:[14,3,381],t:7,e:"modification"}],n:50,r:"data.selected",p:[13,3,356]}," ",{t:4,f:[{p:[17,3,437],t:7,e:"span",a:{"class":"bad"},f:["No shuttle selected."]}],n:50,x:{r:["data.selected"],s:"!_0"},p:[16,3,411]}]}]}]},r.exports.components=r.exports.components||{};var i={modification:t(291),templates:t(293),status:t(292)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,291:291,292:292,293:293}],291:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:["Selected: ",{t:2,r:"data.selected.name",p:[1,30,29]}]},f:[{t:4,f:[{p:[3,5,96],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.selected.description",p:[3,37,128]}]}],n:50,r:"data.selected.description",p:[2,3,57]}," ",{t:4,f:[{p:[6,5,224],t:7,e:"ui-section",a:{label:"Admin Notes"},f:[{t:2,r:"data.selected.admin_notes",p:[6,37,256]}]}],n:50,r:"data.selected.admin_notes",p:[5,3,185]}]}," ",{t:4,f:[{p:[11,3,361],t:7,e:"ui-display",a:{title:["Existing Shuttle: ",{t:2,r:"data.existing_shuttle.name",p:[11,40,398]}]},f:["Status: ",{t:2,r:"data.existing_shuttle.status",p:[12,13,444]}," ",{t:4,f:["(",{t:2,r:"data.existing_shuttle.timeleft",p:[14,8,526]},")"],n:50,r:"data.existing_shuttle.timer",p:[13,5,482]}," ",{p:[16,5,580],t:7,e:"ui-button",a:{action:"jump_to",params:['{"type": "mobile", "id": "',{t:2,r:"data.existing_shuttle.id",p:[17,41,649]},'"}']},f:["Jump To"]}]}],n:50,r:"data.existing_shuttle",p:[10,1,328]},{t:4,f:[{p:[24,3,778],t:7,e:"ui-display",a:{title:"Existing Shuttle: None"}}],n:50,x:{r:["data.existing_shuttle"],s:"!_0"},p:[23,1,744]},{p:[27,1,847],t:7,e:"ui-button",a:{action:"preview",params:['{"shuttle_id": "',{t:2,r:"data.selected.shuttle_id",p:[28,27,902]},'"}']},f:["Preview"]}," ",{p:[31,1,961],t:7,e:"ui-button",a:{action:"load",params:['{"shuttle_id": "',{t:2,r:"data.selected.shuttle_id",p:[32,27,1013]},'"}'],style:"danger"},f:["Load"]}," ",{p:[37,1,1089],t:7,e:"ui-display",a:{title:"Status"},f:[]}]},e.exports=a.extend(r.exports)},{205:205}],292:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,27],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[2,22,46]}," (",{t:2,r:"id",p:[2,32,56]},")"]},f:[{t:2,r:"status",p:[3,5,71]}," ",{t:4,f:["(",{t:2,r:"timeleft",p:[5,8,109]},")"],n:50,r:"timer",p:[4,5,87]}," ",{p:[7,5,141],t:7,e:"ui-button",a:{action:"jump_to",params:['{"type": "mobile", "id": "',{t:2,r:"id",p:[7,67,203]},'"}']},f:["Jump To"]}," ",{p:[10,5,252],t:7,e:"ui-button",a:{action:"fast_travel",params:['{"id": "',{t:2,r:"id",p:[10,53,300]},'"}'],state:[{t:2,x:{r:["can_fast_travel"],s:'_0?null:"disabled"'},p:[10,70,317]}]},f:["Fast Travel"]}]}],n:52,r:"data.shuttles",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],293:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.templates_tabs",p:[1,16,15]}]},f:[{t:4,f:[{p:[3,5,74],t:7,e:"tab",a:{name:[{t:2,r:"port_id",p:[3,16,85]}]},f:[{t:4,f:[{p:[5,9,135],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[5,28,154]}]},f:[{t:4,f:[{p:[7,13,209],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"description",p:[7,45,241]}]}],n:50,r:"description",p:[6,11,176]}," ",{t:4,f:[{p:[10,13,333],t:7,e:"ui-section",a:{label:"Admin Notes"},f:[{t:2,r:"admin_notes",p:[10,45,365]}]}],n:50,r:"admin_notes",p:[9,11,300]}," ",{p:[13,11,426],t:7,e:"ui-button",a:{action:"select_template",params:['{"shuttle_id": "',{t:2,r:"shuttle_id",p:[14,37,499]},'"}'],state:[{t:2,x:{r:["data.selected.shuttle_id","shuttle_id"],s:'_0==_1?"selected":null'},p:[15,20,537]}]},f:[{t:2,x:{r:["data.selected.shuttle_id","shuttle_id"],s:'_0==_1?"Selected":"Select"'},p:[17,13,630]}]}]}],n:52,r:"templates",p:[4,7,106]}]}],n:52,r:"data.templates",p:[2,3,44]}]}]},e.exports=a.extend(r.exports)},{205:205}],294:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{occupantStatState:function(){switch(this.get("data.occupant.stat")){case 0:return"good";case 1:return"average";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[15,1,280],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[16,3,313],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[17,3,346],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[17,9,352]}]}]}," ",{t:4,f:[{p:[20,5,466],t:7,e:"ui-section",a:{label:"State"},f:[{p:[21,7,500],t:7,e:"span",a:{"class":[{t:2,r:"occupantStatState",p:[21,20,513]}]},f:[{t:2,x:{r:["data.occupant.stat"],s:'_0==0?"Conscious":_0==1?"Unconcious":"Dead"'},p:[21,43,536]}]}]}," ",{p:[23,5,658],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[24,7,693],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[24,20,706]}],max:[{t:2,r:"data.occupant.maxHealth",p:[24,54,740]}],value:[{t:2,r:"data.occupant.health",p:[24,90,776]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[25,16,818]}]},f:[{t:2,x:{r:["adata.occupant.health"],s:"Math.round(_0)"},p:[25,68,870]}]}]}," ",{t:4,f:[{p:[28,7,1107],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[28,26,1126]}]},f:[{p:[29,9,1147],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[29,30,1168]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[29,66,1204]}],state:"bad"},f:[{t:2,x:{r:["type","adata.occupant"],s:"Math.round(_1[_0])"},p:[29,103,1241]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[27,5,941]}," ",{p:[32,5,1328],t:7,e:"ui-section",a:{label:"Cells"},f:[{p:[33,9,1364],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"bad":"good"'},p:[33,22,1377]}]},f:[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"Damaged":"Healthy"'},p:[33,68,1423]}]}]}," ",{p:[35,5,1506],t:7,e:"ui-section",a:{label:"Brain"},f:[{p:[36,9,1542],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"bad":"good"'},p:[36,22,1555]}]},f:[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"Abnormal":"Healthy"'},p:[36,68,1601]}]}]}," ",{p:[38,5,1685],t:7,e:"ui-section",a:{label:"Bloodstream"},f:[{t:4,f:[{p:[40,11,1772],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,1)"},p:[40,54,1815]}," units of ",{t:2,r:"name",p:[40,89,1850]}]},{p:[40,104,1865],t:7,e:"br"}],n:52,r:"adata.occupant.reagents",p:[39,9,1727]},{t:4,n:51,f:[{p:[42,11,1900],t:7,e:"span",a:{"class":"good"},f:["Pure"]}],r:"adata.occupant.reagents"}]}],n:50,r:"data.occupied",p:[19,3,439]}]}," ",{p:[47,1,1996],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[48,2,2028],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[49,5,2059],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"unlock":"lock"'},p:[49,22,2076]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Open":"Closed"'},p:[49,71,2125]}]}]}," ",{p:[51,3,2190],t:7,e:"ui-section",a:{label:"Inject"},f:[{t:4,f:[{p:[53,7,2251],t:7,e:"ui-button",a:{icon:"flask",state:[{t:2,x:{r:["data.occupied","allowed"],s:'_0&&_1?null:"disabled"'},p:[53,38,2282]}],action:"inject",params:['{"chem": "',{t:2,r:"id",p:[53,122,2366]},'"}']},f:[{t:2,r:"name",p:[53,132,2376]}]},{p:[53,152,2396],t:7,e:"br"}],n:52,r:"data.chems",p:[52,5,2223]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],295:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,25],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[2,22,44]}],labelcolor:[{t:2,r:"htmlcolor",p:[2,44,66]}],candystripe:0,right:0},f:[{p:[3,5,105],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[3,32,132],t:7,e:"span",a:{"class":[{t:2,x:{r:["status"],s:'_0=="Dead"?"bad bold":_0=="Unconscious"?"average bold":"good"'},p:[3,45,145]}]},f:[{t:2,r:"status",p:[3,132,232]}]}]}," ",{p:[4,5,268],t:7,e:"ui-section",a:{label:"Jelly"},f:[{t:2,r:"exoticblood",p:[4,31,294]}]}," ",{p:[5,5,328],t:7,e:"ui-section",a:{label:"Location"},f:[{t:2,r:"area",p:[5,34,357]}]}," ",{p:[7,5,386],t:7,e:"ui-button",a:{state:[{t:2,r:"swap_button_state",p:[8,14,411]}],action:"swap",params:['{"ref": "',{t:2,r:"ref",p:[9,38,472]},'"}']},f:[{t:2,x:{r:["is_current"],s:'_0?"You Are Here":"Swap"'},p:[10,7,491]}]}]}],n:52,r:"data.bodies",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],296:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{capacityPercentState:function(){var t=this.get("data.capacityPercent");return t>50?"good":t>15?"average":"bad"},inputState:function(){return this.get("data.capacityPercent")>=100?"good":this.get("data.inputting")?"average":"bad"},outputState:function(){return this.get("data.outputting")?"good":this.get("data.charge")>0?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[24,1,663],t:7,e:"ui-display",a:{title:"Storage"},f:[{p:[25,3,695],t:7,e:"ui-section",a:{label:"Stored Energy"},f:[{p:[26,5,735],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.capacityPercent",p:[26,38,768]}],state:[{t:2,r:"capacityPercentState",p:[26,71,801]}]},f:[{t:2,x:{r:["adata.capacityPercent"],s:"Math.fixed(_0)"},p:[26,97,827]},"%"]}]}]}," ",{p:[29,1,908],t:7,e:"ui-display",a:{title:"Input"},f:[{p:[30,3,938],t:7,e:"ui-section",a:{label:"Charge Mode"},f:[{p:[31,5,976],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"refresh":"close"'},p:[31,22,993]}],style:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"selected":null'},p:[31,74,1045]}],action:"tryinput"},f:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"Auto":"Off"'},p:[32,25,1113]}]},"   [",{p:[34,6,1182],t:7,e:"span",a:{"class":[{t:2,r:"inputState",p:[34,19,1195]}]},f:[{t:2,x:{r:["data.capacityPercent","data.inputting"],s:'_0>=100?"Fully Charged":_1?"Charging":"Not Charging"'},p:[34,35,1211]}]},"]"]}," ",{p:[36,3,1335],t:7,e:"ui-section",a:{label:"Target Input"},f:[{p:[37,5,1374],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.inputLevelMax",p:[37,26,1395]}],value:[{t:2,r:"data.inputLevel",p:[37,57,1426]}]},f:[{t:2,x:{r:["adata.inputLevel"],s:"Math.round(_0)"},p:[37,78,1447]},"W"]}]}," ",{p:[39,3,1509],t:7,e:"ui-section",a:{label:"Adjust Input"},f:[{p:[40,5,1548],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.inputLevel"],s:'_0==0?"disabled":null'},p:[40,44,1587]}],action:"input",params:'{"target": "min"}'}}," ",{p:[41,5,1682],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.inputLevel"],s:'_0==0?"disabled":null'},p:[41,39,1716]}],action:"input",params:'{"adjust": -10000}'}}," ",{p:[42,5,1812],t:7,e:"ui-button",a:{icon:"pencil",action:"input",params:'{"target": "input"}'},f:["Set"]}," ",{p:[43,5,1902],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.inputLevel","data.inputLevelMax"],s:'_0==_1?"disabled":null'},p:[43,38,1935]}],action:"input",params:'{"adjust": 10000}'}}," ",{p:[44,5,2047],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.inputLevel","data.inputLevelMax"],s:'_0==_1?"disabled":null'},p:[44,43,2085]}],action:"input",params:'{"target": "max"}'}}]}," ",{p:[46,3,2212],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[47,3,2246],t:7,e:"span",f:[{t:2,x:{r:["adata.inputAvailable"],s:"Math.round(_0)"},p:[47,9,2252]},"W"]}]}]}," ",{p:[50,1,2329],t:7,e:"ui-display",a:{title:"Output"},f:[{p:[51,3,2360],t:7,e:"ui-section",a:{label:"Output Mode"},f:[{p:[52,5,2398],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"power-off":"close"'},p:[52,22,2415]}],style:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"selected":null'},p:[52,77,2470]}],action:"tryoutput"},f:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"On":"Off"'},p:[53,26,2540]}]},"   [",{p:[55,6,2608],t:7,e:"span",a:{"class":[{t:2,r:"outputState",p:[55,19,2621]}]},f:[{t:2,x:{r:["data.outputting","data.charge"],s:'_0?"Sending":_1>0?"Not Sending":"No Charge"'},p:[55,36,2638]}]},"]"]}," ",{p:[57,3,2745],t:7,e:"ui-section",a:{label:"Target Output"},f:[{p:[58,5,2785],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.outputLevelMax",p:[58,26,2806]}],value:[{t:2,r:"data.outputLevel",p:[58,58,2838]}]},f:[{t:2,x:{r:["adata.outputLevel"],s:"Math.round(_0)"},p:[58,80,2860]},"W"]}]}," ",{p:[60,3,2923],t:7,e:"ui-section",a:{label:"Adjust Output"},f:[{p:[61,5,2963],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.outputLevel"],s:'_0==0?"disabled":null'},p:[61,44,3002]}],action:"output",params:'{"target": "min"}'}}," ",{p:[62,5,3099],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.outputLevel"],s:'_0==0?"disabled":null'},p:[62,39,3133]}],action:"output",params:'{"adjust": -10000}'}}," ",{p:[63,5,3231],t:7,e:"ui-button",a:{icon:"pencil",action:"output",params:'{"target": "input"}'},f:["Set"]}," ",{p:[64,5,3322],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.outputLevel","data.outputLevelMax"],s:'_0==_1?"disabled":null'},p:[64,38,3355]}],action:"output",params:'{"adjust": 10000}'}}," ",{p:[65,5,3470],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.outputLevel","data.outputLevelMax"],s:'_0==_1?"disabled":null'},p:[65,43,3508]}],action:"output",params:'{"target": "max"}'}}]}," ",{p:[67,3,3638],t:7,e:"ui-section",a:{label:"Outputting"},f:[{p:[68,3,3673],t:7,e:"span",f:[{t:2,x:{r:["adata.outputUsed"],s:"Math.round(_0)"},p:[68,9,3679]},"W"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],297:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,3,31],t:7,e:"ui-section",a:{label:"Generated Power"},f:[{t:2,x:{r:["adata.generated"],s:"Math.round(_0)"},p:[3,5,73]},"W"]}," ",{p:[5,3,126],t:7,e:"ui-section",a:{label:"Orientation"},f:[{p:[6,5,164],t:7,e:"span",f:[{t:2,x:{r:["adata.angle"],s:"Math.round(_0)"},p:[6,11,170]},"° (",{t:2,r:"data.direction",p:[6,45,204]},")"]}]}," ",{p:[8,3,251],t:7,e:"ui-section",a:{label:"Adjust Angle"},f:[{p:[9,5,290],t:7,e:"ui-button",a:{icon:"step-backward",action:"angle",params:'{"adjust": -15}'},f:["15°"]}," ",{p:[10,5,387],t:7,e:"ui-button",a:{icon:"backward",action:"angle",params:'{"adjust": -5}'},f:["5°"]}," ",{p:[11,5,477],t:7,e:"ui-button",a:{icon:"forward",action:"angle",params:'{"adjust": 5}'},f:["5°"]}," ",{p:[12,5,565],t:7,e:"ui-button",a:{icon:"step-forward",action:"angle",params:'{"adjust": 15}'},f:["15°"]}]}]}," ",{p:[15,1,687],t:7,e:"ui-display",a:{title:"Tracking"},f:[{p:[16,3,720],t:7,e:"ui-section",a:{label:"Tracker Mode"},f:[{p:[17,5,759],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.tracking_state"],s:'_0==0?"selected":null'},p:[17,36,790]}],action:"tracking",params:'{"mode": 0}'},f:["Off"]}," ",{p:[19,5,907],t:7,e:"ui-button",a:{icon:"clock-o",state:[{t:2,x:{r:["data.tracking_state"],s:'_0==1?"selected":null'},p:[19,38,940]}],action:"tracking",params:'{"mode": 1}'},f:["Timed"]}," ",{p:[21,5,1059],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.connected_tracker","data.tracking_state"],s:'_0?_1==2?"selected":null:"disabled"'},p:[21,38,1092]}],action:"tracking",params:'{"mode": 2}'},f:["Auto"]}]}," ",{p:[24,3,1262],t:7,e:"ui-section",a:{label:"Tracking Rate"},f:[{p:[25,3,1300],t:7,e:"span",f:[{t:2,x:{r:["adata.tracking_rate"],s:"Math.round(_0)"},p:[25,9,1306]},"°/h (",{t:2,r:"data.rotating_way",p:[25,53,1350]},")"]}]}," ",{p:[27,3,1399],t:7,e:"ui-section",a:{label:"Adjust Rate"},f:[{p:[28,5,1437],t:7,e:"ui-button",a:{icon:"fast-backward",action:"rate",params:'{"adjust": -180}'},f:["180°"]}," ",{p:[29,5,1535],t:7,e:"ui-button",a:{icon:"step-backward",action:"rate",params:'{"adjust": -30}'},f:["30°"]}," ",{p:[30,5,1631],t:7,e:"ui-button",a:{icon:"backward",action:"rate",params:'{"adjust": -5}'},f:["5°"]}," ",{p:[31,5,1720],t:7,e:"ui-button",a:{icon:"forward",action:"rate",params:'{"adjust": 5}'},f:["5°"]}," ",{p:[32,5,1807],t:7,e:"ui-button",a:{icon:"step-forward",action:"rate",params:'{"adjust": 30}'},f:["30°"]}," ",{p:[33,5,1901],t:7,e:"ui-button",a:{icon:"fast-forward",action:"rate",params:'{"adjust": 180}'},f:["180°"]}]}]}," ",{p:{button:[{p:[38,5,2088],t:7,e:"ui-button",a:{icon:"refresh",action:"refresh"},f:["Refresh"]}]},t:7,e:"ui-display",a:{title:"Devices",button:0},f:[" ",{p:[40,2,2169],t:7,e:"ui-section",a:{label:"Solar Tracker"},f:[{p:[41,5,2209],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected_tracker"],s:'_0?"good":"bad"'},p:[41,18,2222]}]},f:[{t:2,x:{r:["data.connected_tracker"],s:'_0?"":"Not "'},p:[41,63,2267]},"Found"]}]}," ",{p:[43,2,2338],t:7,e:"ui-section",a:{label:"Solar Panels"},f:[{p:[44,3,2375],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected_panels"],s:'_0?"good":"bad"'},p:[44,16,2388]}]},f:[{t:2,x:{r:["adata.connected_panels"],s:"Math.round(_0)"},p:[44,60,2432]}," Panels Connected"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],298:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{t:4,f:[{p:[4,7,87],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.hasPowercell"],s:'_0?null:"disabled"'},p:[4,38,118]}],action:"eject"},f:["Eject"]}],n:50,r:"data.open",p:[3,5,62]}]},t:7,e:"ui-display",a:{title:"Power",button:0},f:[" ",{p:[7,3,226],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[8,5,258],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[8,22,275]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[9,14,326]}],state:[{t:2,x:{r:["data.hasPowercell"],s:'_0?null:"disabled"'},p:[9,54,366]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[10,22,431]}]}]}," ",{p:[12,3,490],t:7,e:"ui-section",a:{label:"Cell"},f:[{t:4,f:[{p:[14,7,554],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.powerLevel",p:[14,40,587]}]},f:[{t:2,x:{r:["adata.powerLevel"],s:"Math.fixed(_0)"},p:[14,61,608]},"%"]}],n:50,r:"data.hasPowercell",p:[13,5,521]},{t:4,n:51,f:[{p:[16,4,667],t:7,e:"span",a:{"class":"bad"},f:["No Cell"]}],r:"data.hasPowercell"}]}]}," ",{p:[20,1,744],t:7,e:"ui-display",a:{title:"Thermostat"},f:[{p:[21,3,779],t:7,e:"ui-section",a:{label:"Current Temperature"},f:[{p:[22,3,823],t:7,e:"span",f:[{t:2,x:{r:["adata.currentTemp"],s:"Math.round(_0)"},p:[22,9,829]},"°C"]}]}," ",{p:[24,2,894],t:7,e:"ui-section",a:{label:"Target Temperature"},f:[{p:[25,3,937],t:7,e:"span",f:[{t:2,x:{r:["adata.targetTemp"],s:"Math.round(_0)"},p:[25,9,943]},"°C"]}]}," ",{t:4,f:[{p:[28,5,1031],t:7,e:"ui-section",a:{label:"Adjust Target"},f:[{p:[29,7,1073],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.targetTemp","data.minTemp"],s:'_0>_1?null:"disabled"'},p:[29,46,1112]}],action:"target",params:'{"adjust": -20}'}}," ",{p:[30,7,1218],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.targetTemp","data.minTemp"],s:'_0>_1?null:"disabled"'},p:[30,41,1252]}],action:"target",params:'{"adjust": -5}'}}," ",{p:[31,7,1357],t:7,e:"ui-button",a:{icon:"pencil",action:"target",params:'{"target": "input"}'},f:["Set"]}," ",{p:[32,7,1450],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.targetTemp","data.maxTemp"],s:'_0<_1?null:"disabled"'},p:[32,40,1483]}],action:"target",params:'{"adjust": 5}'}}," ",{p:[33,7,1587],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.targetTemp","data.maxTemp"],s:'_0<_1?null:"disabled"'},p:[33,45,1625]}],action:"target",params:'{"adjust": 20}'}}]}],n:50,r:"data.open",p:[27,3,1008]}," ",{p:[36,3,1754],t:7,e:"ui-section",a:{label:"Mode"},f:[{t:4,f:[{p:[38,7,1808],t:7,e:"ui-button",a:{icon:"long-arrow-up",state:[{t:2,x:{r:["data.mode"],s:'_0=="heat"?"selected":null'},p:[38,46,1847]}],action:"mode",params:'{"mode": "heat"}'},f:["Heat"]}," ",{p:[39,7,1956],t:7,e:"ui-button",a:{icon:"long-arrow-down",state:[{t:2,x:{r:["data.mode"],s:'_0=="cool"?"selected":null'},p:[39,48,1997]}],action:"mode",params:'{"mode": "cool"}'},f:["Cool"]}," ",{ +-p:[40,7,2106],t:7,e:"ui-button",a:{icon:"arrows-v",state:[{t:2,x:{r:["data.mode"],s:'_0=="auto"?"selected":null'},p:[40,41,2140]}],action:"mode",params:'{"mode": "auto"}'},f:["Auto"]}],n:50,r:"data.open",p:[37,3,1783]},{t:4,n:51,f:[{p:[42,4,2258],t:7,e:"span",f:[{t:2,x:{r:["text","data.mode"],s:"_0.titleCase(_1)"},p:[42,10,2264]}]}],r:"data.open"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],299:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,31],t:7,e:"ui-display",a:{title:[{t:2,r:"class",p:[2,22,50]}," Alarms"]},f:[{p:[3,5,74],t:7,e:"ul",f:[{t:4,f:[{p:[5,9,107],t:7,e:"li",f:[{t:2,r:".",p:[5,13,111]}]}],n:52,r:".",p:[4,7,86]},{t:4,n:51,f:[{p:[7,9,147],t:7,e:"li",f:["System Nominal"]}],r:"."}]}]}],n:52,i:"class",r:"data.alarms",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],300:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,42],t:7,e:"ui-notice",f:[{p:[3,5,59],t:7,e:"span",f:["Biological entity detected in contents. Please remove."]}]}],n:50,x:{r:["data.occupied","data.safeties"],s:"_0&&_1"},p:[1,1,0]},{t:4,f:[{p:[7,3,179],t:7,e:"ui-notice",f:[{p:[8,5,196],t:7,e:"span",f:["Contents are being disinfected. Please wait."]}]}],n:50,r:"data.uv_active",p:[6,1,153]},{t:4,n:51,f:[{p:{button:[{t:4,f:[{p:[13,25,369],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[13,42,386]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Unlock":"Lock"'},p:[13,93,437]}]}],n:50,x:{r:["data.open"],s:"!_0"},p:[13,7,351]}," ",{t:4,f:[{p:[14,27,519],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"sign-out":"sign-in"'},p:[14,44,536]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Close":"Open"'},p:[14,98,590]}]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[14,7,499]}]},t:7,e:"ui-display",a:{title:"Storage",button:0},f:[" ",{t:4,f:[{p:[17,7,692],t:7,e:"ui-notice",f:[{p:[18,9,713],t:7,e:"span",f:["Unit Locked"]}]}],n:50,r:"data.locked",p:[16,5,665]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.open"],s:"_0"},f:[{p:[21,9,793],t:7,e:"ui-section",a:{label:"Helmet"},f:[{p:[22,11,832],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.helmet"],s:'_0?"square":"square-o"'},p:[22,28,849]}],state:[{t:2,x:{r:["data.helmet"],s:'_0?null:"disabled"'},p:[22,75,896]}],action:"dispense",params:'{"item": "helmet"}'},f:[{t:2,x:{r:["data.helmet"],s:'_0||"Empty"'},p:[23,59,992]}]}]}," ",{p:[25,9,1063],t:7,e:"ui-section",a:{label:"Suit"},f:[{p:[26,11,1100],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.suit"],s:'_0?"square":"square-o"'},p:[26,28,1117]}],state:[{t:2,x:{r:["data.suit"],s:'_0?null:"disabled"'},p:[26,74,1163]}],action:"dispense",params:'{"item": "suit"}'},f:[{t:2,x:{r:["data.suit"],s:'_0||"Empty"'},p:[27,57,1255]}]}]}," ",{p:[29,9,1324],t:7,e:"ui-section",a:{label:"Mask"},f:[{p:[30,11,1361],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mask"],s:'_0?"square":"square-o"'},p:[30,28,1378]}],state:[{t:2,x:{r:["data.mask"],s:'_0?null:"disabled"'},p:[30,74,1424]}],action:"dispense",params:'{"item": "mask"}'},f:[{t:2,x:{r:["data.mask"],s:'_0||"Empty"'},p:[31,57,1516]}]}]}," ",{p:[33,9,1585],t:7,e:"ui-section",a:{label:"Storage"},f:[{p:[34,11,1625],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.storage"],s:'_0?"square":"square-o"'},p:[34,28,1642]}],state:[{t:2,x:{r:["data.storage"],s:'_0?null:"disabled"'},p:[34,77,1691]}],action:"dispense",params:'{"item": "storage"}'},f:[{t:2,x:{r:["data.storage"],s:'_0||"Empty"'},p:[35,60,1789]}]}]}]},{t:4,n:50,x:{r:["data.open"],s:"!(_0)"},f:[" ",{p:[38,7,1873],t:7,e:"ui-button",a:{icon:"recycle",state:[{t:2,x:{r:["data.occupied","data.safeties"],s:'_0&&_1?"disabled":null'},p:[38,40,1906]}],action:"uv"},f:["Disinfect"]}]}],r:"data.locked"}]}],r:"data.uv_active"}]},e.exports=a.extend(r.exports)},{205:205}],301:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,5,18],t:7,e:"ui-section",a:{label:"Dispense"},f:[{p:[3,9,57],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.plasma"],s:'_0?"square":"square-o"'},p:[3,26,74]}],state:[{t:2,x:{r:["data.plasma"],s:'_0?null:"disabled"'},p:[3,74,122]}],action:"plasma"},f:["Plasma (",{t:2,x:{r:["adata.plasma"],s:"Math.round(_0)"},p:[4,37,196]},")"]}," ",{p:[5,9,247],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.oxygen"],s:'_0?"square":"square-o"'},p:[5,26,264]}],state:[{t:2,x:{r:["data.oxygen"],s:'_0?null:"disabled"'},p:[5,74,312]}],action:"oxygen"},f:["Oxygen (",{t:2,x:{r:["adata.oxygen"],s:"Math.round(_0)"},p:[6,37,386]},")"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],302:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{tankPressureState:function(){var t=this.get("data.tankPressure");return t>=200?"good":t>=100?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[14,1,295],t:7,e:"ui-notice",f:[{p:[15,3,310],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.connected"],s:'_0?"is":"is not"'},p:[15,23,330]}," connected to a mask."]}]}," ",{p:[17,1,409],t:7,e:"ui-display",f:[{p:[18,3,425],t:7,e:"ui-section",a:{label:"Tank Pressure"},f:[{p:[19,7,467],t:7,e:"ui-bar",a:{min:"0",max:"1013",value:[{t:2,r:"data.tankPressure",p:[19,41,501]}],state:[{t:2,r:"tankPressureState",p:[20,16,540]}]},f:[{t:2,x:{r:["adata.tankPressure"],s:"Math.round(_0)"},p:[20,39,563]}," kPa"]}]}," ",{p:[22,3,631],t:7,e:"ui-section",a:{label:"Release Pressure"},f:[{p:[23,5,674],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.minReleasePressure",p:[23,18,687]}],max:[{t:2,r:"data.maxReleasePressure",p:[23,52,721]}],value:[{t:2,r:"data.releasePressure",p:[24,14,764]}]},f:[{t:2,x:{r:["adata.releasePressure"],s:"Math.round(_0)"},p:[24,40,790]}," kPa"]}]}," ",{p:[26,3,861],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[27,5,906],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.releasePressure","data.defaultReleasePressure"],s:'_0!=_1?null:"disabled"'},p:[27,38,939]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[29,5,1095],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.releasePressure","data.minReleasePressure"],s:'_0>_1?null:"disabled"'},p:[29,36,1126]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[31,5,1273],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[32,5,1368],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.releasePressure","data.maxReleasePressure"],s:'_0<_1?null:"disabled"'},p:[32,35,1398]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],303:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,5,33],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[3,9,75],t:7,e:"span",f:[{t:2,x:{r:["adata.temperature"],s:"Math.fixed(_0,2)"},p:[3,15,81]}," K"]}]}," ",{p:[5,5,151],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,9,190],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.fixed(_0,2)"},p:[6,15,196]}," kPa"]}]}]}," ",{p:[9,1,276],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[10,5,311],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[11,9,347],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[11,26,364]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[11,70,408]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[12,28,469]}]}]}," ",{p:[14,5,531],t:7,e:"ui-section",a:{label:"Target Temperature"},f:[{p:[15,9,580],t:7,e:"ui-button",a:{icon:"fast-backward",style:[{t:2,x:{r:["data.target","data.min"],s:'_0==_1?"disabled":null'},p:[15,48,619]}],action:"target",params:'{"adjust": -20}'}}," ",{p:[17,9,733],t:7,e:"ui-button",a:{icon:"backward",style:[{t:2,x:{r:["data.target","data.min"],s:'_0==_1?"disabled":null'},p:[17,43,767]}],action:"target",params:'{"adjust": -5}'}}," ",{p:[19,9,880],t:7,e:"ui-button",a:{icon:"pencil",action:"target",params:'{"target": "input"}'},f:[{t:2,x:{r:["adata.target"],s:"Math.fixed(_0,2)"},p:[19,79,950]}]}," ",{p:[20,9,1003],t:7,e:"ui-button",a:{icon:"forward",style:[{t:2,x:{r:["data.target","data.max"],s:'_0==_1?"disabled":null'},p:[20,42,1036]}],action:"target",params:'{"adjust": 5}'}}," ",{p:[22,9,1148],t:7,e:"ui-button",a:{icon:"fast-forward",style:[{t:2,x:{r:["data.target","data.max"],s:'_0==_1?"disabled":null'},p:[22,47,1186]}],action:"target",params:'{"adjust": 20}'}}]}]}]},e.exports=a.extend(r.exports)},{205:205}],304:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{},oninit:function(){this.on({hover:function(t){var e=this.get("data.telecrystals");e>=t.context.params.cost&&this.set("hovered",t.context.params)},unhover:function(t){this.set("hovered")}})}}}(r),r.exports.template={v:3,t:[" ",{p:{button:[{t:4,f:[{p:[23,7,482],t:7,e:"ui-button",a:{icon:"lock",action:"lock"},f:["Lock"]}],n:50,r:"data.lockable",p:[22,5,453]}]},t:7,e:"ui-display",a:{title:"Uplink",button:0},f:[" ",{p:[26,3,568],t:7,e:"ui-section",a:{label:"Telecrystals",right:0},f:[{p:[27,5,613],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.telecrystals"],s:'_0>0?"good":"bad"'},p:[27,18,626]}]},f:[{t:2,r:"data.telecrystals",p:[27,62,670]}," TC"]}]}]}," ",{t:4,f:[{p:[31,3,764],t:7,e:"ui-display",f:[{p:[32,2,779],t:7,e:"ui-button",a:{action:"select",params:['{"category": "',{t:2,r:"name",p:[32,51,828]},'"}']},f:[{t:2,r:"name",p:[32,63,840]}]}," ",{t:4,f:[{p:[34,4,883],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[34,23,902]}],candystripe:0,right:0},f:[{p:[35,3,934],t:7,e:"ui-button",a:{tooltip:[{t:2,r:"name",p:[35,23,954]},": ",{t:2,r:"desc",p:[35,33,964]}],"tooltip-side":"left",state:[{t:2,x:{r:["data.telecrystals","hovered.cost","cost","hovered.item","name"],s:'_0<_2||(_0-_1<_2&&_3!=_4)?"disabled":null'},p:[36,12,1006]}],action:"buy",params:['{"category": "',{t:2,r:"category",p:[37,40,1165]},'", "item": ',{t:2,r:"name",p:[37,63,1188]},', "cost": ',{t:2,r:"cost",p:[37,81,1206]},"}"]},v:{hover:"hover",unhover:"unhover"},f:[{t:2,r:"cost",p:[38,43,1260]}," TC"]}]}],n:52,r:"items",p:[33,2,863]}]}],n:52,r:"data.categories",p:[30,1,735]}]},e.exports=a.extend(r.exports)},{205:205}],305:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{healthState:function(t){var e=this.get("data.vr_avatar.maxhealth");return t>e/1.5?"good":t>e/3?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[14,1,292],t:7,e:"ui-display",f:[{t:4,f:[{p:[16,3,333],t:7,e:"ui-display",a:{title:"Virtual Avatar"},f:[{p:[17,4,373],t:7,e:"ui-section",a:{label:"Name"},f:[{t:2,r:"data.vr_avatar.name",p:[18,5,404]}]}," ",{p:[20,4,450],t:7,e:"ui-section",a:{label:"Status"},f:[{t:2,r:"data.vr_avatar.status",p:[21,5,483]}]}," ",{p:[23,4,531],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[24,5,564],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.vr_avatar.maxhealth",p:[24,26,585]}],value:[{t:2,r:"adata.vr_avatar.health",p:[24,64,623]}],state:[{t:2,x:{r:["healthState","adata.vr_avatar.health"],s:"_0(_1)"},p:[24,99,658]}]},f:[{t:2,x:{r:["adata.vr_avatar.health"],s:"Math.round(_0)"},p:[24,140,699]},"/",{t:2,r:"adata.vr_avatar.maxhealth",p:[24,179,738]}]}]}]}],n:50,r:"data.vr_avatar",p:[15,2,307]},{t:4,n:51,f:[{p:[28,3,826],t:7,e:"ui-display",a:{title:"Virtual Avatar"},f:["No Virtual Avatar detected"]}],r:"data.vr_avatar"}," ",{p:[32,2,922],t:7,e:"ui-display",a:{title:"VR Commands"},f:[{p:[33,3,958],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.toggle_open"],s:'_0?"times":"plus"'},p:[33,20,975]}],action:"toggle_open"},f:[{t:2,x:{r:["data.toggle_open"],s:'_0?"Close":"Open"'},p:[34,4,1042]}," the VR Sleeper"]}," ",{t:4,f:[{p:[37,4,1144],t:7,e:"ui-button",a:{icon:"signal",action:"vr_connect"},f:["Connect to VR"]}],n:50,r:"data.isoccupant",p:[36,3,1116]}," ",{t:4,f:[{p:[42,4,1267],t:7,e:"ui-button",a:{icon:"ban",action:"delete_avatar"},f:["Delete Virtual Avatar"]}],n:50,r:"data.vr_avatar",p:[41,3,1240]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],306:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{t:4,f:[{p:[3,5,42],t:7,e:"ui-section",a:{label:[{t:2,r:"color",p:[3,24,61]},{t:2,x:{r:["wire"],s:'_0?" ("+_0+")":""'},p:[3,33,70]}],labelcolor:[{t:2,r:"color",p:[3,80,117]}],candystripe:0,right:0},f:[{p:[4,7,154],t:7,e:"ui-button",a:{action:"cut",params:['{"wire":"',{t:2,r:"color",p:[4,48,195]},'"}']},f:[{t:2,x:{r:["cut"],s:'_0?"Mend":"Cut"'},p:[4,61,208]}]}," ",{p:[5,7,252],t:7,e:"ui-button",a:{action:"pulse",params:['{"wire":"',{t:2,r:"color",p:[5,50,295]},'"}']},f:["Pulse"]}," ",{p:[6,7,333],t:7,e:"ui-button",a:{action:"attach",params:['{"wire":"',{t:2,r:"color",p:[6,51,377]},'"}']},f:[{t:2,x:{r:["attached"],s:'_0?"Detach":"Attach"'},p:[6,64,390]}]}]}],n:52,r:"data.wires",p:[2,3,16]}]}," ",{t:4,f:[{p:[11,3,508],t:7,e:"ui-display",f:[{t:4,f:[{p:[13,7,555],t:7,e:"ui-section",f:[{t:2,r:".",p:[13,19,567]}]}],n:52,r:"data.status",p:[12,5,526]}]}],n:50,r:"data.status",p:[10,1,485]}]},e.exports=a.extend(r.exports)},{205:205}],307:[function(t,e,n){(function(e){"use strict";var n=t(205),a=e.interopRequireDefault(n);t(194),t(1),t(190),t(193);var r=t(308),i=e.interopRequireDefault(r),o=t(309),s=t(191),u=t(192),p=e.interopRequireDefault(u);a["default"].DEBUG=/minified/.test(function(){}),Object.assign(Math,t(313)),window.initialize=function(e){window.tgui||(window.tgui=new i["default"]({el:"#container",data:function(){var n=JSON.parse(e);return{constants:t(310),text:t(314),config:n.config,data:n.data,adata:n.data}}}))};var c=document.getElementById("data"),l=c.textContent,f=c.getAttribute("data-ref");"{}"!==l&&(window.initialize(l),c.remove()),(0,o.act)(f,"tgui:initialize"),(0,s.loadCSS)("font-awesome.min.css");var d=new p["default"]("FontAwesome");d.check("").then(function(){return document.body.classList.add("icons")})["catch"](function(){return document.body.classList.add("no-icons")})}).call(this,t("babel/external-helpers"))},{1:1,190:190,191:191,192:192,193:193,194:194,205:205,308:308,309:309,310:310,313:313,314:314,"babel/external-helpers":"babel/external-helpers"}],308:[function(t,e,n){var a=t(205),r={exports:{}};!function(e){"use strict";var n=t(309),a=t(311);e.exports={components:{"ui-bar":t(206),"ui-button":t(207),"ui-display":t(208),"ui-input":t(209),"ui-linegraph":t(210),"ui-notice":t(211),"ui-section":t(213),"ui-subdisplay":t(214),"ui-tabs":t(215)},events:{enter:t(203).enter,space:t(203).space},transitions:{fade:t(204)},onconfig:function(){var e=this.get("config.interface"),n={airalarm:t(219),"airalarm/back":t(220),"airalarm/modes":t(221),"airalarm/scrubbers":t(222),"airalarm/status":t(223),"airalarm/thresholds":t(224),"airalarm/vents":t(225),airlock_electronics:t(226),apc:t(227),atmos_alert:t(228),atmos_control:t(229),atmos_filter:t(230),atmos_mixer:t(231),atmos_pump:t(232),brig_timer:t(233),bsa:t(234),canister:t(235),cargo:t(236),cellular_emporium:t(237),chem_dispenser:t(238),chem_heater:t(239),chem_master:t(240),clockwork_slab:t(241),codex_gigas:t(242),computer_fabricator:t(243),crayon:t(244),cryo:t(245),disposal_unit:t(246),dna_vault:t(247),eightball:t(248),emergency_shuttle_console:t(249),engraved_message:t(250),error:t(251),firealarm:t(252),gps:t(253),gulag_console:t(254),gulag_item_reclaimer:t(255),holodeck:t(256),implantchair:t(257),intellicard:t(258),keycard_auth:t(259),labor_claim_console:t(260),language_menu:t(261),launchpad_remote:t(262),mech_bay_power_console:t(263),mulebot:t(264),ntnet_relay:t(265),ntos_ai_restorer:t(266),ntos_card:t(267),ntos_configuration:t(268),ntos_file_manager:t(269),ntos_main:t(270),ntos_net_chat:t(271),ntos_net_dos:t(272),ntos_net_downloader:t(273),ntos_net_monitor:t(274),ntos_net_transfer:t(275),ntos_power_monitor:t(276),ntos_revelation:t(277),ntos_station_alert:t(278),ntos_supermatter_monitor:t(279),ntosheader:t(280),nuclear_bomb:t(281),ore_redemption_machine:t(282),pandemic:t(283),personal_crafting:t(284),portable_pump:t(285),portable_scrubber:t(286),power_monitor:t(287),radio:t(288),sat_control:t(289),shuttle_manipulator:t(290),"shuttle_manipulator/modification":t(291),"shuttle_manipulator/status":t(292),"shuttle_manipulator/templates":t(293),sleeper:t(294),slime_swap_body:t(295),smes:t(296),solar_control:t(297),space_heater:t(298),station_alert:t(299),suit_storage_unit:t(300),tank_dispenser:t(301),tanks:t(302),thermomachine:t(303),uplink:t(304),vr_sleeper:t(305),wires:t(306)};e in n?this.components["interface"]=n[e]:this.components["interface"]=n.error},oninit:function(){this.observe("config.style",function(t,e,n){t&&document.body.classList.add(t),e&&document.body.classList.remove(e)})},oncomplete:function(){if(this.get("config.locked")){var t=(0,a.lock)(window.screenLeft,window.screenTop),e=t.x,r=t.y;(0,n.winset)(this.get("config.window"),"pos",e+","+r)}(0,n.winset)("mapwindow.map","focus",!0)}}}(r),r.exports.template={v:3,t:[" "," "," "," ",{p:[56,1,1874],t:7,e:"titlebar",f:[{t:3,r:"config.title",p:[56,11,1884]}]}," ",{p:[57,1,1915],t:7,e:"main",f:[{p:[58,3,1925],t:7,e:"warnings"}," ",{p:[59,3,1940],t:7,e:"interface"}]}," ",{t:4,f:[{p:[62,3,1990],t:7,e:"resize"}],n:50,r:"config.titlebar",p:[61,1,1963]}]},r.exports.components=r.exports.components||{};var i={warnings:t(218),titlebar:t(217),resize:t(212)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{203:203,204:204,205:205,206:206,207:207,208:208,209:209,210:210,211:211,212:212,213:213,214:214,215:215,217:217,218:218,219:219,220:220,221:221,222:222,223:223,224:224,225:225,226:226,227:227,228:228,229:229,230:230,231:231,232:232,233:233,234:234,235:235,236:236,237:237,238:238,239:239,240:240,241:241,242:242,243:243,244:244,245:245,246:246,247:247,248:248,249:249,250:250,251:251,252:252,253:253,254:254,255:255,256:256,257:257,258:258,259:259,260:260,261:261,262:262,263:263,264:264,265:265,266:266,267:267,268:268,269:269,270:270,271:271,272:272,273:273,274:274,275:275,276:276,277:277,278:278,279:279,280:280,281:281,282:282,283:283,284:284,285:285,286:286,287:287,288:288,289:289,290:290,291:291,292:292,293:293,294:294,295:295,296:296,297:297,298:298,299:299,300:300,301:301,302:302,303:303,304:304,305:305,306:306,309:309,311:311}],309:[function(t,e,n){"use strict";function a(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return"byond://"+e+"?"+Object.keys(t).map(function(e){return o(e)+"="+o(t[e])}).join("&")}function r(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};window.location.href=a(Object.assign({src:t,action:e},n))}function i(t,e,n){var r;window.location.href=a((r={},r[t+"."+e]=n,r),"winset")}n.__esModule=!0,n.href=a,n.act=r,n.winset=i;var o=encodeURIComponent},{}],310:[function(t,e,n){"use strict";n.__esModule=!0;n.UI_INTERACTIVE=2,n.UI_UPDATE=1,n.UI_DISABLED=0,n.UI_CLOSE=-1},{}],311:[function(t,e,n){"use strict";function a(t,e){return 0>t?t=0:t+window.innerWidth>window.screen.availWidth&&(t=window.screen.availWidth-window.innerWidth),0>e?e=0:e+window.innerHeight>window.screen.availHeight&&(e=window.screen.availHeight-window.innerHeight),{x:t,y:e}}function r(t){if(t.preventDefault(),this.get("drag")){if(this.get("x")){var e=t.screenX-this.get("x")+window.screenLeft,n=t.screenY-this.get("y")+window.screenTop;if(this.get("config.locked")){var r=a(e,n);e=r.x,n=r.y}(0,s.winset)(this.get("config.window"),"pos",e+","+n)}this.set({x:t.screenX,y:t.screenY})}}function i(t,e){return t=Math.clamp(100,window.screen.width,t),e=Math.clamp(100,window.screen.height,e),{x:t,y:e}}function o(t){if(t.preventDefault(),this.get("resize")){if(this.get("x")){var e=t.screenX-this.get("x")+window.innerWidth,n=t.screenY-this.get("y")+window.innerHeight,a=i(e,n);e=a.x,n=a.y,(0,s.winset)(this.get("config.window"),"size",e+","+n)}this.set({x:t.screenX,y:t.screenY})}}n.__esModule=!0,n.lock=a,n.drag=r,n.sane=i,n.resize=o;var s=t(309)},{309:309}],312:[function(t,e,n){"use strict";function a(t,e){for(var n=t,a=Array.isArray(n),i=0,n=a?n:n[Symbol.iterator]();;){var o;if(a){if(i>=n.length)break;o=n[i++]}else{if(i=n.next(),i.done)break;o=i.value}var s=o;s.textContent.toLowerCase().includes(e)?(s.style.display="",r(s,e)):s.style.display="none"}}function r(t,e){for(var n=t.queryAll("section"),a=t.query("header").textContent.toLowerCase().includes(e),r=n,i=Array.isArray(r),o=0,r=i?r:r[Symbol.iterator]();;){var s;if(i){if(o>=r.length)break;s=r[o++]}else{if(o=r.next(),o.done)break;s=o.value}var u=s;a||u.textContent.toLowerCase().includes(e)?u.style.display="":u.style.display="none"}}n.__esModule=!0,n.filterMulti=a,n.filter=r},{}],313:[function(t,e,n){"use strict";function a(t,e,n){return Math.max(t,Math.min(n,e))}function r(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return+(Math.round(t+"e"+e)+"e-"+e)}n.__esModule=!0,n.clamp=a,n.fixed=r},{}],314:[function(t,e,n){"use strict";function a(t){return t[0].toUpperCase()+t.slice(1).toLowerCase()}function r(t){return t.replace(/\w\S*/g,a)}function i(t,e){for(t=""+t;t.length1){for(var u=Array(o),p=0;o>p;p++)u[p]=arguments[p+3];n.children=u}return{$$typeof:t,type:e,key:void 0===a?null:""+a,ref:null,props:n,_owner:null}}}(),e.asyncIterator=function(t){if("function"==typeof Symbol){if(Symbol.asyncIterator){var e=t[Symbol.asyncIterator];if(null!=e)return e.call(t)}if(Symbol.iterator)return t[Symbol.iterator]()}throw new TypeError("Object is not async iterable")},e.asyncGenerator=function(){function t(t){this.value=t}function e(e){function n(t,e){return new Promise(function(n,r){var s={key:t,arg:e,resolve:n,reject:r,next:null};o?o=o.next=s:(i=o=s,a(t,e))})}function a(n,i){try{var o=e[n](i),s=o.value;s instanceof t?Promise.resolve(s.value).then(function(t){a("next",t)},function(t){a("throw",t)}):r(o.done?"return":"normal",o.value)}catch(u){r("throw",u)}}function r(t,e){switch(t){case"return":i.resolve({value:e,done:!0});break;case"throw":i.reject(e);break;default:i.resolve({value:e,done:!1})}i=i.next,i?a(i.key,i.arg):o=null}var i,o;this._invoke=n,"function"!=typeof e["return"]&&(this["return"]=void 0)}return"function"==typeof Symbol&&Symbol.asyncIterator&&(e.prototype[Symbol.asyncIterator]=function(){return this}),e.prototype.next=function(t){return this._invoke("next",t)},e.prototype["throw"]=function(t){return this._invoke("throw",t)},e.prototype["return"]=function(t){return this._invoke("return",t)},{wrap:function(t){return function(){return new e(t.apply(this,arguments))}},await:function(e){return new t(e)}}}(),e.asyncGeneratorDelegate=function(t,e){function n(n,a){return r=!0,a=new Promise(function(e){e(t[n](a))}),{done:!1,value:e(a)}}var a={},r=!1;return"function"==typeof Symbol&&Symbol.iterator&&(a[Symbol.iterator]=function(){return this}),a.next=function(t){return r?(r=!1,t):n("next",t)},"function"==typeof t["throw"]&&(a["throw"]=function(t){if(r)throw r=!1,t;return n("throw",t)}),"function"==typeof t["return"]&&(a["return"]=function(t){return n("return",t)}),a},e.asyncToGenerator=function(t){return function(){var e=t.apply(this,arguments);return new Promise(function(t,n){function a(r,i){try{var o=e[r](i),s=o.value}catch(u){return void n(u)}return o.done?void t(s):Promise.resolve(s).then(function(t){a("next",t)},function(t){a("throw",t)})}return a("next")})}},e.classCallCheck=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},e.createClass=function(){function t(t,e){for(var n=0;n=0||Object.prototype.hasOwnProperty.call(t,a)&&(n[a]=t[a]);return n},e.possibleConstructorReturn=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},e.selfGlobal=void 0===t?self:t,e.set=function a(t,e,n,r){var i=Object.getOwnPropertyDescriptor(t,e);if(void 0===i){var o=Object.getPrototypeOf(t);null!==o&&a(o,e,n,r)}else if("value"in i&&i.writable)i.value=n;else{var s=i.set;void 0!==s&&s.call(r,n)}return n},e.slicedToArray=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),e.slicedToArrayLoose=function(t,e){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t)){for(var n,a=[],r=t[Symbol.iterator]();!(n=r.next()).done&&(a.push(n.value),!e||a.length!==e););return a}throw new TypeError("Invalid attempt to destructure non-iterable instance")},e.taggedTemplateLiteral=function(t,e){return Object.freeze(Object.defineProperties(t,{raw:{value:Object.freeze(e)}}))},e.taggedTemplateLiteralLoose=function(t,e){return t.raw=e,t},e.temporalRef=function(t,e,n){if(t===n)throw new ReferenceError(e+" is not defined - temporal dead zone");return t},e.temporalUndefined={},e.toArray=function(t){return Array.isArray(t)?t:Array.from(t)},e.toConsumableArray=function(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);ee/2?"average":"bad"},bigState:function(t,e,n){return charge>n?"bad":t>e?"average":"good"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[23,1,421],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[27,2,462],t:7,e:"ui-button",a:{action:"PRG_clear"},f:["Back to Menu"]},{p:[27,56,516],t:7,e:"br"}," ",{p:[28,3,524],t:7,e:"ui-display",a:{title:"Supermatter Status:"},f:[{p:[29,3,568],t:7,e:"ui-section",a:{label:"Core Integrity"},f:[{p:[30,5,609],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"adata.SM_integrity",p:[30,38,642]}],state:[{t:2,x:{r:["integState","adata.SM_integrity"],s:"_0(_1)"},p:[30,69,673]}]},f:[{t:2,r:"data.SM_integrity",p:[30,105,709]},"%"]}]}," ",{p:[32,3,761],t:7,e:"ui-section",a:{label:"Relative EER"},f:[{p:[33,5,800],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_power"],s:"_0(_1,150,300)"},p:[33,18,813]}]},f:[{t:2,r:"data.SM_power",p:[33,55,850]}," MeV/cm3"]}]}," ",{p:[35,3,903],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[36,5,941],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_ambienttemp"],s:"_0(_1,4000,5000)"},p:[36,18,954]}]},f:[{t:2,r:"data.SM_ambienttemp",p:[36,63,999]}," K"]}]}," ",{p:[38,3,1052],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[39,5,1087],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_ambientpressure"],s:"_0(_1,5000,10000)"},p:[39,18,1100]}]},f:[{t:2,r:"data.SM_ambientpressure",p:[39,68,1150]}," kPa"]}]}]}," ",{p:[42,3,1227],t:7,e:"hr"},{p:[42,7,1231],t:7,e:"br"}," ",{p:[43,3,1239],t:7,e:"ui-display",a:{title:"Gas Composition:"},f:[{t:4,f:[{p:[45,5,1307],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[45,24,1326]}]},f:[{t:2,r:"amount",p:[46,6,1343]}," %"]}],n:52,r:"data.gases",p:[44,4,1281]}]}],n:50,r:"data.active",p:[26,1,440]},{t:4,n:51,f:[{p:[51,2,1418],t:7,e:"ui-button",a:{action:"PRG_refresh"},f:["Refresh"]},{p:[51,53,1469],t:7,e:"br"}," ",{p:[52,2,1476],t:7,e:"ui-display",a:{title:"Detected Supermatters"},f:[{t:4,f:[{p:[54,3,1552],t:7,e:"ui-section",a:{label:"Area"},f:[{t:2,r:"area_name",p:[55,5,1583]}," - (#",{t:2,r:"uid",p:[55,23,1601]},")"]}," ",{p:[57,3,1630],t:7,e:"ui-section",a:{label:"Integrity"},f:[{t:2,r:"integrity",p:[58,5,1666]}," %"]}," ",{p:[60,3,1702],t:7,e:"ui-section",a:{label:"Options"},f:[{p:[61,5,1736],t:7,e:"ui-button",a:{action:"PRG_set",params:['{"target" : "',{t:2,r:"uid",p:[61,54,1785]},'"}']},f:["View Details"]}]}],n:52,r:"data.supermatters",p:[53,2,1521]}]}],r:"data.active"}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(280)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,280:280}],280:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"item",style:"float: left"},f:[{p:[2,2,41],t:7,e:"table",f:[{p:[2,9,48],t:7,e:"tr",f:[{t:4,f:[{p:[4,3,113],t:7,e:"td",f:[{p:[4,7,117],t:7,e:"img",a:{src:[{t:2,r:"data.PC_batteryicon",p:[4,17,127]}]}}]}],n:50,x:{r:["data.PC_batteryicon","data.PC_showbatteryicon"],s:"_0&&_1"},p:[3,2,55]}," ",{t:4,f:[{p:[7,3,226],t:7,e:"td",f:[{p:[7,7,230],t:7,e:"b",f:[{t:2,r:"data.PC_batterypercent",p:[7,10,233]}]}]}],n:50,x:{r:["data.PC_batterypercent","data.PC_showbatteryicon"],s:"_0&&_1"},p:[6,2,165]}," ",{t:4,f:[{p:[10,3,305],t:7,e:"td",f:[{p:[10,7,309],t:7,e:"img",a:{src:[{t:2,r:"data.PC_ntneticon",p:[10,17,319]}]}}]}],n:50,r:"data.PC_ntneticon",p:[9,2,276]}," ",{t:4,f:[{p:[13,3,386],t:7,e:"td",f:[{p:[13,7,390],t:7,e:"img",a:{src:[{t:2,r:"data.PC_apclinkicon",p:[13,17,400]}]}}]}],n:50,r:"data.PC_apclinkicon",p:[12,2,355]}," ",{t:4,f:[{p:[16,3,469],t:7,e:"td",f:[{p:[16,7,473],t:7,e:"b",f:[{t:2,r:"data.PC_stationtime",p:[16,10,476]}]}]}],n:50,r:"data.PC_stationtime",p:[15,2,438]}," ",{t:4,f:[{p:[19,3,552],t:7,e:"td",f:[{p:[19,7,556],t:7,e:"img",a:{src:[{t:2,r:"icon",p:[19,17,566]}]}}]}],n:52,r:"data.PC_programheaders",p:[18,2,516]}]}]}]}," ",{p:[23,1,609],t:7,e:"div",a:{style:"float: right; margin-top: 5px"},f:[{p:[24,2,655],t:7,e:"ui-button",a:{action:"PC_shutdown"},f:["Shutdown"]}," ",{t:4,f:[{p:[26,3,745],t:7,e:"ui-button",a:{action:"PC_exit"},f:["EXIT PROGRAM"]}," ",{p:[27,3,801],t:7,e:"ui-button",a:{action:"PC_minimize"},f:["Minimize Program"]}],n:50,r:"data.PC_showexitprogram",p:[25,2,710]}]}," ",{p:[30,1,881],t:7,e:"div",a:{style:"clear: both"}}]},e.exports=a.extend(r.exports)},{205:205}],281:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Auth. Disk:"},f:[{t:4,f:[{p:[3,7,69],t:7,e:"ui-button",a:{icon:"eject",style:"selected",action:"eject_disk"},f:["++++++++++"]}],n:50,r:"data.disk_present",p:[2,3,36]},{t:4,n:51,f:[{p:[5,7,172],t:7,e:"ui-button",a:{icon:"plus",action:"insert_disk"},f:["----------"]}],r:"data.disk_present"}]}," ",{p:[8,1,266],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[9,3,297],t:7,e:"span",f:[{t:2,r:"data.status1",p:[9,9,303]},"-",{t:2,r:"data.status2",p:[9,26,320]}]}]}," ",{p:[11,1,360],t:7,e:"ui-display",a:{title:"Timer"},f:[{p:[12,3,390],t:7,e:"ui-section",a:{label:"Time to Detonation"},f:[{p:[13,5,435],t:7,e:"span",f:[{t:2,x:{r:["data.timing","data.time_left","data.timer_set"],s:"_0?_1:_2"},p:[13,11,441]}]}]}," ",{t:4,f:[{p:[16,5,540],t:7,e:"ui-section",a:{label:"Adjust Timer"},f:[{p:[17,7,581],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_default"],s:'_0&&_1&&_2?null:"disabled"'},p:[17,40,614]}],action:"timer",params:'{"change": "reset"}'},f:["Reset"]}," ",{p:[19,7,786],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_min"],s:'_0&&_1&&_2?null:"disabled"'},p:[19,38,817]}],action:"timer",params:'{"change": "decrease"}'},f:["Decrease"]}," ",{p:[21,7,991],t:7,e:"ui-button",a:{icon:"pencil",state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[21,39,1023]}],action:"timer",params:'{"change": "input"}'},f:["Set"]}," ",{p:[22,7,1155],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_max"],s:'_0&&_1&&_2?null:"disabled"'},p:[22,37,1185]}],action:"timer",params:'{"change": "increase"}'},f:["Increase"]}]}],n:51,r:"data.timing",p:[15,3,518]}," ",{p:[26,3,1394],t:7,e:"ui-section",a:{label:"Timer"},f:[{p:[27,5,1426],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"danger":"caution"'},p:[27,38,1459]}],action:"toggle_timer",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.safety"],s:'_0&&_1&&!_2?null:"disabled"'},p:[29,14,1542]}]},f:[{t:2,x:{r:["data.timing"],s:'_0?"On":"Off"'},p:[30,7,1631]}]}]}]}," ",{p:[34,1,1713],t:7,e:"ui-display",a:{title:"Anchoring"},f:[{p:[35,3,1747],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[36,12,1770]}],icon:[{t:2,x:{r:["data.anchored"],s:'_0?"lock":"unlock"'},p:[37,11,1846]}],style:[{t:2,x:{r:["data.anchored"],s:'_0?null:"caution"'},p:[38,12,1897]}],action:"anchor"},f:[{t:2,x:{r:["data.anchored"],s:'_0?"Engaged":"Off"'},p:[39,21,1956]}]}]}," ",{p:[41,1,2022],t:7,e:"ui-display",a:{title:"Safety"},f:[{p:[42,3,2053],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[43,12,2076]}],icon:[{t:2,x:{r:["data.safety"],s:'_0?"lock":"unlock"'},p:[44,11,2152]}],action:"safety",style:[{t:2,x:{r:["data.safety"],s:'_0?"caution":"danger"'},p:[45,12,2217]}]},f:[{p:[46,7,2265],t:7,e:"span",f:[{t:2,x:{r:["data.safety"],s:'_0?"On":"Off"'},p:[46,13,2271]}]}]}]}," ",{p:[49,1,2341],t:7,e:"ui-display",a:{title:"Code"},f:[{p:[50,3,2370],t:7,e:"ui-section",a:{label:"Message"},f:[{t:2,r:"data.message",p:[50,31,2398]}]}," ",{p:[51,3,2431],t:7,e:"ui-section",a:{label:"Keypad"},f:[{p:[52,5,2464],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[52,39,2498]}],params:'{"digit":"1"}'},f:["1"]}," ",{p:[53,5,2583],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[53,39,2617]}],params:'{"digit":"2"}'},f:["2"]}," ",{p:[54,5,2702],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[54,39,2736]}],params:'{"digit":"3"}'},f:["3"]}," ",{p:[55,5,2821],t:7,e:"br"}," ",{p:[56,5,2831],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[56,39,2865]}],params:'{"digit":"4"}'},f:["4"]}," ",{p:[57,5,2950],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[57,39,2984]}],params:'{"digit":"5"}'},f:["5"]}," ",{p:[58,5,3069],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[58,39,3103]}],params:'{"digit":"6"}'},f:["6"]}," ",{p:[59,5,3188],t:7,e:"br"}," ",{p:[60,5,3198],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[60,39,3232]}],params:'{"digit":"7"}'},f:["7"]}," ",{p:[61,5,3317],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[61,39,3351]}],params:'{"digit":"8"}'},f:["8"]}," ",{p:[62,5,3436],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[62,39,3470]}],params:'{"digit":"9"}'},f:["9"]}," ",{p:[63,5,3555],t:7,e:"br"}," ",{p:[64,5,3565],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[64,39,3599]}],params:'{"digit":"R"}'},f:["R"]}," ",{p:[65,5,3684],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[65,39,3718]}],params:'{"digit":"0"}'},f:["0"]}," ",{p:[66,5,3803],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[66,39,3837]}],params:'{"digit":"E"}'},f:["E"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],282:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,2,15],t:7,e:"ui-section",f:["This machine only accepts ore. Gibtonite and Slag are not accepted."]}," ",{p:[5,2,117],t:7,e:"ui-section",f:["Current unclaimed points: ",{t:2,r:"data.unclaimedPoints",p:[6,29,159]}," ",{t:4,f:[{p:[8,4,220],t:7,e:"ui-button",a:{action:"Claim"},f:["Claim Points"]}],n:50,r:"data.unclaimedPoints",p:[7,3,187]}]}," ",{p:[13,2,311],t:7,e:"ui-section",f:[{t:4,f:[{p:[15,4,350],t:7,e:"ui-button",a:{action:"Eject"},f:["Eject ID"]}," You have ",{t:2,r:"data.claimedPoints",p:[18,13,421]}," mining points collected."],n:50,r:"data.hasID",p:[14,3,327]},{t:4,n:51,f:[{p:[20,4,485],t:7,e:"ui-button",a:{action:"Insert"},f:["Insert ID"]}],r:"data.hasID"}]}]}," ",{p:[26,1,588],t:7,e:"ui-display",f:[{t:4,f:[{p:[28,3,627],t:7,e:"ui-section",f:[{p:[29,4,644],t:7,e:"ui-button",a:{action:"diskEject",icon:"eject"},f:["Eject Disk"]}]}," ",{t:4,f:[{p:[34,4,772],t:7,e:"ui-section",a:{"class":"candystripe"},f:[{p:[35,5,808],t:7,e:"ui-button",a:{action:"diskUpload",state:[{t:2,x:{r:["canupload"],s:'(_0)?null:"disabled"'},p:[35,42,845]}],icon:"upload",align:"right",params:['{ "design" : "',{t:2,r:"index",p:[35,129,932]},'" }']},f:["Upload"]}," File ",{t:2,r:"index",p:[38,10,988]},": ",{t:2,r:"name",p:[38,21,999]}]}],n:52,r:"data.diskDesigns",p:[33,3,741]}],n:50,r:"data.hasDisk",p:[27,2,603]},{t:4,n:51,f:[{p:[42,3,1053],t:7,e:"ui-section",f:[{p:[43,4,1070],t:7,e:"ui-button",a:{action:"diskInsert",icon:"floppy-o"},f:["Insert Disk"]}]}],r:"data.hasDisk"}]}," ",{p:[49,1,1195],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[50,2,1227],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[51,4,1261],t:7,e:"section",a:{"class":"cell"},f:["Mineral"]}," ",{p:[54,4,1316],t:7,e:"section",a:{"class":"cell"},f:["Sheets"]}," ",{p:[57,4,1370],t:7,e:"section",a:{"class":"cell"},f:[]}," ",{p:[59,4,1412],t:7,e:"section",a:{"class":"cell"},f:[{p:[60,5,1440],t:7,e:"ui-button",a:{"class":"center mineral",grid:0,action:"Release",params:'{"id" : "all"}'},f:["Release All"]}]}," ",{p:[64,4,1576],t:7,e:"section",a:{"class":"cell"},f:["Ore Value"]}]}," ",{t:4,f:[{p:[69,3,1673],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[70,4,1707],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[71,5,1735]}]}," ",{p:[73,4,1763],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[74,5,1805]}]}," ",{p:[76,4,1835],t:7,e:"section",a:{"class":"cell"},f:[{p:[77,5,1863],t:7,e:"input",a:{value:[{t:2,r:"sheets",p:[77,18,1876]}],placeholder:"###","class":"number"}}]}," ",{p:[79,4,1941],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[80,5,1983],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[80,59,2037]}],params:['{ "id" : ',{t:2,r:"id",p:[80,114,2092]},', "sheets" : ',{t:2,r:"sheets",p:[80,133,2111]}," }"]},f:["Release"]}]}," ",{p:[84,4,2178],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"value",p:[85,5,2220]}]}]}],n:52,r:"data.materials",p:[68,2,1645]}," ",{t:4,f:[{p:[90,3,2298],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[91,4,2332],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[92,5,2360]}]}," ",{p:[94,4,2388],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[95,5,2430]}]}," ",{p:[97,4,2460],t:7,e:"section",a:{"class":"cell"},f:[{p:[98,5,2488],t:7,e:"input",a:{value:[{t:2,r:"sheets",p:[98,18,2501]}],placeholder:"###","class":"number"}}]}," ",{p:[100,4,2566],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[101,5,2608],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"Smelt",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[101,57,2660]}],params:['{ "id" : ',{t:2,r:"id",p:[101,113,2716]},', "sheets" : ',{t:2,r:"sheets",p:[101,132,2735]}," }"]},f:["Smelt"]}]}," ",{p:[105,4,2799],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[106,5,2841],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"SmeltAll",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[106,60,2896]}],params:['{ "id" : ',{t:2,r:"id",p:[106,116,2952]}," }"]},f:["Smelt All"]}]}]}],n:52,r:"data.alloys",p:[89,2,2273]}]}]},e.exports=a.extend(r.exports)},{205:205}],283:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:{button:[{p:[4,4,87],t:7,e:"ui-button",a:{icon:"remove",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[4,36,119]}],action:"empty_eject_beaker"},f:["Empty and eject"]}," ",{p:[7,4,231],t:7,e:"ui-button",a:{icon:"trash",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[7,35,262]}],action:"empty_beaker"},f:["Empty"]}," ",{p:[10,4,358],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[10,35,389]}],action:"eject_beaker"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{t:4,f:[{p:[15,4,528],t:7,e:"ui-section",f:[{t:4,f:[{p:[17,6,578],t:7,e:"span",a:{"class":"bad"},f:["The beaker is empty!"]}],n:50,r:"data.beaker_empty",p:[16,5,546]},{t:4,n:51,f:[{p:[19,6,644],t:7,e:"ui-subdisplay",a:{title:"Blood"},f:[{t:4,f:[{p:[21,8,712],t:7,e:"ui-section",a:{label:"Blood DNA"},f:[{t:2,r:"data.blood.dna",p:[21,38,742]}]}," ",{p:[22,8,782],t:7,e:"ui-section",a:{label:"Blood type"},f:[{t:2,r:"data.blood.type",p:[22,39,813]}]}],n:50,r:"data.has_blood",p:[20,7,681]},{t:4,n:51,f:[{p:[24,8,870],t:7,e:"ui-section",f:[{p:[25,9,892],t:7,e:"span",a:{"class":"average"},f:["No blood sample detected."]}]}],r:"data.has_blood"}]}],r:"data.beaker_empty"}]}],n:50,r:"data.has_beaker",p:[14,3,500]},{t:4,n:51,f:[{p:[32,4,1054],t:7,e:"ui-section",f:[{p:[33,5,1072],t:7,e:"span",a:{"class":"bad"},f:["No beaker loaded."]}]}],r:"data.has_beaker"}]}," ",{t:4,f:[{p:[38,3,1188],t:7,e:"ui-display",a:{title:"Diseases"},f:[{t:4,f:[{p:{button:[{t:4,f:[{p:[43,8,1343],t:7,e:"ui-button",a:{icon:"pencil",action:"rename_disease",state:[{t:2,x:{r:["can_rename"],s:'_0?"":"disabled"'},p:[43,64,1399]}],params:['{"index": ',{t:2,r:"index",p:[43,116,1451]},"}"]},f:["Name advanced disease"]}],n:50,r:"is_adv",p:[42,7,1320]}," ",{p:[47,7,1538],t:7,e:"ui-button",a:{icon:"flask",action:"create_culture_bottle",state:[{t:2,x:{r:["data.is_ready"],s:'_0?"":"disabled"'},p:[47,69,1600]}],params:['{"index": ',{t:2,r:"index",p:[47,124,1655]},"}"]},f:["Create virus culture bottle"]}]},t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[40,24,1269]}],button:0},f:[" ",{p:[51,6,1749],t:7,e:"ui-section",a:{label:"Disease agent"},f:[{t:2,r:"agent",p:[51,40,1783]}]}," ",{p:[52,6,1812],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"description",p:[52,38,1844]}]}," ",{p:[53,6,1879],t:7,e:"ui-section",a:{label:"Spread"},f:[{t:2,r:"spread",p:[53,33,1906]}]}," ",{p:[54,6,1936],t:7,e:"ui-section",a:{label:"Possible cure"},f:[{t:2,r:"cure",p:[54,40,1970]}]}," ",{t:4,f:[{p:[56,7,2021],t:7,e:"ui-section",a:{label:"Symptoms"},f:[{t:4,f:[{p:[58,9,2087],t:7,e:"ui-button",a:{action:"symptom_details",state:"",params:['{"picked_symptom": ',{t:2,r:"sym_index",p:[58,81,2159]},', "index": ',{t:2,r:"index",p:[58,105,2183]},"}"]},f:[{t:2,r:"name",p:[59,10,2206]}," "]},{p:[60,21,2236],t:7,e:"br"}],n:52,r:"symptoms",p:[57,8,2059]}]}," ",{p:[63,7,2289],t:7,e:"ui-section",a:{label:"Resistance"},f:[{t:2,r:"resistance",p:[63,38,2320]}]}," ",{p:[64,7,2355],t:7,e:"ui-section",a:{label:"Stealth"},f:[{t:2,r:"stealth",p:[64,35,2383]}]}," ",{p:[65,7,2415],t:7,e:"ui-section",a:{label:"Stage speed"},f:[{t:2,r:"stage_speed",p:[65,39,2447]}]}," ",{p:[66,7,2483],t:7,e:"ui-section",a:{label:"Transmittability"},f:[{t:2,r:"transmission",p:[66,44,2520]}]}],n:50,r:"is_adv",p:[55,6,1999]}]}],n:52,r:"data.viruses",p:[39,4,1222]},{t:4,n:51,f:[{p:[70,5,2601],t:7,e:"ui-section",f:[{p:[71,6,2620],t:7,e:"span",a:{"class":"average"},f:["No detectable virus in the blood sample."]}]}],r:"data.viruses"}]}," ",{p:[75,3,2743],t:7,e:"ui-display",a:{title:"Antibodies"},f:[{t:4,f:[{p:[77,5,2811],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[77,24,2830]}]},f:[{p:[78,7,2848],t:7,e:"ui-button",a:{icon:"eyedropper",state:[{t:2,x:{r:["data.is_ready"],s:'_0?"":"disabled"'},p:[78,43,2884]}],action:"create_vaccine_bottle",params:['{"index": ',{t:2,r:"id",p:[78,129,2970]},"}"]},f:["Create vaccine bottle"]}]}],n:52,r:"data.resistances",p:[76,4,2779]},{t:4,n:51,f:[{p:[83,5,3067],t:7,e:"ui-section",f:[{p:[84,6,3086],t:7,e:"span",a:{"class":"average"},f:["No antibodies detected in the blood sample."]}]}],r:"data.resistances"}]}],n:50,r:"data.has_blood",p:[37,2,1162]}],n:50,x:{r:["data.mode"],s:"_0==1"},p:[1,1,0]},{t:4,n:51,f:[{p:[90,2,3231],t:7,e:"ui-button",a:{icon:"undo",state:"",action:"back"},f:["Back"]}," ",{t:4,f:[{p:[94,4,3330],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[94,23,3349]}]},f:[{p:[95,4,3364],t:7,e:"ui-section",f:[{t:2,r:"desc",p:[96,5,3382]}," ",{t:4,f:[{p:[98,5,3417],t:7,e:"br"}," ",{p:[99,5,3428],t:7,e:"b",f:["This symptom has been neutered, and has no effect. It will still affect the virus' statistics."]}],n:50,r:"neutered",p:[97,4,3395]}]}," ",{p:[102,4,3564],t:7,e:"ui-section",f:[{p:[103,5,3582],t:7,e:"ui-section",a:{label:"Level"},f:[{t:2,r:"level",p:[103,31,3608]}]}," ",{p:[104,5,3636],t:7,e:"ui-section",a:{label:"Resistance"},f:[{t:2,r:"resistance",p:[104,36,3667]}]}," ",{p:[105,5,3700],t:7,e:"ui-section",a:{label:"Stealth"},f:[{t:2,r:"stealth",p:[105,33,3728]}]}," ",{p:[106,5,3758],t:7,e:"ui-section",a:{label:"Stage speed"},f:[{t:2,r:"stage_speed",p:[106,37,3790]}]}," ",{p:[107,5,3824],t:7,e:"ui-section",a:{label:"Transmittability"},f:[{t:2,r:"transmission",p:[107,42,3861]}]}]}," ",{p:[109,4,3913],t:7,e:"ui-subdisplay",a:{title:"Effect Thresholds"},f:[{p:[110,5,3960],t:7,e:"ui-section",f:[{t:3,r:"threshold_desc",p:[110,17,3972]}]}]}]}],n:53,r:"data.symptom",p:[93,2,3303]}],x:{r:["data.mode"],s:"_0==1"}}]},e.exports=a.extend(r.exports)},{205:205}],284:[function(t,e,n){var a=t(205),r={exports:{}};!function(e){"use strict";var n=t(312);e.exports={data:{filter:"",tooltiptext:function(t,e,n){var a="";return t&&(a+="REQUIREMENTS: "+t+" "),e&&(a+="CATALYSTS: "+e+" "),n&&(a+="TOOLS: "+n),a}},oninit:function(){var t=this;this.on({hover:function(t){this.set("hovered",t.context.params)},unhover:function(t){this.set("hovered")}}),this.observe("filter",function(e,a,r){var i=null;i=t.get("data.display_compact")?t.findAll(".section"):t.findAll(".display:not(:first-child)"),(0,n.filterMulti)(i,t.get("filter").toLowerCase())},{init:!1})}}}(r),r.exports.template={v:3,t:[" ",{p:[48,1,1342],t:7,e:"ui-display",a:{title:[{t:2,r:"data.category",p:[48,20,1361]},{t:4,f:[" : ",{t:2,r:"data.subcategory",p:[48,64,1405]}],n:50,r:"data.subcategory",p:[48,37,1378]}]},f:[{t:4,f:[{p:[50,3,1459],t:7,e:"ui-section",f:["Crafting... ",{p:[51,16,1488],t:7,e:"i",a:{"class":"fa-spin fa fa-spinner"}}]}],n:50,r:"data.busy",p:[49,2,1438]},{t:4,n:51,f:[{p:[54,3,1557],t:7,e:"ui-section",f:[{p:[55,4,1574],t:7,e:"table",a:{style:"width:100%"},f:[{p:[56,5,1606],t:7,e:"tr",f:[{p:[57,6,1617],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[58,7,1659],t:7,e:"ui-button",a:{icon:"arrow-left",action:"backwardCat"},f:[{t:2,r:"data.prev_cat",p:[59,8,1718]}]}]}," ",{p:[62,6,1774],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[63,7,1816],t:7,e:"ui-button",a:{icon:"arrow-right",action:"forwardCat"},f:[{t:2,r:"data.next_cat",p:[64,7,1874]}]}]}," ",{p:[67,6,1930],t:7,e:"td",a:{style:"float:right!important"},f:[{t:4,f:[{p:[69,7,2014],t:7,e:"ui-button",a:{icon:"lock",action:"toggle_recipes"},f:["Showing Craftable Recipes"]}],n:50,r:"data.display_craftable_only",p:[68,6,1971]},{t:4,n:51,f:[{p:[73,7,2138],t:7,e:"ui-button",a:{icon:"unlock",action:"toggle_recipes"},f:["Showing All Recipes"]}],r:"data.display_craftable_only"}]}," ",{p:[78,6,2268],t:7,e:"td",a:{style:"float:right!important"},f:[{p:[79,7,2310],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.display_compact"],s:'_0?"check-square-o":"square-o"'},p:[79,24,2327]}],action:"toggle_compact"},f:["Compact"]}]}]}," ",{p:[84,5,2474],t:7,e:"tr",f:[{t:4,f:[{p:[86,6,2515],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[87,7,2557],t:7,e:"ui-button",a:{icon:"arrow-left",action:"backwardSubCat"},f:[{t:2,r:"data.prev_subcat",p:[88,8,2619]}]}]}," ",{p:[91,6,2678],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[92,7,2720],t:7,e:"ui-button",a:{icon:"arrow-right",action:"forwardSubCat"},f:[{t:2,r:"data.next_subcat",p:[93,8,2782]}]}]}],n:50,r:"data.subcategory",p:[85,5,2484]}]}]}," ",{t:4,f:[{t:4,f:[" ",{p:[101,6,2992],t:7,e:"ui-input",a:{value:[{t:2,r:"filter",p:[101,23,3009]}],placeholder:"Filter.."}}],n:51,r:"data.display_compact",p:[100,5,2902]}],n:50,r:"config.fancy",p:[99,4,2876]}]}," ",{t:4,f:[{p:[106,5,3144],t:7,e:"ui-display",f:[{t:4,f:[{p:[108,6,3193],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[108,25,3212]}]},f:[{p:[109,7,3230],t:7,e:"ui-button",a:{tooltip:[{t:2,x:{r:["tooltiptext","req_text","catalyst_text","tool_text"],s:"_0(_1,_2,_3)"},p:[109,27,3250]}],"tooltip-side":"right",action:"make",params:['{"recipe": "',{t:2,r:"ref",p:[109,135,3358]},'"}'],icon:"gears"},v:{hover:"hover",unhover:"unhover"},f:["Craft"]}]}],n:52,r:"data.can_craft",p:[107,5,3162]}," ",{t:4,f:[{t:4,f:[{p:[116,7,3567],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[116,26,3586]}]},f:[{p:[117,8,3605],t:7,e:"ui-button",a:{tooltip:[{t:2,x:{r:["tooltiptext","req_text","catalyst_text","tool_text"],s:"_0(_1,_2,_3)"},p:[117,28,3625]}],"tooltip-side":"right",state:"disabled",icon:"gears"},v:{hover:"hover",unhover:"unhover"},f:["Craft"]}]}],n:52,r:"data.cant_craft",p:[115,6,3534]}],n:51,r:"data.display_craftable_only",p:[114,5,3495]}]}],n:50,r:"data.display_compact",p:[105,4,3110]},{t:4,n:51,f:[{t:4,f:[{p:[126,6,3947],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[126,25,3966]}]},f:[{t:4,f:[{p:[128,8,4009],t:7,e:"ui-section",a:{label:"Requirements"},f:[{t:2,r:"req_text",p:[129,9,4052]}]}],n:50,r:"req_text",p:[127,7,3984]}," ",{t:4,f:[{p:[133,8,4139],t:7,e:"ui-section",a:{label:"Catalysts"},f:[{t:2,r:"catalyst_text",p:[134,9,4179]}]}],n:50,r:"catalyst_text",p:[132,7,4109]}," ",{t:4,f:[{p:[138,8,4267],t:7,e:"ui-section",a:{label:"Tools"},f:[{t:2,r:"tool_text",p:[139,9,4303]}]}],n:50,r:"tool_text",p:[137,7,4241]}," ",{p:[142,7,4361],t:7,e:"ui-section",f:[{p:[143,8,4382],t:7,e:"ui-button",a:{icon:"gears",action:"make",params:['{"recipe": "',{t:2,r:"ref",p:[143,66,4440]},'"}']},f:["Craft"]}]}]}],n:52,r:"data.can_craft",p:[125,5,3916]}," ",{t:4,f:[{t:4,f:[{p:[151,7,4621],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[151,26,4640]}]},f:[{t:4,f:[{p:[153,9,4685],t:7,e:"ui-section",a:{label:"Requirements"},f:[{t:2,r:"req_text",p:[154,10,4729]}]}],n:50,r:"req_text",p:[152,8,4659]}," ",{t:4,f:[{p:[158,9,4820],t:7,e:"ui-section",a:{label:"Catalysts"},f:[{t:2,r:"catalyst_text",p:[159,10,4861]}]}],n:50,r:"catalyst_text",p:[157,8,4789]}," ",{t:4,f:[{p:[163,9,4953],t:7,e:"ui-section",a:{label:"Tools"},f:[{t:2,r:"tool_text",p:[164,10,4990]}]}],n:50,r:"tool_text",p:[162,8,4926]}]}],n:52,r:"data.cant_craft",p:[150,6,4588]}],n:51,r:"data.display_craftable_only",p:[149,5,4549]}],r:"data.display_compact"}],r:"data.busy"}]}]},e.exports=a.extend(r.exports)},{205:205,312:312}],285:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.holding"],s:'_0?"is":"is not"'},p:[2,23,35]}," connected to a tank."]}]}," ",{p:[4,1,113],t:7,e:"ui-display",a:{title:"Status",button:0},f:[{p:[5,3,151],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,5,186],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[6,11,192]}," kPa"]}]}," ",{p:[8,3,254],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[9,5,285],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected"],s:'_0?"good":"average"'},p:[9,18,298]}]},f:[{t:2,x:{r:["data.connected"],s:'_0?"Connected":"Not Connected"'},p:[9,59,339]}]}]}]}," ",{p:[12,1,430],t:7,e:"ui-display",a:{title:"Pump"},f:[{p:[13,3,459],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,5,491],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[14,22,508]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":"null"'},p:[15,14,559]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[16,22,616]}]}]}," ",{p:[18,3,675],t:7,e:"ui-section",a:{label:"Direction"},f:[{p:[19,5,711],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.direction"],s:'_0=="out"?"sign-out":"sign-in"'},p:[19,22,728]}],action:"direction"},f:[{t:2,x:{r:["data.direction"],s:'_0=="out"?"Out":"In"'},p:[20,26,808]}]}]}," ",{p:[22,3,883],t:7,e:"ui-section",a:{label:"Target Pressure"},f:[{p:[23,5,925],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.min_pressure",p:[23,18,938]}],max:[{t:2,r:"data.max_pressure",p:[23,46,966]}],value:[{t:2,r:"data.target_pressure",p:[24,14,1003]}]},f:[{t:2,x:{r:["adata.target_pressure"],s:"Math.round(_0)"},p:[24,40,1029]}," kPa"]}]}," ",{p:[26,3,1100],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[27,5,1145],t:7,e:"ui-button", ++a:{icon:"refresh",state:[{t:2,x:{r:["data.target_pressure","data.default_pressure"],s:'_0!=_1?null:"disabled"'},p:[27,38,1178]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[29,5,1328],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.target_pressure","data.min_pressure"],s:'_0>_1?null:"disabled"'},p:[29,36,1359]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[31,5,1500],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[32,5,1595],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.target_pressure","data.max_pressure"],s:'_0<_1?null:"disabled"'},p:[32,35,1625]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}]}," ",{p:{button:[{t:4,f:[{p:[39,7,1891],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.on"],s:'_0?"danger":null'},p:[39,38,1922]}],action:"eject"},f:["Eject"]}],n:50,r:"data.holding",p:[38,5,1863]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[43,3,2042],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holding.name",p:[44,4,2073]}]}," ",{p:[46,3,2115],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holding.pressure"],s:"Math.round(_0)"},p:[47,4,2149]}," kPa"]}],n:50,r:"data.holding",p:[42,3,2018]},{t:4,n:51,f:[{p:[50,3,2223],t:7,e:"ui-section",f:[{p:[51,4,2240],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.holding"}]}]},e.exports=a.extend(r.exports)},{205:205}],286:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.holding"],s:'_0?"is":"is not"'},p:[2,23,35]}," connected to a tank."]}]}," ",{p:[4,1,113],t:7,e:"ui-display",a:{title:"Status",button:0},f:[{p:[5,3,151],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,5,186],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[6,11,192]}," kPa"]}]}," ",{p:[8,3,254],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[9,5,285],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected"],s:'_0?"good":"average"'},p:[9,18,298]}]},f:[{t:2,x:{r:["data.connected"],s:'_0?"Connected":"Not Connected"'},p:[9,59,339]}]}]}]}," ",{p:[12,1,430],t:7,e:"ui-display",a:{title:"Filter"},f:[{p:[13,3,461],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,5,493],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[14,22,510]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":"null"'},p:[15,14,561]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[16,22,618]}]}]}]}," ",{p:{button:[{t:4,f:[{p:[22,7,787],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.on"],s:'_0?"danger":null'},p:[22,38,818]}],action:"eject"},f:["Eject"]}],n:50,r:"data.holding",p:[21,5,759]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[26,3,938],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holding.name",p:[27,4,969]}]}," ",{p:[29,3,1011],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holding.pressure"],s:"Math.round(_0)"},p:[30,4,1045]}," kPa"]}],n:50,r:"data.holding",p:[25,3,914]},{t:4,n:51,f:[{p:[33,3,1119],t:7,e:"ui-section",f:[{p:[34,4,1136],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.holding"}]}]},e.exports=a.extend(r.exports)},{205:205}],287:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{chargingState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},chargingMode:function(t){return 2==t?"Full":1==t?"Charging":"Draining"},channelState:function(t){return t>=2?"good":"bad"},channelPower:function(t){return t>=2?"On":"Off"},channelMode:function(t){return 1==t||3==t?"Auto":"Manual"}},computed:{graphData:function(){var t=this.get("data.history");return Object.keys(t).map(function(e){return t[e].map(function(t,e){return{x:e,y:t}})})}}}}(r),r.exports.template={v:3,t:[" ",{p:[42,1,1035],t:7,e:"ui-display",a:{title:"Network"},f:[{t:4,f:[{p:[44,5,1093],t:7,e:"ui-linegraph",a:{points:[{t:2,r:"graphData",p:[44,27,1115]}],height:"500",legend:'["Available", "Load"]',colors:'["rgb(0, 102, 0)", "rgb(153, 0, 0)"]',xunit:"seconds ago",xfactor:[{t:2,r:"data.interval",p:[46,38,1267]}],yunit:"W",yfactor:"1",xinc:[{t:2,x:{r:["data.stored"],s:"_0/10"},p:[47,15,1323]}],yinc:"9"}}],n:50,r:"config.fancy",p:[43,3,1067]},{t:4,n:51,f:[{p:[49,5,1373],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[50,7,1411],t:7,e:"span",f:[{t:2,r:"data.supply",p:[50,13,1417]}," W"]}]}," ",{p:[52,5,1466],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[53,9,1501],t:7,e:"span",f:[{t:2,r:"data.demand",p:[53,15,1507]}," W"]}]}],r:"config.fancy"}]}," ",{p:[57,1,1578],t:7,e:"ui-display",a:{title:"Areas"},f:[{p:[58,3,1608],t:7,e:"ui-section",a:{nowrap:0},f:[{p:[59,5,1633],t:7,e:"div",a:{"class":"content"},f:["Area"]}," ",{p:[60,5,1670],t:7,e:"div",a:{"class":"content"},f:["Charge"]}," ",{p:[61,5,1709],t:7,e:"div",a:{"class":"content"},f:["Load"]}," ",{p:[62,5,1746],t:7,e:"div",a:{"class":"content"},f:["Status"]}," ",{p:[63,5,1785],t:7,e:"div",a:{"class":"content"},f:["Equipment"]}," ",{p:[64,5,1827],t:7,e:"div",a:{"class":"content"},f:["Lighting"]}," ",{p:[65,5,1868],t:7,e:"div",a:{"class":"content"},f:["Environment"]}]}," ",{t:4,f:[{p:[68,5,1953],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[68,24,1972]}],nowrap:0},f:[{p:[69,7,1997],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].charge)"},p:[69,28,2018]}," %"]}," ",{p:[70,7,2076],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].load)"},p:[70,28,2097]}," W"]}," ",{p:[71,7,2153],t:7,e:"div",a:{"class":"content"},f:[{p:[71,28,2174],t:7,e:"span",a:{"class":[{t:2,x:{r:["chargingState","charging"],s:"_0(_1)"},p:[71,41,2187]}]},f:[{t:2,x:{r:["chargingMode","charging"],s:"_0(_1)"},p:[71,70,2216]}]}]}," ",{p:[72,7,2263],t:7,e:"div",a:{"class":"content"},f:[{p:[72,28,2284],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","eqp"],s:"_0(_1)"},p:[72,41,2297]}]},f:[{t:2,x:{r:["channelPower","eqp"],s:"_0(_1)"},p:[72,64,2320]}," [",{p:[72,87,2343],t:7,e:"span",f:[{t:2,x:{r:["channelMode","eqp"],s:"_0(_1)"},p:[72,93,2349]}]},"]"]}]}," ",{p:[73,7,2398],t:7,e:"div",a:{"class":"content"},f:[{p:[73,28,2419],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","lgt"],s:"_0(_1)"},p:[73,41,2432]}]},f:[{t:2,x:{r:["channelPower","lgt"],s:"_0(_1)"},p:[73,64,2455]}," [",{p:[73,87,2478],t:7,e:"span",f:[{t:2,x:{r:["channelMode","lgt"],s:"_0(_1)"},p:[73,93,2484]}]},"]"]}]}," ",{p:[74,7,2533],t:7,e:"div",a:{"class":"content"},f:[{p:[74,28,2554],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","env"],s:"_0(_1)"},p:[74,41,2567]}]},f:[{t:2,x:{r:["channelPower","env"],s:"_0(_1)"},p:[74,64,2590]}," [",{p:[74,87,2613],t:7,e:"span",f:[{t:2,x:{r:["channelMode","env"],s:"_0(_1)"},p:[74,93,2619]}]},"]"]}]}]}],n:52,r:"data.areas",p:[67,3,1927]}]}]},e.exports=a.extend(r.exports)},{205:205}],288:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{readableFrequency:function(){return Math.round(this.get("adata.frequency"))/10}}}}(r),r.exports.template={v:3,t:[" ",{p:[11,1,177],t:7,e:"ui-display",a:{title:"Settings"},f:[{t:4,f:[{p:[13,5,236],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,7,270],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.listening"],s:'_0?"power-off":"close"'},p:[14,24,287]}],style:[{t:2,x:{r:["data.listening"],s:'_0?"selected":null'},p:[14,75,338]}],action:"listen"},f:[{t:2,x:{r:["data.listening"],s:'_0?"On":"Off"'},p:[16,9,413]}]}]}],n:50,r:"data.headset",p:[12,3,210]},{t:4,n:51,f:[{p:[19,5,494],t:7,e:"ui-section",a:{label:"Microphone"},f:[{p:[20,7,533],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.broadcasting"],s:'_0?"power-off":"close"'},p:[20,24,550]}],style:[{t:2,x:{r:["data.broadcasting"],s:'_0?"selected":null'},p:[20,78,604]}],action:"broadcast"},f:[{t:2,x:{r:["data.broadcasting"],s:'_0?"Engaged":"Disengaged"'},p:[22,9,685]}]}]}," ",{p:[24,5,769],t:7,e:"ui-section",a:{label:"Speaker"},f:[{p:[25,7,805],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.listening"],s:'_0?"power-off":"close"'},p:[25,24,822]}],style:[{t:2,x:{r:["data.listening"],s:'_0?"selected":null'},p:[25,75,873]}],action:"listen"},f:[{t:2,x:{r:["data.listening"],s:'_0?"Engaged":"Disengaged"'},p:[27,9,948]}]}]}],r:"data.headset"}," ",{t:4,f:[{p:[31,5,1064],t:7,e:"ui-section",a:{label:"High Volume"},f:[{p:[32,7,1104],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.useCommand"],s:'_0?"power-off":"close"'},p:[32,24,1121]}],style:[{t:2,x:{r:["data.useCommand"],s:'_0?"selected":null'},p:[32,76,1173]}],action:"command"},f:[{t:2,x:{r:["data.useCommand"],s:'_0?"On":"Off"'},p:[34,9,1250]}]}]}],n:50,r:"data.command",p:[30,3,1038]}]}," ",{p:[38,1,1342],t:7,e:"ui-display",a:{title:"Channel"},f:[{p:[39,3,1374],t:7,e:"ui-section",a:{label:"Frequency"},f:[{t:4,f:[{p:[41,7,1439],t:7,e:"span",f:[{t:2,r:"readableFrequency",p:[41,13,1445]}]}],n:50,r:"data.freqlock",p:[40,5,1410]},{t:4,n:51,f:[{p:[43,7,1495],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.frequency","data.minFrequency"],s:'_0==_1?"disabled":null'},p:[43,46,1534]}],action:"frequency",params:'{"adjust": -1}'}}," ",{p:[44,7,1646],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.frequency","data.minFrequency"],s:'_0==_1?"disabled":null'},p:[44,41,1680]}],action:"frequency",params:'{"adjust": -.2}'}}," ",{p:[45,7,1793],t:7,e:"ui-button",a:{icon:"pencil",action:"frequency",params:'{"tune": "input"}'},f:[{t:2,r:"readableFrequency",p:[45,78,1864]}]}," ",{p:[46,7,1905],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.frequency","data.maxFrequency"],s:'_0==_1?"disabled":null'},p:[46,40,1938]}],action:"frequency",params:'{"adjust": .2}'}}," ",{p:[47,7,2050],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.frequency","data.maxFrequency"],s:'_0==_1?"disabled":null'},p:[47,45,2088]}],action:"frequency",params:'{"adjust": 1}'}}],r:"data.freqlock"}]}," ",{t:4,f:[{p:[51,5,2262],t:7,e:"ui-section",a:{label:"Subspace Transmission"},f:[{p:[52,7,2312],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.subspace"],s:'_0?"power-off":"close"'},p:[52,24,2329]}],style:[{t:2,x:{r:["data.subspace"],s:'_0?"selected":null'},p:[52,74,2379]}],action:"subspace"},f:[{t:2,x:{r:["data.subspace"],s:'_0?"Active":"Inactive"'},p:[53,29,2447]}]}]}],n:50,r:"data.subspaceSwitchable",p:[50,3,2225]}," ",{t:4,f:[{p:[57,5,2578],t:7,e:"ui-section",a:{label:"Channels"},f:[{t:4,f:[{p:[59,9,2656],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["."],s:'_0?"check-square-o":"square-o"'},p:[59,26,2673]}],style:[{t:2,x:{r:["."],s:'_0?"selected":null'},p:[60,18,2730]}],action:"channel",params:['{"channel": "',{t:2,r:"channel",p:[61,49,2806]},'"}']},f:[{t:2,r:"channel",p:[62,11,2833]}]},{p:[62,34,2856],t:7,e:"br"}],n:52,i:"channel",r:"data.channels",p:[58,7,2615]}]}],n:50,x:{r:["data.subspace","data.channels"],s:"_0&&_1"},p:[56,3,2534]}]}]},e.exports=a.extend(r.exports)},{205:205}],289:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,23],t:7,e:"ui-notice",f:[{t:2,r:"data.notice",p:[3,5,40]}]}],n:50,r:"data.notice",p:[1,1,0]},{p:[6,1,82],t:7,e:"ui-display",a:{title:"Satellite Network Control",button:0},f:[{t:4,f:[{p:[8,4,168],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[9,9,209],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[9,31,231]}]}," ",{p:[10,9,253],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"mode",p:[10,30,274]}]}," ",{p:[11,9,298],t:7,e:"div",a:{"class":"content"},f:[{p:[12,11,331],t:7,e:"ui-button",a:{action:"toggle",params:['{"id": "',{t:2,r:"id",p:[12,54,374]},'"}']},f:[{t:2,x:{r:["active"],s:'_0?"Deactivate":"Activate"'},p:[12,64,384]}]}]}]}],n:52,r:"data.satellites",p:[7,2,138]}]}," ",{t:4,f:[{p:[18,1,528],t:7,e:"ui-display",a:{title:"Station Shield Coverage"},f:[{p:[19,3,576],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.meteor_shield_coverage_max",p:[19,24,597]}],value:[{t:2,r:"data.meteor_shield_coverage",p:[19,68,641]}]},f:[{t:2,x:{r:["data.meteor_shield_coverage","data.meteor_shield_coverage_max"],s:"100*_0/_1"},p:[19,101,674]}," %"]}," ",{p:[20,1,758],t:7,e:"ui-display",f:[]}]}],n:50,r:"data.meteor_shield",p:[17,1,500]}]},e.exports=a.extend(r.exports)},{205:205}],290:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[" "," "," ",{p:[5,1,200],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.tabs",p:[5,16,215]}]},f:[{p:[6,2,233],t:7,e:"tab",a:{name:"Status"},f:[{p:[7,3,256],t:7,e:"status"}]}," ",{p:[9,2,277],t:7,e:"tab",a:{name:"Templates"},f:[{p:[10,3,303],t:7,e:"templates"}]}," ",{p:[12,2,327],t:7,e:"tab",a:{name:"Modification"},f:[{t:4,f:[{p:[14,3,381],t:7,e:"modification"}],n:50,r:"data.selected",p:[13,3,356]}," ",{t:4,f:[{p:[17,3,437],t:7,e:"span",a:{"class":"bad"},f:["No shuttle selected."]}],n:50,x:{r:["data.selected"],s:"!_0"},p:[16,3,411]}]}]}]},r.exports.components=r.exports.components||{};var i={modification:t(291),templates:t(293),status:t(292)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{205:205,291:291,292:292,293:293}],291:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:["Selected: ",{t:2,r:"data.selected.name",p:[1,30,29]}]},f:[{t:4,f:[{p:[3,5,96],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.selected.description",p:[3,37,128]}]}],n:50,r:"data.selected.description",p:[2,3,57]}," ",{t:4,f:[{p:[6,5,224],t:7,e:"ui-section",a:{label:"Admin Notes"},f:[{t:2,r:"data.selected.admin_notes",p:[6,37,256]}]}],n:50,r:"data.selected.admin_notes",p:[5,3,185]}]}," ",{t:4,f:[{p:[11,3,361],t:7,e:"ui-display",a:{title:["Existing Shuttle: ",{t:2,r:"data.existing_shuttle.name",p:[11,40,398]}]},f:["Status: ",{t:2,r:"data.existing_shuttle.status",p:[12,13,444]}," ",{t:4,f:["(",{t:2,r:"data.existing_shuttle.timeleft",p:[14,8,526]},")"],n:50,r:"data.existing_shuttle.timer",p:[13,5,482]}," ",{p:[16,5,580],t:7,e:"ui-button",a:{action:"jump_to",params:['{"type": "mobile", "id": "',{t:2,r:"data.existing_shuttle.id",p:[17,41,649]},'"}']},f:["Jump To"]}]}],n:50,r:"data.existing_shuttle",p:[10,1,328]},{t:4,f:[{p:[24,3,778],t:7,e:"ui-display",a:{title:"Existing Shuttle: None"}}],n:50,x:{r:["data.existing_shuttle"],s:"!_0"},p:[23,1,744]},{p:[27,1,847],t:7,e:"ui-button",a:{action:"preview",params:['{"shuttle_id": "',{t:2,r:"data.selected.shuttle_id",p:[28,27,902]},'"}']},f:["Preview"]}," ",{p:[31,1,961],t:7,e:"ui-button",a:{action:"load",params:['{"shuttle_id": "',{t:2,r:"data.selected.shuttle_id",p:[32,27,1013]},'"}'],style:"danger"},f:["Load"]}," ",{p:[37,1,1089],t:7,e:"ui-display",a:{title:"Status"},f:[]}]},e.exports=a.extend(r.exports)},{205:205}],292:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,27],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[2,22,46]}," (",{t:2,r:"id",p:[2,32,56]},")"]},f:[{t:2,r:"status",p:[3,5,71]}," ",{t:4,f:["(",{t:2,r:"timeleft",p:[5,8,109]},")"],n:50,r:"timer",p:[4,5,87]}," ",{p:[7,5,141],t:7,e:"ui-button",a:{action:"jump_to",params:['{"type": "mobile", "id": "',{t:2,r:"id",p:[7,67,203]},'"}']},f:["Jump To"]}," ",{p:[10,5,252],t:7,e:"ui-button",a:{action:"fast_travel",params:['{"id": "',{t:2,r:"id",p:[10,53,300]},'"}'],state:[{t:2,x:{r:["can_fast_travel"],s:'_0?null:"disabled"'},p:[10,70,317]}]},f:["Fast Travel"]}]}],n:52,r:"data.shuttles",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],293:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.templates_tabs",p:[1,16,15]}]},f:[{t:4,f:[{p:[3,5,74],t:7,e:"tab",a:{name:[{t:2,r:"port_id",p:[3,16,85]}]},f:[{t:4,f:[{p:[5,9,135],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[5,28,154]}]},f:[{t:4,f:[{p:[7,13,209],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"description",p:[7,45,241]}]}],n:50,r:"description",p:[6,11,176]}," ",{t:4,f:[{p:[10,13,333],t:7,e:"ui-section",a:{label:"Admin Notes"},f:[{t:2,r:"admin_notes",p:[10,45,365]}]}],n:50,r:"admin_notes",p:[9,11,300]}," ",{p:[13,11,426],t:7,e:"ui-button",a:{action:"select_template",params:['{"shuttle_id": "',{t:2,r:"shuttle_id",p:[14,37,499]},'"}'],state:[{t:2,x:{r:["data.selected.shuttle_id","shuttle_id"],s:'_0==_1?"selected":null'},p:[15,20,537]}]},f:[{t:2,x:{r:["data.selected.shuttle_id","shuttle_id"],s:'_0==_1?"Selected":"Select"'},p:[17,13,630]}]}]}],n:52,r:"templates",p:[4,7,106]}]}],n:52,r:"data.templates",p:[2,3,44]}]}]},e.exports=a.extend(r.exports)},{205:205}],294:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{occupantStatState:function(){switch(this.get("data.occupant.stat")){case 0:return"good";case 1:return"average";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[15,1,280],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[16,3,313],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[17,3,346],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[17,9,352]}]}]}," ",{t:4,f:[{p:[20,5,466],t:7,e:"ui-section",a:{label:"State"},f:[{p:[21,7,500],t:7,e:"span",a:{"class":[{t:2,r:"occupantStatState",p:[21,20,513]}]},f:[{t:2,x:{r:["data.occupant.stat"],s:'_0==0?"Conscious":_0==1?"Unconcious":"Dead"'},p:[21,43,536]}]}]}," ",{p:[23,5,658],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[24,7,693],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[24,20,706]}],max:[{t:2,r:"data.occupant.maxHealth",p:[24,54,740]}],value:[{t:2,r:"data.occupant.health",p:[24,90,776]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[25,16,818]}]},f:[{t:2,x:{r:["adata.occupant.health"],s:"Math.round(_0)"},p:[25,68,870]}]}]}," ",{t:4,f:[{p:[28,7,1107],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[28,26,1126]}]},f:[{p:[29,9,1147],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[29,30,1168]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[29,66,1204]}],state:"bad"},f:[{t:2,x:{r:["type","adata.occupant"],s:"Math.round(_1[_0])"},p:[29,103,1241]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[27,5,941]}," ",{p:[32,5,1328],t:7,e:"ui-section",a:{label:"Cells"},f:[{p:[33,9,1364],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"bad":"good"'},p:[33,22,1377]}]},f:[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"Damaged":"Healthy"'},p:[33,68,1423]}]}]}," ",{p:[35,5,1506],t:7,e:"ui-section",a:{label:"Brain"},f:[{p:[36,9,1542],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"bad":"good"'},p:[36,22,1555]}]},f:[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"Abnormal":"Healthy"'},p:[36,68,1601]}]}]}," ",{p:[38,5,1685],t:7,e:"ui-section",a:{label:"Bloodstream"},f:[{t:4,f:[{p:[40,11,1772],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,1)"},p:[40,54,1815]}," units of ",{t:2,r:"name",p:[40,89,1850]}]},{p:[40,104,1865],t:7,e:"br"}],n:52,r:"adata.occupant.reagents",p:[39,9,1727]},{t:4,n:51,f:[{p:[42,11,1900],t:7,e:"span",a:{"class":"good"},f:["Pure"]}],r:"adata.occupant.reagents"}]}],n:50,r:"data.occupied",p:[19,3,439]}]}," ",{p:[47,1,1996],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[48,2,2028],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[49,5,2059],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"unlock":"lock"'},p:[49,22,2076]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Open":"Closed"'},p:[49,71,2125]}]}]}," ",{p:[51,3,2190],t:7,e:"ui-section",a:{label:"Inject"},f:[{t:4,f:[{p:[53,7,2251],t:7,e:"ui-button",a:{icon:"flask",state:[{t:2,x:{r:["data.occupied","allowed"],s:'_0&&_1?null:"disabled"'},p:[53,38,2282]}],action:"inject",params:['{"chem": "',{t:2,r:"id",p:[53,122,2366]},'"}']},f:[{t:2,r:"name",p:[53,132,2376]}]},{p:[53,152,2396],t:7,e:"br"}],n:52,r:"data.chems",p:[52,5,2223]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],295:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,25],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[2,22,44]}],labelcolor:[{t:2,r:"htmlcolor",p:[2,44,66]}],candystripe:0,right:0},f:[{p:[3,5,105],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[3,32,132],t:7,e:"span",a:{"class":[{t:2,x:{r:["status"],s:'_0=="Dead"?"bad bold":_0=="Unconscious"?"average bold":"good"'},p:[3,45,145]}]},f:[{t:2,r:"status",p:[3,132,232]}]}]}," ",{p:[4,5,268],t:7,e:"ui-section",a:{label:"Jelly"},f:[{t:2,r:"exoticblood",p:[4,31,294]}]}," ",{p:[5,5,328],t:7,e:"ui-section",a:{label:"Location"},f:[{t:2,r:"area",p:[5,34,357]}]}," ",{p:[7,5,386],t:7,e:"ui-button",a:{state:[{t:2,r:"swap_button_state",p:[8,14,411]}],action:"swap",params:['{"ref": "',{t:2,r:"ref",p:[9,38,472]},'"}']},f:[{t:2,x:{r:["is_current"],s:'_0?"You Are Here":"Swap"'},p:[10,7,491]}]}]}],n:52,r:"data.bodies",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],296:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{capacityPercentState:function(){var t=this.get("data.capacityPercent");return t>50?"good":t>15?"average":"bad"},inputState:function(){return this.get("data.capacityPercent")>=100?"good":this.get("data.inputting")?"average":"bad"},outputState:function(){return this.get("data.outputting")?"good":this.get("data.charge")>0?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[24,1,663],t:7,e:"ui-display",a:{title:"Storage"},f:[{p:[25,3,695],t:7,e:"ui-section",a:{label:"Stored Energy"},f:[{p:[26,5,735],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.capacityPercent",p:[26,38,768]}],state:[{t:2,r:"capacityPercentState",p:[26,71,801]}]},f:[{t:2,x:{r:["adata.capacityPercent"],s:"Math.fixed(_0)"},p:[26,97,827]},"%"]}]}]}," ",{p:[29,1,908],t:7,e:"ui-display",a:{title:"Input"},f:[{p:[30,3,938],t:7,e:"ui-section",a:{label:"Charge Mode"},f:[{p:[31,5,976],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"refresh":"close"'},p:[31,22,993]}],style:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"selected":null'},p:[31,74,1045]}],action:"tryinput"},f:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"Auto":"Off"'},p:[32,25,1113]}]},"   [",{p:[34,6,1182],t:7,e:"span",a:{"class":[{t:2,r:"inputState",p:[34,19,1195]}]},f:[{t:2,x:{r:["data.capacityPercent","data.inputting"],s:'_0>=100?"Fully Charged":_1?"Charging":"Not Charging"'},p:[34,35,1211]}]},"]"]}," ",{p:[36,3,1335],t:7,e:"ui-section",a:{label:"Target Input"},f:[{p:[37,5,1374],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.inputLevelMax",p:[37,26,1395]}],value:[{t:2,r:"data.inputLevel",p:[37,57,1426]}]},f:[{t:2,x:{r:["adata.inputLevel"],s:"Math.round(_0)"},p:[37,78,1447]},"W"]}]}," ",{p:[39,3,1509],t:7,e:"ui-section",a:{label:"Adjust Input"},f:[{p:[40,5,1548],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.inputLevel"],s:'_0==0?"disabled":null'},p:[40,44,1587]}],action:"input",params:'{"target": "min"}'}}," ",{p:[41,5,1682],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.inputLevel"],s:'_0==0?"disabled":null'},p:[41,39,1716]}],action:"input",params:'{"adjust": -10000}'}}," ",{p:[42,5,1812],t:7,e:"ui-button",a:{icon:"pencil",action:"input",params:'{"target": "input"}'},f:["Set"]}," ",{p:[43,5,1902],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.inputLevel","data.inputLevelMax"],s:'_0==_1?"disabled":null'},p:[43,38,1935]}],action:"input",params:'{"adjust": 10000}'}}," ",{p:[44,5,2047],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.inputLevel","data.inputLevelMax"],s:'_0==_1?"disabled":null'},p:[44,43,2085]}],action:"input",params:'{"target": "max"}'}}]}," ",{p:[46,3,2212],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[47,3,2246],t:7,e:"span",f:[{t:2,x:{r:["adata.inputAvailable"],s:"Math.round(_0)"},p:[47,9,2252]},"W"]}]}]}," ",{p:[50,1,2329],t:7,e:"ui-display",a:{title:"Output"},f:[{p:[51,3,2360],t:7,e:"ui-section",a:{label:"Output Mode"},f:[{p:[52,5,2398],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"power-off":"close"'},p:[52,22,2415]}],style:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"selected":null'},p:[52,77,2470]}],action:"tryoutput"},f:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"On":"Off"'},p:[53,26,2540]}]},"   [",{p:[55,6,2608],t:7,e:"span",a:{"class":[{t:2,r:"outputState",p:[55,19,2621]}]},f:[{t:2,x:{r:["data.outputting","data.charge"],s:'_0?"Sending":_1>0?"Not Sending":"No Charge"'},p:[55,36,2638]}]},"]"]}," ",{p:[57,3,2745],t:7,e:"ui-section",a:{label:"Target Output"},f:[{p:[58,5,2785],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.outputLevelMax",p:[58,26,2806]}],value:[{t:2,r:"data.outputLevel",p:[58,58,2838]}]},f:[{t:2,x:{r:["adata.outputLevel"],s:"Math.round(_0)"},p:[58,80,2860]},"W"]}]}," ",{p:[60,3,2923],t:7,e:"ui-section",a:{label:"Adjust Output"},f:[{p:[61,5,2963],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.outputLevel"],s:'_0==0?"disabled":null'},p:[61,44,3002]}],action:"output",params:'{"target": "min"}'}}," ",{p:[62,5,3099],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.outputLevel"],s:'_0==0?"disabled":null'},p:[62,39,3133]}],action:"output",params:'{"adjust": -10000}'}}," ",{p:[63,5,3231],t:7,e:"ui-button",a:{icon:"pencil",action:"output",params:'{"target": "input"}'},f:["Set"]}," ",{p:[64,5,3322],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.outputLevel","data.outputLevelMax"],s:'_0==_1?"disabled":null'},p:[64,38,3355]}],action:"output",params:'{"adjust": 10000}'}}," ",{p:[65,5,3470],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.outputLevel","data.outputLevelMax"],s:'_0==_1?"disabled":null'},p:[65,43,3508]}],action:"output",params:'{"target": "max"}'}}]}," ",{p:[67,3,3638],t:7,e:"ui-section",a:{label:"Outputting"},f:[{p:[68,3,3673],t:7,e:"span",f:[{t:2,x:{r:["adata.outputUsed"],s:"Math.round(_0)"},p:[68,9,3679]},"W"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],297:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,3,31],t:7,e:"ui-section",a:{label:"Generated Power"},f:[{t:2,x:{r:["adata.generated"],s:"Math.round(_0)"},p:[3,5,73]},"W"]}," ",{p:[5,3,126],t:7,e:"ui-section",a:{label:"Orientation"},f:[{p:[6,5,164],t:7,e:"span",f:[{t:2,x:{r:["adata.angle"],s:"Math.round(_0)"},p:[6,11,170]},"° (",{t:2,r:"data.direction",p:[6,45,204]},")"]}]}," ",{p:[8,3,251],t:7,e:"ui-section",a:{label:"Adjust Angle"},f:[{p:[9,5,290],t:7,e:"ui-button",a:{icon:"step-backward",action:"angle",params:'{"adjust": -15}'},f:["15°"]}," ",{p:[10,5,387],t:7,e:"ui-button",a:{icon:"backward",action:"angle",params:'{"adjust": -5}'},f:["5°"]}," ",{p:[11,5,477],t:7,e:"ui-button",a:{icon:"forward",action:"angle",params:'{"adjust": 5}'},f:["5°"]}," ",{p:[12,5,565],t:7,e:"ui-button",a:{icon:"step-forward",action:"angle",params:'{"adjust": 15}'},f:["15°"]}]}]}," ",{p:[15,1,687],t:7,e:"ui-display",a:{title:"Tracking"},f:[{p:[16,3,720],t:7,e:"ui-section",a:{label:"Tracker Mode"},f:[{p:[17,5,759],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.tracking_state"],s:'_0==0?"selected":null'},p:[17,36,790]}],action:"tracking",params:'{"mode": 0}'},f:["Off"]}," ",{p:[19,5,907],t:7,e:"ui-button",a:{icon:"clock-o",state:[{t:2,x:{r:["data.tracking_state"],s:'_0==1?"selected":null'},p:[19,38,940]}],action:"tracking",params:'{"mode": 1}'},f:["Timed"]}," ",{p:[21,5,1059],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.connected_tracker","data.tracking_state"],s:'_0?_1==2?"selected":null:"disabled"'},p:[21,38,1092]}],action:"tracking",params:'{"mode": 2}'},f:["Auto"]}]}," ",{p:[24,3,1262],t:7,e:"ui-section",a:{label:"Tracking Rate"},f:[{p:[25,3,1300],t:7,e:"span",f:[{t:2,x:{r:["adata.tracking_rate"],s:"Math.round(_0)"},p:[25,9,1306]},"°/h (",{t:2,r:"data.rotating_way",p:[25,53,1350]},")"]}]}," ",{p:[27,3,1399],t:7,e:"ui-section",a:{label:"Adjust Rate"},f:[{p:[28,5,1437],t:7,e:"ui-button",a:{icon:"fast-backward",action:"rate",params:'{"adjust": -180}'},f:["180°"]}," ",{p:[29,5,1535],t:7,e:"ui-button",a:{icon:"step-backward",action:"rate",params:'{"adjust": -30}'},f:["30°"]}," ",{p:[30,5,1631],t:7,e:"ui-button",a:{icon:"backward",action:"rate",params:'{"adjust": -5}'},f:["5°"]}," ",{p:[31,5,1720],t:7,e:"ui-button",a:{icon:"forward",action:"rate",params:'{"adjust": 5}'},f:["5°"]}," ",{p:[32,5,1807],t:7,e:"ui-button",a:{icon:"step-forward",action:"rate",params:'{"adjust": 30}'},f:["30°"]}," ",{p:[33,5,1901],t:7,e:"ui-button",a:{icon:"fast-forward",action:"rate",params:'{"adjust": 180}'},f:["180°"]}]}]}," ",{p:{button:[{p:[38,5,2088],t:7,e:"ui-button",a:{icon:"refresh",action:"refresh"},f:["Refresh"]}]},t:7,e:"ui-display",a:{title:"Devices",button:0},f:[" ",{p:[40,2,2169],t:7,e:"ui-section",a:{label:"Solar Tracker"},f:[{p:[41,5,2209],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected_tracker"],s:'_0?"good":"bad"'},p:[41,18,2222]}]},f:[{t:2,x:{r:["data.connected_tracker"],s:'_0?"":"Not "'},p:[41,63,2267]},"Found"]}]}," ",{p:[43,2,2338],t:7,e:"ui-section",a:{label:"Solar Panels"},f:[{p:[44,3,2375],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected_panels"],s:'_0?"good":"bad"'},p:[44,16,2388]}]},f:[{t:2,x:{r:["adata.connected_panels"],s:"Math.round(_0)"},p:[44,60,2432]}," Panels Connected"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],298:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{t:4,f:[{p:[4,7,87],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.hasPowercell"],s:'_0?null:"disabled"'},p:[4,38,118]}],action:"eject"},f:["Eject"]}],n:50,r:"data.open",p:[3,5,62]}]},t:7,e:"ui-display",a:{title:"Power",button:0},f:[" ",{p:[7,3,226],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[8,5,258],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[8,22,275]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[9,14,326]}],state:[{t:2,x:{r:["data.hasPowercell"],s:'_0?null:"disabled"'},p:[9,54,366]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[10,22,431]}]}]}," ",{p:[12,3,490],t:7,e:"ui-section",a:{label:"Cell"},f:[{t:4,f:[{p:[14,7,554],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.powerLevel",p:[14,40,587]}]},f:[{t:2,x:{r:["adata.powerLevel"],s:"Math.fixed(_0)"},p:[14,61,608]},"%"]}],n:50,r:"data.hasPowercell",p:[13,5,521]},{t:4,n:51,f:[{p:[16,4,667],t:7,e:"span",a:{"class":"bad"},f:["No Cell"]}],r:"data.hasPowercell"}]}]}," ",{p:[20,1,744],t:7,e:"ui-display",a:{title:"Thermostat"},f:[{p:[21,3,779],t:7,e:"ui-section",a:{label:"Current Temperature"},f:[{p:[22,3,823],t:7,e:"span",f:[{t:2,x:{r:["adata.currentTemp"],s:"Math.round(_0)"},p:[22,9,829]},"°C"]}]}," ",{p:[24,2,894],t:7,e:"ui-section",a:{label:"Target Temperature"},f:[{p:[25,3,937],t:7,e:"span",f:[{t:2,x:{r:["adata.targetTemp"],s:"Math.round(_0)"},p:[25,9,943]},"°C"]}]}," ",{t:4,f:[{p:[28,5,1031],t:7,e:"ui-section",a:{label:"Adjust Target"},f:[{p:[29,7,1073],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.targetTemp","data.minTemp"],s:'_0>_1?null:"disabled"'},p:[29,46,1112]}],action:"target",params:'{"adjust": -20}'}}," ",{p:[30,7,1218],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.targetTemp","data.minTemp"],s:'_0>_1?null:"disabled"'},p:[30,41,1252]}],action:"target",params:'{"adjust": -5}'}}," ",{p:[31,7,1357],t:7,e:"ui-button",a:{icon:"pencil",action:"target",params:'{"target": "input"}'},f:["Set"]}," ",{p:[32,7,1450],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.targetTemp","data.maxTemp"],s:'_0<_1?null:"disabled"'},p:[32,40,1483]}],action:"target",params:'{"adjust": 5}'}}," ",{p:[33,7,1587],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.targetTemp","data.maxTemp"],s:'_0<_1?null:"disabled"'},p:[33,45,1625]}],action:"target",params:'{"adjust": 20}'}}]}],n:50,r:"data.open",p:[27,3,1008]}," ",{p:[36,3,1754],t:7,e:"ui-section",a:{label:"Mode"},f:[{t:4,f:[{p:[38,7,1808],t:7,e:"ui-button",a:{icon:"long-arrow-up",state:[{t:2,x:{r:["data.mode"],s:'_0=="heat"?"selected":null'},p:[38,46,1847]}],action:"mode",params:'{"mode": "heat"}'},f:["Heat"]}," ",{p:[39,7,1956],t:7, ++e:"ui-button",a:{icon:"long-arrow-down",state:[{t:2,x:{r:["data.mode"],s:'_0=="cool"?"selected":null'},p:[39,48,1997]}],action:"mode",params:'{"mode": "cool"}'},f:["Cool"]}," ",{p:[40,7,2106],t:7,e:"ui-button",a:{icon:"arrows-v",state:[{t:2,x:{r:["data.mode"],s:'_0=="auto"?"selected":null'},p:[40,41,2140]}],action:"mode",params:'{"mode": "auto"}'},f:["Auto"]}],n:50,r:"data.open",p:[37,3,1783]},{t:4,n:51,f:[{p:[42,4,2258],t:7,e:"span",f:[{t:2,x:{r:["text","data.mode"],s:"_0.titleCase(_1)"},p:[42,10,2264]}]}],r:"data.open"}]}]}]},e.exports=a.extend(r.exports)},{205:205}],299:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,31],t:7,e:"ui-display",a:{title:[{t:2,r:"class",p:[2,22,50]}," Alarms"]},f:[{p:[3,5,74],t:7,e:"ul",f:[{t:4,f:[{p:[5,9,107],t:7,e:"li",f:[{t:2,r:".",p:[5,13,111]}]}],n:52,r:".",p:[4,7,86]},{t:4,n:51,f:[{p:[7,9,147],t:7,e:"li",f:["System Nominal"]}],r:"."}]}]}],n:52,i:"class",r:"data.alarms",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{205:205}],300:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,42],t:7,e:"ui-notice",f:[{p:[3,5,59],t:7,e:"span",f:["Biological entity detected in contents. Please remove."]}]}],n:50,x:{r:["data.occupied","data.safeties"],s:"_0&&_1"},p:[1,1,0]},{t:4,f:[{p:[7,3,179],t:7,e:"ui-notice",f:[{p:[8,5,196],t:7,e:"span",f:["Contents are being disinfected. Please wait."]}]}],n:50,r:"data.uv_active",p:[6,1,153]},{t:4,n:51,f:[{p:{button:[{t:4,f:[{p:[13,25,369],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[13,42,386]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Unlock":"Lock"'},p:[13,93,437]}]}],n:50,x:{r:["data.open"],s:"!_0"},p:[13,7,351]}," ",{t:4,f:[{p:[14,27,519],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"sign-out":"sign-in"'},p:[14,44,536]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Close":"Open"'},p:[14,98,590]}]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[14,7,499]}]},t:7,e:"ui-display",a:{title:"Storage",button:0},f:[" ",{t:4,f:[{p:[17,7,692],t:7,e:"ui-notice",f:[{p:[18,9,713],t:7,e:"span",f:["Unit Locked"]}]}],n:50,r:"data.locked",p:[16,5,665]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.open"],s:"_0"},f:[{p:[21,9,793],t:7,e:"ui-section",a:{label:"Helmet"},f:[{p:[22,11,832],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.helmet"],s:'_0?"square":"square-o"'},p:[22,28,849]}],state:[{t:2,x:{r:["data.helmet"],s:'_0?null:"disabled"'},p:[22,75,896]}],action:"dispense",params:'{"item": "helmet"}'},f:[{t:2,x:{r:["data.helmet"],s:'_0||"Empty"'},p:[23,59,992]}]}]}," ",{p:[25,9,1063],t:7,e:"ui-section",a:{label:"Suit"},f:[{p:[26,11,1100],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.suit"],s:'_0?"square":"square-o"'},p:[26,28,1117]}],state:[{t:2,x:{r:["data.suit"],s:'_0?null:"disabled"'},p:[26,74,1163]}],action:"dispense",params:'{"item": "suit"}'},f:[{t:2,x:{r:["data.suit"],s:'_0||"Empty"'},p:[27,57,1255]}]}]}," ",{p:[29,9,1324],t:7,e:"ui-section",a:{label:"Mask"},f:[{p:[30,11,1361],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mask"],s:'_0?"square":"square-o"'},p:[30,28,1378]}],state:[{t:2,x:{r:["data.mask"],s:'_0?null:"disabled"'},p:[30,74,1424]}],action:"dispense",params:'{"item": "mask"}'},f:[{t:2,x:{r:["data.mask"],s:'_0||"Empty"'},p:[31,57,1516]}]}]}," ",{p:[33,9,1585],t:7,e:"ui-section",a:{label:"Storage"},f:[{p:[34,11,1625],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.storage"],s:'_0?"square":"square-o"'},p:[34,28,1642]}],state:[{t:2,x:{r:["data.storage"],s:'_0?null:"disabled"'},p:[34,77,1691]}],action:"dispense",params:'{"item": "storage"}'},f:[{t:2,x:{r:["data.storage"],s:'_0||"Empty"'},p:[35,60,1789]}]}]}]},{t:4,n:50,x:{r:["data.open"],s:"!(_0)"},f:[" ",{p:[38,7,1873],t:7,e:"ui-button",a:{icon:"recycle",state:[{t:2,x:{r:["data.occupied","data.safeties"],s:'_0&&_1?"disabled":null'},p:[38,40,1906]}],action:"uv"},f:["Disinfect"]}]}],r:"data.locked"}]}],r:"data.uv_active"}]},e.exports=a.extend(r.exports)},{205:205}],301:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,5,18],t:7,e:"ui-section",a:{label:"Dispense"},f:[{p:[3,9,57],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.plasma"],s:'_0?"square":"square-o"'},p:[3,26,74]}],state:[{t:2,x:{r:["data.plasma"],s:'_0?null:"disabled"'},p:[3,74,122]}],action:"plasma"},f:["Plasma (",{t:2,x:{r:["adata.plasma"],s:"Math.round(_0)"},p:[4,37,196]},")"]}," ",{p:[5,9,247],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.oxygen"],s:'_0?"square":"square-o"'},p:[5,26,264]}],state:[{t:2,x:{r:["data.oxygen"],s:'_0?null:"disabled"'},p:[5,74,312]}],action:"oxygen"},f:["Oxygen (",{t:2,x:{r:["adata.oxygen"],s:"Math.round(_0)"},p:[6,37,386]},")"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],302:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={computed:{tankPressureState:function(){var t=this.get("data.tankPressure");return t>=200?"good":t>=100?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[14,1,295],t:7,e:"ui-notice",f:[{p:[15,3,310],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.connected"],s:'_0?"is":"is not"'},p:[15,23,330]}," connected to a mask."]}]}," ",{p:[17,1,409],t:7,e:"ui-display",f:[{p:[18,3,425],t:7,e:"ui-section",a:{label:"Tank Pressure"},f:[{p:[19,7,467],t:7,e:"ui-bar",a:{min:"0",max:"1013",value:[{t:2,r:"data.tankPressure",p:[19,41,501]}],state:[{t:2,r:"tankPressureState",p:[20,16,540]}]},f:[{t:2,x:{r:["adata.tankPressure"],s:"Math.round(_0)"},p:[20,39,563]}," kPa"]}]}," ",{p:[22,3,631],t:7,e:"ui-section",a:{label:"Release Pressure"},f:[{p:[23,5,674],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.minReleasePressure",p:[23,18,687]}],max:[{t:2,r:"data.maxReleasePressure",p:[23,52,721]}],value:[{t:2,r:"data.releasePressure",p:[24,14,764]}]},f:[{t:2,x:{r:["adata.releasePressure"],s:"Math.round(_0)"},p:[24,40,790]}," kPa"]}]}," ",{p:[26,3,861],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[27,5,906],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.releasePressure","data.defaultReleasePressure"],s:'_0!=_1?null:"disabled"'},p:[27,38,939]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[29,5,1095],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.releasePressure","data.minReleasePressure"],s:'_0>_1?null:"disabled"'},p:[29,36,1126]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[31,5,1273],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[32,5,1368],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.releasePressure","data.maxReleasePressure"],s:'_0<_1?null:"disabled"'},p:[32,35,1398]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],303:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,5,33],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[3,9,75],t:7,e:"span",f:[{t:2,x:{r:["adata.temperature"],s:"Math.fixed(_0,2)"},p:[3,15,81]}," K"]}]}," ",{p:[5,5,151],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,9,190],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.fixed(_0,2)"},p:[6,15,196]}," kPa"]}]}]}," ",{p:[9,1,276],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[10,5,311],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[11,9,347],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[11,26,364]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[11,70,408]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[12,28,469]}]}]}," ",{p:[14,5,531],t:7,e:"ui-section",a:{label:"Target Temperature"},f:[{p:[15,9,580],t:7,e:"ui-button",a:{icon:"fast-backward",style:[{t:2,x:{r:["data.target","data.min"],s:'_0==_1?"disabled":null'},p:[15,48,619]}],action:"target",params:'{"adjust": -20}'}}," ",{p:[17,9,733],t:7,e:"ui-button",a:{icon:"backward",style:[{t:2,x:{r:["data.target","data.min"],s:'_0==_1?"disabled":null'},p:[17,43,767]}],action:"target",params:'{"adjust": -5}'}}," ",{p:[19,9,880],t:7,e:"ui-button",a:{icon:"pencil",action:"target",params:'{"target": "input"}'},f:[{t:2,x:{r:["adata.target"],s:"Math.fixed(_0,2)"},p:[19,79,950]}]}," ",{p:[20,9,1003],t:7,e:"ui-button",a:{icon:"forward",style:[{t:2,x:{r:["data.target","data.max"],s:'_0==_1?"disabled":null'},p:[20,42,1036]}],action:"target",params:'{"adjust": 5}'}}," ",{p:[22,9,1148],t:7,e:"ui-button",a:{icon:"fast-forward",style:[{t:2,x:{r:["data.target","data.max"],s:'_0==_1?"disabled":null'},p:[22,47,1186]}],action:"target",params:'{"adjust": 20}'}}]}]}]},e.exports=a.extend(r.exports)},{205:205}],304:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{},oninit:function(){this.on({hover:function(t){var e=this.get("data.telecrystals");e>=t.context.params.cost&&this.set("hovered",t.context.params)},unhover:function(t){this.set("hovered")}})}}}(r),r.exports.template={v:3,t:[" ",{p:{button:[{t:4,f:[{p:[23,7,482],t:7,e:"ui-button",a:{icon:"lock",action:"lock"},f:["Lock"]}],n:50,r:"data.lockable",p:[22,5,453]}]},t:7,e:"ui-display",a:{title:"Uplink",button:0},f:[" ",{p:[26,3,568],t:7,e:"ui-section",a:{label:"Telecrystals",right:0},f:[{p:[27,5,613],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.telecrystals"],s:'_0>0?"good":"bad"'},p:[27,18,626]}]},f:[{t:2,r:"data.telecrystals",p:[27,62,670]}," TC"]}]}]}," ",{t:4,f:[{p:[31,3,764],t:7,e:"ui-display",f:[{p:[32,2,779],t:7,e:"ui-button",a:{action:"select",params:['{"category": "',{t:2,r:"name",p:[32,51,828]},'"}']},f:[{t:2,r:"name",p:[32,63,840]}]}," ",{t:4,f:[{p:[34,4,883],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[34,23,902]}],candystripe:0,right:0},f:[{p:[35,3,934],t:7,e:"ui-button",a:{tooltip:[{t:2,r:"name",p:[35,23,954]},": ",{t:2,r:"desc",p:[35,33,964]}],"tooltip-side":"left",state:[{t:2,x:{r:["data.telecrystals","hovered.cost","cost","hovered.item","name"],s:'_0<_2||(_0-_1<_2&&_3!=_4)?"disabled":null'},p:[36,12,1006]}],action:"buy",params:['{"category": "',{t:2,r:"category",p:[37,40,1165]},'", "item": ',{t:2,r:"name",p:[37,63,1188]},', "cost": ',{t:2,r:"cost",p:[37,81,1206]},"}"]},v:{hover:"hover",unhover:"unhover"},f:[{t:2,r:"cost",p:[38,43,1260]}," TC"]}]}],n:52,r:"items",p:[33,2,863]}]}],n:52,r:"data.categories",p:[30,1,735]}]},e.exports=a.extend(r.exports)},{205:205}],305:[function(t,e,n){var a=t(205),r={exports:{}};!function(t){"use strict";t.exports={data:{healthState:function(t){var e=this.get("data.vr_avatar.maxhealth");return t>e/1.5?"good":t>e/3?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[14,1,292],t:7,e:"ui-display",f:[{t:4,f:[{p:[16,3,333],t:7,e:"ui-display",a:{title:"Virtual Avatar"},f:[{p:[17,4,373],t:7,e:"ui-section",a:{label:"Name"},f:[{t:2,r:"data.vr_avatar.name",p:[18,5,404]}]}," ",{p:[20,4,450],t:7,e:"ui-section",a:{label:"Status"},f:[{t:2,r:"data.vr_avatar.status",p:[21,5,483]}]}," ",{p:[23,4,531],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[24,5,564],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.vr_avatar.maxhealth",p:[24,26,585]}],value:[{t:2,r:"adata.vr_avatar.health",p:[24,64,623]}],state:[{t:2,x:{r:["healthState","adata.vr_avatar.health"],s:"_0(_1)"},p:[24,99,658]}]},f:[{t:2,x:{r:["adata.vr_avatar.health"],s:"Math.round(_0)"},p:[24,140,699]},"/",{t:2,r:"adata.vr_avatar.maxhealth",p:[24,179,738]}]}]}]}],n:50,r:"data.vr_avatar",p:[15,2,307]},{t:4,n:51,f:[{p:[28,3,826],t:7,e:"ui-display",a:{title:"Virtual Avatar"},f:["No Virtual Avatar detected"]}],r:"data.vr_avatar"}," ",{p:[32,2,922],t:7,e:"ui-display",a:{title:"VR Commands"},f:[{p:[33,3,958],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.toggle_open"],s:'_0?"times":"plus"'},p:[33,20,975]}],action:"toggle_open"},f:[{t:2,x:{r:["data.toggle_open"],s:'_0?"Close":"Open"'},p:[34,4,1042]}," the VR Sleeper"]}," ",{t:4,f:[{p:[37,4,1144],t:7,e:"ui-button",a:{icon:"signal",action:"vr_connect"},f:["Connect to VR"]}],n:50,r:"data.isoccupant",p:[36,3,1116]}," ",{t:4,f:[{p:[42,4,1267],t:7,e:"ui-button",a:{icon:"ban",action:"delete_avatar"},f:["Delete Virtual Avatar"]}],n:50,r:"data.vr_avatar",p:[41,3,1240]}]}]}]},e.exports=a.extend(r.exports)},{205:205}],306:[function(t,e,n){var a=t(205),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{t:4,f:[{p:[3,5,42],t:7,e:"ui-section",a:{label:[{t:2,r:"color",p:[3,24,61]},{t:2,x:{r:["wire"],s:'_0?" ("+_0+")":""'},p:[3,33,70]}],labelcolor:[{t:2,r:"color",p:[3,80,117]}],candystripe:0,right:0},f:[{p:[4,7,154],t:7,e:"ui-button",a:{action:"cut",params:['{"wire":"',{t:2,r:"color",p:[4,48,195]},'"}']},f:[{t:2,x:{r:["cut"],s:'_0?"Mend":"Cut"'},p:[4,61,208]}]}," ",{p:[5,7,252],t:7,e:"ui-button",a:{action:"pulse",params:['{"wire":"',{t:2,r:"color",p:[5,50,295]},'"}']},f:["Pulse"]}," ",{p:[6,7,333],t:7,e:"ui-button",a:{action:"attach",params:['{"wire":"',{t:2,r:"color",p:[6,51,377]},'"}']},f:[{t:2,x:{r:["attached"],s:'_0?"Detach":"Attach"'},p:[6,64,390]}]}]}],n:52,r:"data.wires",p:[2,3,16]}]}," ",{t:4,f:[{p:[11,3,508],t:7,e:"ui-display",f:[{t:4,f:[{p:[13,7,555],t:7,e:"ui-section",f:[{t:2,r:".",p:[13,19,567]}]}],n:52,r:"data.status",p:[12,5,526]}]}],n:50,r:"data.status",p:[10,1,485]}]},e.exports=a.extend(r.exports)},{205:205}],307:[function(t,e,n){(function(e){"use strict";var n=t(205),a=e.interopRequireDefault(n);t(194),t(1),t(190),t(193);var r=t(308),i=e.interopRequireDefault(r),o=t(309),s=t(191),u=t(192),p=e.interopRequireDefault(u);a["default"].DEBUG=/minified/.test(function(){}),Object.assign(Math,t(313)),window.initialize=function(e){window.tgui||(window.tgui=new i["default"]({el:"#container",data:function(){var n=JSON.parse(e);return{constants:t(310),text:t(314),config:n.config,data:n.data,adata:n.data}}}))};var c=document.getElementById("data"),l=c.textContent,f=c.getAttribute("data-ref");"{}"!==l&&(window.initialize(l),c.remove()),(0,o.act)(f,"tgui:initialize"),(0,s.loadCSS)("font-awesome.min.css");var d=new p["default"]("FontAwesome");d.check("").then(function(){return document.body.classList.add("icons")})["catch"](function(){return document.body.classList.add("no-icons")})}).call(this,t("babel/external-helpers"))},{1:1,190:190,191:191,192:192,193:193,194:194,205:205,308:308,309:309,310:310,313:313,314:314,"babel/external-helpers":"babel/external-helpers"}],308:[function(t,e,n){var a=t(205),r={exports:{}};!function(e){"use strict";var n=t(309),a=t(311);e.exports={components:{"ui-bar":t(206),"ui-button":t(207),"ui-display":t(208),"ui-input":t(209),"ui-linegraph":t(210),"ui-notice":t(211),"ui-section":t(213),"ui-subdisplay":t(214),"ui-tabs":t(215)},events:{enter:t(203).enter,space:t(203).space},transitions:{fade:t(204)},onconfig:function(){var e=this.get("config.interface"),n={airalarm:t(219),"airalarm/back":t(220),"airalarm/modes":t(221),"airalarm/scrubbers":t(222),"airalarm/status":t(223),"airalarm/thresholds":t(224),"airalarm/vents":t(225),airlock_electronics:t(226),apc:t(227),atmos_alert:t(228),atmos_control:t(229),atmos_filter:t(230),atmos_mixer:t(231),atmos_pump:t(232),brig_timer:t(233),bsa:t(234),canister:t(235),cargo:t(236),cellular_emporium:t(237),chem_dispenser:t(238),chem_heater:t(239),chem_master:t(240),clockwork_slab:t(241),codex_gigas:t(242),computer_fabricator:t(243),crayon:t(244),cryo:t(245),disposal_unit:t(246),dna_vault:t(247),eightball:t(248),emergency_shuttle_console:t(249),engraved_message:t(250),error:t(251),firealarm:t(252),gps:t(253),gulag_console:t(254),gulag_item_reclaimer:t(255),holodeck:t(256),implantchair:t(257),intellicard:t(258),keycard_auth:t(259),labor_claim_console:t(260),language_menu:t(261),launchpad_remote:t(262),mech_bay_power_console:t(263),mulebot:t(264),ntnet_relay:t(265),ntos_ai_restorer:t(266),ntos_card:t(267),ntos_configuration:t(268),ntos_file_manager:t(269),ntos_main:t(270),ntos_net_chat:t(271),ntos_net_dos:t(272),ntos_net_downloader:t(273),ntos_net_monitor:t(274),ntos_net_transfer:t(275),ntos_power_monitor:t(276),ntos_revelation:t(277),ntos_station_alert:t(278),ntos_supermatter_monitor:t(279),ntosheader:t(280),nuclear_bomb:t(281),ore_redemption_machine:t(282),pandemic:t(283),personal_crafting:t(284),portable_pump:t(285),portable_scrubber:t(286),power_monitor:t(287),radio:t(288),sat_control:t(289),shuttle_manipulator:t(290),"shuttle_manipulator/modification":t(291),"shuttle_manipulator/status":t(292),"shuttle_manipulator/templates":t(293),sleeper:t(294),slime_swap_body:t(295),smes:t(296),solar_control:t(297),space_heater:t(298),station_alert:t(299),suit_storage_unit:t(300),tank_dispenser:t(301),tanks:t(302),thermomachine:t(303),uplink:t(304),vr_sleeper:t(305),wires:t(306)};e in n?this.components["interface"]=n[e]:this.components["interface"]=n.error},oninit:function(){this.observe("config.style",function(t,e,n){t&&document.body.classList.add(t),e&&document.body.classList.remove(e)})},oncomplete:function(){if(this.get("config.locked")){var t=(0,a.lock)(window.screenLeft,window.screenTop),e=t.x,r=t.y;(0,n.winset)(this.get("config.window"),"pos",e+","+r)}(0,n.winset)("mapwindow.map","focus",!0)}}}(r),r.exports.template={v:3,t:[" "," "," "," ",{p:[56,1,1874],t:7,e:"titlebar",f:[{t:3,r:"config.title",p:[56,11,1884]}]}," ",{p:[57,1,1915],t:7,e:"main",f:[{p:[58,3,1925],t:7,e:"warnings"}," ",{p:[59,3,1940],t:7,e:"interface"}]}," ",{t:4,f:[{p:[62,3,1990],t:7,e:"resize"}],n:50,r:"config.titlebar",p:[61,1,1963]}]},r.exports.components=r.exports.components||{};var i={warnings:t(218),titlebar:t(217),resize:t(212)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{203:203,204:204,205:205,206:206,207:207,208:208,209:209,210:210,211:211,212:212,213:213,214:214,215:215,217:217,218:218,219:219,220:220,221:221,222:222,223:223,224:224,225:225,226:226,227:227,228:228,229:229,230:230,231:231,232:232,233:233,234:234,235:235,236:236,237:237,238:238,239:239,240:240,241:241,242:242,243:243,244:244,245:245,246:246,247:247,248:248,249:249,250:250,251:251,252:252,253:253,254:254,255:255,256:256,257:257,258:258,259:259,260:260,261:261,262:262,263:263,264:264,265:265,266:266,267:267,268:268,269:269,270:270,271:271,272:272,273:273,274:274,275:275,276:276,277:277,278:278,279:279,280:280,281:281,282:282,283:283,284:284,285:285,286:286,287:287,288:288,289:289,290:290,291:291,292:292,293:293,294:294,295:295,296:296,297:297,298:298,299:299,300:300,301:301,302:302,303:303,304:304,305:305,306:306,309:309,311:311}],309:[function(t,e,n){"use strict";function a(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return"byond://"+e+"?"+Object.keys(t).map(function(e){return o(e)+"="+o(t[e])}).join("&")}function r(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};window.location.href=a(Object.assign({src:t,action:e},n))}function i(t,e,n){var r;window.location.href=a((r={},r[t+"."+e]=n,r),"winset")}n.__esModule=!0,n.href=a,n.act=r,n.winset=i;var o=encodeURIComponent},{}],310:[function(t,e,n){"use strict";n.__esModule=!0;n.UI_INTERACTIVE=2,n.UI_UPDATE=1,n.UI_DISABLED=0,n.UI_CLOSE=-1},{}],311:[function(t,e,n){"use strict";function a(t,e){return 0>t?t=0:t+window.innerWidth>window.screen.availWidth&&(t=window.screen.availWidth-window.innerWidth),0>e?e=0:e+window.innerHeight>window.screen.availHeight&&(e=window.screen.availHeight-window.innerHeight),{x:t,y:e}}function r(t){if(t.preventDefault(),this.get("drag")){if(this.get("x")){var e=t.screenX-this.get("x")+window.screenLeft,n=t.screenY-this.get("y")+window.screenTop;if(this.get("config.locked")){var r=a(e,n);e=r.x,n=r.y}(0,s.winset)(this.get("config.window"),"pos",e+","+n)}this.set({x:t.screenX,y:t.screenY})}}function i(t,e){return t=Math.clamp(100,window.screen.width,t),e=Math.clamp(100,window.screen.height,e),{x:t,y:e}}function o(t){if(t.preventDefault(),this.get("resize")){if(this.get("x")){var e=t.screenX-this.get("x")+window.innerWidth,n=t.screenY-this.get("y")+window.innerHeight,a=i(e,n);e=a.x,n=a.y,(0,s.winset)(this.get("config.window"),"size",e+","+n)}this.set({x:t.screenX,y:t.screenY})}}n.__esModule=!0,n.lock=a,n.drag=r,n.sane=i,n.resize=o;var s=t(309)},{309:309}],312:[function(t,e,n){"use strict";function a(t,e){for(var n=t,a=Array.isArray(n),i=0,n=a?n:n[Symbol.iterator]();;){var o;if(a){if(i>=n.length)break;o=n[i++]}else{if(i=n.next(),i.done)break;o=i.value}var s=o;s.textContent.toLowerCase().includes(e)?(s.style.display="",r(s,e)):s.style.display="none"}}function r(t,e){for(var n=t.queryAll("section"),a=t.query("header").textContent.toLowerCase().includes(e),r=n,i=Array.isArray(r),o=0,r=i?r:r[Symbol.iterator]();;){var s;if(i){if(o>=r.length)break;s=r[o++]}else{if(o=r.next(),o.done)break;s=o.value}var u=s;a||u.textContent.toLowerCase().includes(e)?u.style.display="":u.style.display="none"}}n.__esModule=!0,n.filterMulti=a,n.filter=r},{}],313:[function(t,e,n){"use strict";function a(t,e,n){return Math.max(t,Math.min(n,e))}function r(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return+(Math.round(t+"e"+e)+"e-"+e)}n.__esModule=!0,n.clamp=a,n.fixed=r},{}],314:[function(t,e,n){"use strict";function a(t){return t[0].toUpperCase()+t.slice(1).toLowerCase()}function r(t){return t.replace(/\w\S*/g,a)}function i(t,e){for(t=""+t;t.length1){for(var u=Array(o),p=0;o>p;p++)u[p]=arguments[p+3];n.children=u}return{$$typeof:t,type:e,key:void 0===a?null:""+a,ref:null,props:n,_owner:null}}}(),e.asyncIterator=function(t){if("function"==typeof Symbol){if(Symbol.asyncIterator){var e=t[Symbol.asyncIterator];if(null!=e)return e.call(t)}if(Symbol.iterator)return t[Symbol.iterator]()}throw new TypeError("Object is not async iterable")},e.asyncGenerator=function(){function t(t){this.value=t}function e(e){function n(t,e){return new Promise(function(n,r){var s={key:t,arg:e,resolve:n,reject:r,next:null};o?o=o.next=s:(i=o=s,a(t,e))})}function a(n,i){try{var o=e[n](i),s=o.value;s instanceof t?Promise.resolve(s.value).then(function(t){a("next",t)},function(t){a("throw",t)}):r(o.done?"return":"normal",o.value)}catch(u){r("throw",u)}}function r(t,e){switch(t){case"return":i.resolve({value:e,done:!0});break;case"throw":i.reject(e);break;default:i.resolve({value:e,done:!1})}i=i.next,i?a(i.key,i.arg):o=null}var i,o;this._invoke=n,"function"!=typeof e["return"]&&(this["return"]=void 0)}return"function"==typeof Symbol&&Symbol.asyncIterator&&(e.prototype[Symbol.asyncIterator]=function(){return this}),e.prototype.next=function(t){return this._invoke("next",t)},e.prototype["throw"]=function(t){return this._invoke("throw",t)},e.prototype["return"]=function(t){return this._invoke("return",t)},{wrap:function(t){return function(){return new e(t.apply(this,arguments))}},await:function(e){return new t(e)}}}(),e.asyncGeneratorDelegate=function(t,e){function n(n,a){return r=!0,a=new Promise(function(e){e(t[n](a))}),{done:!1,value:e(a)}}var a={},r=!1;return"function"==typeof Symbol&&Symbol.iterator&&(a[Symbol.iterator]=function(){return this}),a.next=function(t){return r?(r=!1,t):n("next",t)},"function"==typeof t["throw"]&&(a["throw"]=function(t){if(r)throw r=!1,t;return n("throw",t)}),"function"==typeof t["return"]&&(a["return"]=function(t){return n("return",t)}),a},e.asyncToGenerator=function(t){return function(){var e=t.apply(this,arguments);return new Promise(function(t,n){function a(r,i){try{var o=e[r](i),s=o.value}catch(u){return void n(u)}return o.done?void t(s):Promise.resolve(s).then(function(t){a("next",t)},function(t){a("throw",t)})}return a("next")})}},e.classCallCheck=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},e.createClass=function(){function t(t,e){for(var n=0;n=0||Object.prototype.hasOwnProperty.call(t,a)&&(n[a]=t[a]);return n},e.possibleConstructorReturn=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},e.selfGlobal=void 0===t?self:t,e.set=function a(t,e,n,r){var i=Object.getOwnPropertyDescriptor(t,e);if(void 0===i){var o=Object.getPrototypeOf(t);null!==o&&a(o,e,n,r)}else if("value"in i&&i.writable)i.value=n;else{var s=i.set;void 0!==s&&s.call(r,n)}return n},e.slicedToArray=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),e.slicedToArrayLoose=function(t,e){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t)){for(var n,a=[],r=t[Symbol.iterator]();!(n=r.next()).done&&(a.push(n.value),!e||a.length!==e););return a}throw new TypeError("Invalid attempt to destructure non-iterable instance")},e.taggedTemplateLiteral=function(t,e){return Object.freeze(Object.defineProperties(t,{raw:{value:Object.freeze(e)}}))},e.taggedTemplateLiteralLoose=function(t,e){return t.raw=e,t},e.temporalRef=function(t,e,n){if(t===n)throw new ReferenceError(e+" is not defined - temporal dead zone");return t},e.temporalUndefined={},e.toArray=function(t){return Array.isArray(t)?t:Array.from(t)},e.toConsumableArray=function(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e - {{#partial button}} - - Empty and eject - - - Empty - - - Eject - - {{/partial}} - {{#if data.has_beaker}} - - {{#if data.beaker_empty}} - The beaker is empty! - {{else}} - - {{#if data.has_blood}} - {{data.blood.dna}} - {{data.blood.type}} - {{else}} - - No blood sample detected. - - {{/if}} - - {{/if}} - - {{else}} - - No beaker loaded. - - {{/if}} - -{{#if data.has_blood}} - - {{#each data.viruses}} - - {{#partial button}} - {{#if is_adv}} - - Name advanced disease - - {{/if}} - - Create virus culture bottle - - {{/partial}} - {{agent}} - {{description}} - {{spread}} - {{cure}} - {{#if is_adv}} - {{resistance}} - {{stealth}} - {{stage_speed}} - - {{#each symptoms}} - {{name}}
- {{/each}} -
+{{#if data.mode == 1}} + + {{#partial button}} + + Empty and eject + + + Empty + + + Eject + + {{/partial}} + {{#if data.has_beaker}} + + {{#if data.beaker_empty}} + The beaker is empty! + {{else}} + + {{#if data.has_blood}} + {{data.blood.dna}} + {{data.blood.type}} + {{else}} + + No blood sample detected. + + {{/if}} + {{/if}} - - {{else}} - - No detectable virus in the blood sample. - - {{/each}} -
- - {{#each data.resistances}} - - - Create vaccine bottle - {{else}} - No antibodies detected in the blood sample. + No beaker loaded. - {{/each}} + {{/if}} -{{/if}} \ No newline at end of file + {{#if data.has_blood}} + + {{#each data.viruses}} + + {{#partial button}} + {{#if is_adv}} + + Name advanced disease + + {{/if}} + + Create virus culture bottle + + {{/partial}} + {{agent}} + {{description}} + {{spread}} + {{cure}} + {{#if is_adv}} + + {{#each symptoms}} + + {{name}} +
+ {{/each}} +
+ {{resistance}} + {{stealth}} + {{stage_speed}} + {{transmission}} + {{/if}} +
+ {{else}} + + No detectable virus in the blood sample. + + {{/each}} +
+ + {{#each data.resistances}} + + + Create vaccine bottle + + + {{else}} + + No antibodies detected in the blood sample. + + {{/each}} + + {{/if}} +{{else}} + + Back + + {{#with data.symptom}} + + + {{desc}} + {{#if neutered}} +
+ This symptom has been neutered, and has no effect. It will still affect the virus' statistics. + {{/if}} +
+ + {{level}} + {{resistance}} + {{stealth}} + {{stage_speed}} + {{transmission}} + + + {{{threshold_desc}}} + + {{/with}} +{{/if}} From 196c9d05974e056d822d66418aa7a408646dd5e6 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 20 Aug 2017 06:01:24 -0500 Subject: [PATCH 018/262] Adds tracking amount of time spent playing departments 2: The fall of the Assistants. --- SQL/database_changelog.txt.rej | 15 +- SQL/tgstation_schema.sql | 16 ++ SQL/tgstation_schema.sql.rej | 9 + SQL/tgstation_schema_prefixed.sql | 16 ++ SQL/tgstation_schema_prefixed.sql.rej | 9 + code/__DEFINES/preferences.dm | 20 +- code/_compile_options.dm | 2 +- code/controllers/configuration.dm | 7 + code/controllers/configuration.dm.rej | 24 +++ code/controllers/subsystem/blackbox.dm | 2 +- code/controllers/subsystem/blackbox.dm.rej | 10 + code/controllers/subsystem/job.dm | 16 ++ .../controllers/subsystem/server_maint.dm.rej | 30 +++ code/datums/mind.dm | 3 +- code/game/gamemodes/antag_spawner.dm.rej | 9 + code/modules/admin/admin.dm | 4 +- code/modules/admin/admin_verbs.dm | 1 + code/modules/admin/admin_verbs.dm.rej | 10 + code/modules/admin/topic.dm | 18 ++ code/modules/admin/verbs/randomverbs.dm.rej | 25 +++ code/modules/client/preferences.dm | 5 + code/modules/client/preferences.dm.rej | 14 ++ code/modules/jobs/job_exp.dm | 194 ++++++++++++++++++ code/modules/jobs/job_exp.dm.rej | 108 ++++++++++ code/modules/jobs/job_types/captain.dm | 5 + code/modules/jobs/job_types/engineering.dm | 7 + code/modules/jobs/job_types/job.dm | 5 + code/modules/jobs/job_types/medical.dm | 9 + code/modules/jobs/job_types/science.dm | 7 + code/modules/jobs/job_types/security.dm | 9 + code/modules/jobs/job_types/silicon.dm | 4 + code/modules/jobs/jobs.dm | 20 ++ code/modules/mob/dead/new_player/login.dm | 3 + code/modules/mob/dead/new_player/login.dm.rej | 9 + .../modules/mob/dead/new_player/new_player.dm | 2 + config/config.txt.rej | 25 +++ tgstation.dme | 1 + 37 files changed, 658 insertions(+), 15 deletions(-) create mode 100644 SQL/tgstation_schema.sql.rej create mode 100644 SQL/tgstation_schema_prefixed.sql.rej create mode 100644 code/controllers/configuration.dm.rej create mode 100644 code/controllers/subsystem/blackbox.dm.rej create mode 100644 code/controllers/subsystem/server_maint.dm.rej create mode 100644 code/game/gamemodes/antag_spawner.dm.rej create mode 100644 code/modules/admin/admin_verbs.dm.rej create mode 100644 code/modules/admin/verbs/randomverbs.dm.rej create mode 100644 code/modules/client/preferences.dm.rej create mode 100644 code/modules/jobs/job_exp.dm create mode 100644 code/modules/jobs/job_exp.dm.rej create mode 100644 code/modules/mob/dead/new_player/login.dm.rej create mode 100644 config/config.txt.rej diff --git a/SQL/database_changelog.txt.rej b/SQL/database_changelog.txt.rej index 1b201ec4aa..f65c192173 100644 --- a/SQL/database_changelog.txt.rej +++ b/SQL/database_changelog.txt.rej @@ -1,15 +1,10 @@ diff a/SQL/database_changelog.txt b/SQL/database_changelog.txt (rejected hunks) -@@ -1,10 +1,10 @@ - Any time you make a change to the schema files, remember to increment the database schema version. Generally increment the minor number, major should be reserved for significant changes to the schema. Both values go up to 255. +@@ -5,7 +5,7 @@ Also, added flags column to the player table. --The latest database version is 3.1; The query to update the schema revision table is: -+The latest database version is 3.0; The query to update the schema revision table is: + CREATE TABLE `role_time` ( `ckey` VARCHAR(32) NOT NULL , `job` VARCHAR(128) NOT NULL , `minutes` INT UNSIGNED NOT NULL, PRIMARY KEY (`ckey`, `job`) ) ENGINE = InnoDB; --UPDATE `schema_revision` SET major = 3, minor = 1 LIMIT 1; -+INSERT INTO `schema_revision` (`major`, `minor`) VALUES (3, 0); - or --UPDATE `SS13_schema_revision` SET major = 3, minor = 1 LIMIT 1; -+INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (3, 0); +-ALTER TABLE `player` ADD `flags` INT NOT NULL AFTER `accountjoindate`; ++ALTER TABLE `player` ADD `flags` INT NOT NULL default '0' AFTER `accountjoindate`; - ---------------------------------------------------- + UPDATE `schema_revision` SET minor = 1; diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql index 4c76e1f275..4c19d0bd20 100644 --- a/SQL/tgstation_schema.sql +++ b/SQL/tgstation_schema.sql @@ -257,6 +257,21 @@ CREATE TABLE `messages` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `role_time` +-- + +DROP TABLE IF EXISTS `role_time`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; + +CREATE TABLE `role_time` +( `ckey` VARCHAR(32) NOT NULL , + `job` VARCHAR(32) NOT NULL , + `minutes` INT UNSIGNED NOT NULL, + PRIMARY KEY (`ckey`, `job`) + ) ENGINE = InnoDB; + -- -- Table structure for table `player` -- @@ -272,6 +287,7 @@ CREATE TABLE `player` ( `computerid` varchar(32) NOT NULL, `lastadminrank` varchar(32) NOT NULL DEFAULT 'Player', `accountjoindate` DATE DEFAULT NULL, + `flags` smallint(5) unsigned DEFAULT '0' NOT NULL, PRIMARY KEY (`ckey`), KEY `idx_player_cid_ckey` (`computerid`,`ckey`), KEY `idx_player_ip_ckey` (`ip`,`ckey`) diff --git a/SQL/tgstation_schema.sql.rej b/SQL/tgstation_schema.sql.rej new file mode 100644 index 0000000000..51068bed4e --- /dev/null +++ b/SQL/tgstation_schema.sql.rej @@ -0,0 +1,9 @@ +diff a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql (rejected hunks) +@@ -268,7 +283,6 @@ CREATE TABLE `player` ( + `ip` int(10) unsigned NOT NULL, + `computerid` varchar(32) NOT NULL, + `lastadminrank` varchar(32) NOT NULL DEFAULT 'Player', +- `exp` mediumtext, + PRIMARY KEY (`id`), + UNIQUE KEY `ckey` (`ckey`), + KEY `idx_player_cid_ckey` (`computerid`,`ckey`), diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql index f717bf96ad..094485df59 100644 --- a/SQL/tgstation_schema_prefixed.sql +++ b/SQL/tgstation_schema_prefixed.sql @@ -253,6 +253,21 @@ CREATE TABLE `SS13_messages` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `SS13_role_time` +-- + +DROP TABLE IF EXISTS `SS13_role_time`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; + +CREATE TABLE `SS13_role_time` +( `ckey` VARCHAR(32) NOT NULL , + `job` VARCHAR(32) NOT NULL , + `minutes` INT UNSIGNED NOT NULL, + PRIMARY KEY (`ckey`, `job`) + ) ENGINE = InnoDB; + -- -- Table structure for table `SS13_player` -- @@ -268,6 +283,7 @@ CREATE TABLE `SS13_player` ( `computerid` varchar(32) NOT NULL, `lastadminrank` varchar(32) NOT NULL DEFAULT 'Player', `accountjoindate` DATE DEFAULT NULL, + `flags` smallint(5) unsigned DEFAULT '0' NOT NULL, PRIMARY KEY (`ckey`), KEY `idx_player_cid_ckey` (`computerid`,`ckey`), KEY `idx_player_ip_ckey` (`ip`,`ckey`) diff --git a/SQL/tgstation_schema_prefixed.sql.rej b/SQL/tgstation_schema_prefixed.sql.rej new file mode 100644 index 0000000000..dd4bc6a7f5 --- /dev/null +++ b/SQL/tgstation_schema_prefixed.sql.rej @@ -0,0 +1,9 @@ +diff a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql (rejected hunks) +@@ -268,7 +297,6 @@ CREATE TABLE `SS13_player` ( + `ip` int(10) unsigned NOT NULL, + `computerid` varchar(32) NOT NULL, + `lastadminrank` varchar(32) NOT NULL DEFAULT 'Player', +- `exp` mediumtext, + PRIMARY KEY (`id`), + UNIQUE KEY `ckey` (`ckey`), + KEY `idx_player_cid_ckey` (`computerid`,`ckey`), diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index f26b750492..b6133df287 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -47,4 +47,22 @@ #define SEC_DEPT_ENGINEERING "Engineering" #define SEC_DEPT_MEDICAL "Medical" #define SEC_DEPT_SCIENCE "Science" -#define SEC_DEPT_SUPPLY "Supply" \ No newline at end of file +#define SEC_DEPT_SUPPLY "Supply" + +// Playtime tracking system, see jobs_exp.dm +#define EXP_TYPE_LIVING "Living" +#define EXP_TYPE_CREW "Crew" +#define EXP_TYPE_COMMAND "Command" +#define EXP_TYPE_ENGINEERING "Engineering" +#define EXP_TYPE_MEDICAL "Medical" +#define EXP_TYPE_SCIENCE "Science" +#define EXP_TYPE_SUPPLY "Supply" +#define EXP_TYPE_SECURITY "Security" +#define EXP_TYPE_SILICON "Silicon" +#define EXP_TYPE_SERVICE "Service" +#define EXP_TYPE_ANTAG "Antag" +#define EXP_TYPE_SPECIAL "Special" +#define EXP_TYPE_GHOST "Ghost" + +//Flags in the players table in the db +#define DB_FLAG_EXEMPT 1 \ No newline at end of file diff --git a/code/_compile_options.dm b/code/_compile_options.dm index a669f1b4f5..fe66b9bf69 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -72,4 +72,4 @@ //Update this whenever the db schema changes //make sure you add an update to the schema_version stable in the db changelog #define DB_MAJOR_VERSION 3 -#define DB_MINOR_VERSION 0 +#define DB_MINOR_VERSION 1 diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index abf2c1f937..daf0537547 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -103,6 +103,13 @@ 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/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 + //Population cap vars var/soft_popcap = 0 var/hard_popcap = 0 diff --git a/code/controllers/configuration.dm.rej b/code/controllers/configuration.dm.rej new file mode 100644 index 0000000000..5d5c2c5055 --- /dev/null +++ b/code/controllers/configuration.dm.rej @@ -0,0 +1,24 @@ +diff a/code/controllers/configuration.dm b/code/controllers/configuration.dm (rejected hunks) +@@ -337,17 +337,17 @@ + if("use_account_age_for_jobs") + use_account_age_for_jobs = 1 + if("use_exp_tracking") +- use_exp_tracking = 1 ++ use_exp_tracking = TRUE + if("use_exp_restrictions_heads") +- use_exp_restrictions_heads = 1 ++ 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 = 1 ++ use_exp_restrictions_heads_department = TRUE + if("use_exp_restrictions_other") +- use_exp_restrictions_other = 1 ++ use_exp_restrictions_other = TRUE + if("use_exp_restrictions_admin_bypass") +- use_exp_restrictions_admin_bypass = 1 ++ use_exp_restrictions_admin_bypass = TRUE + if("lobby_countdown") + lobby_countdown = text2num(value) + if("round_end_countdown") diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm index 3344afcaaa..5f53f870dc 100644 --- a/code/controllers/subsystem/blackbox.dm +++ b/code/controllers/subsystem/blackbox.dm @@ -1,7 +1,7 @@ SUBSYSTEM_DEF(blackbox) name = "Blackbox" wait = 6000 - flags = SS_NO_TICK_CHECK | SS_NO_INIT + flags = SS_NO_TICK_CHECK runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME init_order = INIT_ORDER_BLACKBOX diff --git a/code/controllers/subsystem/blackbox.dm.rej b/code/controllers/subsystem/blackbox.dm.rej new file mode 100644 index 0000000000..5bd713172b --- /dev/null +++ b/code/controllers/subsystem/blackbox.dm.rej @@ -0,0 +1,10 @@ +diff a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm (rejected hunks) +@@ -40,7 +40,7 @@ SUBSYSTEM_DEF(blackbox) + + if(config.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 +- SSblackbox.update_exp(10,FALSE) ++ update_exp(10,FALSE) + + + /datum/controller/subsystem/blackbox/Recover() diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index f28373ef22..1be36e5ac7 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -73,6 +73,8 @@ SUBSYSTEM_DEF(job) return 0 if(!job.player_old_enough(player.client)) return 0 + if(job.required_playtime_remaining(player.client)) + return 0 var/position_limit = job.total_positions if(!latejoin) position_limit = job.spawn_positions @@ -95,6 +97,9 @@ SUBSYSTEM_DEF(job) if(!job.player_old_enough(player.client)) Debug("FOC player not old enough, Player: [player]") continue + if(job.required_playtime_remaining(player.client)) + Debug("FOC player not enough xp, Player: [player]") + continue if(flag && (!(flag in player.client.prefs.be_special))) Debug("FOC flag failed, Player: [player], Flag: [flag], ") continue @@ -130,6 +135,10 @@ SUBSYSTEM_DEF(job) Debug("GRJ player not old enough, Player: [player]") continue + if(job.required_playtime_remaining(player.client)) + Debug("GRJ player not enough xp, Player: [player]") + continue + if(player.mind && job.title in player.mind.restricted_roles) Debug("GRJ incompatible with antagonist role, Player: [player], Job: [job.title]") continue @@ -300,6 +309,10 @@ SUBSYSTEM_DEF(job) Debug("DO player not old enough, Player: [player], Job:[job.title]") continue + if(job.required_playtime_remaining(player.client)) + Debug("DO player not enough xp, Player: [player], Job:[job.title]") + continue + if(player.mind && job.title in player.mind.restricted_roles) Debug("DO incompatible with antagonist role, Player: [player], Job:[job.title]") continue @@ -463,6 +476,9 @@ SUBSYSTEM_DEF(job) if(!job.player_old_enough(player.client)) level6++ continue + if(job.required_playtime_remaining(player.client)) + level6++ + continue if(player.client.prefs.GetJobDepartment(job, 1) & job.flag) level1++ else if(player.client.prefs.GetJobDepartment(job, 2) & job.flag) diff --git a/code/controllers/subsystem/server_maint.dm.rej b/code/controllers/subsystem/server_maint.dm.rej new file mode 100644 index 0000000000..486375b505 --- /dev/null +++ b/code/controllers/subsystem/server_maint.dm.rej @@ -0,0 +1,30 @@ +diff a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm (rejected hunks) +@@ -6,18 +6,16 @@ SUBSYSTEM_DEF(server_maint) + flags = SS_POST_FIRE_TIMING|SS_FIRE_IN_LOBBY + priority = 10 + var/list/currentrun +- var/triggertime = null + + /datum/controller/subsystem/server_maint/Initialize(timeofday) + if (config.hub) + world.visibility = 1 +- triggertime = REALTIMEOFDAY + ..() + + /datum/controller/subsystem/server_maint/fire(resumed = FALSE) + if(!resumed) + src.currentrun = GLOB.clients.Copy() +- ++ + var/list/currentrun = src.currentrun + var/round_started = SSticker.HasRoundStarted() + +@@ -39,8 +37,3 @@ SUBSYSTEM_DEF(server_maint) + return + + #undef PING_BUFFER_TIME +- if(config.sql_enabled) +- sql_poll_population() +- if(config.use_exp_tracking) +- if(REALTIMEOFDAY > (triggertime +3000)) //server maint fires once at roundstart then once every 10 minutes. a 5 min check skips the first fire +- update_exp(10,0) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index a31aab8607..7cc4558882 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1468,6 +1468,7 @@ if(!(src in SSticker.mode.syndicates)) SSticker.mode.syndicates += src SSticker.mode.update_synd_icons_added(src) + assigned_role = "Syndicate" special_role = "Syndicate" SSticker.mode.forge_syndicate_objectives(src) SSticker.mode.greet_syndicate(src) @@ -1715,7 +1716,7 @@ /mob/living/carbon/human/mind_initialize() ..() if(!mind.assigned_role) - mind.assigned_role = "Assistant" //defualt + mind.assigned_role = "Unassigned" //default //XENO /mob/living/carbon/alien/mind_initialize() diff --git a/code/game/gamemodes/antag_spawner.dm.rej b/code/game/gamemodes/antag_spawner.dm.rej new file mode 100644 index 0000000000..ea9a00132a --- /dev/null +++ b/code/game/gamemodes/antag_spawner.dm.rej @@ -0,0 +1,9 @@ +diff a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm (rejected hunks) +@@ -108,6 +108,7 @@ + new_objective.explanation_text = "Protect [usr.real_name], the wizard." + M.mind.objectives += new_objective + SSticker.mode.apprentices += M.mind ++ M.mind.assigned_role = "Apprentice" + M.mind.special_role = "apprentice" + SSticker.mode.update_wiz_icons_added(M.mind) + M << sound('sound/effects/magic.ogg') diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 5943e753a0..e6a1b3d383 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -31,6 +31,8 @@ if(M.client) body += " played by [M.client] " body += "\[[M.client.holder ? M.client.holder.rank : "Player"]\]" + if(config.use_exp_tracking) + body += "\[" + M.client.get_exp_living() + "\]" if(isnewplayer(M)) body += " Hasn't Entered Game " @@ -442,7 +444,7 @@ if("Hard Restart (No Delay, No Feeback Reason)") world.Reboot() if("Hardest Restart (No actions, just reboot)") - world.Reboot(fast_track = TRUE) + world.Reboot(fast_track = TRUE) if("Service Restart (Force restart DD)") GLOB.reboot_mode = REBOOT_MODE_HARD world.ServiceReboot() diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 3276a319db..6403c9028f 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -61,6 +61,7 @@ GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin()) /client/proc/cmd_admin_local_narrate, /*sends text to all mobs within view of atom*/ /client/proc/cmd_admin_create_centcom_report, /client/proc/cmd_change_command_name, + /client/proc/cmd_admin_check_player_exp, /* shows players by playtime */ /client/proc/toggle_antag_hud, /*toggle display of the admin antag hud*/ /client/proc/toggle_AI_interact, /*toggle admin ability to interact with machines as an AI*/ /client/proc/customiseSNPC, /* Customise any interactive crewmembers in the world */ diff --git a/code/modules/admin/admin_verbs.dm.rej b/code/modules/admin/admin_verbs.dm.rej new file mode 100644 index 0000000000..c2f884d37c --- /dev/null +++ b/code/modules/admin/admin_verbs.dm.rej @@ -0,0 +1,10 @@ +diff a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm (rejected hunks) +@@ -663,7 +664,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, AVerbsHideable()) + + if(!holder) + return +- ++ + if(has_antag_hud()) + toggle_antag_hud() + diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index ac047429c8..85ae68dabc 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -22,6 +22,24 @@ else if(href_list["stickyban"]) stickyban(href_list["stickyban"],href_list) + else if(href_list["getplaytimewindow"]) + if(!check_rights(R_ADMIN)) + return + var/mob/M = locate(href_list["getplaytimewindow"]) in GLOB.mob_list + if(!M) + to_chat(usr, "ERROR: Mob not found.") + return + cmd_show_exp_panel(M.client) + + else if(href_list["toggleexempt"]) + if(!check_rights(R_ADMIN)) + return + var/client/C = locate(href_list["toggleexempt"]) in GLOB.clients + if(!C) + to_chat(usr, "ERROR: Client not found.") + return + toggle_exempt_status(C) + else if(href_list["makeAntag"]) if (!SSticker.mode) to_chat(usr, "Not until the round starts!") diff --git a/code/modules/admin/verbs/randomverbs.dm.rej b/code/modules/admin/verbs/randomverbs.dm.rej new file mode 100644 index 0000000000..9941251566 --- /dev/null +++ b/code/modules/admin/verbs/randomverbs.dm.rej @@ -0,0 +1,25 @@ +diff a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm (rejected hunks) +@@ -1246,7 +1246,8 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits + to_chat(usr, "ERROR: Client not found.") + return + +- C.set_db_player_flags() ++ 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) +@@ -1254,6 +1255,8 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits + else + newstate = TRUE + +- message_admins("[key_name_admin(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name_admin(C)]") +- log_admin("[key_name(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name(C)]") +- C.update_flag_db(DB_FLAG_EXEMPT, newstate) +\ No newline at end of file ++ 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)]") ++ 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 4c23db3f86..f7b2cb341b 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -36,6 +36,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/tgui_lock = TRUE var/windowflashing = TRUE var/toggles = TOGGLES_DEFAULT + var/db_flags var/chat_toggles = TOGGLES_DEFAULT_CHAT var/ghost_form = "ghost" var/ghost_orbit = GHOST_ORBIT_CIRCLE @@ -580,6 +581,10 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(jobban_isbanned(user, rank)) HTML += "[rank] BANNED" continue + var/required_playtime_remaining = job.required_playtime_remaining(user.client) + if(required_playtime_remaining) + HTML += "[rank] \[ [get_exp_format(required_playtime_remaining)] as [job.get_exp_req_type()] \] " + continue if(!job.player_old_enough(user.client)) var/available_in_days = job.available_in_days(user.client) HTML += "[rank] \[IN [(available_in_days)] DAYS\]" diff --git a/code/modules/client/preferences.dm.rej b/code/modules/client/preferences.dm.rej new file mode 100644 index 0000000000..02e6ad2d76 --- /dev/null +++ b/code/modules/client/preferences.dm.rej @@ -0,0 +1,14 @@ +diff a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm (rejected hunks) +@@ -130,12 +130,6 @@ GLOBAL_LIST_EMPTY(preferences_datums) + menuoptions = list() + return + +-/datum/preferences/vv_edit_var(var_name, var_value) +- var/static/list/banned_edits = list("exp") +- if(var_name in banned_edits) +- return FALSE +- return ..() +- + /datum/preferences/proc/ShowChoices(mob/user) + if(!user || !user.client) + return diff --git a/code/modules/jobs/job_exp.dm b/code/modules/jobs/job_exp.dm new file mode 100644 index 0000000000..e65de15279 --- /dev/null +++ b/code/modules/jobs/job_exp.dm @@ -0,0 +1,194 @@ +GLOBAL_LIST_EMPTY(exp_to_update) +GLOBAL_PROTECT(exp_to_update) + + +// Procs +/datum/job/proc/required_playtime_remaining(client/C) + if(!C) + return 0 + if(!config.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)) + return 0 + var/isexempt = C.prefs.db_flags & DB_FLAG_EXEMPT + if(isexempt) + return 0 + var/my_exp = C.calc_exp_type(get_exp_req_type()) + var/job_requirement = get_exp_req_amount() + if(my_exp >= job_requirement) + return 0 + else + return (job_requirement - my_exp) + +/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 + 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) + return exp_type_department + return exp_type + +/proc/job_is_xp_locked(jobtitle) + if(!config.use_exp_restrictions_heads && jobtitle in GLOB.command_positions) + return FALSE + if(!config.use_exp_restrictions_other && !(jobtitle in GLOB.command_positions)) + return FALSE + return TRUE + +/client/proc/calc_exp_type(exptype) + var/list/explist = prefs.exp.Copy() + var/amount = 0 + var/list/typelist = GLOB.exp_jobsmap[exptype] + if(!typelist) + return -1 + for(var/job in typelist["titles"]) + if(job in explist) + amount += explist[job] + return amount + +/client/proc/get_exp_report() + if(!config.use_exp_tracking) + return "Tracking is disabled in the server configuration file." + var/list/play_records = prefs.exp + if(!play_records.len) + set_exp_from_db() + play_records = prefs.exp + if(!play_records.len) + return "[key] has no records." + var/return_text = list() + return_text += "
    " + var/list/exp_data = list() + for(var/category in SSjob.name_occupations) + if(play_records[category]) + exp_data[category] = text2num(play_records[category]) + else + exp_data[category] = 0 + for(var/category in GLOB.exp_specialmap) + if(play_records[category]) + exp_data[category] = text2num(play_records[category]) + else + exp_data[category] = 0 + if(prefs.db_flags & DB_FLAG_EXEMPT) + return_text += "
  • Exempt (all jobs auto-unlocked)
  • " + + for(var/dep in exp_data) + if(exp_data[dep] > 0) + if(exp_data[EXP_TYPE_LIVING] > 0) + var/percentage = num2text(round(exp_data[dep]/exp_data[EXP_TYPE_LIVING]*100)) + 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)) + return_text += "
  • Admin (all jobs auto-unlocked)
  • " + return_text += "
" + var/list/jobs_locked = list() + var/list/jobs_unlocked = list() + for(var/datum/job/job in SSjob.occupations) + if(job.exp_requirements && job.exp_type) + if(!job_is_xp_locked(job.title)) + continue + else if(!job.required_playtime_remaining(mob.client)) + jobs_unlocked += job.title + else + var/xp_req = job.get_exp_req_amount() + jobs_locked += "[job.title] [get_exp_format(text2num(calc_exp_type(job.get_exp_req_type())))] / [get_exp_format(xp_req)] as [job.get_exp_req_type()])" + if(jobs_unlocked.len) + return_text += "

Jobs Unlocked:
  • " + return_text += jobs_unlocked.Join("
  • ") + return_text += "
" + if(jobs_locked.len) + return_text += "

Jobs Not Unlocked:
  • " + return_text += jobs_locked.Join("
  • ") + return_text += "
" + return return_text + + +/client/proc/get_exp_living() + if(!prefs.exp) + return "No data" + var/exp_living = text2num(prefs.exp[EXP_TYPE_LIVING]) + return get_exp_format(exp_living) + +/proc/get_exp_format(expnum) + if(expnum > 60) + return num2text(round(expnum / 60)) + "h" + else if(expnum > 0) + return num2text(expnum) + "m" + else + return "0h" + +/datum/controller/subsystem/blackbox/proc/update_exp(mins, ann = FALSE) + if(!SSdbcore.Connect()) + return -1 + for(var/client/L in GLOB.clients) + if(L.is_afk()) + continue + addtimer(CALLBACK(L,/client/proc/update_exp_list,mins,ann),10) + CHECK_TICK + +/proc/update_exp_db() + SSdbcore.MassInsert(format_table_name("role_time"),GLOB.exp_to_update,TRUE) + LAZYCLEARLIST(GLOB.exp_to_update) + +//Manual incrementing/updating +/* +/client/proc/update_exp_client(minutes, announce_changes = FALSE) + if(!src ||!ckey || !config.use_exp_tracking) + return + if(!SSdbcore.Connect()) + return -1 + var/datum/DBQuery/exp_read = SSdbcore.NewQuery("SELECT job, minutes FROM [format_table_name("role_time")] WHERE ckey = '[sanitizeSQL(ckey)]'") + if(!exp_read.Execute()) + var/err = exp_read.ErrorMsg() + log_sql("SQL ERROR during exp_update_client read. Error : \[[err]\]\n") + message_admins("SQL ERROR during exp_update_client read. Error : \[[err]\]\n") + return -1 + var/list/play_records = list() + while(exp_read.NextRow()) + play_records[exp_read.item[1]] = text2num(exp_read.item[2]) + + for(var/rtype in SSjob.name_occupations) + if(!play_records[rtype]) + play_records[rtype] = 0 + for(var/rtype in GLOB.exp_specialmap) + if(!play_records[rtype]) + play_records[rtype] = 0 + var/list/old_records = play_records.Copy() + if(mob.stat != DEAD && mob.mind.assigned_role) + play_records[EXP_TYPE_LIVING] += minutes + if(announce_changes) + to_chat(mob,"You got: [minutes] Living EXP!") + for(var/job in SSjob.name_occupations) + if(mob.mind.assigned_role == job) + play_records[job] += minutes + if(announce_changes) + to_chat(mob,"You got: [minutes] [job] EXP!") + if(mob.mind.special_role && !mob.mind.var_edited) + play_records[EXP_TYPE_SPECIAL] += minutes + if(announce_changes) + to_chat(mob,"You got: [minutes] [mob.mind.special_role] EXP!") + else if(isobserver(mob)) + play_records[EXP_TYPE_GHOST] += minutes + if(announce_changes) + to_chat(mob,"You got: [minutes] Ghost EXP!") + else if(minutes) //Let "refresh" checks go through + return + prefs.exp = play_records + + for(var/jtype in play_records) + var jobname = jtype + var time = play_records[jtype] + var/datum/DBQuery/update_query = SSdbcore.NewQuery("INSERT INTO [format_table_name("role_time")] (`ckey`, `job`, `minutes`) VALUES ('[sanitizeSQL(ckey)]', '[jobname]', '[time]') ON DUPLICATE KEY UPDATE time = '[time]'") + if(!update_query.Execute()) + var/err = update_queryd.ErrorMsg() + log_game("SQL ERROR during exp_update_client update. Error : \[[err]\]\n") + message_admins("SQL ERROR during exp_update_client update. Error : \[[err]\]\n") + return \ No newline at end of file diff --git a/code/modules/jobs/job_exp.dm.rej b/code/modules/jobs/job_exp.dm.rej new file mode 100644 index 0000000000..128a479acd --- /dev/null +++ b/code/modules/jobs/job_exp.dm.rej @@ -0,0 +1,108 @@ +diff a/code/modules/jobs/job_exp.dm b/code/modules/jobs/job_exp.dm (rejected hunks) +@@ -140,15 +140,12 @@ 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) +- return ++ return -1 + if(!SSdbcore.Connect()) + return -1 + var/datum/DBQuery/exp_read = SSdbcore.NewQuery("SELECT job, minutes FROM [format_table_name("role_time")] WHERE ckey = '[sanitizeSQL(ckey)]'") + if(!exp_read.Execute()) +- var/err = exp_read.ErrorMsg() +- log_sql("SQL ERROR during exp_update_client read. Error : \[[err]\]\n") +- message_admins("SQL ERROR during exp_update_client read. Error : \[[err]\]\n") +- return ++ return -1 + var/list/play_records = list() + while(exp_read.NextRow()) + play_records[exp_read.item[1]] = text2num(exp_read.item[2]) +@@ -172,42 +169,24 @@ GLOBAL_PROTECT(exp_to_update) + if(!set_db_player_flags()) + return -1 + +- var/datum/DBQuery/flag_read = SSdbcore.NewQuery("SELECT flags FROM [format_table_name("player")] WHERE ckey='[sanitizeSQL(ckey)]'") +- +- if(!flag_read.Execute()) +- var/err = flag_read.ErrorMsg() +- log_sql("SQL ERROR during player flags read. Error : \[[err]\]\n") +- message_admins("SQL ERROR during player flags read. Error : \[[err]\]\n") +- return +- +- var/playerflags = null +- if(flag_read.NextRow()) +- playerflags = text2num(flag_read.item[1]) +- +- if((playerflags & newflag) && !state) ++ if((prefs.db_flags & newflag) && !state) + prefs.db_flags &= ~newflag + else + prefs.db_flags |= newflag + + var/datum/DBQuery/flag_update = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET flags = '[prefs.db_flags]' WHERE ckey='[sanitizeSQL(ckey)]'") + +- + if(!flag_update.Execute()) +- var/err = flag_update.ErrorMsg() +- log_sql("SQL ERROR during exp_exempt update. Error : \[[err]\]\n") +- message_admins("SQL ERROR during exp_exempt update. Error : \[[err]\]\n") +- return ++ return -1 ++ + + /client/proc/update_exp_list(minutes, announce_changes = FALSE) + if(!config.use_exp_tracking) +- return ++ return -1 + if(!SSdbcore.Connect()) + return -1 + var/datum/DBQuery/exp_read = SSdbcore.NewQuery("SELECT job, minutes FROM [format_table_name("role_time")] WHERE ckey = '[sanitizeSQL(ckey)]'") + if(!exp_read.Execute()) +- var/err = exp_read.ErrorMsg() +- log_sql("SQL ERROR during exp_update_client read. Error : \[[err]\]\n") +- message_admins("SQL ERROR during exp_update_client read. Error : \[[err]\]\n") + return -1 + var/list/play_records = list() + while(exp_read.NextRow()) +@@ -241,9 +220,13 @@ GLOBAL_PROTECT(exp_to_update) + if(announce_changes) + to_chat(mob,"You got: [minutes] [role] EXP!") + if(mob.mind.special_role && !mob.mind.var_edited) +- play_records[mob.mind.special_role] += minutes ++ var/trackedrole = mob.mind.special_role ++ var/gangrole = lookforgangrole(mob.mind.special_role) ++ if(gangrole) ++ trackedrole = gangrole ++ play_records[trackedrole] += minutes + if(announce_changes) +- to_chat(src,"You got: [minutes] [mob.mind.special_role] EXP!") ++ to_chat(src,"You got: [minutes] [trackedrole] EXP!") + if(!rolefound) + play_records["Unknown"] += minutes + else +@@ -276,11 +259,21 @@ GLOBAL_PROTECT(exp_to_update) + var/datum/DBQuery/flags_read = SSdbcore.NewQuery("SELECT flags FROM [format_table_name("player")] WHERE ckey='[ckey]'") + + if(!flags_read.Execute()) +- var/err = flags_read.ErrorMsg() +- log_sql("SQL ERROR during player flags read. Error : \[[err]\]\n") +- message_admins("SQL ERROR during player flags read. Error : \[[err]\]\n") + return FALSE + + if(flags_read.NextRow()) + prefs.db_flags = text2num(flags_read.item[1]) ++ else if(isnull(prefs.db_flags)) ++ prefs.db_flags = 0 //This PROBABLY won't happen, but better safe than sorry. + return TRUE ++ ++//Since each gang is tracked as a different antag type, records need to be generalized or you get up to 57 different possible records ++/proc/lookforgangrole(rolecheck) ++ if(findtext(rolecheck,"Gangster")) ++ return "Gangster" ++ else if(findtext(rolecheck,"Gang Boss")) ++ return "Gang Boss" ++ else if(findtext(rolecheck,"Gang Lieutenant")) ++ return "Gang Lieutenant" ++ else ++ return FALSE +\ No newline at end of file diff --git a/code/modules/jobs/job_types/captain.dm b/code/modules/jobs/job_types/captain.dm index b9d01b7c02..47efea04ac 100755 --- a/code/modules/jobs/job_types/captain.dm +++ b/code/modules/jobs/job_types/captain.dm @@ -13,6 +13,8 @@ Captain selection_color = "#ccccff" req_admin_notify = 1 minimal_player_age = 14 + exp_requirements = 180 + exp_type = EXP_TYPE_CREW outfit = /datum/outfit/job/captain @@ -64,6 +66,9 @@ Head of Personnel selection_color = "#ddddff" req_admin_notify = 1 minimal_player_age = 10 + exp_requirements = 180 + exp_type = EXP_TYPE_CREW + exp_type_department = EXP_TYPE_SUPPLY outfit = /datum/outfit/job/hop diff --git a/code/modules/jobs/job_types/engineering.dm b/code/modules/jobs/job_types/engineering.dm index 40800998c0..4070a00e97 100644 --- a/code/modules/jobs/job_types/engineering.dm +++ b/code/modules/jobs/job_types/engineering.dm @@ -14,6 +14,9 @@ Chief Engineer selection_color = "#ffeeaa" req_admin_notify = 1 minimal_player_age = 7 + exp_requirements = 180 + exp_type = EXP_TYPE_CREW + exp_type_department = EXP_TYPE_ENGINEERING outfit = /datum/outfit/job/ce @@ -72,6 +75,8 @@ Station Engineer spawn_positions = 5 supervisors = "the chief engineer" selection_color = "#fff5cc" + exp_requirements = 60 + exp_type = EXP_TYPE_CREW outfit = /datum/outfit/job/engineer @@ -127,6 +132,8 @@ Atmospheric Technician spawn_positions = 2 supervisors = "the chief engineer" selection_color = "#fff5cc" + exp_requirements = 60 + exp_type = EXP_TYPE_CREW outfit = /datum/outfit/job/atmos diff --git a/code/modules/jobs/job_types/job.dm b/code/modules/jobs/job_types/job.dm index 0a1622626c..4e57096994 100644 --- a/code/modules/jobs/job_types/job.dm +++ b/code/modules/jobs/job_types/job.dm @@ -43,6 +43,11 @@ var/outfit = null + var/exp_requirements = 0 + + var/exp_type = "" + var/exp_type_department = "" + //Only override this proc //H is usually a human unless an /equip override transformed it /datum/job/proc/after_spawn(mob/living/H, mob/M) diff --git a/code/modules/jobs/job_types/medical.dm b/code/modules/jobs/job_types/medical.dm index 196f74764f..6b72d851a5 100644 --- a/code/modules/jobs/job_types/medical.dm +++ b/code/modules/jobs/job_types/medical.dm @@ -14,6 +14,9 @@ Chief Medical Officer selection_color = "#ffddf0" req_admin_notify = 1 minimal_player_age = 7 + exp_requirements = 180 + exp_type = EXP_TYPE_CREW + exp_type_department = EXP_TYPE_MEDICAL outfit = /datum/outfit/job/cmo @@ -90,6 +93,8 @@ Chemist spawn_positions = 2 supervisors = "the chief medical officer" selection_color = "#ffeef0" + exp_type = EXP_TYPE_CREW + exp_requirements = 60 outfit = /datum/outfit/job/chemist @@ -124,6 +129,8 @@ Geneticist spawn_positions = 2 supervisors = "the chief medical officer and research director" selection_color = "#ffeef0" + exp_type = EXP_TYPE_CREW + exp_requirements = 60 outfit = /datum/outfit/job/geneticist @@ -158,6 +165,8 @@ Virologist spawn_positions = 1 supervisors = "the chief medical officer" selection_color = "#ffeef0" + exp_type = EXP_TYPE_CREW + exp_requirements = 60 outfit = /datum/outfit/job/virologist diff --git a/code/modules/jobs/job_types/science.dm b/code/modules/jobs/job_types/science.dm index aa9dd1b179..68d3bdeca9 100644 --- a/code/modules/jobs/job_types/science.dm +++ b/code/modules/jobs/job_types/science.dm @@ -14,6 +14,9 @@ Research Director selection_color = "#ffddff" req_admin_notify = 1 minimal_player_age = 7 + exp_type_department = EXP_TYPE_SCIENCE + exp_requirements = 180 + exp_type = EXP_TYPE_CREW outfit = /datum/outfit/job/rd @@ -68,6 +71,8 @@ Scientist spawn_positions = 3 supervisors = "the research director" selection_color = "#ffeeff" + exp_requirements = 60 + exp_type = EXP_TYPE_CREW outfit = /datum/outfit/job/scientist @@ -101,6 +106,8 @@ Roboticist spawn_positions = 2 supervisors = "research director" selection_color = "#ffeeff" + exp_requirements = 60 + exp_type = EXP_TYPE_CREW outfit = /datum/outfit/job/roboticist diff --git a/code/modules/jobs/job_types/security.dm b/code/modules/jobs/job_types/security.dm index 88c73db19a..64b3c0ea8e 100644 --- a/code/modules/jobs/job_types/security.dm +++ b/code/modules/jobs/job_types/security.dm @@ -20,6 +20,9 @@ Head of Security selection_color = "#ffdddd" req_admin_notify = 1 minimal_player_age = 14 + exp_requirements = 300 + exp_type = EXP_TYPE_CREW + exp_type_department = EXP_TYPE_SECURITY outfit = /datum/outfit/job/hos @@ -71,6 +74,8 @@ Warden supervisors = "the head of security" selection_color = "#ffeeee" minimal_player_age = 7 + exp_requirements = 300 + exp_type = EXP_TYPE_CREW outfit = /datum/outfit/job/warden @@ -121,6 +126,8 @@ Detective supervisors = "the head of security" selection_color = "#ffeeee" minimal_player_age = 7 + exp_requirements = 300 + exp_type = EXP_TYPE_CREW outfit = /datum/outfit/job/detective @@ -169,6 +176,8 @@ Security Officer supervisors = "the head of security, and the head of your assigned department (if applicable)" selection_color = "#ffeeee" minimal_player_age = 7 + exp_requirements = 300 + exp_type = EXP_TYPE_CREW outfit = /datum/outfit/job/security diff --git a/code/modules/jobs/job_types/silicon.dm b/code/modules/jobs/job_types/silicon.dm index 0b6380bfaf..2e0a710d41 100644 --- a/code/modules/jobs/job_types/silicon.dm +++ b/code/modules/jobs/job_types/silicon.dm @@ -12,6 +12,8 @@ AI supervisors = "your laws" req_admin_notify = 1 minimal_player_age = 30 + exp_requirements = 180 + exp_type = EXP_TYPE_CREW /datum/job/ai/equip(mob/living/carbon/human/H) return H.AIize(FALSE) @@ -44,6 +46,8 @@ Cyborg 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) diff --git a/code/modules/jobs/jobs.dm b/code/modules/jobs/jobs.dm index 2d7caa5fc4..b5ec8fa27a 100644 --- a/code/modules/jobs/jobs.dm +++ b/code/modules/jobs/jobs.dm @@ -59,6 +59,26 @@ GLOBAL_LIST_INIT(nonhuman_positions, list( "Cyborg", "pAI")) +GLOBAL_LIST_INIT(exp_jobsmap, list( + EXP_TYPE_CREW = list("titles" = command_positions | engineering_positions | medical_positions | science_positions | supply_positions | security_positions | civilian_positions | list("AI","Cyborg")), // crew positions + EXP_TYPE_COMMAND = list("titles" = command_positions), + EXP_TYPE_ENGINEERING = list("titles" = engineering_positions), + EXP_TYPE_MEDICAL = list("titles" = medical_positions), + EXP_TYPE_SCIENCE = list("titles" = science_positions), + EXP_TYPE_SUPPLY = list("titles" = supply_positions), + EXP_TYPE_SECURITY = list("titles" = security_positions), + EXP_TYPE_SILICON = list("titles" = list("AI","Cyborg")), + EXP_TYPE_SERVICE = list("titles" = civilian_positions), +)) + +GLOBAL_LIST_INIT(exp_specialmap, list( + EXP_TYPE_LIVING = list(), // all living mobs + EXP_TYPE_ANTAG = list(), + EXP_TYPE_SPECIAL = list("Lifebringer","Ash Walker","Exile","Servant Golem","Free Golem","Hermit","Translocated Vet","Escaped Prisoner","Hotel Staff","SuperFriend","Space Syndicate","Ancient Crew","Space Doctor","Space Bartender","Beach Bum","Skeleton","Zombie","Space Bar Patron","Lavaland Syndicate","Ghost Role"), // Ghost roles + EXP_TYPE_GHOST = list() // dead people, observers +)) +GLOBAL_PROTECT(exp_jobsmap) +GLOBAL_PROTECT(exp_specialmap) /proc/guest_jobbans(job) return ((job in GLOB.command_positions) || (job in GLOB.nonhuman_positions) || (job in GLOB.security_positions)) diff --git a/code/modules/mob/dead/new_player/login.dm b/code/modules/mob/dead/new_player/login.dm index 9a49c23cfc..4de3b1d4dd 100644 --- a/code/modules/mob/dead/new_player/login.dm +++ b/code/modules/mob/dead/new_player/login.dm @@ -1,4 +1,7 @@ /mob/dead/new_player/Login() + if(config.use_exp_tracking) + client.set_exp_from_db() + client.set_db_player_flags() if(!mind) mind = new /datum/mind(key) mind.active = 1 diff --git a/code/modules/mob/dead/new_player/login.dm.rej b/code/modules/mob/dead/new_player/login.dm.rej new file mode 100644 index 0000000000..b7361e13ff --- /dev/null +++ b/code/modules/mob/dead/new_player/login.dm.rej @@ -0,0 +1,9 @@ +diff a/code/modules/mob/dead/new_player/login.dm b/code/modules/mob/dead/new_player/login.dm (rejected hunks) +@@ -1,5 +1,6 @@ + /mob/dead/new_player/Login() +- client.update_exp_client(0, 0) ++ if(config.use_exp_tracking) ++ client.update_exp_client(0, 0) + if(!mind) + mind = new /datum/mind(key) + mind.active = 1 diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index 2cea8e32f2..96e24dee83 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -307,6 +307,8 @@ return 0 if(!job.player_old_enough(src.client)) 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)) return 0 return 1 diff --git a/config/config.txt.rej b/config/config.txt.rej new file mode 100644 index 0000000000..fee79cf699 --- /dev/null +++ b/config/config.txt.rej @@ -0,0 +1,25 @@ +diff a/config/config.txt b/config/config.txt (rejected hunks) +@@ -32,17 +32,17 @@ BAN_LEGACY_SYSTEM + ## Uncomment this to have the job system use the player's account creation date, rather than the when they first joined the server for job timers. + #USE_ACCOUNT_AGE_FOR_JOBS + +-##Unhash this to track player playtime in the database. Requires database to be enabled. ++## Unhash this to track player playtime in the database. Requires database to be enabled. + #USE_EXP_TRACKING +-##Unhash this to enable playtime requirements for head jobs. ++## Unhash this to enable playtime requirements for head jobs. + #USE_EXP_RESTRICTIONS_HEADS +-##Unhash this to override head jobs' playtime requirements with this number of hours. ++## Unhash this to override head jobs' playtime requirements with this number of hours. + #USE_EXP_RESTRICTIONS_HEADS_HOURS 15 +-##Unhash this to change head jobs' playtime requirements so that they're based on department playtime, rather than crew playtime. ++## Unhash this to change head jobs' playtime requirements so that they're based on department playtime, rather than crew playtime. + #USE_EXP_RESTRICTIONS_HEADS_DEPARTMENT +-##Unhash this to enable playtime requirements for certain non-head jobs, like Engineer and Scientist. ++## Unhash this to enable playtime requirements for certain non-head jobs, like Engineer and Scientist. + #USE_EXP_RESTRICTIONS_OTHER +-##Allows admins to bypass job playtime requirements. ++## Allows admins to bypass job playtime requirements. + #USE_EXP_RESTRICTIONS_ADMIN_BYPASS + + diff --git a/tgstation.dme b/tgstation.dme index 1475d2335c..31f9768bc1 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -1449,6 +1449,7 @@ #include "code\modules\hydroponics\grown\tomato.dm" #include "code\modules\hydroponics\grown\towercap.dm" #include "code\modules\jobs\access.dm" +#include "code\modules\jobs\job_exp.dm" #include "code\modules\jobs\jobs.dm" #include "code\modules\jobs\job_types\assistant.dm" #include "code\modules\jobs\job_types\captain.dm" From d1fc5ce3859e674847935d2ccfceaa5e413b0781 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 20 Aug 2017 10:51:46 -0500 Subject: [PATCH 019/262] Moves playtime tracking change entry below header --- SQL/database_changelog.txt.rej | 39 ++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/SQL/database_changelog.txt.rej b/SQL/database_changelog.txt.rej index 1b201ec4aa..b4ec2b6394 100644 --- a/SQL/database_changelog.txt.rej +++ b/SQL/database_changelog.txt.rej @@ -1,15 +1,36 @@ diff a/SQL/database_changelog.txt b/SQL/database_changelog.txt (rejected hunks) -@@ -1,10 +1,10 @@ - Any time you make a change to the schema files, remember to increment the database schema version. Generally increment the minor number, major should be reserved for significant changes to the schema. Both values go up to 255. +@@ -1,3 +1,12 @@ ++Any time you make a change to the schema files, remember to increment the database schema version. Generally increment the minor number, major should be reserved for significant changes to the schema. Both values go up to 255. ++ ++The latest database version is 3.1; The query to update the schema revision table is: ++ ++INSERT INTO `schema_revision` (`major`, `minor`) VALUES (3, 1); ++or ++INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (3, 1); ++ ++---------------------------------------------------- --The latest database version is 3.1; The query to update the schema revision table is: -+The latest database version is 3.0; The query to update the schema revision table is: + 20th July 2017, by Shadowlight213 + Added role_time table to track time spent playing departments. +@@ -7,21 +16,10 @@ CREATE TABLE `role_time` ( `ckey` VARCHAR(32) NOT NULL , `job` VARCHAR(128) NOT --UPDATE `schema_revision` SET major = 3, minor = 1 LIMIT 1; -+INSERT INTO `schema_revision` (`major`, `minor`) VALUES (3, 0); - or --UPDATE `SS13_schema_revision` SET major = 3, minor = 1 LIMIT 1; -+INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (3, 0); + ALTER TABLE `player` ADD `flags` INT NOT NULL default '0' AFTER `accountjoindate`; + +-UPDATE `schema_revision` SET minor = 1; +- + Remember to add a prefix to the table name if you use them. ---------------------------------------------------- +-Any time you make a change to the schema files, remember to increment the database schema version. Generally increment the minor number, major should be reserved for significant changes to the schema. Both values go up to 255. +- +-The latest database version is 3.0; The query to update the schema revision table is: +- +-INSERT INTO `schema_revision` (`major`, `minor`) VALUES (3, 0); +-or +-INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (3, 0); +- +----------------------------------------------------- + 28 June 2017, by oranges + Added schema_revision to store the current db revision, why start at 3.0? + From 3862fb5d5eb2c6edeff096495d1714192771260c Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 20 Aug 2017 19:41:58 -0500 Subject: [PATCH 020/262] Add logging of deathgasp last words and suicide stats to the death table --- SQL/database_changelog.txt.rej | 35 ++++++++++++++++++----- SQL/tgstation_schema.sql | 2 ++ SQL/tgstation_schema_prefixed.sql | 2 ++ code/_compile_options.dm | 2 +- code/controllers/subsystem/blackbox.dm | 4 ++- code/modules/mob/living/living_defines.dm | 2 ++ code/modules/mob/living/say.dm | 1 + 7 files changed, 39 insertions(+), 9 deletions(-) diff --git a/SQL/database_changelog.txt.rej b/SQL/database_changelog.txt.rej index 1b201ec4aa..41fdcf49c3 100644 --- a/SQL/database_changelog.txt.rej +++ b/SQL/database_changelog.txt.rej @@ -1,15 +1,36 @@ diff a/SQL/database_changelog.txt b/SQL/database_changelog.txt (rejected hunks) -@@ -1,10 +1,10 @@ +@@ -1,26 +1,20 @@ Any time you make a change to the schema files, remember to increment the database schema version. Generally increment the minor number, major should be reserved for significant changes to the schema. Both values go up to 255. --The latest database version is 3.1; The query to update the schema revision table is: -+The latest database version is 3.0; The query to update the schema revision table is: +-The latest database version is 3.2; The query to update the schema revision table is: ++The latest database version is 3.1; The query to update the schema revision table is: --UPDATE `schema_revision` SET major = 3, minor = 1 LIMIT 1; -+INSERT INTO `schema_revision` (`major`, `minor`) VALUES (3, 0); +-INSERT INTO `schema_revision` (`major`, `minor`) VALUES (3, 2); ++INSERT INTO `schema_revision` (`major`, `minor`) VALUES (3, 1); or --UPDATE `SS13_schema_revision` SET major = 3, minor = 1 LIMIT 1; -+INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (3, 0); +-INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (3, 2); ++INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (3, 1); + + ---------------------------------------------------- + +-18 August 2017, by nfreader, bump to 3.2 ++18 August 2017, by Cyberboss and nfreader, bump to 3.1 + +-Modified table 'death', adding the column 'suicide'. ++Modified table 'death', adding the columns `last_words` and 'suicide'. + +-ALTER TABLE `death` ADD COLUMN `suicide` tinyint(0) NOT NULL DEFAULT '0' AFTER `last_words` +- +----------------------------------------------------- +- +-16 August 2017, by Cyberboss, bump to 3.1 +- +-Modified table 'death', adding the column 'last_words'. +- +-ALTER TABLE `death` ADD COLUMN `last_words` varchar(255) DEFAULT NULL AFTER `staminaloss` ++ALTER TABLE `death` ++ADD COLUMN `last_words` varchar(255) DEFAULT NULL AFTER `staminaloss`, ++ADD COLUMN `suicide` tinyint(0) NOT NULL DEFAULT '0' AFTER `last_words`; ---------------------------------------------------- diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql index 4c76e1f275..8159b3d9c1 100644 --- a/SQL/tgstation_schema.sql +++ b/SQL/tgstation_schema.sql @@ -151,6 +151,8 @@ CREATE TABLE `death` ( `toxloss` smallint(5) unsigned NOT NULL, `cloneloss` smallint(5) unsigned NOT NULL, `staminaloss` smallint(5) unsigned NOT NULL, + `last_words` varchar(255) DEFAULT NULL, + `suicide` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql index f717bf96ad..92db271b2c 100644 --- a/SQL/tgstation_schema_prefixed.sql +++ b/SQL/tgstation_schema_prefixed.sql @@ -148,6 +148,8 @@ CREATE TABLE `SS13_death` ( `toxloss` smallint(5) unsigned NOT NULL, `cloneloss` smallint(5) unsigned NOT NULL, `staminaloss` smallint(5) unsigned NOT NULL, + `last_words` varchar(255) DEFAULT NULL, + `suicide` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; diff --git a/code/_compile_options.dm b/code/_compile_options.dm index a669f1b4f5..fe66b9bf69 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -72,4 +72,4 @@ //Update this whenever the db schema changes //make sure you add an update to the schema_version stable in the db changelog #define DB_MAJOR_VERSION 3 -#define DB_MINOR_VERSION 0 +#define DB_MINOR_VERSION 1 diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm index 3344afcaaa..11eb703a8a 100644 --- a/code/controllers/subsystem/blackbox.dm +++ b/code/controllers/subsystem/blackbox.dm @@ -198,8 +198,10 @@ SUBSYSTEM_DEF(blackbox) var/x_coord = sanitizeSQL(L.x) var/y_coord = sanitizeSQL(L.y) var/z_coord = sanitizeSQL(L.z) + var/last_words = sanitizeSQL(L.last_words) + var/suicide = sanitizeSQL(L.suiciding) var/map = sanitizeSQL(SSmapping.config.map_name) - var/datum/DBQuery/query_report_death = SSdbcore.NewQuery("INSERT INTO [format_table_name("death")] (pod, x_coord, y_coord, z_coord, mapname, server_ip, server_port, round_id, tod, job, special, name, byondkey, laname, lakey, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss) VALUES ('[sqlpod]', '[x_coord]', '[y_coord]', '[z_coord]', '[map]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', [GLOB.round_id], '[SQLtime()]', '[sqljob]', '[sqlspecial]', '[sqlname]', '[sqlkey]', '[laname]', '[lakey]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina])") + var/datum/DBQuery/query_report_death = SSdbcore.NewQuery("INSERT INTO [format_table_name("death")] (pod, x_coord, y_coord, z_coord, mapname, server_ip, server_port, round_id, tod, job, special, name, byondkey, laname, lakey, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, last_words) VALUES ('[sqlpod]', '[x_coord]', '[y_coord]', '[z_coord]', '[map]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', [GLOB.round_id], '[SQLtime()]', '[sqljob]', '[sqlspecial]', '[sqlname]', '[sqlkey]', '[laname]', '[lakey]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina], [last_words], [suicide])") query_report_death.Execute() /datum/controller/subsystem/blackbox/proc/Seal() diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 6cb3a8daa9..f32ca97b09 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -75,3 +75,5 @@ var/datum/riding/riding_datum var/datum/language/selected_default_language + + var/last_words //used for database logging diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 68e2b150f3..cf1b95b98d 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -155,6 +155,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list( var/message_len = length(message) message = copytext(message, 1, health_diff) + "[message_len > health_diff ? "-.." : "..."]" message = Ellipsis(message, 10, 1) + last_words = message message_mode = MODE_WHISPER_CRIT succumbed = TRUE else From 365b16e298c7a4058c8edaebb59392da5a3314db Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Mon, 21 Aug 2017 19:47:23 -0700 Subject: [PATCH 021/262] saving work --- code/citadel/custom_loadout/read_from_file.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/citadel/custom_loadout/read_from_file.dm b/code/citadel/custom_loadout/read_from_file.dm index f5b668da92..eb75c88c2e 100644 --- a/code/citadel/custom_loadout/read_from_file.dm +++ b/code/citadel/custom_loadout/read_from_file.dm @@ -73,4 +73,5 @@ GLOBAL_LIST(custom_item_list) ret[item_path] += GLOB.custom_item_list[ckey][char][job][item_path] else ret[item_path] = GLOB.custom_item_list[ckey][char][job][item_path] + to_chat(world, "debug: parsing returned [english_list(ret)]") return ret From 95fee82fcb3dee5a004cf916f2ffc255068ef1b7 Mon Sep 17 00:00:00 2001 From: kevinz000 Date: Mon, 21 Aug 2017 20:35:16 -0700 Subject: [PATCH 022/262] tgui compile --- tgui/assets/tgui.css | 2 +- tgui/assets/tgui.js | 33 +- tgui/package-lock.json | 4577 ++++++++++++++++++++++++++++++++++++++++ tgui/package.json | 5 +- 4 files changed, 4598 insertions(+), 19 deletions(-) create mode 100644 tgui/package-lock.json diff --git a/tgui/assets/tgui.css b/tgui/assets/tgui.css index ffe61666b9..e0cc437429 100644 --- a/tgui/assets/tgui.css +++ b/tgui/assets/tgui.css @@ -1 +1 @@ -@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.clockwork{background:linear-gradient(180deg,#b18b25 0,#5f380e);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffb18b25",endColorstr="#ff5f380e",GradientType=0)}body.clockwork .normal{color:#b18b25}body.clockwork .good{color:#cfba47}body.clockwork .average{color:#896b19}body.clockwork .bad{color:#5f380e}body.clockwork .highlight{color:#b18b25}body.clockwork main{display:block;margin-top:32px;padding:2px 6px 0}body.clockwork hr{height:2px;background-color:#b18b25;border:none}body.clockwork .hidden{display:none}body.clockwork .bar .barText,body.clockwork span.button{color:#b18b25;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.clockwork .bold{font-weight:700}body.clockwork .italic{font-style:italic}body.clockwork [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.clockwork div[data-tooltip],body.clockwork span[data-tooltip]{position:relative}body.clockwork div[data-tooltip]:after,body.clockwork span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #170800;background-color:#2d1400}body.clockwork div[data-tooltip]:hover:after,body.clockwork span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.clockwork div[data-tooltip].tooltip-top:after,body.clockwork span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-left:after,body.clockwork span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #170800;background:#2d1400}body.clockwork .bar .barText{position:absolute;top:0;right:3px}body.clockwork .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#b18b25}body.clockwork .bar .barFill.good{background-color:#cfba47}body.clockwork .bar .barFill.average{background-color:#896b19}body.clockwork .bar .barFill.bad{background-color:#5f380e}body.clockwork span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #170800}body.clockwork span.button .fa{padding-right:2px}body.clockwork span.button.normal{transition:background-color .5s;background-color:#5f380e}body.clockwork span.button.normal.active:focus,body.clockwork span.button.normal.active:hover{transition:background-color .25s;background-color:#704211;outline:0}body.clockwork span.button.disabled{transition:background-color .5s;background-color:#2d1400}body.clockwork span.button.disabled.active:focus,body.clockwork span.button.disabled.active:hover{transition:background-color .25s;background-color:#441e00;outline:0}body.clockwork span.button.selected{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.selected.active:focus,body.clockwork span.button.selected.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.toggle{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.toggle.active:focus,body.clockwork span.button.toggle.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.caution{transition:background-color .5s;background-color:#be6209}body.clockwork span.button.caution.active:focus,body.clockwork span.button.caution.active:hover{transition:background-color .25s;background-color:#cd6a0a;outline:0}body.clockwork span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.clockwork span.button.danger.active:focus,body.clockwork span.button.danger.active:hover{transition:background-color .25s;background-color:#abaf00;outline:0}body.clockwork span.button.gridable{width:125px;margin:2px 0}body.clockwork span.button.gridable.center{text-align:center;width:75px}body.clockwork span.button+span:not(.button),body.clockwork span:not(.button)+span.button{margin-left:5px}body.clockwork div.display{width:100%;padding:4px;margin:6px 0;background-color:#2d1400;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400);background-color:rgba(45,20,0,.9);box-shadow:inset 0 0 5px rgba(0,0,0,.3)}body.clockwork div.display.tabular{padding:0;margin:0}body.clockwork div.display header,body.clockwork div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#cfba47;border-bottom:2px solid #b18b25}body.clockwork div.display header .buttonRight,body.clockwork div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.clockwork div.display article,body.clockwork div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.clockwork input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#b18b25;background-color:#cfba47;border:1px solid #272727}body.clockwork input.number{width:35px}body.clockwork input::-webkit-input-placeholder{color:#999}body.clockwork input:-ms-input-placeholder{color:#999}body.clockwork input::placeholder{color:#999}body.clockwork input::-ms-clear{display:none}body.clockwork svg.linegraph{overflow:hidden}body.clockwork div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#2d1400;font-weight:700;font-style:italic;background-color:#000;background-image:repeating-linear-gradient(-45deg,#000,#000 10px,#170800 0,#170800 20px)}body.clockwork div.notice .label{color:#2d1400}body.clockwork div.notice .content:only-of-type{padding:0}body.clockwork div.notice hr{background-color:#896b19}body.clockwork div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #5f380e;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .cell,body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.clockwork section{display:table-row;width:100%}body.clockwork section:not(:first-child){padding-top:4px}body.clockwork section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.clockwork section .label{width:1%;padding-right:32px;white-space:nowrap;color:#b18b25}body.clockwork section .content:not(:last-child){padding-right:16px}body.clockwork section .line{width:100%}body.clockwork section .cell:not(:first-child){text-align:center;padding-top:0}body.clockwork section .cell span.button{width:75px}body.clockwork section:not(:last-child){padding-right:4px}body.clockwork div.subdisplay{width:100%;margin:0}body.clockwork header.titlebar .close,body.clockwork header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#cfba47}body.clockwork header.titlebar .close:hover,body.clockwork header.titlebar .minimize:hover{color:#d1bd50}body.clockwork header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#5f380e;border-bottom:1px solid #170800;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.clockwork header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.clockwork header.titlebar .title{position:absolute;top:6px;left:46px;color:#cfba47;font-size:16px;white-space:nowrap}body.clockwork header.titlebar .minimize{position:absolute;top:6px;right:46px}body.clockwork header.titlebar .close{position:absolute;top:4px;right:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgNDI1IDIwMCIgb3BhY2l0eT0iLjMzIj4NCiAgPHBhdGggZD0ibSAxNzguMDAzOTksMC4wMzg2OSAtNzEuMjAzOTMsMCBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTYuNzYxMzQsNi4wMjU1NSBsIDAsMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM0LDYuMDI1NTQgbCA1My4xMDcyLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xMDEuNTQ0MDE4IDcyLjIxNjI4LDEwNC42OTkzOTggYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDUuNzYwMTUsMi44NzAxNiBsIDczLjU1NDg3LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xODcuODcxNDcgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM1LC02LjAyNTU1IGwgLTU0LjcxNjQ0LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTMzLDYuMDI1NTUgbCAwLDEwMi42MTkzNSBMIDE4My43NjQxMywyLjkwODg2IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNS43NjAxNCwtMi44NzAxNyB6IiAvPg0KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPg0KICA8cGF0aCBkPSJtIDQyMC4xNTUzNSwxNzcuODkxMTkgYSAxMy40MTIwMzgsMTIuNTAxODQyIDAgMCAxIC04LjYzMjk1LDIyLjA2OTUxIGwgLTY2LjExODMyLDAgYSA1LjM2NDgxNTIsNS4wMDA3MzcgMCAwIDEgLTUuMzY0ODIsLTUuMDAwNzQgbCAwLC03OS44NzkzMSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.toggle{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.toggle.active:focus,body.nanotrasen span.button.toggle.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button.gridable.center{text-align:center;width:75px}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display.tabular{padding:0;margin:0}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input.number{width:35px}body.nanotrasen input::-webkit-input-placeholder{color:#999}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen section .cell:not(:first-child){text-align:center;padding-top:0}body.nanotrasen section .cell span.button{width:75px}body.nanotrasen section:not(:last-child){padding-right:4px}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgMjAwIDI4OS43NDIiIG9wYWNpdHk9Ii4zMyI+DQogIDxwYXRoIGQ9Im0gOTMuNTM3Njc3LDAgYyAtMTguMTEzMTI1LDAgLTM0LjIyMDEzMywzLjExMTY0IC00OC4zMjM0ODQsOS4zMzQzNyAtMTMuOTY1MDkyLDYuMjIxNjcgLTI0LjYxMjQ0MiwxNS4wNzExNCAtMzEuOTQwNjUxLDI2LjU0NzEgLTcuMTg5OTM5OCwxMS4zMzc4OSAtMTAuMzAxMjI2NiwyNC43NDkxMSAtMTAuMzAxMjI2Niw0MC4yMzQ3OCAwLDEwLjY0NjYyIDIuNzI1MDAyNiwyMC40NjQ2NSA4LjE3NTExMTYsMjkuNDUyNTggNS42MTUyNzcsOC45ODY4NiAxNC4wMzgyNzcsMTcuMzUyMDQgMjUuMjY4ODIxLDI1LjA5NDM2IDExLjIzMDU0NCw3LjYwNTMxIDI2LjUwNzQyMSwxNS40MTgzNSA0NS44MzA1MTQsMjMuNDM3ODIgMTkuOTgzNzQ4LDguMjk1NTcgMzQuODQ4ODQ4LDE1LjU1NDcxIDQ0LjU5Mjk5OCwyMS43NzYzOCA5Ljc0NDE0LDYuMjIyNzMgMTYuNzYxNywxMi44NTg1IDIxLjA1NTcyLDE5LjkwOTUxIDQuMjk0MDQsNy4wNTIwOCA2LjQ0MTkzLDE1Ljc2NDA4IDYuNDQxOTMsMjYuMTM0NTkgMCwxNi4xNzcwMiAtNS4yMDE5NiwyOC40ODIyMiAtMTUuNjA2NzMsMzYuOTE2ODIgLTEwLjIzOTYsOC40MzQ3IC0yNS4wMjIwMywxMi42NTIzIC00NC4zNDUxNjksMTIuNjUyMyAtMTQuMDM4MTcxLDAgLTI1LjUxNTI0NywtMS42NTk0IC0zNC40MzM2MTgsLTQuOTc3NyAtOC45MTgzNywtMy40NTY2IC0xNi4xODU1NzIsLTguNzExMyAtMjEuODAwODM5LC0xNS43NjMzIC01LjYxNTI3NywtNy4wNTIxIC0xMC4wNzQ3OTUsLTE2LjY2MDg4IC0xMy4zNzc4OTksLTI4LjgyODEyIGwgLTI0Ljc3MzE2MjYyOTM5NDUsMCAwLDU2LjgyNjMyIEMgMzMuODU2NzY5LDI4Ni4wNzYwMSA2My43NDkwNCwyODkuNzQyMDEgODkuNjc4MzgzLDI4OS43NDIwMSBjIDE2LjAyMDAyNywwIDMwLjcxOTc4NywtMS4zODI3IDQ0LjA5NzMzNywtNC4xNDc5IDEzLjU0MjcyLC0yLjkwNDMgMjUuMTA0MSwtNy40Njc2IDM0LjY4MzA5LC0xMy42ODkzIDkuNzQ0MTMsLTYuMzU5NyAxNy4zNDA0MiwtMTQuNTE5NSAyMi43OTA1MiwtMjQuNDc0OCA1LjQ1MDEsLTEwLjA5MzMyIDguMTc1MTEsLTIyLjM5OTU5IDguMTc1MTEsLTM2LjkxNjgyIDAsLTEyLjk5NzY0IC0zLjMwMjEsLTI0LjMzNTM5IC05LjkwODI5LC0zNC4wMTQ2IC02LjQ0MTA1LC05LjgxNzI1IC0xNS41MjU0NSwtMTguNTI3MDcgLTI3LjI1MTQ2LC0yNi4xMzEzMyAtMTEuNTYwODUsLTcuNjA0MjcgLTI3LjkxMDgzLC0xNS44MzE0MiAtNDkuMDUwNjYsLTI0LjY4MDIyIC0xNy41MDY0NCwtNy4xOTAxMiAtMzAuNzE5NjY4LC0xMy42ODk0OCAtMzkuNjM4MDM4LC0xOS40OTcwMSAtOC45MTgzNzEsLTUuODA3NTIgLTE4LjYwNzQ3NCwtMTIuNDM0MDkgLTI0LjA5NjUyNCwtMTguODc0MTcgLTUuNDI2MDQzLC02LjM2NjE2IC05LjY1ODgyNiwtMTUuMDcwMDMgLTkuNjU4ODI2LC0yNC44ODcyOSAwLC05LjI2NDAxIDIuMDc1NDE0LC0xNy4yMTM0NSA2LjIyMzQ1NCwtMjMuODUwMzMgMTEuMDk4Mjk4LC0xNC4zOTc0OCA0MS4yODY2MzgsLTEuNzk1MDcgNDUuMDc1NjA5LDI0LjM0NzYyIDQuODM5MzkyLDYuNzc0OTEgOC44NDkzNSwxNi4yNDcyOSAxMi4wMjk1MTUsMjguNDE1NiBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNC40NzgyNSwtNS45MjQ0OCAtOS45NTQ4OCwtMTAuNjMyMjIgLTE1LjkwODM3LC0xNC4zNzQxMSAxLjY0MDU1LDAuNDc5MDUgMy4xOTAzOSwxLjAyMzc2IDQuNjM4NjUsMS42NDAyNCA2LjQ5ODYxLDIuNjI2MDcgMTIuMTY3OTMsNy4zMjc0NyAxNy4wMDczLDE0LjEwMzQ1IDQuODM5MzksNi43NzQ5MSA4Ljg0OTM1LDE2LjI0NTY3IDEyLjAyOTUyLDI4LjQxMzk3IDAsMCA4LjQ4MTI4LC0wLjEyODk0IDguNDg5NzgsLTAuMDAyIDAuNDE3NzYsNi40MTQ5NCAtMS43NTMzOSw5LjQ1Mjg2IC00LjEyMzQyLDEyLjU2MTA0IC0yLjQxNzQsMy4xNjk3OCAtNS4xNDQ4Niw2Ljc4OTczIC00LjAwMjc4LDEzLjAwMjkgMS41MDc4Niw4LjIwMzE4IDEwLjE4MzU0LDEwLjU5NjQyIDE0LjYyMTk0LDkuMzExNTQgLTMuMzE4NDIsLTAuNDk5MTEgLTUuMzE4NTUsLTEuNzQ5NDggLTUuMzE4NTUsLTEuNzQ5NDggMCwwIDEuODc2NDYsMC45OTg2OCA1LjY1MTE3LC0xLjM1OTgxIC0zLjI3Njk1LDAuOTU1NzEgLTEwLjcwNTI5LC0wLjc5NzM4IC0xMS44MDEyNSwtNi43NjMxMyAtMC45NTc1MiwtNS4yMDg2MSAwLjk0NjU0LC03LjI5NTE0IDMuNDAxMTMsLTEwLjUxNDgyIDIuNDU0NjIsLTMuMjE5NjggNS4yODQyNiwtNi45NTgzMSA0LjY4NDMsLTE0LjQ4ODI0IGwgMC4wMDMsMC4wMDIgOC45MjY3NiwwIDAsLTU1Ljk5OTY3IGMgLTE1LjA3MTI1LC0zLjg3MTY4IC0yNy42NTMxNCwtNi4zNjA0MiAtMzcuNzQ2NzEsLTcuNDY1ODYgLTkuOTU1MzEsLTEuMTA3NTUgLTIwLjE4ODIzLC0xLjY1OTgxIC0zMC42OTY2MTMsLTEuNjU5ODEgeiBtIDcwLjMyMTYwMywxNy4zMDg5MyAwLjIzODA1LDQwLjMwNDkgYyAxLjMxODA4LDEuMjI2NjYgMi40Mzk2NSwyLjI3ODE1IDMuMzQwODEsMy4xMDYwMiA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNCwxNi4yNDU2NiAxMi4wMjk1MSwyOC40MTM5NyBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNi42NzczMSwtNC41OTM4MSAtMTkuODM2NDMsLTEwLjQ3MzA5IC0zNi4xNDA3MSwtMTUuODI1MjIgeiBtIC0yOC4xMjA0OSw1LjYwNTUxIDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzcsLTYuNDY2OTcgLTEzLjg0Njc4LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDUsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gMTUuMjIxOTUsMjQuMDA4NDggOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzOCwtNi40NjY5NyAtMTMuODQ2NzksLTkuNzE3MjYgLTguNTY0NzksLTE3LjcxNjU1IHogbSAyMi43OTcwNCwwIGMgMi43NzE1LDcuOTk5MjkgMS43ODc0MSwxMS4yNDk1OCAtNC40OTM1NCwxNy43MTY1NSBsIDQuNDkzNTQsLTE3LjcxNjU1IHogbSAtOTkuMTEzODQsMi4yMDc2NCA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM4MiwtNi40NjY5NyAtMTMuODQ2NzgyLC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk1NDIsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff750000",endColorstr="#ff340404",GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.toggle{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.toggle.active:focus,body.syndicate span.button.toggle.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button.gridable.center{text-align:center;width:75px}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display.tabular{padding:0;margin:0}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input.number{width:35px}body.syndicate input::-webkit-input-placeholder{color:#999}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate section .cell:not(:first-child){text-align:center;padding-top:0}body.syndicate section .cell span.button{width:75px}body.syndicate section:not(:last-child){padding-right:4px}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"} \ No newline at end of file +@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.clockwork{background:linear-gradient(180deg,#b18b25 0,#5f380e);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffb18b25",endColorstr="#ff5f380e",GradientType=0)}body.clockwork .normal{color:#b18b25}body.clockwork .good{color:#cfba47}body.clockwork .average{color:#896b19}body.clockwork .bad{color:#5f380e}body.clockwork .highlight{color:#b18b25}body.clockwork main{display:block;margin-top:32px;padding:2px 6px 0}body.clockwork hr{height:2px;background-color:#b18b25;border:none}body.clockwork .hidden{display:none}body.clockwork .bar .barText,body.clockwork span.button{color:#b18b25;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.clockwork .bold{font-weight:700}body.clockwork .italic{font-style:italic}body.clockwork [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.clockwork div[data-tooltip],body.clockwork span[data-tooltip]{position:relative}body.clockwork div[data-tooltip]:after,body.clockwork span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #170800;background-color:#2d1400}body.clockwork div[data-tooltip]:hover:after,body.clockwork span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.clockwork div[data-tooltip].tooltip-top:after,body.clockwork span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-left:after,body.clockwork span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #170800;background:#2d1400}body.clockwork .bar .barText{position:absolute;top:0;right:3px}body.clockwork .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#b18b25}body.clockwork .bar .barFill.good{background-color:#cfba47}body.clockwork .bar .barFill.average{background-color:#896b19}body.clockwork .bar .barFill.bad{background-color:#5f380e}body.clockwork span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #170800}body.clockwork span.button .fa{padding-right:2px}body.clockwork span.button.normal{transition:background-color .5s;background-color:#5f380e}body.clockwork span.button.normal.active:focus,body.clockwork span.button.normal.active:hover{transition:background-color .25s;background-color:#704211;outline:0}body.clockwork span.button.disabled{transition:background-color .5s;background-color:#2d1400}body.clockwork span.button.disabled.active:focus,body.clockwork span.button.disabled.active:hover{transition:background-color .25s;background-color:#441e00;outline:0}body.clockwork span.button.selected{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.selected.active:focus,body.clockwork span.button.selected.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.toggle{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.toggle.active:focus,body.clockwork span.button.toggle.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.caution{transition:background-color .5s;background-color:#be6209}body.clockwork span.button.caution.active:focus,body.clockwork span.button.caution.active:hover{transition:background-color .25s;background-color:#cd6a0a;outline:0}body.clockwork span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.clockwork span.button.danger.active:focus,body.clockwork span.button.danger.active:hover{transition:background-color .25s;background-color:#abaf00;outline:0}body.clockwork span.button.gridable{width:125px;margin:2px 0}body.clockwork span.button.gridable.center{text-align:center;width:75px}body.clockwork span.button+span:not(.button),body.clockwork span:not(.button)+span.button{margin-left:5px}body.clockwork div.display{width:100%;padding:4px;margin:6px 0;background-color:#2d1400;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400);background-color:rgba(45,20,0,.9);box-shadow:inset 0 0 5px rgba(0,0,0,.3)}body.clockwork div.display.tabular{padding:0;margin:0}body.clockwork div.display header,body.clockwork div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#cfba47;border-bottom:2px solid #b18b25}body.clockwork div.display header .buttonRight,body.clockwork div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.clockwork div.display article,body.clockwork div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.clockwork input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#b18b25;background-color:#cfba47;border:1px solid #272727}body.clockwork input.number{width:35px}body.clockwork input::-webkit-input-placeholder{color:#999}body.clockwork input:-ms-input-placeholder{color:#999}body.clockwork input::placeholder{color:#999}body.clockwork input::-ms-clear{display:none}body.clockwork svg.linegraph{overflow:hidden}body.clockwork div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#2d1400;font-weight:700;font-style:italic;background-color:#000;background-image:repeating-linear-gradient(-45deg,#000,#000 10px,#170800 0,#170800 20px)}body.clockwork div.notice .label{color:#2d1400}body.clockwork div.notice .content:only-of-type{padding:0}body.clockwork div.notice hr{background-color:#896b19}body.clockwork div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #5f380e;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .cell,body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.clockwork section{display:table-row;width:100%}body.clockwork section:not(:first-child){padding-top:4px}body.clockwork section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.clockwork section .label{width:1%;padding-right:32px;white-space:nowrap;color:#b18b25}body.clockwork section .content:not(:last-child){padding-right:16px}body.clockwork section .line{width:100%}body.clockwork section .cell:not(:first-child){text-align:center;padding-top:0}body.clockwork section .cell span.button{width:75px}body.clockwork section:not(:last-child){padding-right:4px}body.clockwork div.subdisplay{width:100%;margin:0}body.clockwork header.titlebar .close,body.clockwork header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#cfba47}body.clockwork header.titlebar .close:hover,body.clockwork header.titlebar .minimize:hover{color:#d1bd50}body.clockwork header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#5f380e;border-bottom:1px solid #170800;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.clockwork header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.clockwork header.titlebar .title{position:absolute;top:6px;left:46px;color:#cfba47;font-size:16px;white-space:nowrap}body.clockwork header.titlebar .minimize{position:absolute;top:6px;right:46px}body.clockwork header.titlebar .close{position:absolute;top:4px;right:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjAiIHZpZXdCb3g9IjAgMCA0MjUgMjAwIiBvcGFjaXR5PSIuMzMiPgogIDxwYXRoIGQ9Im0gMTc4LjAwMzk5LDAuMDM4NjkgLTcxLjIwMzkzLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM0LDYuMDI1NTUgbCAwLDE4Ny44NzE0NyBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgNi43NjEzNCw2LjAyNTU0IGwgNTMuMTA3MiwwIGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM1LC02LjAyNTU0IGwgMCwtMTAxLjU0NDAxOCA3Mi4yMTYyOCwxMDQuNjk5Mzk4IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA1Ljc2MDE1LDIuODcwMTYgbCA3My41NTQ4NywwIGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM1LC02LjAyNTU0IGwgMCwtMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNi43NjEzNSwtNi4wMjU1NSBsIC01NC43MTY0NCwwIGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNi43NjEzMyw2LjAyNTU1IGwgMCwxMDIuNjE5MzUgTCAxODMuNzY0MTMsMi45MDg4NiBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTUuNzYwMTQsLTIuODcwMTcgeiIgLz4KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPgogIDxwYXRoIGQ9Im0gNDIwLjE1NTM1LDE3Ny44OTExOSBhIDEzLjQxMjAzOCwxMi41MDE4NDIgMCAwIDEgLTguNjMyOTUsMjIuMDY5NTEgbCAtNjYuMTE4MzIsMCBhIDUuMzY0ODE1Miw1LjAwMDczNyAwIDAgMSAtNS4zNjQ4MiwtNS4wMDA3NCBsIDAsLTc5Ljg3OTMxIHoiIC8+Cjwvc3ZnPgo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4KPCEtLSBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS1zYS80LjAvIC0tPgo=") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.toggle{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.toggle.active:focus,body.nanotrasen span.button.toggle.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button.gridable.center{text-align:center;width:75px}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display.tabular{padding:0;margin:0}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input.number{width:35px}body.nanotrasen input::-webkit-input-placeholder{color:#999}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen section .cell:not(:first-child){text-align:center;padding-top:0}body.nanotrasen section .cell span.button{width:75px}body.nanotrasen section:not(:last-child){padding-right:4px}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjAiIHZpZXdCb3g9IjAgMCAyMDAgMjg5Ljc0MiIgb3BhY2l0eT0iLjMzIj4KICA8cGF0aCBkPSJtIDkzLjUzNzY3NywwIGMgLTE4LjExMzEyNSwwIC0zNC4yMjAxMzMsMy4xMTE2NCAtNDguMzIzNDg0LDkuMzM0MzcgLTEzLjk2NTA5Miw2LjIyMTY3IC0yNC42MTI0NDIsMTUuMDcxMTQgLTMxLjk0MDY1MSwyNi41NDcxIC03LjE4OTkzOTgsMTEuMzM3ODkgLTEwLjMwMTIyNjYsMjQuNzQ5MTEgLTEwLjMwMTIyNjYsNDAuMjM0NzggMCwxMC42NDY2MiAyLjcyNTAwMjYsMjAuNDY0NjUgOC4xNzUxMTE2LDI5LjQ1MjU4IDUuNjE1Mjc3LDguOTg2ODYgMTQuMDM4Mjc3LDE3LjM1MjA0IDI1LjI2ODgyMSwyNS4wOTQzNiAxMS4yMzA1NDQsNy42MDUzMSAyNi41MDc0MjEsMTUuNDE4MzUgNDUuODMwNTE0LDIzLjQzNzgyIDE5Ljk4Mzc0OCw4LjI5NTU3IDM0Ljg0ODg0OCwxNS41NTQ3MSA0NC41OTI5OTgsMjEuNzc2MzggOS43NDQxNCw2LjIyMjczIDE2Ljc2MTcsMTIuODU4NSAyMS4wNTU3MiwxOS45MDk1MSA0LjI5NDA0LDcuMDUyMDggNi40NDE5MywxNS43NjQwOCA2LjQ0MTkzLDI2LjEzNDU5IDAsMTYuMTc3MDIgLTUuMjAxOTYsMjguNDgyMjIgLTE1LjYwNjczLDM2LjkxNjgyIC0xMC4yMzk2LDguNDM0NyAtMjUuMDIyMDMsMTIuNjUyMyAtNDQuMzQ1MTY5LDEyLjY1MjMgLTE0LjAzODE3MSwwIC0yNS41MTUyNDcsLTEuNjU5NCAtMzQuNDMzNjE4LC00Ljk3NzcgLTguOTE4MzcsLTMuNDU2NiAtMTYuMTg1NTcyLC04LjcxMTMgLTIxLjgwMDgzOSwtMTUuNzYzMyAtNS42MTUyNzcsLTcuMDUyMSAtMTAuMDc0Nzk1LC0xNi42NjA4OCAtMTMuMzc3ODk5LC0yOC44MjgxMiBsIC0yNC43NzMxNjI2MjkzOTQ1LDAgMCw1Ni44MjYzMiBDIDMzLjg1Njc2OSwyODYuMDc2MDEgNjMuNzQ5MDQsMjg5Ljc0MjAxIDg5LjY3ODM4MywyODkuNzQyMDEgYyAxNi4wMjAwMjcsMCAzMC43MTk3ODcsLTEuMzgyNyA0NC4wOTczMzcsLTQuMTQ3OSAxMy41NDI3MiwtMi45MDQzIDI1LjEwNDEsLTcuNDY3NiAzNC42ODMwOSwtMTMuNjg5MyA5Ljc0NDEzLC02LjM1OTcgMTcuMzQwNDIsLTE0LjUxOTUgMjIuNzkwNTIsLTI0LjQ3NDggNS40NTAxLC0xMC4wOTMzMiA4LjE3NTExLC0yMi4zOTk1OSA4LjE3NTExLC0zNi45MTY4MiAwLC0xMi45OTc2NCAtMy4zMDIxLC0yNC4zMzUzOSAtOS45MDgyOSwtMzQuMDE0NiAtNi40NDEwNSwtOS44MTcyNSAtMTUuNTI1NDUsLTE4LjUyNzA3IC0yNy4yNTE0NiwtMjYuMTMxMzMgLTExLjU2MDg1LC03LjYwNDI3IC0yNy45MTA4MywtMTUuODMxNDIgLTQ5LjA1MDY2LC0yNC42ODAyMiAtMTcuNTA2NDQsLTcuMTkwMTIgLTMwLjcxOTY2OCwtMTMuNjg5NDggLTM5LjYzODAzOCwtMTkuNDk3MDEgLTguOTE4MzcxLC01LjgwNzUyIC0xOC42MDc0NzQsLTEyLjQzNDA5IC0yNC4wOTY1MjQsLTE4Ljg3NDE3IC01LjQyNjA0MywtNi4zNjYxNiAtOS42NTg4MjYsLTE1LjA3MDAzIC05LjY1ODgyNiwtMjQuODg3MjkgMCwtOS4yNjQwMSAyLjA3NTQxNCwtMTcuMjEzNDUgNi4yMjM0NTQsLTIzLjg1MDMzIDExLjA5ODI5OCwtMTQuMzk3NDggNDEuMjg2NjM4LC0xLjc5NTA3IDQ1LjA3NTYwOSwyNC4zNDc2MiA0LjgzOTM5Miw2Ljc3NDkxIDguODQ5MzUsMTYuMjQ3MjkgMTIuMDI5NTE1LDI4LjQxNTYgbCAyMC41MzIzNCwwIDAsLTU1Ljk5OTY3IGMgLTQuNDc4MjUsLTUuOTI0NDggLTkuOTU0ODgsLTEwLjYzMjIyIC0xNS45MDgzNywtMTQuMzc0MTEgMS42NDA1NSwwLjQ3OTA1IDMuMTkwMzksMS4wMjM3NiA0LjYzODY1LDEuNjQwMjQgNi40OTg2MSwyLjYyNjA3IDEyLjE2NzkzLDcuMzI3NDcgMTcuMDA3MywxNC4xMDM0NSA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNSwxNi4yNDU2NyAxMi4wMjk1MiwyOC40MTM5NyAwLDAgOC40ODEyOCwtMC4xMjg5NCA4LjQ4OTc4LC0wLjAwMiAwLjQxNzc2LDYuNDE0OTQgLTEuNzUzMzksOS40NTI4NiAtNC4xMjM0MiwxMi41NjEwNCAtMi40MTc0LDMuMTY5NzggLTUuMTQ0ODYsNi43ODk3MyAtNC4wMDI3OCwxMy4wMDI5IDEuNTA3ODYsOC4yMDMxOCAxMC4xODM1NCwxMC41OTY0MiAxNC42MjE5NCw5LjMxMTU0IC0zLjMxODQyLC0wLjQ5OTExIC01LjMxODU1LC0xLjc0OTQ4IC01LjMxODU1LC0xLjc0OTQ4IDAsMCAxLjg3NjQ2LDAuOTk4NjggNS42NTExNywtMS4zNTk4MSAtMy4yNzY5NSwwLjk1NTcxIC0xMC43MDUyOSwtMC43OTczOCAtMTEuODAxMjUsLTYuNzYzMTMgLTAuOTU3NTIsLTUuMjA4NjEgMC45NDY1NCwtNy4yOTUxNCAzLjQwMTEzLC0xMC41MTQ4MiAyLjQ1NDYyLC0zLjIxOTY4IDUuMjg0MjYsLTYuOTU4MzEgNC42ODQzLC0xNC40ODgyNCBsIDAuMDAzLDAuMDAyIDguOTI2NzYsMCAwLC01NS45OTk2NyBjIC0xNS4wNzEyNSwtMy44NzE2OCAtMjcuNjUzMTQsLTYuMzYwNDIgLTM3Ljc0NjcxLC03LjQ2NTg2IC05Ljk1NTMxLC0xLjEwNzU1IC0yMC4xODgyMywtMS42NTk4MSAtMzAuNjk2NjEzLC0xLjY1OTgxIHogbSA3MC4zMjE2MDMsMTcuMzA4OTMgMC4yMzgwNSw0MC4zMDQ5IGMgMS4zMTgwOCwxLjIyNjY2IDIuNDM5NjUsMi4yNzgxNSAzLjM0MDgxLDMuMTA2MDIgNC44MzkzOSw2Ljc3NDkxIDguODQ5MzQsMTYuMjQ1NjYgMTIuMDI5NTEsMjguNDEzOTcgbCAyMC41MzIzNCwwIDAsLTU1Ljk5OTY3IGMgLTYuNjc3MzEsLTQuNTkzODEgLTE5LjgzNjQzLC0xMC40NzMwOSAtMzYuMTQwNzEsLTE1LjgyNTIyIHogbSAtMjguMTIwNDksNS42MDU1MSA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM3LC02LjQ2Njk3IC0xMy44NDY3OCwtOS43MTcyNiAtOC41NjQ3OSwtMTcuNzE2NTUgeiBtIDIyLjc5NzA1LDAgYyAyLjc3MTUsNy45OTkyOSAxLjc4NzQxLDExLjI0OTU4IC00LjQ5MzU0LDE3LjcxNjU1IGwgNC40OTM1NCwtMTcuNzE2NTUgeiBtIDE1LjIyMTk1LDI0LjAwODQ4IDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzgsLTYuNDY2OTcgLTEzLjg0Njc5LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDQsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gLTk5LjExMzg0LDIuMjA3NjQgOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzODIsLTYuNDY2OTcgLTEzLjg0Njc4MiwtOS43MTcyNiAtOC41NjQ3OSwtMTcuNzE2NTUgeiBtIDIyLjc5NTQyLDAgYyAyLjc3MTUsNy45OTkyOSAxLjc4NzQxLDExLjI0OTU4IC00LjQ5MzU0LDE3LjcxNjU1IGwgNC40OTM1NCwtMTcuNzE2NTUgeiIgLz4KPC9zdmc+CjwhLS0gVGhpcyB3b3JrIGlzIGxpY2Vuc2VkIHVuZGVyIGEgQ3JlYXRpdmUgQ29tbW9ucyBBdHRyaWJ1dGlvbi1TaGFyZUFsaWtlIDQuMCBJbnRlcm5hdGlvbmFsIExpY2Vuc2UuIC0tPgo8IS0tIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LXNhLzQuMC8gLS0+Cg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff750000",endColorstr="#ff340404",GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.toggle{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.toggle.active:focus,body.syndicate span.button.toggle.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button.gridable.center{text-align:center;width:75px}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display.tabular{padding:0;margin:0}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input.number{width:35px}body.syndicate input::-webkit-input-placeholder{color:#999}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate section .cell:not(:first-child){text-align:center;padding-top:0}body.syndicate section .cell span.button{width:75px}body.syndicate section:not(:last-child){padding-right:4px}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"} \ No newline at end of file diff --git a/tgui/assets/tgui.js b/tgui/assets/tgui.js index 89a66ecaf0..7c6113d948 100644 --- a/tgui/assets/tgui.js +++ b/tgui/assets/tgui.js @@ -1,16 +1,17 @@ -require=function t(e,n,a){function r(o,s){if(!n[o]){if(!e[o]){var u="function"==typeof require&&require;if(!s&&u)return u(o,!0);if(i)return i(o,!0);var p=Error("Cannot find module '"+o+"'");throw p.code="MODULE_NOT_FOUND",p}var c=n[o]={exports:{}};e[o][0].call(c.exports,function(t){var n=e[o][1][t];return r(n?n:t)},c,c.exports,t,e,n,a)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o2?p[2]:void 0,l=Math.min((void 0===c?o:r(c,o))-u,o-s),f=1;for(s>u&&u+l>s&&(f=-1,u+=l-1,s+=l-1);l-- >0;)u in n?n[s]=n[u]:delete n[s],s+=f,u+=f;return n}},{76:76,79:79,80:80}],6:[function(t,e,n){"use strict";var a=t(80),r=t(76),i=t(79);e.exports=[].fill||function(t){for(var e=a(this),n=i(e.length),o=arguments,s=o.length,u=r(s>1?o[1]:void 0,n),p=s>2?o[2]:void 0,c=void 0===p?n:r(p,n);c>u;)e[u++]=t;return e}},{76:76,79:79,80:80}],7:[function(t,e,n){var a=t(78),r=t(79),i=t(76);e.exports=function(t){return function(e,n,o){var s,u=a(e),p=r(u.length),c=i(o,p);if(t&&n!=n){for(;p>c;)if(s=u[c++],s!=s)return!0}else for(;p>c;c++)if((t||c in u)&&u[c]===n)return t||c;return!t&&-1}}},{76:76,78:78,79:79}],8:[function(t,e,n){var a=t(17),r=t(34),i=t(80),o=t(79),s=t(9);e.exports=function(t){var e=1==t,n=2==t,u=3==t,p=4==t,c=6==t,l=5==t||c;return function(f,d,h){for(var m,v,g=i(f),b=r(g),y=a(d,h,3),x=o(b.length),_=0,w=e?s(f,x):n?s(f,0):void 0;x>_;_++)if((l||_ in b)&&(m=b[_],v=y(m,_,g),t))if(e)w[_]=v;else if(v)switch(t){case 3:return!0;case 5:return m;case 6:return _;case 2:w.push(m)}else if(p)return!1;return c?-1:u||p?p:w}}},{17:17,34:34,79:79,80:80,9:9}],9:[function(t,e,n){var a=t(38),r=t(36),i=t(83)("species");e.exports=function(t,e){var n;return r(t)&&(n=t.constructor,"function"!=typeof n||n!==Array&&!r(n.prototype)||(n=void 0),a(n)&&(n=n[i],null===n&&(n=void 0))),new(void 0===n?Array:n)(e)}},{36:36,38:38,83:83}],10:[function(t,e,n){var a=t(11),r=t(83)("toStringTag"),i="Arguments"==a(function(){return arguments}());e.exports=function(t){var e,n,o;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=(e=Object(t))[r])?n:i?a(e):"Object"==(o=a(e))&&"function"==typeof e.callee?"Arguments":o}},{11:11,83:83}],11:[function(t,e,n){var a={}.toString;e.exports=function(t){return a.call(t).slice(8,-1)}},{}],12:[function(t,e,n){"use strict";var a=t(46),r=t(31),i=t(60),o=t(17),s=t(69),u=t(18),p=t(27),c=t(42),l=t(44),f=t(82)("id"),d=t(30),h=t(38),m=t(65),v=t(19),g=Object.isExtensible||h,b=v?"_s":"size",y=0,x=function(t,e){if(!h(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!d(t,f)){if(!g(t))return"F";if(!e)return"E";r(t,f,++y)}return"O"+t[f]},_=function(t,e){var n,a=x(e);if("F"!==a)return t._i[a];for(n=t._f;n;n=n.n)if(n.k==e)return n};e.exports={getConstructor:function(t,e,n,r){var c=t(function(t,i){s(t,c,e),t._i=a.create(null),t._f=void 0,t._l=void 0,t[b]=0,void 0!=i&&p(i,n,t[r],t)});return i(c.prototype,{clear:function(){for(var t=this,e=t._i,n=t._f;n;n=n.n)n.r=!0,n.p&&(n.p=n.p.n=void 0),delete e[n.i];t._f=t._l=void 0,t[b]=0},"delete":function(t){var e=this,n=_(e,t);if(n){var a=n.n,r=n.p;delete e._i[n.i],n.r=!0,r&&(r.n=a),a&&(a.p=r),e._f==n&&(e._f=a),e._l==n&&(e._l=r),e[b]--}return!!n},forEach:function(t){for(var e,n=o(t,arguments.length>1?arguments[1]:void 0,3);e=e?e.n:this._f;)for(n(e.v,e.k,this);e&&e.r;)e=e.p},has:function(t){return!!_(this,t)}}),v&&a.setDesc(c.prototype,"size",{get:function(){return u(this[b])}}),c},def:function(t,e,n){var a,r,i=_(t,e);return i?i.v=n:(t._l=i={i:r=x(e,!0),k:e,v:n,p:a=t._l,n:void 0,r:!1},t._f||(t._f=i),a&&(a.n=i),t[b]++,"F"!==r&&(t._i[r]=i)),t},getEntry:_,setStrong:function(t,e,n){c(t,e,function(t,e){this._t=t,this._k=e,this._l=void 0},function(){for(var t=this,e=t._k,n=t._l;n&&n.r;)n=n.p;return t._t&&(t._l=n=n?n.n:t._t._f)?"keys"==e?l(0,n.k):"values"==e?l(0,n.v):l(0,[n.k,n.v]):(t._t=void 0,l(1))},n?"entries":"values",!n,!0),m(e)}}},{17:17,18:18,19:19,27:27,30:30,31:31,38:38,42:42,44:44,46:46,60:60,65:65,69:69,82:82}],13:[function(t,e,n){var a=t(27),r=t(10);e.exports=function(t){return function(){if(r(this)!=t)throw TypeError(t+"#toJSON isn't generic");var e=[];return a(this,!1,e.push,e),e}}},{10:10,27:27}],14:[function(t,e,n){"use strict";var a=t(31),r=t(60),i=t(4),o=t(38),s=t(69),u=t(27),p=t(8),c=t(30),l=t(82)("weak"),f=Object.isExtensible||o,d=p(5),h=p(6),m=0,v=function(t){return t._l||(t._l=new g)},g=function(){this.a=[]},b=function(t,e){return d(t.a,function(t){return t[0]===e})};g.prototype={get:function(t){var e=b(this,t);return e?e[1]:void 0},has:function(t){return!!b(this,t)},set:function(t,e){var n=b(this,t);n?n[1]=e:this.a.push([t,e])},"delete":function(t){var e=h(this.a,function(e){return e[0]===t});return~e&&this.a.splice(e,1),!!~e}},e.exports={getConstructor:function(t,e,n,a){var i=t(function(t,r){s(t,i,e),t._i=m++,t._l=void 0,void 0!=r&&u(r,n,t[a],t)});return r(i.prototype,{"delete":function(t){return o(t)?f(t)?c(t,l)&&c(t[l],this._i)&&delete t[l][this._i]:v(this)["delete"](t):!1},has:function(t){return o(t)?f(t)?c(t,l)&&c(t[l],this._i):v(this).has(t):!1}}),i},def:function(t,e,n){return f(i(e))?(c(e,l)||a(e,l,{}),e[l][t._i]=n):v(t).set(e,n),t},frozenStore:v,WEAK:l}},{27:27,30:30,31:31,38:38,4:4,60:60,69:69,8:8,82:82}],15:[function(t,e,n){"use strict";var a=t(29),r=t(22),i=t(61),o=t(60),s=t(27),u=t(69),p=t(38),c=t(24),l=t(43),f=t(66);e.exports=function(t,e,n,d,h,m){var v=a[t],g=v,b=h?"set":"add",y=g&&g.prototype,x={},_=function(t){var e=y[t];i(y,t,"delete"==t?function(t){return m&&!p(t)?!1:e.call(this,0===t?0:t)}:"has"==t?function(t){return m&&!p(t)?!1:e.call(this,0===t?0:t)}:"get"==t?function(t){return m&&!p(t)?void 0:e.call(this,0===t?0:t)}:"add"==t?function(t){return e.call(this,0===t?0:t),this}:function(t,n){return e.call(this,0===t?0:t,n),this})};if("function"==typeof g&&(m||y.forEach&&!c(function(){(new g).entries().next()}))){var w,k=new g,E=k[b](m?{}:-0,1)!=k,S=c(function(){k.has(1)}),C=l(function(t){new g(t)});C||(g=e(function(e,n){u(e,g,t);var a=new v;return void 0!=n&&s(n,h,a[b],a),a}),g.prototype=y,y.constructor=g),m||k.forEach(function(t,e){w=1/e===-(1/0)}),(S||w)&&(_("delete"),_("has"),h&&_("get")),(w||E)&&_(b),m&&y.clear&&delete y.clear}else g=d.getConstructor(e,t,h,b),o(g.prototype,n);return f(g,t),x[t]=g,r(r.G+r.W+r.F*(g!=v),x),m||d.setStrong(g,t,h),g}},{22:22,24:24,27:27,29:29,38:38,43:43,60:60,61:61,66:66,69:69}],16:[function(t,e,n){var a=e.exports={version:"1.2.6"};"number"==typeof __e&&(__e=a)},{}],17:[function(t,e,n){var a=t(2);e.exports=function(t,e,n){if(a(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,a){return t.call(e,n,a)};case 3:return function(n,a,r){return t.call(e,n,a,r)}}return function(){return t.apply(e,arguments)}}},{2:2}],18:[function(t,e,n){e.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},{}],19:[function(t,e,n){e.exports=!t(24)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},{24:24}],20:[function(t,e,n){var a=t(38),r=t(29).document,i=a(r)&&a(r.createElement);e.exports=function(t){return i?r.createElement(t):{}}},{29:29,38:38}],21:[function(t,e,n){var a=t(46);e.exports=function(t){var e=a.getKeys(t),n=a.getSymbols;if(n)for(var r,i=n(t),o=a.isEnum,s=0;i.length>s;)o.call(t,r=i[s++])&&e.push(r);return e}},{46:46}],22:[function(t,e,n){var a=t(29),r=t(16),i=t(31),o=t(61),s=t(17),u="prototype",p=function(t,e,n){var c,l,f,d,h=t&p.F,m=t&p.G,v=t&p.S,g=t&p.P,b=t&p.B,y=m?a:v?a[e]||(a[e]={}):(a[e]||{})[u],x=m?r:r[e]||(r[e]={}),_=x[u]||(x[u]={});m&&(n=e);for(c in n)l=!h&&y&&c in y,f=(l?y:n)[c],d=b&&l?s(f,a):g&&"function"==typeof f?s(Function.call,f):f,y&&!l&&o(y,c,f),x[c]!=f&&i(x,c,d),g&&_[c]!=f&&(_[c]=f)};a.core=r,p.F=1,p.G=2,p.S=4,p.P=8,p.B=16,p.W=32,e.exports=p},{16:16,17:17,29:29,31:31,61:61}],23:[function(t,e,n){var a=t(83)("match");e.exports=function(t){var e=/./;try{"/./"[t](e)}catch(n){try{return e[a]=!1,!"/./"[t](e)}catch(r){}}return!0}},{83:83}],24:[function(t,e,n){e.exports=function(t){try{return!!t()}catch(e){return!0}}},{}],25:[function(t,e,n){"use strict";var a=t(31),r=t(61),i=t(24),o=t(18),s=t(83);e.exports=function(t,e,n){var u=s(t),p=""[t];i(function(){var e={};return e[u]=function(){return 7},7!=""[t](e)})&&(r(String.prototype,t,n(o,u,p)),a(RegExp.prototype,u,2==e?function(t,e){return p.call(t,this,e)}:function(t){return p.call(t,this)}))}},{18:18,24:24,31:31,61:61,83:83}],26:[function(t,e,n){"use strict";var a=t(4);e.exports=function(){var t=a(this),e="";return t.global&&(e+="g"),t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),t.unicode&&(e+="u"),t.sticky&&(e+="y"),e}},{4:4}],27:[function(t,e,n){var a=t(17),r=t(40),i=t(35),o=t(4),s=t(79),u=t(84);e.exports=function(t,e,n,p){var c,l,f,d=u(t),h=a(n,p,e?2:1),m=0;if("function"!=typeof d)throw TypeError(t+" is not iterable!");if(i(d))for(c=s(t.length);c>m;m++)e?h(o(l=t[m])[0],l[1]):h(t[m]);else for(f=d.call(t);!(l=f.next()).done;)r(f,h,l.value,e)}},{17:17,35:35,4:4,40:40,79:79,84:84}],28:[function(t,e,n){var a=t(78),r=t(46).getNames,i={}.toString,o="object"==typeof window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],s=function(t){try{return r(t)}catch(e){return o.slice()}};e.exports.get=function(t){return o&&"[object Window]"==i.call(t)?s(t):r(a(t))}},{46:46,78:78}],29:[function(t,e,n){var a=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=a)},{}],30:[function(t,e,n){var a={}.hasOwnProperty;e.exports=function(t,e){return a.call(t,e)}},{}],31:[function(t,e,n){var a=t(46),r=t(59);e.exports=t(19)?function(t,e,n){return a.setDesc(t,e,r(1,n))}:function(t,e,n){return t[e]=n,t}},{19:19,46:46,59:59}],32:[function(t,e,n){e.exports=t(29).document&&document.documentElement},{29:29}],33:[function(t,e,n){e.exports=function(t,e,n){var a=void 0===n;switch(e.length){case 0:return a?t():t.call(n);case 1:return a?t(e[0]):t.call(n,e[0]);case 2:return a?t(e[0],e[1]):t.call(n,e[0],e[1]);case 3:return a?t(e[0],e[1],e[2]):t.call(n,e[0],e[1],e[2]);case 4:return a?t(e[0],e[1],e[2],e[3]):t.call(n,e[0],e[1],e[2],e[3])}return t.apply(n,e)}},{}],34:[function(t,e,n){var a=t(11);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==a(t)?t.split(""):Object(t)}},{11:11}],35:[function(t,e,n){var a=t(45),r=t(83)("iterator"),i=Array.prototype;e.exports=function(t){return void 0!==t&&(a.Array===t||i[r]===t)}},{45:45,83:83}],36:[function(t,e,n){var a=t(11);e.exports=Array.isArray||function(t){return"Array"==a(t)}},{11:11}],37:[function(t,e,n){var a=t(38),r=Math.floor;e.exports=function(t){return!a(t)&&isFinite(t)&&r(t)===t}},{38:38}],38:[function(t,e,n){e.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},{}],39:[function(t,e,n){var a=t(38),r=t(11),i=t(83)("match");e.exports=function(t){var e;return a(t)&&(void 0!==(e=t[i])?!!e:"RegExp"==r(t))}},{11:11,38:38,83:83}],40:[function(t,e,n){var a=t(4);e.exports=function(t,e,n,r){try{return r?e(a(n)[0],n[1]):e(n)}catch(i){var o=t["return"];throw void 0!==o&&a(o.call(t)),i}}},{4:4}],41:[function(t,e,n){"use strict";var a=t(46),r=t(59),i=t(66),o={};t(31)(o,t(83)("iterator"),function(){return this}),e.exports=function(t,e,n){t.prototype=a.create(o,{next:r(1,n)}),i(t,e+" Iterator")}},{31:31,46:46,59:59,66:66,83:83}],42:[function(t,e,n){"use strict";var a=t(48),r=t(22),i=t(61),o=t(31),s=t(30),u=t(45),p=t(41),c=t(66),l=t(46).getProto,f=t(83)("iterator"),d=!([].keys&&"next"in[].keys()),h="@@iterator",m="keys",v="values",g=function(){return this};e.exports=function(t,e,n,b,y,x,_){p(n,e,b);var w,k,E=function(t){if(!d&&t in A)return A[t];switch(t){case m:return function(){return new n(this,t)};case v:return function(){return new n(this,t)}}return function(){return new n(this,t)}},S=e+" Iterator",C=y==v,P=!1,A=t.prototype,O=A[f]||A[h]||y&&A[y],T=O||E(y);if(O){var M=l(T.call(new t));c(M,S,!0),!a&&s(A,h)&&o(M,f,g),C&&O.name!==v&&(P=!0,T=function(){return O.call(this)})}if(a&&!_||!d&&!P&&A[f]||o(A,f,T),u[e]=T,u[S]=g,y)if(w={values:C?T:E(v),keys:x?T:E(m),entries:C?E("entries"):T},_)for(k in w)k in A||i(A,k,w[k]);else r(r.P+r.F*(d||P),e,w);return w}},{22:22,30:30,31:31,41:41,45:45,46:46,48:48,61:61,66:66,83:83}],43:[function(t,e,n){var a=t(83)("iterator"),r=!1;try{var i=[7][a]();i["return"]=function(){r=!0},Array.from(i,function(){throw 2})}catch(o){}e.exports=function(t,e){if(!e&&!r)return!1;var n=!1;try{var i=[7],o=i[a]();o.next=function(){return{done:n=!0}},i[a]=function(){return o},t(i)}catch(s){}return n}},{83:83}],44:[function(t,e,n){e.exports=function(t,e){return{value:e,done:!!t}}},{}],45:[function(t,e,n){e.exports={}},{}],46:[function(t,e,n){var a=Object;e.exports={create:a.create,getProto:a.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:a.getOwnPropertyDescriptor,setDesc:a.defineProperty,setDescs:a.defineProperties,getKeys:a.keys,getNames:a.getOwnPropertyNames,getSymbols:a.getOwnPropertySymbols,each:[].forEach}},{}],47:[function(t,e,n){var a=t(46),r=t(78);e.exports=function(t,e){for(var n,i=r(t),o=a.getKeys(i),s=o.length,u=0;s>u;)if(i[n=o[u++]]===e)return n}},{46:46,78:78}],48:[function(t,e,n){e.exports=!1},{}],49:[function(t,e,n){e.exports=Math.expm1||function(t){return 0==(t=+t)?t:t>-1e-6&&1e-6>t?t+t*t/2:Math.exp(t)-1}},{}],50:[function(t,e,n){e.exports=Math.log1p||function(t){return(t=+t)>-1e-8&&1e-8>t?t-t*t/2:Math.log(1+t)}},{}],51:[function(t,e,n){e.exports=Math.sign||function(t){return 0==(t=+t)||t!=t?t:0>t?-1:1}},{}],52:[function(t,e,n){var a,r,i,o=t(29),s=t(75).set,u=o.MutationObserver||o.WebKitMutationObserver,p=o.process,c=o.Promise,l="process"==t(11)(p),f=function(){var t,e,n;for(l&&(t=p.domain)&&(p.domain=null,t.exit());a;)e=a.domain,n=a.fn,e&&e.enter(),n(),e&&e.exit(),a=a.next;r=void 0,t&&t.enter()};if(l)i=function(){p.nextTick(f)};else if(u){var d=1,h=document.createTextNode("");new u(f).observe(h,{characterData:!0}),i=function(){h.data=d=-d}}else i=c&&c.resolve?function(){c.resolve().then(f)}:function(){s.call(o,f)};e.exports=function(t){var e={fn:t,next:void 0,domain:l&&p.domain};r&&(r.next=e),a||(a=e,i()),r=e}},{11:11,29:29,75:75}],53:[function(t,e,n){var a=t(46),r=t(80),i=t(34);e.exports=t(24)(function(){var t=Object.assign,e={},n={},a=Symbol(),r="abcdefghijklmnopqrst";return e[a]=7,r.split("").forEach(function(t){n[t]=t}),7!=t({},e)[a]||Object.keys(t({},n)).join("")!=r})?function(t,e){for(var n=r(t),o=arguments,s=o.length,u=1,p=a.getKeys,c=a.getSymbols,l=a.isEnum;s>u;)for(var f,d=i(o[u++]),h=c?p(d).concat(c(d)):p(d),m=h.length,v=0;m>v;)l.call(d,f=h[v++])&&(n[f]=d[f]);return n}:Object.assign},{24:24,34:34,46:46,80:80}],54:[function(t,e,n){var a=t(22),r=t(16),i=t(24);e.exports=function(t,e){var n=(r.Object||{})[t]||Object[t],o={};o[t]=e(n),a(a.S+a.F*i(function(){n(1)}),"Object",o)}},{16:16,22:22,24:24}],55:[function(t,e,n){var a=t(46),r=t(78),i=a.isEnum;e.exports=function(t){return function(e){for(var n,o=r(e),s=a.getKeys(o),u=s.length,p=0,c=[];u>p;)i.call(o,n=s[p++])&&c.push(t?[n,o[n]]:o[n]);return c}}},{46:46,78:78}],56:[function(t,e,n){var a=t(46),r=t(4),i=t(29).Reflect;e.exports=i&&i.ownKeys||function(t){var e=a.getNames(r(t)),n=a.getSymbols;return n?e.concat(n(t)):e}},{29:29,4:4,46:46}],57:[function(t,e,n){"use strict";var a=t(58),r=t(33),i=t(2);e.exports=function(){for(var t=i(this),e=arguments.length,n=Array(e),o=0,s=a._,u=!1;e>o;)(n[o]=arguments[o++])===s&&(u=!0);return function(){var a,i=this,o=arguments,p=o.length,c=0,l=0;if(!u&&!p)return r(t,n,i);if(a=n.slice(),u)for(;e>c;c++)a[c]===s&&(a[c]=o[l++]);for(;p>l;)a.push(o[l++]);return r(t,a,i)}}},{2:2,33:33,58:58}],58:[function(t,e,n){e.exports=t(29)},{29:29}],59:[function(t,e,n){e.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},{}],60:[function(t,e,n){var a=t(61);e.exports=function(t,e){for(var n in e)a(t,n,e[n]);return t}},{61:61}],61:[function(t,e,n){var a=t(29),r=t(31),i=t(82)("src"),o="toString",s=Function[o],u=(""+s).split(o);t(16).inspectSource=function(t){return s.call(t)},(e.exports=function(t,e,n,o){"function"==typeof n&&(n.hasOwnProperty(i)||r(n,i,t[e]?""+t[e]:u.join(e+"")),n.hasOwnProperty("name")||r(n,"name",e)),t===a?t[e]=n:(o||delete t[e],r(t,e,n))})(Function.prototype,o,function(){return"function"==typeof this&&this[i]||s.call(this)})},{16:16,29:29,31:31,82:82}],62:[function(t,e,n){e.exports=function(t,e){var n=e===Object(e)?function(t){return e[t]}:e;return function(e){return(e+"").replace(t,n)}}},{}],63:[function(t,e,n){e.exports=Object.is||function(t,e){return t===e?0!==t||1/t===1/e:t!=t&&e!=e}},{}],64:[function(t,e,n){var a=t(46).getDesc,r=t(38),i=t(4),o=function(t,e){if(i(t),!r(e)&&null!==e)throw TypeError(e+": can't set as prototype!")};e.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(e,n,r){try{r=t(17)(Function.call,a(Object.prototype,"__proto__").set,2),r(e,[]),n=!(e instanceof Array)}catch(i){n=!0}return function(t,e){return o(t,e),n?t.__proto__=e:r(t,e),t}}({},!1):void 0),check:o}},{17:17,38:38,4:4,46:46}],65:[function(t,e,n){"use strict";var a=t(29),r=t(46),i=t(19),o=t(83)("species");e.exports=function(t){var e=a[t];i&&e&&!e[o]&&r.setDesc(e,o,{configurable:!0,get:function(){return this}})}},{19:19,29:29,46:46,83:83}],66:[function(t,e,n){var a=t(46).setDesc,r=t(30),i=t(83)("toStringTag");e.exports=function(t,e,n){t&&!r(t=n?t:t.prototype,i)&&a(t,i,{configurable:!0,value:e})}},{30:30,46:46,83:83}],67:[function(t,e,n){var a=t(29),r="__core-js_shared__",i=a[r]||(a[r]={});e.exports=function(t){return i[t]||(i[t]={})}},{29:29}],68:[function(t,e,n){var a=t(4),r=t(2),i=t(83)("species");e.exports=function(t,e){var n,o=a(t).constructor;return void 0===o||void 0==(n=a(o)[i])?e:r(n)}},{2:2,4:4,83:83}],69:[function(t,e,n){e.exports=function(t,e,n){if(!(t instanceof e))throw TypeError(n+": use the 'new' operator!");return t}},{}],70:[function(t,e,n){var a=t(77),r=t(18);e.exports=function(t){return function(e,n){var i,o,s=r(e)+"",u=a(n),p=s.length;return 0>u||u>=p?t?"":void 0:(i=s.charCodeAt(u),55296>i||i>56319||u+1===p||(o=s.charCodeAt(u+1))<56320||o>57343?t?s.charAt(u):i:t?s.slice(u,u+2):(i-55296<<10)+(o-56320)+65536)}}},{18:18,77:77}],71:[function(t,e,n){var a=t(39),r=t(18);e.exports=function(t,e,n){if(a(e))throw TypeError("String#"+n+" doesn't accept regex!");return r(t)+""}},{18:18,39:39}],72:[function(t,e,n){var a=t(79),r=t(73),i=t(18);e.exports=function(t,e,n,o){var s=i(t)+"",u=s.length,p=void 0===n?" ":n+"",c=a(e);if(u>=c)return s;""==p&&(p=" ");var l=c-u,f=r.call(p,Math.ceil(l/p.length));return f.length>l&&(f=f.slice(0,l)),o?f+s:s+f}},{18:18,73:73,79:79}],73:[function(t,e,n){"use strict";var a=t(77),r=t(18);e.exports=function(t){var e=r(this)+"",n="",i=a(t);if(0>i||i==1/0)throw RangeError("Count can't be negative");for(;i>0;(i>>>=1)&&(e+=e))1&i&&(n+=e);return n}},{18:18,77:77}],74:[function(t,e,n){var a=t(22),r=t(18),i=t(24),o=" \n\x0B\f\r   ᠎ â€â€‚         âŸã€€\u2028\u2029\ufeff",s="["+o+"]",u="​…",p=RegExp("^"+s+s+"*"),c=RegExp(s+s+"*$"),l=function(t,e){var n={};n[t]=e(f),a(a.P+a.F*i(function(){return!!o[t]()||u[t]()!=u}),"String",n)},f=l.trim=function(t,e){return t=r(t)+"",1&e&&(t=t.replace(p,"")),2&e&&(t=t.replace(c,"")),t};e.exports=l},{18:18,22:22,24:24}],75:[function(t,e,n){var a,r,i,o=t(17),s=t(33),u=t(32),p=t(20),c=t(29),l=c.process,f=c.setImmediate,d=c.clearImmediate,h=c.MessageChannel,m=0,v={},g="onreadystatechange",b=function(){var t=+this;if(v.hasOwnProperty(t)){var e=v[t];delete v[t],e()}},y=function(t){b.call(t.data)};f&&d||(f=function(t){for(var e=[],n=1;arguments.length>n;)e.push(arguments[n++]);return v[++m]=function(){s("function"==typeof t?t:Function(t),e)},a(m),m},d=function(t){delete v[t]},"process"==t(11)(l)?a=function(t){l.nextTick(o(b,t,1))}:h?(r=new h,i=r.port2,r.port1.onmessage=y,a=o(i.postMessage,i,1)):c.addEventListener&&"function"==typeof postMessage&&!c.importScripts?(a=function(t){c.postMessage(t+"","*")},c.addEventListener("message",y,!1)):a=g in p("script")?function(t){u.appendChild(p("script"))[g]=function(){u.removeChild(this),b.call(t)}}:function(t){setTimeout(o(b,t,1),0)}),e.exports={set:f,clear:d}},{11:11,17:17,20:20,29:29,32:32,33:33}],76:[function(t,e,n){var a=t(77),r=Math.max,i=Math.min;e.exports=function(t,e){return t=a(t),0>t?r(t+e,0):i(t,e)}},{77:77}],77:[function(t,e,n){var a=Math.ceil,r=Math.floor;e.exports=function(t){return isNaN(t=+t)?0:(t>0?r:a)(t)}},{}],78:[function(t,e,n){var a=t(34),r=t(18);e.exports=function(t){return a(r(t))}},{18:18,34:34}],79:[function(t,e,n){var a=t(77),r=Math.min;e.exports=function(t){return t>0?r(a(t),9007199254740991):0}},{77:77}],80:[function(t,e,n){var a=t(18);e.exports=function(t){return Object(a(t))}},{18:18}],81:[function(t,e,n){var a=t(38);e.exports=function(t,e){if(!a(t))return t;var n,r;if(e&&"function"==typeof(n=t.toString)&&!a(r=n.call(t)))return r;if("function"==typeof(n=t.valueOf)&&!a(r=n.call(t)))return r;if(!e&&"function"==typeof(n=t.toString)&&!a(r=n.call(t)))return r;throw TypeError("Can't convert object to primitive value")}},{38:38}],82:[function(t,e,n){var a=0,r=Math.random();e.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++a+r).toString(36))}},{}],83:[function(t,e,n){var a=t(67)("wks"),r=t(82),i=t(29).Symbol;e.exports=function(t){return a[t]||(a[t]=i&&i[t]||(i||r)("Symbol."+t))}},{29:29,67:67,82:82}],84:[function(t,e,n){var a=t(10),r=t(83)("iterator"),i=t(45);e.exports=t(16).getIteratorMethod=function(t){return void 0!=t?t[r]||t["@@iterator"]||i[a(t)]:void 0}},{10:10,16:16,45:45,83:83}],85:[function(t,e,n){"use strict";var a,r=t(46),i=t(22),o=t(19),s=t(59),u=t(32),p=t(20),c=t(30),l=t(11),f=t(33),d=t(24),h=t(4),m=t(2),v=t(38),g=t(80),b=t(78),y=t(77),x=t(76),_=t(79),w=t(34),k=t(82)("__proto__"),E=t(8),S=t(7)(!1),C=Object.prototype,P=Array.prototype,A=P.slice,O=P.join,T=r.setDesc,M=r.getDesc,R=r.setDescs,j={};o||(a=!d(function(){return 7!=T(p("div"),"a",{get:function(){return 7}}).a}),r.setDesc=function(t,e,n){if(a)try{return T(t,e,n)}catch(r){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(h(t)[e]=n.value),t},r.getDesc=function(t,e){if(a)try{return M(t,e)}catch(n){}return c(t,e)?s(!C.propertyIsEnumerable.call(t,e),t[e]):void 0},r.setDescs=R=function(t,e){h(t);for(var n,a=r.getKeys(e),i=a.length,o=0;i>o;)r.setDesc(t,n=a[o++],e[n]);return t}),i(i.S+i.F*!o,"Object",{getOwnPropertyDescriptor:r.getDesc,defineProperty:r.setDesc,defineProperties:R});var L="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(","),D=L.concat("length","prototype"),N=L.length,F=function(){var t,e=p("iframe"),n=N,a=">";for(e.style.display="none",u.appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write("" - HTML += "" + continue + if((job_civilian_low & ASSISTANT) && (rank != "Assistant") && !jobban_isbanned(user, "Assistant")) + HTML += "[rank]" + continue + if(config.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 + HTML += "[rank]" + continue + if((rank in GLOB.command_positions) || (rank == "AI"))//Bold head jobs + HTML += "[rank]" + else + HTML += "[rank]" + + HTML += "" + continue + + HTML += "[prefLevelLabel]" + HTML += "" + + for(var/i = 1, i < (limit - index), i += 1) // Finish the column so it is even + HTML += "" + + HTML += "
" // Table within a table for alignment, also allows you to easily add more colomns. - HTML += "" - var/index = -1 - - //The job before the current job. I only use this to get the previous jobs color when I'm filling in blank rows. - var/datum/job/lastJob - - for(var/datum/job/job in SSjob.occupations) - - index += 1 - if((index >= limit) || (job.title in splitJobs)) - width += widthPerColumn - if((index < limit) && (lastJob != null)) - //If the cells were broken up by a job in the splitJob list then it will fill in the rest of the cells with - //the last job's selection color. Creating a rather nice effect. - for(var/i = 0, i < (limit - index), i += 1) - HTML += "" - HTML += "
  
" - index = 0 - - HTML += "" - continue + var/chat_toggles = TOGGLES_DEFAULT_CHAT + var/ghost_form = "ghost" + var/ghost_orbit = GHOST_ORBIT_CIRCLE + var/ghost_accs = GHOST_ACCS_DEFAULT_OPTION + var/ghost_others = GHOST_OTHERS_DEFAULT_OPTION + var/ghost_hud = 1 + var/inquisitive_ghost = 1 + var/allow_midround_antag = 1 + var/preferred_map = null + + var/uses_glasses_colour = 0 + + //character preferences + var/real_name //our character's name + var/be_random_name = 0 //whether we'll have a random name every round + var/be_random_body = 0 //whether we'll have a random body every round + var/gender = MALE //gender of character (well duh) + var/age = 30 //age of character + var/underwear = "Nude" //underwear type + var/undershirt = "Nude" //undershirt type + var/socks = "Nude" //socks type + var/backbag = DBACKPACK //backpack type + var/hair_style = "Bald" //Hair type + var/hair_color = "000" //Hair color + var/facial_hair_style = "Shaved" //Face hair type + var/facial_hair_color = "000" //Facial hair color + var/skin_tone = "caucasian1" //Skin color + var/eye_color = "000" //Eye color + var/datum/species/pref_species = new /datum/species/human() //Mutant race + var/list/features = list("mcolor" = "FFF", + "mcolor2" = "FFF", + "mcolor3" = "FFF", + "tail_lizard" = "Smooth", + "tail_human" = "None", + "snout" = "Round", + "horns" = "None", + "ears" = "None", + "wings" = "None", + "frills" = "None", + "spines" = "None", + "body_markings" = "None", + "mam_body_markings" = "None", + "mam_ears" = "None", + "mam_tail" = "None", + "mam_tail_animated" = "None", + "xenodorsal" = "None", + "xenohead" = "None", + "xenotail" = "None", + "legs" = "Normal Legs", + "taur" = "None", + "exhibitionist" = FALSE, + "genitals_use_skintone" = FALSE, + "has_cock" = FALSE, + "cock_shape" = "Human", + "cock_length" = 6, + "cock_girth_ratio" = COCK_GIRTH_RATIO_DEF, + "cock_color" = "fff", + "has_sheath" = FALSE, + "sheath_color" = "fff", + "has_balls" = FALSE, + "balls_internal" = FALSE, + "balls_color" = "fff", + "balls_amount" = 2, + "balls_sack_size" = BALLS_SACK_SIZE_DEF, + "balls_size" = BALLS_SIZE_DEF, + "balls_cum_rate" = CUM_RATE, + "balls_cum_mult" = CUM_RATE_MULT, + "balls_efficiency" = CUM_EFFICIENCY, + "balls_fluid" = "semen", + "has_ovi" = FALSE, + "ovi_shape" = "knotted", + "ovi_length" = 6, + "ovi_color" = "fff", + "has_eggsack" = FALSE, + "eggsack_internal" = TRUE, + "eggsack_color" = "fff", + "eggsack_size" = BALLS_SACK_SIZE_DEF, + "eggsack_egg_color" = "fff", + "eggsack_egg_size" = EGG_GIRTH_DEF, + "has_breasts" = FALSE, + "breasts_color" = "fff", + "breasts_size" = "C", + "breasts_shape" = "Pair", + "breasts_fluid" = "milk", + "has_vag" = FALSE, + "vag_shape" = "Human", + "vag_color" = "fff", + "vag_clits" = 1, + "vag_clit_diam" = 0.25, + "vag_clit_len" = 0.25, + "has_womb" = FALSE, + "womb_cum_rate" = CUM_RATE, + "womb_cum_mult" = CUM_RATE_MULT, + "womb_efficiency" = CUM_EFFICIENCY, + "womb_fluid" = "femcum", + "flavor_text" = "" + )//MAKE SURE TO UPDATE THE LIST IN MOBS.DM IF YOU'RE GOING TO ADD TO THIS LIST, OTHERWISE THINGS MIGHT GET FUCKEY + + var/list/custom_names = list("clown", "mime", "ai", "cyborg", "religion", "deity") + var/prefered_security_department = SEC_DEPT_RANDOM + + //Mob preview + var/icon/preview_icon = null + + //Jobs, uses bitflags + var/job_civilian_high = 0 + var/job_civilian_med = 0 + var/job_civilian_low = 0 + + var/job_medsci_high = 0 + var/job_medsci_med = 0 + var/job_medsci_low = 0 + + var/job_engsec_high = 0 + var/job_engsec_med = 0 + var/job_engsec_low = 0 + + // Want randomjob if preferences already filled - Donkie + var/joblessrole = BERANDOMJOB //defaults to 1 for fewer assistants + + // 0 = character settings, 1 = game preferences, 2 = character appearance + var/current_tab = 0 + + // OOC Metadata: + var/metadata = "" + + var/unlock_content = 0 + + var/list/ignoring = list() + + var/clientfps = 0 + + var/parallax + + var/uplink_spawn_loc = UPLINK_PDA + + var/list/exp + var/list/menuoptions + + //citadel code + var/arousable = TRUE //Allows players to disable arousal from the character creation menu + +/datum/preferences/New(client/C) + parent = C + custom_names["ai"] = pick(GLOB.ai_names) + custom_names["cyborg"] = pick(GLOB.ai_names) + custom_names["clown"] = pick(GLOB.clown_names) + custom_names["mime"] = pick(GLOB.mime_names) + if(istype(C)) + if(!IsGuestKey(C.key)) + load_path(C.ckey) + unlock_content = C.IsByondMember() + if(unlock_content) + max_save_slots = 16 + var/loaded_preferences_successfully = load_preferences() + if(loaded_preferences_successfully) + if(load_character()) + return + //we couldn't load character data so just randomize the character appearance + name + random_character() //let's create a random character then - rather than a fat, bald and naked man. + real_name = pref_species.random_name(gender,1) + if(!loaded_preferences_successfully) + save_preferences() + save_character() //let's save this new random character so it doesn't keep generating new ones. + menuoptions = list() + return + +/datum/preferences/proc/ShowChoices(mob/user) + if(!user || !user.client) + return + if(current_tab == 2) + update_preview_icon(nude=TRUE) + else + update_preview_icon(nude=FALSE) + user << browse_rsc(preview_icon, "previewicon.png") + var/dat = "
" + + dat += "Character Settings" + dat += "Character Appearance" + dat += "Game Preferences" + + if(!path) + dat += "
Please create an account to save your preferences
" + + dat += "
" + + dat += "
" + + switch(current_tab) + if (0) // Character Settings# + if(path) + var/savefile/S = new /savefile(path) + if(S) + dat += "
" + var/name + for(var/i=1, i<=max_save_slots, i++) + S.cd = "/character[i]" + S["real_name"] >> name + if(!name) + name = "Character[i]" + //if(i!=1) dat += " | " + dat += "[name] " + dat += "
" + + dat += "

Occupation Choices

" + dat += "Set Occupation Preferences
" + dat += "

Identity

" + dat += "
" - var/rank = job.title - lastJob = job - if(jobban_isbanned(user, rank)) - HTML += "[rank] BANNED
" + + dat += "
" + if(jobban_isbanned(user, "appearance")) + dat += "You are banned from using custom names and appearances. You can continue to adjust your characters, but you will be randomised once you join the game.
" + dat += "Random Name " + dat += "Always Random Name: [be_random_name ? "Yes" : "No"]
" + + dat += "Name: " + dat += "[real_name]
" + + dat += "Gender: [gender == MALE ? "Male" : "Female"]
" + dat += "Age: [age]
" + dat += "Arousal:[arousable == TRUE ? "Enabled" : "Disabled"]
" + dat += "Exhibitionist:[features["exhibitionist"] == TRUE ? "Yes" : "No"]
" + dat += "Special Names:
" + dat += "Clown: [custom_names["clown"]] " + dat += "Mime:[custom_names["mime"]]
" + dat += "AI: [custom_names["ai"]] " + dat += "Cyborg: [custom_names["cyborg"]]
" + dat += "Chaplain religion: [custom_names["religion"]] " + dat += "Chaplain deity: [custom_names["deity"]]
" + + dat += "Custom job preferences:
" + dat += "Prefered security department: [prefered_security_department]
" + + dat += "
" + + dat += "
" +// dat += "Size: [character_size]
" + dat += "
" + + if (1) // Game Preferences + dat += "
" + dat += "

General Settings

" + dat += "UI Style: [UI_style]
" + dat += "Keybindings: [(hotkeys) ? "Hotkeys" : "Default"]
" + dat += "Action Buttons: [(buttons_locked) ? "Locked In Place" : "Unlocked"]
" + dat += "tgui Style: [(tgui_fancy) ? "Fancy" : "No Frills"]
" + dat += "tgui Monitors: [(tgui_lock) ? "Primary" : "All"]
" + dat += "Window Flashing: [(windowflashing) ? "Yes" : "No"]
" + dat += "Play admin midis: [(toggles & SOUND_MIDI) ? "Yes" : "No"]
" + dat += "Play lobby music: [(toggles & SOUND_LOBBY) ? "Yes" : "No"]
" + dat += "Ghost ears: [(chat_toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]
" + dat += "Ghost sight: [(chat_toggles & CHAT_GHOSTSIGHT) ? "All Emotes" : "Nearest Creatures"]
" + dat += "Ghost whispers: [(chat_toggles & CHAT_GHOSTWHISPER) ? "All Speech" : "Nearest Creatures"]
" + dat += "Ghost radio: [(chat_toggles & CHAT_GHOSTRADIO) ? "Yes" : "No"]
" + 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) + dat += "OOC Notes: Edit
" + + if(user.client) + if(user.client.holder) + dat += "Adminhelp Sound: [(toggles & SOUND_ADMINHELP)?"On":"Off"]
" + dat += "Announce Login: [(toggles & ANNOUNCE_LOGIN)?"On":"Off"]
" + + if(unlock_content || check_rights_for(user.client, R_ADMIN)) + dat += "OOC:     Change
" + + if(unlock_content) + dat += "BYOND Membership Publicity: [(toggles & MEMBER_PUBLIC) ? "Public" : "Hidden"]
" + dat += "Ghost Form: [ghost_form]
" + dat += "Ghost Orbit: [ghost_orbit]
" + + var/button_name = "If you see this something went wrong." + switch(ghost_accs) + if(GHOST_ACCS_FULL) + button_name = GHOST_ACCS_FULL_NAME + if(GHOST_ACCS_DIR) + button_name = GHOST_ACCS_DIR_NAME + if(GHOST_ACCS_NONE) + button_name = GHOST_ACCS_NONE_NAME + + dat += "Ghost Accessories: [button_name]
" + + switch(ghost_others) + if(GHOST_OTHERS_THEIR_SETTING) + button_name = GHOST_OTHERS_THEIR_SETTING_NAME + if(GHOST_OTHERS_DEFAULT_SPRITE) + button_name = GHOST_OTHERS_DEFAULT_SPRITE_NAME + if(GHOST_OTHERS_SIMPLE) + button_name = GHOST_OTHERS_SIMPLE_NAME + + dat += "Ghosts of Others: [button_name]
" + + if (config.maprotation) + var/p_map = preferred_map + if (!p_map) + p_map = "Default" + if (config.defaultmap) + p_map += " ([config.defaultmap.map_name])" + else + if (p_map in config.maplist) + var/datum/map_config/VM = config.maplist[p_map] + if (!VM) + p_map += " (No longer exists)" + else + p_map = VM.map_name + else + p_map += " (No longer exists)" + if(config.allow_map_voting) + dat += "Preferred Map: [p_map]
" + + dat += "FPS: [clientfps]
" + + dat += "Parallax (Fancy Space): " + switch (parallax) + if (PARALLAX_LOW) + dat += "Low" + if (PARALLAX_MED) + dat += "Medium" + if (PARALLAX_INSANE) + dat += "Insane" + if (PARALLAX_DISABLE) + dat += "Disabled" + else + dat += "High" + dat += "
" + + dat += "
" + + dat += "

Special Role Settings

" + + if(jobban_isbanned(user, "Syndicate")) + dat += "You are banned from antagonist roles." + src.be_special = list() + + + for (var/i in GLOB.special_roles) + if(jobban_isbanned(user, i)) + 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 + 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) + + if(days_remaining) + dat += "Be [capitalize(i)]: \[IN [days_remaining] DAYS]
" + else + dat += "Be [capitalize(i)]: [(i in be_special) ? "Yes" : "No"]
" + + dat += "
" + + //Character Appearance + if(2) + dat += "" + */ + + + dat += "
" + dat += "

" + dat += "Set Flavor Text
" + if(lentext(features["flavor_text"]) <= 40) + if(!lentext(features["flavor_text"])) + dat += "\[...\]" + else + 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 + dat += "

Body

" + dat += "Gender: [gender == MALE ? "Male" : "Female"]
" + dat += "Species:[pref_species.id]
" + dat += "Random Body
" + dat += "Always Random Body: [be_random_body ? "Yes" : "No"]
" + if((MUTCOLORS in pref_species.species_traits) || (MUTCOLORS_PARTSONLY in pref_species.species_traits)) + dat += "Primary Color:     Change
" + dat += "Secondary Color:     Change
" + dat += "Tertiary Color:     Change
" + if(pref_species.use_skintones) + dat += "Skin Tone: [skin_tone]
" + dat += "Genitals Use Skintone:[features["genitals_use_skintone"] == TRUE ? "Enabled" : "Disabled"]
" + + if(HAIR in pref_species.species_traits) + dat += "Hair Style: [hair_style]
" + dat += "Hair Color:     Change
" + dat += "Facial Hair Style: [facial_hair_style]
" + dat += "Facial Hair Color:     Change
" + if(EYECOLOR in pref_species.species_traits) + dat += "Eye Color:     Change
" + if("tail_lizard" in pref_species.mutant_bodyparts) + dat += "Tail: [features["tail_lizard"]]
" + else if("mam_tail" in pref_species.mutant_bodyparts) + dat += "Tail: [features["mam_tail"]]
" + else if("tail_human" in pref_species.mutant_bodyparts) + dat += "Tail: [features["tail_human"]]
" + if("snout" in pref_species.mutant_bodyparts) + dat += "Snout: [features["snout"]]
" + if("horns" in pref_species.mutant_bodyparts) + dat += "Snout: [features["horns"]]
" + if("frills" in pref_species.mutant_bodyparts) + dat += "Frills: [features["frills"]]
" + if("spines" in pref_species.mutant_bodyparts) + dat += "Spines: [features["spines"]]
" + if("body_markings" in pref_species.mutant_bodyparts) + dat += "Body Markings: [features["body_markings"]]
" + else if("mam_body_markings" in pref_species.mutant_bodyparts) + dat += "Body Markings: [features["mam_body_markings"]]
" + if("mam_ears" in pref_species.mutant_bodyparts) + dat += "Ears: [features["mam_ears"]]
" + else if("ears" in pref_species.mutant_bodyparts) + dat += "Ears: [features["ears"]]
" + if("legs" in pref_species.mutant_bodyparts) + dat += "Legs: [features["legs"]]
" + if("taur" in pref_species.mutant_bodyparts) + dat += "Taur: [features["taur"]]
" + if("wings" in pref_species.mutant_bodyparts && GLOB.r_wings_list.len >1) + dat += "Wings: [features["wings"]]
" + if("xenohead" in pref_species.mutant_bodyparts) + dat += "Caste: [features["xenohead"]]
" + if("xenotail" in pref_species.mutant_bodyparts) + dat += "Tail: [features["xenotail"]]
" + if("xenodorsal" in pref_species.mutant_bodyparts) + dat += "Dorsal Tubes: [features["xenodorsal"]]
" + + dat += "
" + + + dat += "

Clothing & Equipment

" +//underwear will be refactored later so it fits in with other wearable equipment and isn't just an overlay +// dat += "Underwear:[underwear]
" +// dat += "Undershirt:[undershirt]
" +// dat += "Socks:[socks]
" + dat += "Backpack:[backbag]
" + dat += "Uplink Location:[uplink_spawn_loc]
" + + dat += "

Genitals

" + if(NOGENITALS in pref_species.species_traits) + dat += "Your species ([pref_species.name]) does not support genitals!
" + else + dat += "Has Penis:[features["has_cock"] == TRUE ? "Yes" : "No"]
" + if(features["has_cock"] == TRUE) + if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) + dat += "Penis Color:   (Skin tone overriding)
" + else + dat += "Penis Color:    Change
" +// dat += "
" + dat += "Penis Shape: [features["cock_shape"]]
" + dat += "Penis Length: [features["cock_length"]] inch(es)
" + dat += "Has Testicles:[features["has_balls"] == TRUE ? "Yes" : "No"]
" + if(features["has_balls"] == TRUE) + if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) + dat += "Testicles Color:   (Skin tone overriding)
" + else + dat += "Testicles Color:    Change
" + dat += "Has Vagina:[features["has_vag"] == TRUE ? "Yes" : "No"]
" + if(features["has_vag"]) + dat += "Vagina Type: [features["vag_shape"]]
" + if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) + dat += "Vagina Color:   (Skin tone overriding)
" + else + dat += "Vagina Color:    Change
" + dat += "Has Womb:[features["has_womb"] == TRUE ? "Yes" : "No"]
" + dat += "Has Breasts:[features["has_breasts"] == TRUE ? "Yes" : "No"]
" + if(features["has_breasts"]) + if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) + dat += "Color:   (Skin tone overriding)
" + else + dat += "Color:    Change
" + dat += "Cup Size:[features["breasts_size"]]
" + dat += "Breast Shape:[features["breasts_shape"]]
" + /* + dat += "

Ovipositor

" + dat += "Has Ovipositor:[features["has_ovi"] == TRUE ? "Yes" : "No"]" + if(features["has_ovi"]) + dat += "Ovi Color:    Change" + dat += "

Eggsack

" + dat += "Has Eggsack:[features["has_eggsack"] == TRUE ? "Yes" : "No"]
" + if(features["has_eggsack"] == TRUE) + dat += "Color:    Change" + dat += "Egg Color:    Change" + dat += "Egg Size:[features["eggsack_egg_size"]]\" Diameter" + + dat += "
" + dat += "
" + + if(!IsGuestKey(user.key)) + dat += "Undo " + dat += "Save Setup " + + dat += "Reset Setup" + dat += "
" + + var/datum/browser/popup = new(user, "preferences", "
Character Setup
", 640, 770) + popup.set_content(dat) + popup.open(0) + +/datum/preferences/proc/SetChoices(mob/user, limit = 17, list/splitJobs = list("Chief Engineer"), widthPerColumn = 295, height = 620) + if(!SSjob) + return + + //limit - The amount of jobs allowed per column. Defaults to 17 to make it look nice. + //splitJobs - Allows you split the table by job. You can make different tables for each department by including their heads. Defaults to CE to make it look nice. + //widthPerColumn - Screen's width for every column. + //height - Screen's height. + + var/width = widthPerColumn + + var/HTML = "
" + if(SSjob.occupations.len <= 0) + HTML += "The job ticker is not yet finished creating jobs, please try again later" + HTML += "
Done

" // Easier to press up here. + + else + HTML += "Choose occupation chances
" + HTML += "
Left-click to raise an occupation preference, right-click to lower it.
" + HTML += "
Done

" // Easier to press up here. + HTML += "" + HTML += "
" // Table within a table for alignment, also allows you to easily add more colomns. + HTML += "" + var/index = -1 + + //The job before the current job. I only use this to get the previous jobs color when I'm filling in blank rows. + var/datum/job/lastJob + + for(var/datum/job/job in SSjob.occupations) + + index += 1 + if((index >= limit) || (job.title in splitJobs)) + width += widthPerColumn + if((index < limit) && (lastJob != null)) + //If the cells were broken up by a job in the splitJob list then it will fill in the rest of the cells with + //the last job's selection color. Creating a rather nice effect. + for(var/i = 0, i < (limit - index), i += 1) + HTML += "" + HTML += "
  
" + index = 0 + + HTML += "" + continue var/required_playtime_remaining = job.required_playtime_remaining(user.client) if(required_playtime_remaining) HTML += "[rank]" continue - if(!job.player_old_enough(user.client)) - var/available_in_days = job.available_in_days(user.client) - HTML += "[rank]" - continue - if((job_civilian_low & ASSISTANT) && (rank != "Assistant") && !jobban_isbanned(user, "Assistant")) - HTML += "[rank]" - continue - if(config.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 - HTML += "[rank]" - continue - if((rank in GLOB.command_positions) || (rank == "AI"))//Bold head jobs - HTML += "[rank]" - else - HTML += "[rank]" - - HTML += "" - continue - - HTML += "[prefLevelLabel]" - HTML += "" - - for(var/i = 1, i < (limit - index), i += 1) // Finish the column so it is even - HTML += "" - - HTML += "
" + var/rank = job.title + lastJob = job + if(jobban_isbanned(user, rank)) + HTML += "[rank] BANNED
\[ [get_exp_format(required_playtime_remaining)] as [job.get_exp_req_type()] \]
\[IN [(available_in_days)] DAYS\]
\[MUTANT\]
\[NON-HUMAN\]
" - - var/prefLevelLabel = "ERROR" - var/prefLevelColor = "pink" - var/prefUpperLevel = -1 // level to assign on left click - var/prefLowerLevel = -1 // level to assign on right click - - if(GetJobDepartment(job, 1) & job.flag) - prefLevelLabel = "High" - prefLevelColor = "slateblue" - prefUpperLevel = 4 - prefLowerLevel = 2 - else if(GetJobDepartment(job, 2) & job.flag) - prefLevelLabel = "Medium" - prefLevelColor = "green" - prefUpperLevel = 1 - prefLowerLevel = 3 - else if(GetJobDepartment(job, 3) & job.flag) - prefLevelLabel = "Low" - prefLevelColor = "orange" - prefUpperLevel = 2 - prefLowerLevel = 4 - else - prefLevelLabel = "NEVER" - prefLevelColor = "red" - prefUpperLevel = 3 - prefLowerLevel = 1 - - - HTML += "" - - if(rank == "Assistant")//Assistant is special - if(job_civilian_low & ASSISTANT) - HTML += "Yes" - else - HTML += "No" - HTML += "
  
" - HTML += "
" - - var/message = "Be an Assistant if preferences unavailable" - if(joblessrole == BERANDOMJOB) - message = "Get random job if preferences unavailable" - else if(joblessrole == RETURNTOLOBBY) - message = "Return to lobby if preferences unavailable" - HTML += "

[message]
" - HTML += "
Reset Preferences
" - - user << browse(null, "window=preferences") - var/datum/browser/popup = new(user, "mob_occupation", "
Occupation Preferences
", width, height) - popup.set_window_options("can_close=0") - popup.set_content(HTML) - popup.open(0) - return - -/datum/preferences/proc/SetJobPreferenceLevel(datum/job/job, level) - if (!job) - return 0 - - if (level == 1) // to high - // remove any other job(s) set to high - job_civilian_med |= job_civilian_high - job_engsec_med |= job_engsec_high - job_medsci_med |= job_medsci_high - job_civilian_high = 0 - job_engsec_high = 0 - job_medsci_high = 0 - - if (job.department_flag == CIVILIAN) - job_civilian_low &= ~job.flag - job_civilian_med &= ~job.flag - job_civilian_high &= ~job.flag - - switch(level) - if (1) - job_civilian_high |= job.flag - if (2) - job_civilian_med |= job.flag - if (3) - job_civilian_low |= job.flag - - return 1 - else if (job.department_flag == ENGSEC) - job_engsec_low &= ~job.flag - job_engsec_med &= ~job.flag - job_engsec_high &= ~job.flag - - switch(level) - if (1) - job_engsec_high |= job.flag - if (2) - job_engsec_med |= job.flag - if (3) - job_engsec_low |= job.flag - - return 1 - else if (job.department_flag == MEDSCI) - job_medsci_low &= ~job.flag - job_medsci_med &= ~job.flag - job_medsci_high &= ~job.flag - - switch(level) - if (1) - job_medsci_high |= job.flag - if (2) - job_medsci_med |= job.flag - if (3) - job_medsci_low |= job.flag - - return 1 - - return 0 - -/datum/preferences/proc/UpdateJobPreference(mob/user, role, desiredLvl) - if(!SSjob || SSjob.occupations.len <= 0) - return - var/datum/job/job = SSjob.GetJob(role) - - if(!job) - user << browse(null, "window=mob_occupation") - ShowChoices(user) - return - - if (!isnum(desiredLvl)) - to_chat(user, "UpdateJobPreference - desired level was not a number. Please notify coders!") - ShowChoices(user) - return - - if(role == "Assistant") - if(job_civilian_low & job.flag) - job_civilian_low &= ~job.flag - else - job_civilian_low |= job.flag - SetChoices(user) - return 1 - - SetJobPreferenceLevel(job, desiredLvl) - SetChoices(user) - - return 1 - - -/datum/preferences/proc/ResetJobs() - - job_civilian_high = 0 - job_civilian_med = 0 - job_civilian_low = 0 - - job_medsci_high = 0 - job_medsci_med = 0 - job_medsci_low = 0 - - job_engsec_high = 0 - job_engsec_med = 0 - job_engsec_low = 0 - - -/datum/preferences/proc/GetJobDepartment(datum/job/job, level) - if(!job || !level) - return 0 - switch(job.department_flag) - if(CIVILIAN) - switch(level) - if(1) - return job_civilian_high - if(2) - return job_civilian_med - if(3) - return job_civilian_low - if(MEDSCI) - switch(level) - if(1) - return job_medsci_high - if(2) - return job_medsci_med - if(3) - return job_medsci_low - if(ENGSEC) - switch(level) - if(1) - return job_engsec_high - if(2) - return job_engsec_med - if(3) - return job_engsec_low - return 0 - -/datum/preferences/proc/process_link(mob/user, list/href_list) - if(href_list["jobbancheck"]) - var/job = sanitizeSQL(href_list["jobbancheck"]) - var/sql_ckey = sanitizeSQL(user.ckey) - var/datum/DBQuery/query_get_jobban = SSdbcore.NewQuery("SELECT reason, bantime, duration, expiration_time, a_ckey FROM [format_table_name("ban")] WHERE ckey = '[sql_ckey]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned) AND job = '[job]'") - if(!query_get_jobban.warn_execute()) - return - if(query_get_jobban.NextRow()) - var/reason = query_get_jobban.item[1] - var/bantime = query_get_jobban.item[2] - var/duration = query_get_jobban.item[3] - var/expiration_time = query_get_jobban.item[4] - var/a_ckey = query_get_jobban.item[5] - var/text - text = "You, or another user of this computer, ([user.ckey]) is banned from playing [job]. The ban reason is:
[reason]
This ban was applied by [a_ckey] on [bantime]" - if(text2num(duration) > 0) - text += ". The ban is for [duration] minutes and expires on [expiration_time] (server time)" - text += ".
" - to_chat(user, text) - return - - if(href_list["preference"] == "job") - switch(href_list["task"]) - if("close") - user << browse(null, "window=mob_occupation") - ShowChoices(user) - if("reset") - ResetJobs() - SetChoices(user) - if("random") - switch(joblessrole) - if(RETURNTOLOBBY) - if(jobban_isbanned(user, "Assistant")) - joblessrole = BERANDOMJOB - else - joblessrole = BEASSISTANT - if(BEASSISTANT) - joblessrole = BERANDOMJOB - if(BERANDOMJOB) - joblessrole = RETURNTOLOBBY - SetChoices(user) - if("setJobLevel") - UpdateJobPreference(user, href_list["text"], text2num(href_list["level"])) - else - SetChoices(user) - return 1 - - switch(href_list["task"]) - if("random") - switch(href_list["preference"]) - if("name") - real_name = pref_species.random_name(gender,1) - if("age") - age = rand(AGE_MIN, AGE_MAX) - if("hair") - hair_color = random_short_color() - if("hair_style") - hair_style = random_hair_style(gender) - if("facial") - facial_hair_color = random_short_color() - if("facial_hair_style") - facial_hair_style = random_facial_hair_style(gender) - if("underwear") - underwear = random_underwear(gender) - if("undershirt") - undershirt = random_undershirt(gender) - if("socks") - socks = random_socks() - if("eyes") - eye_color = random_eye_color() - if("s_tone") - skin_tone = random_skin_tone() - if("bag") - backbag = pick(GLOB.backbaglist) - if("all") - random_character() - - if("input") - switch(href_list["preference"]) - if("ghostform") - if(unlock_content) - var/new_form = input(user, "Thanks for supporting BYOND - Choose your ghostly form:","Thanks for supporting BYOND",null) as null|anything in GLOB.ghost_forms - if(new_form) - ghost_form = new_form - if("ghostorbit") - if(unlock_content) - var/new_orbit = input(user, "Thanks for supporting BYOND - Choose your ghostly orbit:","Thanks for supporting BYOND", null) as null|anything in GLOB.ghost_orbits - if(new_orbit) - ghost_orbit = new_orbit - - if("ghostaccs") - var/new_ghost_accs = alert("Do you want your ghost to show full accessories where possible, hide accessories but still use the directional sprites where possible, or also ignore the directions and stick to the default sprites?",,GHOST_ACCS_FULL_NAME, GHOST_ACCS_DIR_NAME, GHOST_ACCS_NONE_NAME) - switch(new_ghost_accs) - if(GHOST_ACCS_FULL_NAME) - ghost_accs = GHOST_ACCS_FULL - if(GHOST_ACCS_DIR_NAME) - ghost_accs = GHOST_ACCS_DIR - if(GHOST_ACCS_NONE_NAME) - ghost_accs = GHOST_ACCS_NONE - - if("ghostothers") - var/new_ghost_others = alert("Do you want the ghosts of others to show up as their own setting, as their default sprites or always as the default white ghost?",,GHOST_OTHERS_THEIR_SETTING_NAME, GHOST_OTHERS_DEFAULT_SPRITE_NAME, GHOST_OTHERS_SIMPLE_NAME) - switch(new_ghost_others) - if(GHOST_OTHERS_THEIR_SETTING_NAME) - ghost_others = GHOST_OTHERS_THEIR_SETTING - if(GHOST_OTHERS_DEFAULT_SPRITE_NAME) - ghost_others = GHOST_OTHERS_DEFAULT_SPRITE - if(GHOST_OTHERS_SIMPLE_NAME) - ghost_others = GHOST_OTHERS_SIMPLE - - if("name") - var/new_name = reject_bad_name( input(user, "Choose your character's name:", "Character Preference") as text|null ) - if(new_name) - real_name = new_name - else - to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .") - - if("age") - var/new_age = input(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX])", "Character Preference") as num|null - if(new_age) - age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN) - - if("flavor_text") - var/msg = input(usr,"Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!","Flavor Text",html_decode(features["flavor_text"])) as message - if(msg != null) - msg = copytext(msg, 1, MAX_MESSAGE_LEN) - msg = html_encode(msg) - features["flavor_text"] = msg - - if("metadata") - var/new_metadata = input(user, "Enter any information you'd like others to see, such as Roleplay-preferences:", "Game Preference" , metadata) as message|null - if(new_metadata) - metadata = sanitize(copytext(new_metadata,1,MAX_MESSAGE_LEN)) - - if("hair") - var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference") as null|color - if(new_hair) - hair_color = sanitize_hexcolor(new_hair) - - - if("hair_style") - var/new_hair_style - if(gender == MALE) - new_hair_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in GLOB.hair_styles_male_list - else - new_hair_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in GLOB.hair_styles_female_list - if(new_hair_style) - hair_style = new_hair_style - - if("next_hair_style") - if (gender == MALE) - hair_style = next_list_item(hair_style, GLOB.hair_styles_male_list) - else - hair_style = next_list_item(hair_style, GLOB.hair_styles_female_list) - - if("previous_hair_style") - if (gender == MALE) - hair_style = previous_list_item(hair_style, GLOB.hair_styles_male_list) - else - hair_style = previous_list_item(hair_style, GLOB.hair_styles_female_list) - - if("facial") - var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference") as null|color - if(new_facial) - facial_hair_color = sanitize_hexcolor(new_facial) - - if("facial_hair_style") - var/new_facial_hair_style - if(gender == MALE) - new_facial_hair_style = input(user, "Choose your character's facial-hair style:", "Character Preference") as null|anything in GLOB.facial_hair_styles_male_list - else - new_facial_hair_style = input(user, "Choose your character's facial-hair style:", "Character Preference") as null|anything in GLOB.facial_hair_styles_female_list - if(new_facial_hair_style) - facial_hair_style = new_facial_hair_style - - if("next_facehair_style") - if (gender == MALE) - facial_hair_style = next_list_item(facial_hair_style, GLOB.facial_hair_styles_male_list) - else - facial_hair_style = next_list_item(facial_hair_style, GLOB.facial_hair_styles_female_list) - - if("previous_facehair_style") - if (gender == MALE) - facial_hair_style = previous_list_item(facial_hair_style, GLOB.facial_hair_styles_male_list) - else - facial_hair_style = previous_list_item(facial_hair_style, GLOB.facial_hair_styles_female_list) - - if("underwear") - var/new_underwear - if(gender == MALE) - new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_m - else - new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_f - if(new_underwear) - underwear = new_underwear - - if("undershirt") - var/new_undershirt - if(gender == MALE) - new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_m - else - new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_f - if(new_undershirt) - undershirt = new_undershirt - - if("socks") - var/new_socks - new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in GLOB.socks_list - if(new_socks) - socks = new_socks - - if("eyes") - var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference") as color|null - if(new_eyes) - eye_color = sanitize_hexcolor(new_eyes) - - if("species") - - var/result = input(user, "Select a species", "Species Selection") as null|anything in GLOB.roundstart_species - - if(result) - var/newtype = GLOB.roundstart_species[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"]) - if(features["mcolor"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3])) - features["mcolor"] = pref_species.default_color - if(features["mcolor2"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3])) - features["mcolor2"] = pref_species.default_color - if(features["mcolor3"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3])) - features["mcolor3"] = pref_species.default_color - - if("mutant_color") - var/new_mutantcolor = input(user, "Choose your character's primary alien/mutant color:", "Character Preference") as color|null - if(new_mutantcolor) - var/temp_hsv = RGBtoHSV(new_mutantcolor) - if(new_mutantcolor == "#000000") - features["mcolor"] = pref_species.default_color - else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin - features["mcolor"] = sanitize_hexcolor(new_mutantcolor) - else - to_chat(user, "Invalid color. Your color is not bright enough.") - - if("mutant_color2") - var/new_mutantcolor = input(user, "Choose your character's secondary alien/mutant color:", "Character Preference") as color|null - if(new_mutantcolor) - var/temp_hsv = RGBtoHSV(new_mutantcolor) - if(new_mutantcolor == "#000000") - features["mcolor2"] = pref_species.default_color - else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin - features["mcolor2"] = sanitize_hexcolor(new_mutantcolor) - else - to_chat(user, "Invalid color. Your color is not bright enough.") - - if("mutant_color3") - var/new_mutantcolor = input(user, "Choose your character's tertiary alien/mutant color:", "Character Preference") as color|null - if(new_mutantcolor) - var/temp_hsv = RGBtoHSV(new_mutantcolor) - if(new_mutantcolor == "#000000") - features["mcolor3"] = pref_species.default_color - else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin - features["mcolor3"] = sanitize_hexcolor(new_mutantcolor) - else - to_chat(user, "Invalid color. Your color is not bright enough.") - - if("tail_lizard") - var/new_tail - new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.tails_list_lizard - if(new_tail) - features["tail_lizard"] = new_tail - if(new_tail != "None") - features["taur"] = "None" - - if("tail_human") - var/new_tail - new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.tails_list_human - if(new_tail) - features["tail_human"] = new_tail - if(new_tail != "None") - features["taur"] = "None" - if("mam_tail") - var/new_tail - new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.mam_tails_list - if(new_tail) - features["mam_tail"] = new_tail - if(new_tail != "None") - features["taur"] = "None" - - if("taur") - var/new_taur - new_taur = input(user, "Choose your character's tauric body:", "Character Preference") as null|anything in GLOB.taur_list - if(new_taur) - features["taur"] = new_taur - if(new_taur != "None") - features["mam_tail"] = "None" - features["xenotail"] = "None" - -/* Doesn't exist yet. will include facial overlays to mimic 5th port species heads. - if("mam_snout") - var/new_snout - new_snout = input(user, "Choose your character's snout:", "Character Preference") as null|anything in GLOB.mam_snouts_list - if(new_snout) - features["snout"] = new_snout -*/ - - if("snout") - var/new_snout - new_snout = input(user, "Choose your character's snout:", "Character Preference") as null|anything in GLOB.snouts_list - if(new_snout) - features["snout"] = new_snout - - if("horns") - var/new_horns - new_horns = input(user, "Choose your character's horns:", "Character Preference") as null|anything in GLOB.horns_list - if(new_horns) - features["horns"] = new_horns - - if("mam_ears") - var/new_ears - new_ears = input(user, "Choose your character's ears:", "Character Preference") as null|anything in GLOB.mam_ears_list - if(new_ears) - features["mam_ears"] = new_ears - - if("ears") - var/new_ears - new_ears = input(user, "Choose your character's ears:", "Character Preference") as null|anything in GLOB.ears_list - if(new_ears) - features["ears"] = new_ears - - if("wings") - var/new_wings - new_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.r_wings_list - if(new_wings) - features["wings"] = new_wings - - if("frills") - var/new_frills - new_frills = input(user, "Choose your character's frills:", "Character Preference") as null|anything in GLOB.frills_list - if(new_frills) - features["frills"] = new_frills - - if("spines") - var/new_spines - new_spines = input(user, "Choose your character's spines:", "Character Preference") as null|anything in GLOB.spines_list - if(new_spines) - features["spines"] = new_spines - - if("body_markings") - var/new_body_markings - new_body_markings = input(user, "Choose your character's body markings:", "Character Preference") as null|anything in GLOB.body_markings_list - if(new_body_markings) - features["body_markings"] = new_body_markings - - if("mam_body_markings") - var/new_mam_body_markings - new_mam_body_markings = input(user, "Choose your character's body markings:", "Character Preference") as null|anything in GLOB.mam_body_markings_list - if(new_mam_body_markings) - features["mam_body_markings"] = new_mam_body_markings - - //Xeno Bodyparts - if("xenohead")//Head or caste type - var/new_head - new_head = input(user, "Choose your character's caste:", "Character Preference") as null|anything in GLOB.xeno_head_list - if(new_head) - features["xenohead"] = new_head - - if("xenotail")//Currently one one type, more maybe later if someone sprites them. Might include animated variants in the future. - var/new_tail - new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.xeno_tail_list - if(new_tail) - features["xenotail"] = new_tail - - if("xenodorsal") - var/new_dors - new_dors = input(user, "Choose your character's dorsal tube type:", "Character Preference") as null|anything in GLOB.xeno_dorsal_list - if(new_dors) - features["xenodorsal"] = new_dors - - if("legs") - var/new_legs - new_legs = input(user, "Choose your character's legs:", "Character Preference") as null|anything in GLOB.legs_list - if(new_legs) - features["legs"] = new_legs - - if("s_tone") - var/new_s_tone = input(user, "Choose your character's skin-tone:", "Character Preference") as null|anything in GLOB.skin_tones - if(new_s_tone) - skin_tone = new_s_tone - - if("ooccolor") - var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference") as color|null - if(new_ooccolor) - ooccolor = sanitize_ooccolor(new_ooccolor) - - if("bag") - var/new_backbag = input(user, "Choose your character's style of bag:", "Character Preference") as null|anything in GLOB.backbaglist - if(new_backbag) - backbag = new_backbag - - if("uplink_loc") - var/new_loc = input(user, "Choose your character's traitor uplink spawn location:", "Character Preference") as null|anything in GLOB.uplink_spawn_loc_list - if(new_loc) - uplink_spawn_loc = new_loc - - if("clown_name") - var/new_clown_name = reject_bad_name( input(user, "Choose your character's clown name:", "Character Preference") as text|null ) - if(new_clown_name) - custom_names["clown"] = new_clown_name - else - to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .") - - if("mime_name") - var/new_mime_name = reject_bad_name( input(user, "Choose your character's mime name:", "Character Preference") as text|null ) - if(new_mime_name) - custom_names["mime"] = new_mime_name - else - to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .") - - if("ai_name") - var/new_ai_name = reject_bad_name( input(user, "Choose your character's AI name:", "Character Preference") as text|null, 1 ) - if(new_ai_name) - custom_names["ai"] = new_ai_name - else - to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, 0-9, -, ' and .") - - if("cyborg_name") - var/new_cyborg_name = reject_bad_name( input(user, "Choose your character's cyborg name:", "Character Preference") as text|null, 1 ) - if(new_cyborg_name) - custom_names["cyborg"] = new_cyborg_name - else - to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, 0-9, -, ' and .") - - if("religion_name") - var/new_religion_name = reject_bad_name( input(user, "Choose your character's religion:", "Character Preference") as text|null ) - if(new_religion_name) - custom_names["religion"] = new_religion_name - else - to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .") - - if("deity_name") - var/new_deity_name = reject_bad_name( input(user, "Choose your character's deity:", "Character Preference") as text|null ) - if(new_deity_name) - custom_names["deity"] = new_deity_name - else - to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .") - - if("sec_dept") - var/department = input(user, "Choose your prefered security department:", "Security Departments") as null|anything in GLOB.security_depts_prefs - if(department) - prefered_security_department = department - - if ("preferred_map") - var/maplist = list() - var/default = "Default" - if (config.defaultmap) - default += " ([config.defaultmap.map_name])" - for (var/M in config.maplist) - var/datum/map_config/VM = config.maplist[M] - var/friendlyname = "[VM.map_name] " - if (VM.voteweight <= 0) - friendlyname += " (disabled)" - maplist[friendlyname] = VM.map_name - maplist[default] = null - var/pickedmap = input(user, "Choose your preferred map. This will be used to help weight random map selection.", "Character Preference") as null|anything in maplist - if (pickedmap) - preferred_map = maplist[pickedmap] - - if ("clientfps") - var/version_message - if (user.client && user.client.byond_version < 511) - version_message = "\nYou need to be using byond version 511 or later to take advantage of this feature, your version of [user.client.byond_version] is too low" - if (world.byond_version < 511) - version_message += "\nThis server does not currently support client side fps. You can set now for when it does." - var/desiredfps = input(user, "Choose your desired fps.[version_message]\n(0 = synced with server tick rate (currently:[world.fps]))", "Character Preference", clientfps) as null|num - if (!isnull(desiredfps)) - clientfps = desiredfps - if (world.byond_version >= 511 && user.client && user.client.byond_version >= 511) - user.client.vars["fps"] = clientfps - if("ui") - var/pickedui = input(user, "Choose your UI style.", "Character Preference") as null|anything in list("Midnight", "Plasmafire", "Retro", "Slimecore", "Operative", "Clockwork") - if(pickedui) - UI_style = pickedui - - //citadel code - if("cock_color") - var/new_cockcolor = input(user, "Penis color:", "Character Preference") as color|null - if(new_cockcolor) - var/temp_hsv = RGBtoHSV(new_cockcolor) - if(new_cockcolor == "#000000") - features["cock_color"] = pref_species.default_color - else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) - features["cock_color"] = sanitize_hexcolor(new_cockcolor) - else - user << "Invalid color. Your color is not bright enough." - - if("cock_length") - var/new_length = input(user, "Penis length in inches:\n([COCK_SIZE_MIN]-[COCK_SIZE_MAX])", "Character Preference") as num|null - if(new_length) - features["cock_length"] = max(min( round(text2num(new_length)), COCK_SIZE_MAX),COCK_SIZE_MIN) - - if("cock_shape") - var/new_shape - new_shape = input(user, "Penis shape:", "Character Preference") as null|anything in GLOB.cock_shapes_list - if(new_shape) - features["cock_shape"] = new_shape - - if("balls_color") - var/new_ballscolor = input(user, "Testicle Color:", "Character Preference") as color|null - if(new_ballscolor) - var/temp_hsv = RGBtoHSV(new_ballscolor) - if(new_ballscolor == "#000000") - features["balls_color"] = pref_species.default_color - else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) - features["balls_color"] = sanitize_hexcolor(new_ballscolor) - else - user << "Invalid color. Your color is not bright enough." - - if("egg_size") - var/new_size - var/list/egg_sizes = list(1,2,3) - new_size = input(user, "Egg Diameter(inches):", "Egg Size") as null|anything in egg_sizes - if(new_size) - features["eggsack_egg_size"] = new_size - - if("egg_color") - var/new_egg_color = input(user, "Egg Color:", "Character Preference") as color|null - if(new_egg_color) - var/temp_hsv = RGBtoHSV(new_egg_color) - if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) - features["eggsack_egg_color"] = sanitize_hexcolor(new_egg_color) - else - user << "Invalid color. Your color is not bright enough." - if("breasts_size") - var/new_size - new_size = input(user, "Breast Size", "Character Preference") as null|anything in GLOB.breasts_size_list - if(new_size) - features["breasts_size"] = new_size - - if("breasts_shape") - var/new_shape - new_shape = input(user, "Breast Shape", "Character Preference") as null|anything in GLOB.breasts_shapes_list - if(new_shape) - features["breasts_shape"] = new_shape - - if("breasts_color") - var/new_breasts_color = input(user, "Breast Color:", "Character Preference") as color|null - if(new_breasts_color) - var/temp_hsv = RGBtoHSV(new_breasts_color) - if(new_breasts_color == "#000000") - features["breasts_color"] = pref_species.default_color - else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) - features["breasts_color"] = sanitize_hexcolor(new_breasts_color) - else - user << "Invalid color. Your color is not bright enough." - if("vag_shape") - var/new_shape - new_shape = input(user, "Vagina Type", "Character Preference") as null|anything in GLOB.vagina_shapes_list - if(new_shape) - features["vag_shape"] = new_shape - if("vag_color") - var/new_vagcolor = input(user, "Vagina color:", "Character Preference") as color|null - if(new_vagcolor) - var/temp_hsv = RGBtoHSV(new_vagcolor) - if(new_vagcolor == "#000000") - features["vag_color"] = pref_species.default_color - else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) - features["vag_color"] = sanitize_hexcolor(new_vagcolor) - else - user << "Invalid color. Your color is not bright enough." - - else - switch(href_list["preference"]) - - //citadel code - if("genital_colour") - switch(features["genitals_use_skintone"]) - if(TRUE) - features["genitals_use_skintone"] = FALSE - if(FALSE) - features["genitals_use_skintone"] = TRUE - else - features["genitals_use_skintone"] = FALSE - if("arousable") - switch(arousable) - if(TRUE) - arousable = FALSE - if(FALSE) - arousable = TRUE - else//failsafe - arousable = FALSE - if("has_cock") - switch(features["has_cock"]) - if(TRUE) - features["has_cock"] = FALSE - if(FALSE) - features["has_cock"] = TRUE - features["has_ovi"] = FALSE - features["has_eggsack"] = FALSE - else - features["has_cock"] = FALSE - features["has_ovi"] = FALSE - if("has_balls") - switch(features["has_balls"]) - if(TRUE) - features["has_balls"] = FALSE - if(FALSE) - features["has_balls"] = TRUE - features["has_eggsack"] = FALSE - else - features["has_balls"] = FALSE - features["has_eggsack"] = FALSE - - if("has_ovi") - switch(features["has_ovi"]) - if(TRUE) - features["has_ovi"] = FALSE - if(FALSE) - features["has_ovi"] = TRUE - features["has_cock"] = FALSE - features["has_balls"] = FALSE - else - features["has_ovi"] = FALSE - features["has_cock"] = FALSE - - if("has_eggsack") - switch(features["has_eggsack"]) - if(TRUE) - features["has_eggsack"] = FALSE - if(FALSE) - features["has_eggsack"] = TRUE - features["has_balls"] = FALSE - else - features["has_eggsack"] = FALSE - features["has_balls"] = FALSE - - if("balls_internal") - switch(features["balls_internal"]) - if(TRUE) - features["balls_internal"] = FALSE - if(FALSE) - features["balls_internal"] = TRUE - features["eggsack_internal"] = FALSE - else - features["balls_internal"] = FALSE - features["eggsack_internal"] = FALSE - - if("eggsack_internal") - switch(features["eggsack_internal"]) - if(TRUE) - features["eggsack_internal"] = FALSE - if(FALSE) - features["eggsack_internal"] = TRUE - features["balls_internal"] = FALSE - else - features["eggsack_internal"] = FALSE - features["balls_internal"] = FALSE - - if("has_breasts") - switch(features["has_breasts"]) - if(TRUE) - features["has_breasts"] = FALSE - if(FALSE) - features["has_breasts"] = TRUE - else - features["has_breasts"] = FALSE - if("has_vag") - switch(features["has_vag"]) - if(TRUE) - features["has_vag"] = FALSE - if(FALSE) - features["has_vag"] = TRUE - else - features["has_vag"] = FALSE - if("has_womb") - switch(features["has_womb"]) - if(TRUE) - features["has_womb"] = FALSE - if(FALSE) - features["has_womb"] = TRUE - else - features["has_womb"] = FALSE - if("exhibitionist") - switch(features["exhibitionist"]) - if(TRUE) - features["exhibitionist"] = FALSE - if(FALSE) - features["exhibitionist"] = TRUE - else - features["exhibitionist"] = FALSE - - if("publicity") - if(unlock_content) - toggles ^= MEMBER_PUBLIC - if("gender") - if(gender == MALE) - gender = FEMALE - else - gender = MALE - underwear = "Nude" - undershirt = "Nude" - socks = "Nude" - facial_hair_style = "Shaved" - hair_style = "Bald" - - if("hotkeys") - hotkeys = !hotkeys - if("action_buttons") - buttons_locked = !buttons_locked - if("tgui_fancy") - tgui_fancy = !tgui_fancy - if("tgui_lock") - tgui_lock = !tgui_lock - if("winflash") - windowflashing = !windowflashing - if("hear_adminhelps") - toggles ^= SOUND_ADMINHELP - if("announce_login") - toggles ^= ANNOUNCE_LOGIN - - if("be_special") - var/be_special_type = href_list["be_special_type"] - if(be_special_type in be_special) - be_special -= be_special_type - else - be_special += be_special_type - - if("name") - be_random_name = !be_random_name - - if("all") - be_random_body = !be_random_body - - if("hear_midis") - toggles ^= SOUND_MIDI - - if("lobby_music") - toggles ^= SOUND_LOBBY - if((toggles & SOUND_LOBBY) && user.client) - user.client.playtitlemusic() - else - user.stop_sound_channel(CHANNEL_LOBBYMUSIC) - - if("ghost_ears") - chat_toggles ^= CHAT_GHOSTEARS - - if("ghost_sight") - chat_toggles ^= CHAT_GHOSTSIGHT - - if("ghost_whispers") - chat_toggles ^= CHAT_GHOSTWHISPER - - if("ghost_radio") - chat_toggles ^= CHAT_GHOSTRADIO - - if("ghost_pda") - chat_toggles ^= CHAT_GHOSTPDA - - if("pull_requests") - chat_toggles ^= CHAT_PULLR - - if("allow_midround_antag") - toggles ^= MIDROUND_ANTAG - - if("parallaxup") - parallax = Wrap(parallax + 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1) - if (parent && parent.mob && parent.mob.hud_used) - parent.mob.hud_used.update_parallax_pref(parent.mob) - - if("parallaxdown") - parallax = Wrap(parallax - 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1) - if (parent && parent.mob && parent.mob.hud_used) - parent.mob.hud_used.update_parallax_pref(parent.mob) - - if("save") - save_preferences() - save_character() - - if("load") - load_preferences() - load_character() - attempt_vr(parent.prefs_vr,"load_vore","") - - if("changeslot") - attempt_vr(parent.prefs_vr,"load_vore","") - if(!load_character(text2num(href_list["num"]))) - random_character() - real_name = random_unique_name(gender) - save_character() - - if("tab") - if (href_list["tab"]) - current_tab = text2num(href_list["tab"]) - - ShowChoices(user) - return 1 - -/datum/preferences/proc/copy_to(mob/living/carbon/human/character, icon_updates = 1) - if(be_random_name) - real_name = pref_species.random_name(gender) - - if(be_random_body) - random_character(gender) - - if(config.humans_need_surnames) - var/firstspace = findtext(real_name, " ") - var/name_length = length(real_name) - if(!firstspace) //we need a surname - real_name += " [pick(GLOB.last_names)]" - else if(firstspace == name_length) - real_name += "[pick(GLOB.last_names)]" - - character.real_name = real_name - character.name = character.real_name - - character.gender = gender - character.age = age - - character.eye_color = eye_color - var/obj/item/organ/eyes/organ_eyes = character.getorgan(/obj/item/organ/eyes) - if(organ_eyes) - if(!initial(organ_eyes.eye_color)) - organ_eyes.eye_color = eye_color - organ_eyes.old_eye_color = eye_color - character.hair_color = hair_color - character.facial_hair_color = facial_hair_color - - character.skin_tone = skin_tone - character.hair_style = hair_style - character.facial_hair_style = facial_hair_style - character.underwear = underwear - character.undershirt = undershirt - character.socks = socks - - character.backbag = backbag - - 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) - chosen_species = pref_species.type - else - chosen_species = /datum/species/human - character.set_species(chosen_species, icon_update=0) - - //citadel code - character.give_genitals() - character.flavor_text = features["flavor_text"] //Let's update their flavor_text at least initially - character.canbearoused = arousable - - if(icon_updates) - character.update_body() - character.update_hair() - character.update_body_parts() - character.update_genitals() + if(!job.player_old_enough(user.client)) + var/available_in_days = job.available_in_days(user.client) + HTML += "[rank]
\[IN [(available_in_days)] DAYS\]
\[MUTANT\]
\[NON-HUMAN\]
" + + var/prefLevelLabel = "ERROR" + var/prefLevelColor = "pink" + var/prefUpperLevel = -1 // level to assign on left click + var/prefLowerLevel = -1 // level to assign on right click + + if(GetJobDepartment(job, 1) & job.flag) + prefLevelLabel = "High" + prefLevelColor = "slateblue" + prefUpperLevel = 4 + prefLowerLevel = 2 + else if(GetJobDepartment(job, 2) & job.flag) + prefLevelLabel = "Medium" + prefLevelColor = "green" + prefUpperLevel = 1 + prefLowerLevel = 3 + else if(GetJobDepartment(job, 3) & job.flag) + prefLevelLabel = "Low" + prefLevelColor = "orange" + prefUpperLevel = 2 + prefLowerLevel = 4 + else + prefLevelLabel = "NEVER" + prefLevelColor = "red" + prefUpperLevel = 3 + prefLowerLevel = 1 + + + HTML += "" + + if(rank == "Assistant")//Assistant is special + if(job_civilian_low & ASSISTANT) + HTML += "Yes" + else + HTML += "No" + HTML += "
  
" + HTML += "" + + var/message = "Be an Assistant if preferences unavailable" + if(joblessrole == BERANDOMJOB) + message = "Get random job if preferences unavailable" + else if(joblessrole == RETURNTOLOBBY) + message = "Return to lobby if preferences unavailable" + HTML += "

[message]
" + HTML += "
Reset Preferences
" + + user << browse(null, "window=preferences") + var/datum/browser/popup = new(user, "mob_occupation", "
Occupation Preferences
", width, height) + popup.set_window_options("can_close=0") + popup.set_content(HTML) + popup.open(0) + return + +/datum/preferences/proc/SetJobPreferenceLevel(datum/job/job, level) + if (!job) + return 0 + + if (level == 1) // to high + // remove any other job(s) set to high + job_civilian_med |= job_civilian_high + job_engsec_med |= job_engsec_high + job_medsci_med |= job_medsci_high + job_civilian_high = 0 + job_engsec_high = 0 + job_medsci_high = 0 + + if (job.department_flag == CIVILIAN) + job_civilian_low &= ~job.flag + job_civilian_med &= ~job.flag + job_civilian_high &= ~job.flag + + switch(level) + if (1) + job_civilian_high |= job.flag + if (2) + job_civilian_med |= job.flag + if (3) + job_civilian_low |= job.flag + + return 1 + else if (job.department_flag == ENGSEC) + job_engsec_low &= ~job.flag + job_engsec_med &= ~job.flag + job_engsec_high &= ~job.flag + + switch(level) + if (1) + job_engsec_high |= job.flag + if (2) + job_engsec_med |= job.flag + if (3) + job_engsec_low |= job.flag + + return 1 + else if (job.department_flag == MEDSCI) + job_medsci_low &= ~job.flag + job_medsci_med &= ~job.flag + job_medsci_high &= ~job.flag + + switch(level) + if (1) + job_medsci_high |= job.flag + if (2) + job_medsci_med |= job.flag + if (3) + job_medsci_low |= job.flag + + return 1 + + return 0 + +/datum/preferences/proc/UpdateJobPreference(mob/user, role, desiredLvl) + if(!SSjob || SSjob.occupations.len <= 0) + return + var/datum/job/job = SSjob.GetJob(role) + + if(!job) + user << browse(null, "window=mob_occupation") + ShowChoices(user) + return + + if (!isnum(desiredLvl)) + to_chat(user, "UpdateJobPreference - desired level was not a number. Please notify coders!") + ShowChoices(user) + return + + if(role == "Assistant") + if(job_civilian_low & job.flag) + job_civilian_low &= ~job.flag + else + job_civilian_low |= job.flag + SetChoices(user) + return 1 + + SetJobPreferenceLevel(job, desiredLvl) + SetChoices(user) + + return 1 + + +/datum/preferences/proc/ResetJobs() + + job_civilian_high = 0 + job_civilian_med = 0 + job_civilian_low = 0 + + job_medsci_high = 0 + job_medsci_med = 0 + job_medsci_low = 0 + + job_engsec_high = 0 + job_engsec_med = 0 + job_engsec_low = 0 + + +/datum/preferences/proc/GetJobDepartment(datum/job/job, level) + if(!job || !level) + return 0 + switch(job.department_flag) + if(CIVILIAN) + switch(level) + if(1) + return job_civilian_high + if(2) + return job_civilian_med + if(3) + return job_civilian_low + if(MEDSCI) + switch(level) + if(1) + return job_medsci_high + if(2) + return job_medsci_med + if(3) + return job_medsci_low + if(ENGSEC) + switch(level) + if(1) + return job_engsec_high + if(2) + return job_engsec_med + if(3) + return job_engsec_low + return 0 + +/datum/preferences/proc/process_link(mob/user, list/href_list) + if(href_list["jobbancheck"]) + var/job = sanitizeSQL(href_list["jobbancheck"]) + var/sql_ckey = sanitizeSQL(user.ckey) + var/datum/DBQuery/query_get_jobban = SSdbcore.NewQuery("SELECT reason, bantime, duration, expiration_time, a_ckey FROM [format_table_name("ban")] WHERE ckey = '[sql_ckey]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned) AND job = '[job]'") + if(!query_get_jobban.warn_execute()) + return + if(query_get_jobban.NextRow()) + var/reason = query_get_jobban.item[1] + var/bantime = query_get_jobban.item[2] + var/duration = query_get_jobban.item[3] + var/expiration_time = query_get_jobban.item[4] + var/a_ckey = query_get_jobban.item[5] + var/text + text = "You, or another user of this computer, ([user.ckey]) is banned from playing [job]. The ban reason is:
[reason]
This ban was applied by [a_ckey] on [bantime]" + if(text2num(duration) > 0) + text += ". The ban is for [duration] minutes and expires on [expiration_time] (server time)" + text += ".
" + to_chat(user, text) + return + + if(href_list["preference"] == "job") + switch(href_list["task"]) + if("close") + user << browse(null, "window=mob_occupation") + ShowChoices(user) + if("reset") + ResetJobs() + SetChoices(user) + if("random") + switch(joblessrole) + if(RETURNTOLOBBY) + if(jobban_isbanned(user, "Assistant")) + joblessrole = BERANDOMJOB + else + joblessrole = BEASSISTANT + if(BEASSISTANT) + joblessrole = BERANDOMJOB + if(BERANDOMJOB) + joblessrole = RETURNTOLOBBY + SetChoices(user) + if("setJobLevel") + UpdateJobPreference(user, href_list["text"], text2num(href_list["level"])) + else + SetChoices(user) + return 1 + + switch(href_list["task"]) + if("random") + switch(href_list["preference"]) + if("name") + real_name = pref_species.random_name(gender,1) + if("age") + age = rand(AGE_MIN, AGE_MAX) + if("hair") + hair_color = random_short_color() + if("hair_style") + hair_style = random_hair_style(gender) + if("facial") + facial_hair_color = random_short_color() + if("facial_hair_style") + facial_hair_style = random_facial_hair_style(gender) + if("underwear") + underwear = random_underwear(gender) + if("undershirt") + undershirt = random_undershirt(gender) + if("socks") + socks = random_socks() + if("eyes") + eye_color = random_eye_color() + if("s_tone") + skin_tone = random_skin_tone() + if("bag") + backbag = pick(GLOB.backbaglist) + if("all") + random_character() + + if("input") + switch(href_list["preference"]) + if("ghostform") + if(unlock_content) + var/new_form = input(user, "Thanks for supporting BYOND - Choose your ghostly form:","Thanks for supporting BYOND",null) as null|anything in GLOB.ghost_forms + if(new_form) + ghost_form = new_form + if("ghostorbit") + if(unlock_content) + var/new_orbit = input(user, "Thanks for supporting BYOND - Choose your ghostly orbit:","Thanks for supporting BYOND", null) as null|anything in GLOB.ghost_orbits + if(new_orbit) + ghost_orbit = new_orbit + + if("ghostaccs") + var/new_ghost_accs = alert("Do you want your ghost to show full accessories where possible, hide accessories but still use the directional sprites where possible, or also ignore the directions and stick to the default sprites?",,GHOST_ACCS_FULL_NAME, GHOST_ACCS_DIR_NAME, GHOST_ACCS_NONE_NAME) + switch(new_ghost_accs) + if(GHOST_ACCS_FULL_NAME) + ghost_accs = GHOST_ACCS_FULL + if(GHOST_ACCS_DIR_NAME) + ghost_accs = GHOST_ACCS_DIR + if(GHOST_ACCS_NONE_NAME) + ghost_accs = GHOST_ACCS_NONE + + if("ghostothers") + var/new_ghost_others = alert("Do you want the ghosts of others to show up as their own setting, as their default sprites or always as the default white ghost?",,GHOST_OTHERS_THEIR_SETTING_NAME, GHOST_OTHERS_DEFAULT_SPRITE_NAME, GHOST_OTHERS_SIMPLE_NAME) + switch(new_ghost_others) + if(GHOST_OTHERS_THEIR_SETTING_NAME) + ghost_others = GHOST_OTHERS_THEIR_SETTING + if(GHOST_OTHERS_DEFAULT_SPRITE_NAME) + ghost_others = GHOST_OTHERS_DEFAULT_SPRITE + if(GHOST_OTHERS_SIMPLE_NAME) + ghost_others = GHOST_OTHERS_SIMPLE + + if("name") + var/new_name = reject_bad_name( input(user, "Choose your character's name:", "Character Preference") as text|null ) + if(new_name) + real_name = new_name + else + to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .") + + if("age") + var/new_age = input(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX])", "Character Preference") as num|null + if(new_age) + age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN) + + if("flavor_text") + var/msg = input(usr,"Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!","Flavor Text",html_decode(features["flavor_text"])) as message + if(msg != null) + msg = copytext(msg, 1, MAX_MESSAGE_LEN) + msg = html_encode(msg) + features["flavor_text"] = msg + + if("metadata") + var/new_metadata = input(user, "Enter any information you'd like others to see, such as Roleplay-preferences:", "Game Preference" , metadata) as message|null + if(new_metadata) + metadata = sanitize(copytext(new_metadata,1,MAX_MESSAGE_LEN)) + + if("hair") + var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference") as null|color + if(new_hair) + hair_color = sanitize_hexcolor(new_hair) + + + if("hair_style") + var/new_hair_style + if(gender == MALE) + new_hair_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in GLOB.hair_styles_male_list + else + new_hair_style = input(user, "Choose your character's hair style:", "Character Preference") as null|anything in GLOB.hair_styles_female_list + if(new_hair_style) + hair_style = new_hair_style + + if("next_hair_style") + if (gender == MALE) + hair_style = next_list_item(hair_style, GLOB.hair_styles_male_list) + else + hair_style = next_list_item(hair_style, GLOB.hair_styles_female_list) + + if("previous_hair_style") + if (gender == MALE) + hair_style = previous_list_item(hair_style, GLOB.hair_styles_male_list) + else + hair_style = previous_list_item(hair_style, GLOB.hair_styles_female_list) + + if("facial") + var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference") as null|color + if(new_facial) + facial_hair_color = sanitize_hexcolor(new_facial) + + if("facial_hair_style") + var/new_facial_hair_style + if(gender == MALE) + new_facial_hair_style = input(user, "Choose your character's facial-hair style:", "Character Preference") as null|anything in GLOB.facial_hair_styles_male_list + else + new_facial_hair_style = input(user, "Choose your character's facial-hair style:", "Character Preference") as null|anything in GLOB.facial_hair_styles_female_list + if(new_facial_hair_style) + facial_hair_style = new_facial_hair_style + + if("next_facehair_style") + if (gender == MALE) + facial_hair_style = next_list_item(facial_hair_style, GLOB.facial_hair_styles_male_list) + else + facial_hair_style = next_list_item(facial_hair_style, GLOB.facial_hair_styles_female_list) + + if("previous_facehair_style") + if (gender == MALE) + facial_hair_style = previous_list_item(facial_hair_style, GLOB.facial_hair_styles_male_list) + else + facial_hair_style = previous_list_item(facial_hair_style, GLOB.facial_hair_styles_female_list) + + if("underwear") + var/new_underwear + if(gender == MALE) + new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_m + else + new_underwear = input(user, "Choose your character's underwear:", "Character Preference") as null|anything in GLOB.underwear_f + if(new_underwear) + underwear = new_underwear + + if("undershirt") + var/new_undershirt + if(gender == MALE) + new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_m + else + new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference") as null|anything in GLOB.undershirt_f + if(new_undershirt) + undershirt = new_undershirt + + if("socks") + var/new_socks + new_socks = input(user, "Choose your character's socks:", "Character Preference") as null|anything in GLOB.socks_list + if(new_socks) + socks = new_socks + + if("eyes") + var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference") as color|null + if(new_eyes) + eye_color = sanitize_hexcolor(new_eyes) + + if("species") + + var/result = input(user, "Select a species", "Species Selection") as null|anything in GLOB.roundstart_species + + if(result) + var/newtype = GLOB.roundstart_species[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"]) + if(features["mcolor"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3])) + features["mcolor"] = pref_species.default_color + if(features["mcolor2"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3])) + features["mcolor2"] = pref_species.default_color + if(features["mcolor3"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3])) + features["mcolor3"] = pref_species.default_color + + if("mutant_color") + var/new_mutantcolor = input(user, "Choose your character's primary alien/mutant color:", "Character Preference") as color|null + if(new_mutantcolor) + var/temp_hsv = RGBtoHSV(new_mutantcolor) + if(new_mutantcolor == "#000000") + features["mcolor"] = pref_species.default_color + else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin + features["mcolor"] = sanitize_hexcolor(new_mutantcolor) + else + to_chat(user, "Invalid color. Your color is not bright enough.") + + if("mutant_color2") + var/new_mutantcolor = input(user, "Choose your character's secondary alien/mutant color:", "Character Preference") as color|null + if(new_mutantcolor) + var/temp_hsv = RGBtoHSV(new_mutantcolor) + if(new_mutantcolor == "#000000") + features["mcolor2"] = pref_species.default_color + else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin + features["mcolor2"] = sanitize_hexcolor(new_mutantcolor) + else + to_chat(user, "Invalid color. Your color is not bright enough.") + + if("mutant_color3") + var/new_mutantcolor = input(user, "Choose your character's tertiary alien/mutant color:", "Character Preference") as color|null + if(new_mutantcolor) + var/temp_hsv = RGBtoHSV(new_mutantcolor) + if(new_mutantcolor == "#000000") + features["mcolor3"] = pref_species.default_color + else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin + features["mcolor3"] = sanitize_hexcolor(new_mutantcolor) + else + to_chat(user, "Invalid color. Your color is not bright enough.") + + if("tail_lizard") + var/new_tail + new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.tails_list_lizard + if(new_tail) + features["tail_lizard"] = new_tail + if(new_tail != "None") + features["taur"] = "None" + + if("tail_human") + var/new_tail + new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.tails_list_human + if(new_tail) + features["tail_human"] = new_tail + if(new_tail != "None") + features["taur"] = "None" + if("mam_tail") + var/new_tail + new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.mam_tails_list + if(new_tail) + features["mam_tail"] = new_tail + if(new_tail != "None") + features["taur"] = "None" + + if("taur") + var/new_taur + new_taur = input(user, "Choose your character's tauric body:", "Character Preference") as null|anything in GLOB.taur_list + if(new_taur) + features["taur"] = new_taur + if(new_taur != "None") + features["mam_tail"] = "None" + features["xenotail"] = "None" + +/* Doesn't exist yet. will include facial overlays to mimic 5th port species heads. + if("mam_snout") + var/new_snout + new_snout = input(user, "Choose your character's snout:", "Character Preference") as null|anything in GLOB.mam_snouts_list + if(new_snout) + features["snout"] = new_snout +*/ + + if("snout") + var/new_snout + new_snout = input(user, "Choose your character's snout:", "Character Preference") as null|anything in GLOB.snouts_list + if(new_snout) + features["snout"] = new_snout + + if("horns") + var/new_horns + new_horns = input(user, "Choose your character's horns:", "Character Preference") as null|anything in GLOB.horns_list + if(new_horns) + features["horns"] = new_horns + + if("mam_ears") + var/new_ears + new_ears = input(user, "Choose your character's ears:", "Character Preference") as null|anything in GLOB.mam_ears_list + if(new_ears) + features["mam_ears"] = new_ears + + if("ears") + var/new_ears + new_ears = input(user, "Choose your character's ears:", "Character Preference") as null|anything in GLOB.ears_list + if(new_ears) + features["ears"] = new_ears + + if("wings") + var/new_wings + new_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.r_wings_list + if(new_wings) + features["wings"] = new_wings + + if("frills") + var/new_frills + new_frills = input(user, "Choose your character's frills:", "Character Preference") as null|anything in GLOB.frills_list + if(new_frills) + features["frills"] = new_frills + + if("spines") + var/new_spines + new_spines = input(user, "Choose your character's spines:", "Character Preference") as null|anything in GLOB.spines_list + if(new_spines) + features["spines"] = new_spines + + if("body_markings") + var/new_body_markings + new_body_markings = input(user, "Choose your character's body markings:", "Character Preference") as null|anything in GLOB.body_markings_list + if(new_body_markings) + features["body_markings"] = new_body_markings + + if("mam_body_markings") + var/new_mam_body_markings + new_mam_body_markings = input(user, "Choose your character's body markings:", "Character Preference") as null|anything in GLOB.mam_body_markings_list + if(new_mam_body_markings) + features["mam_body_markings"] = new_mam_body_markings + + //Xeno Bodyparts + if("xenohead")//Head or caste type + var/new_head + new_head = input(user, "Choose your character's caste:", "Character Preference") as null|anything in GLOB.xeno_head_list + if(new_head) + features["xenohead"] = new_head + + if("xenotail")//Currently one one type, more maybe later if someone sprites them. Might include animated variants in the future. + var/new_tail + new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in GLOB.xeno_tail_list + if(new_tail) + features["xenotail"] = new_tail + + if("xenodorsal") + var/new_dors + new_dors = input(user, "Choose your character's dorsal tube type:", "Character Preference") as null|anything in GLOB.xeno_dorsal_list + if(new_dors) + features["xenodorsal"] = new_dors + + if("legs") + var/new_legs + new_legs = input(user, "Choose your character's legs:", "Character Preference") as null|anything in GLOB.legs_list + if(new_legs) + features["legs"] = new_legs + + if("s_tone") + var/new_s_tone = input(user, "Choose your character's skin-tone:", "Character Preference") as null|anything in GLOB.skin_tones + if(new_s_tone) + skin_tone = new_s_tone + + if("ooccolor") + var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference") as color|null + if(new_ooccolor) + ooccolor = sanitize_ooccolor(new_ooccolor) + + if("bag") + var/new_backbag = input(user, "Choose your character's style of bag:", "Character Preference") as null|anything in GLOB.backbaglist + if(new_backbag) + backbag = new_backbag + + if("uplink_loc") + var/new_loc = input(user, "Choose your character's traitor uplink spawn location:", "Character Preference") as null|anything in GLOB.uplink_spawn_loc_list + if(new_loc) + uplink_spawn_loc = new_loc + + if("clown_name") + var/new_clown_name = reject_bad_name( input(user, "Choose your character's clown name:", "Character Preference") as text|null ) + if(new_clown_name) + custom_names["clown"] = new_clown_name + else + to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .") + + if("mime_name") + var/new_mime_name = reject_bad_name( input(user, "Choose your character's mime name:", "Character Preference") as text|null ) + if(new_mime_name) + custom_names["mime"] = new_mime_name + else + to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .") + + if("ai_name") + var/new_ai_name = reject_bad_name( input(user, "Choose your character's AI name:", "Character Preference") as text|null, 1 ) + if(new_ai_name) + custom_names["ai"] = new_ai_name + else + to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, 0-9, -, ' and .") + + if("cyborg_name") + var/new_cyborg_name = reject_bad_name( input(user, "Choose your character's cyborg name:", "Character Preference") as text|null, 1 ) + if(new_cyborg_name) + custom_names["cyborg"] = new_cyborg_name + else + to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, 0-9, -, ' and .") + + if("religion_name") + var/new_religion_name = reject_bad_name( input(user, "Choose your character's religion:", "Character Preference") as text|null ) + if(new_religion_name) + custom_names["religion"] = new_religion_name + else + to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .") + + if("deity_name") + var/new_deity_name = reject_bad_name( input(user, "Choose your character's deity:", "Character Preference") as text|null ) + if(new_deity_name) + custom_names["deity"] = new_deity_name + else + to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .") + + if("sec_dept") + var/department = input(user, "Choose your prefered security department:", "Security Departments") as null|anything in GLOB.security_depts_prefs + if(department) + prefered_security_department = department + + if ("preferred_map") + var/maplist = list() + var/default = "Default" + if (config.defaultmap) + default += " ([config.defaultmap.map_name])" + for (var/M in config.maplist) + var/datum/map_config/VM = config.maplist[M] + var/friendlyname = "[VM.map_name] " + if (VM.voteweight <= 0) + friendlyname += " (disabled)" + maplist[friendlyname] = VM.map_name + maplist[default] = null + var/pickedmap = input(user, "Choose your preferred map. This will be used to help weight random map selection.", "Character Preference") as null|anything in maplist + if (pickedmap) + preferred_map = maplist[pickedmap] + + if ("clientfps") + var/version_message + if (user.client && user.client.byond_version < 511) + version_message = "\nYou need to be using byond version 511 or later to take advantage of this feature, your version of [user.client.byond_version] is too low" + if (world.byond_version < 511) + version_message += "\nThis server does not currently support client side fps. You can set now for when it does." + var/desiredfps = input(user, "Choose your desired fps.[version_message]\n(0 = synced with server tick rate (currently:[world.fps]))", "Character Preference", clientfps) as null|num + if (!isnull(desiredfps)) + clientfps = desiredfps + if (world.byond_version >= 511 && user.client && user.client.byond_version >= 511) + user.client.vars["fps"] = clientfps + if("ui") + var/pickedui = input(user, "Choose your UI style.", "Character Preference") as null|anything in list("Midnight", "Plasmafire", "Retro", "Slimecore", "Operative", "Clockwork") + if(pickedui) + UI_style = pickedui + + //citadel code + if("cock_color") + var/new_cockcolor = input(user, "Penis color:", "Character Preference") as color|null + if(new_cockcolor) + var/temp_hsv = RGBtoHSV(new_cockcolor) + if(new_cockcolor == "#000000") + features["cock_color"] = pref_species.default_color + else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) + features["cock_color"] = sanitize_hexcolor(new_cockcolor) + else + user << "Invalid color. Your color is not bright enough." + + if("cock_length") + var/new_length = input(user, "Penis length in inches:\n([COCK_SIZE_MIN]-[COCK_SIZE_MAX])", "Character Preference") as num|null + if(new_length) + features["cock_length"] = max(min( round(text2num(new_length)), COCK_SIZE_MAX),COCK_SIZE_MIN) + + if("cock_shape") + var/new_shape + new_shape = input(user, "Penis shape:", "Character Preference") as null|anything in GLOB.cock_shapes_list + if(new_shape) + features["cock_shape"] = new_shape + + if("balls_color") + var/new_ballscolor = input(user, "Testicle Color:", "Character Preference") as color|null + if(new_ballscolor) + var/temp_hsv = RGBtoHSV(new_ballscolor) + if(new_ballscolor == "#000000") + features["balls_color"] = pref_species.default_color + else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) + features["balls_color"] = sanitize_hexcolor(new_ballscolor) + else + user << "Invalid color. Your color is not bright enough." + + if("egg_size") + var/new_size + var/list/egg_sizes = list(1,2,3) + new_size = input(user, "Egg Diameter(inches):", "Egg Size") as null|anything in egg_sizes + if(new_size) + features["eggsack_egg_size"] = new_size + + if("egg_color") + var/new_egg_color = input(user, "Egg Color:", "Character Preference") as color|null + if(new_egg_color) + var/temp_hsv = RGBtoHSV(new_egg_color) + if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) + features["eggsack_egg_color"] = sanitize_hexcolor(new_egg_color) + else + user << "Invalid color. Your color is not bright enough." + if("breasts_size") + var/new_size + new_size = input(user, "Breast Size", "Character Preference") as null|anything in GLOB.breasts_size_list + if(new_size) + features["breasts_size"] = new_size + + if("breasts_shape") + var/new_shape + new_shape = input(user, "Breast Shape", "Character Preference") as null|anything in GLOB.breasts_shapes_list + if(new_shape) + features["breasts_shape"] = new_shape + + if("breasts_color") + var/new_breasts_color = input(user, "Breast Color:", "Character Preference") as color|null + if(new_breasts_color) + var/temp_hsv = RGBtoHSV(new_breasts_color) + if(new_breasts_color == "#000000") + features["breasts_color"] = pref_species.default_color + else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) + features["breasts_color"] = sanitize_hexcolor(new_breasts_color) + else + user << "Invalid color. Your color is not bright enough." + if("vag_shape") + var/new_shape + new_shape = input(user, "Vagina Type", "Character Preference") as null|anything in GLOB.vagina_shapes_list + if(new_shape) + features["vag_shape"] = new_shape + if("vag_color") + var/new_vagcolor = input(user, "Vagina color:", "Character Preference") as color|null + if(new_vagcolor) + var/temp_hsv = RGBtoHSV(new_vagcolor) + if(new_vagcolor == "#000000") + features["vag_color"] = pref_species.default_color + else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) + features["vag_color"] = sanitize_hexcolor(new_vagcolor) + else + user << "Invalid color. Your color is not bright enough." + + else + switch(href_list["preference"]) + + //citadel code + if("genital_colour") + switch(features["genitals_use_skintone"]) + if(TRUE) + features["genitals_use_skintone"] = FALSE + if(FALSE) + features["genitals_use_skintone"] = TRUE + else + features["genitals_use_skintone"] = FALSE + if("arousable") + switch(arousable) + if(TRUE) + arousable = FALSE + if(FALSE) + arousable = TRUE + else//failsafe + arousable = FALSE + if("has_cock") + switch(features["has_cock"]) + if(TRUE) + features["has_cock"] = FALSE + if(FALSE) + features["has_cock"] = TRUE + features["has_ovi"] = FALSE + features["has_eggsack"] = FALSE + else + features["has_cock"] = FALSE + features["has_ovi"] = FALSE + if("has_balls") + switch(features["has_balls"]) + if(TRUE) + features["has_balls"] = FALSE + if(FALSE) + features["has_balls"] = TRUE + features["has_eggsack"] = FALSE + else + features["has_balls"] = FALSE + features["has_eggsack"] = FALSE + + if("has_ovi") + switch(features["has_ovi"]) + if(TRUE) + features["has_ovi"] = FALSE + if(FALSE) + features["has_ovi"] = TRUE + features["has_cock"] = FALSE + features["has_balls"] = FALSE + else + features["has_ovi"] = FALSE + features["has_cock"] = FALSE + + if("has_eggsack") + switch(features["has_eggsack"]) + if(TRUE) + features["has_eggsack"] = FALSE + if(FALSE) + features["has_eggsack"] = TRUE + features["has_balls"] = FALSE + else + features["has_eggsack"] = FALSE + features["has_balls"] = FALSE + + if("balls_internal") + switch(features["balls_internal"]) + if(TRUE) + features["balls_internal"] = FALSE + if(FALSE) + features["balls_internal"] = TRUE + features["eggsack_internal"] = FALSE + else + features["balls_internal"] = FALSE + features["eggsack_internal"] = FALSE + + if("eggsack_internal") + switch(features["eggsack_internal"]) + if(TRUE) + features["eggsack_internal"] = FALSE + if(FALSE) + features["eggsack_internal"] = TRUE + features["balls_internal"] = FALSE + else + features["eggsack_internal"] = FALSE + features["balls_internal"] = FALSE + + if("has_breasts") + switch(features["has_breasts"]) + if(TRUE) + features["has_breasts"] = FALSE + if(FALSE) + features["has_breasts"] = TRUE + else + features["has_breasts"] = FALSE + if("has_vag") + switch(features["has_vag"]) + if(TRUE) + features["has_vag"] = FALSE + if(FALSE) + features["has_vag"] = TRUE + else + features["has_vag"] = FALSE + if("has_womb") + switch(features["has_womb"]) + if(TRUE) + features["has_womb"] = FALSE + if(FALSE) + features["has_womb"] = TRUE + else + features["has_womb"] = FALSE + if("exhibitionist") + switch(features["exhibitionist"]) + if(TRUE) + features["exhibitionist"] = FALSE + if(FALSE) + features["exhibitionist"] = TRUE + else + features["exhibitionist"] = FALSE + + if("publicity") + if(unlock_content) + toggles ^= MEMBER_PUBLIC + if("gender") + if(gender == MALE) + gender = FEMALE + else + gender = MALE + underwear = "Nude" + undershirt = "Nude" + socks = "Nude" + facial_hair_style = "Shaved" + hair_style = "Bald" + + if("hotkeys") + hotkeys = !hotkeys + if("action_buttons") + buttons_locked = !buttons_locked + if("tgui_fancy") + tgui_fancy = !tgui_fancy + if("tgui_lock") + tgui_lock = !tgui_lock + if("winflash") + windowflashing = !windowflashing + if("hear_adminhelps") + toggles ^= SOUND_ADMINHELP + if("announce_login") + toggles ^= ANNOUNCE_LOGIN + + if("be_special") + var/be_special_type = href_list["be_special_type"] + if(be_special_type in be_special) + be_special -= be_special_type + else + be_special += be_special_type + + if("name") + be_random_name = !be_random_name + + if("all") + be_random_body = !be_random_body + + if("hear_midis") + toggles ^= SOUND_MIDI + + if("lobby_music") + toggles ^= SOUND_LOBBY + if((toggles & SOUND_LOBBY) && user.client) + user.client.playtitlemusic() + else + user.stop_sound_channel(CHANNEL_LOBBYMUSIC) + + if("ghost_ears") + chat_toggles ^= CHAT_GHOSTEARS + + if("ghost_sight") + chat_toggles ^= CHAT_GHOSTSIGHT + + if("ghost_whispers") + chat_toggles ^= CHAT_GHOSTWHISPER + + if("ghost_radio") + chat_toggles ^= CHAT_GHOSTRADIO + + if("ghost_pda") + chat_toggles ^= CHAT_GHOSTPDA + + if("pull_requests") + chat_toggles ^= CHAT_PULLR + + if("allow_midround_antag") + toggles ^= MIDROUND_ANTAG + + if("parallaxup") + parallax = Wrap(parallax + 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1) + if (parent && parent.mob && parent.mob.hud_used) + parent.mob.hud_used.update_parallax_pref(parent.mob) + + if("parallaxdown") + parallax = Wrap(parallax - 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1) + if (parent && parent.mob && parent.mob.hud_used) + parent.mob.hud_used.update_parallax_pref(parent.mob) + + if("save") + save_preferences() + save_character() + + if("load") + load_preferences() + load_character() + attempt_vr(parent.prefs_vr,"load_vore","") + + if("changeslot") + attempt_vr(parent.prefs_vr,"load_vore","") + if(!load_character(text2num(href_list["num"]))) + random_character() + real_name = random_unique_name(gender) + save_character() + + if("tab") + if (href_list["tab"]) + current_tab = text2num(href_list["tab"]) + + ShowChoices(user) + return 1 + +/datum/preferences/proc/copy_to(mob/living/carbon/human/character, icon_updates = 1) + if(be_random_name) + real_name = pref_species.random_name(gender) + + if(be_random_body) + random_character(gender) + + if(config.humans_need_surnames) + var/firstspace = findtext(real_name, " ") + var/name_length = length(real_name) + if(!firstspace) //we need a surname + real_name += " [pick(GLOB.last_names)]" + else if(firstspace == name_length) + real_name += "[pick(GLOB.last_names)]" + + character.real_name = real_name + character.name = character.real_name + + character.gender = gender + character.age = age + + character.eye_color = eye_color + var/obj/item/organ/eyes/organ_eyes = character.getorgan(/obj/item/organ/eyes) + if(organ_eyes) + if(!initial(organ_eyes.eye_color)) + organ_eyes.eye_color = eye_color + organ_eyes.old_eye_color = eye_color + character.hair_color = hair_color + character.facial_hair_color = facial_hair_color + + character.skin_tone = skin_tone + character.hair_style = hair_style + character.facial_hair_style = facial_hair_style + character.underwear = underwear + character.undershirt = undershirt + character.socks = socks + + character.backbag = backbag + + 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) + chosen_species = pref_species.type + else + chosen_species = /datum/species/human + character.set_species(chosen_species, icon_update=0) + + //citadel code + character.give_genitals() + character.flavor_text = features["flavor_text"] //Let's update their flavor_text at least initially + character.canbearoused = arousable + + if(icon_updates) + character.update_body() + character.update_hair() + character.update_body_parts() + character.update_genitals() From fed956efec1b096388b387dfa28a4663541de34e Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 2 Sep 2017 06:56:35 -0500 Subject: [PATCH 060/262] Update job_exp.dm --- code/modules/jobs/job_exp.dm | 147 +++++++++++++++++++++++++++-------- 1 file changed, 116 insertions(+), 31 deletions(-) diff --git a/code/modules/jobs/job_exp.dm b/code/modules/jobs/job_exp.dm index e65de15279..fc61fcf40b 100644 --- a/code/modules/jobs/job_exp.dm +++ b/code/modules/jobs/job_exp.dm @@ -132,24 +132,61 @@ GLOBAL_PROTECT(exp_to_update) if(L.is_afk()) continue addtimer(CALLBACK(L,/client/proc/update_exp_list,mins,ann),10) - CHECK_TICK -/proc/update_exp_db() +/datum/controller/subsystem/blackbox/proc/update_exp_db() SSdbcore.MassInsert(format_table_name("role_time"),GLOB.exp_to_update,TRUE) LAZYCLEARLIST(GLOB.exp_to_update) -//Manual incrementing/updating -/* -/client/proc/update_exp_client(minutes, announce_changes = FALSE) - if(!src ||!ckey || !config.use_exp_tracking) - return +//resets a client's exp to what was in the db. +/client/proc/set_exp_from_db() + if(!config.use_exp_tracking) + return -1 + if(!SSdbcore.Connect()) + return -1 + var/datum/DBQuery/exp_read = SSdbcore.NewQuery("SELECT job, minutes FROM [format_table_name("role_time")] WHERE ckey = '[sanitizeSQL(ckey)]'") + if(!exp_read.Execute()) + return -1 + var/list/play_records = list() + while(exp_read.NextRow()) + play_records[exp_read.item[1]] = text2num(exp_read.item[2]) + + for(var/rtype in SSjob.name_occupations) + if(!play_records[rtype]) + play_records[rtype] = 0 + for(var/rtype in GLOB.exp_specialmap) + if(!play_records[rtype]) + play_records[rtype] = 0 + + prefs.exp = play_records + + +//updates player db flags +/client/proc/update_flag_db(newflag, state = FALSE) + + if(!SSdbcore.Connect()) + return -1 + + if(!set_db_player_flags()) + return -1 + + if((prefs.db_flags & newflag) && !state) + prefs.db_flags &= ~newflag + else + prefs.db_flags |= newflag + + var/datum/DBQuery/flag_update = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET flags = '[prefs.db_flags]' WHERE ckey='[sanitizeSQL(ckey)]'") + + if(!flag_update.Execute()) + return -1 + + +/client/proc/update_exp_list(minutes, announce_changes = FALSE) + if(!config.use_exp_tracking) + return -1 if(!SSdbcore.Connect()) return -1 var/datum/DBQuery/exp_read = SSdbcore.NewQuery("SELECT job, minutes FROM [format_table_name("role_time")] WHERE ckey = '[sanitizeSQL(ckey)]'") if(!exp_read.Execute()) - var/err = exp_read.ErrorMsg() - log_sql("SQL ERROR during exp_update_client read. Error : \[[err]\]\n") - message_admins("SQL ERROR during exp_update_client read. Error : \[[err]\]\n") return -1 var/list/play_records = list() while(exp_read.NextRow()) @@ -162,33 +199,81 @@ GLOBAL_PROTECT(exp_to_update) if(!play_records[rtype]) play_records[rtype] = 0 var/list/old_records = play_records.Copy() - if(mob.stat != DEAD && mob.mind.assigned_role) - play_records[EXP_TYPE_LIVING] += minutes - if(announce_changes) - to_chat(mob,"You got: [minutes] Living EXP!") - for(var/job in SSjob.name_occupations) - if(mob.mind.assigned_role == job) - play_records[job] += minutes - if(announce_changes) - to_chat(mob,"You got: [minutes] [job] EXP!") - if(mob.mind.special_role && !mob.mind.var_edited) - play_records[EXP_TYPE_SPECIAL] += minutes + if(isliving(mob)) + if(mob.stat != DEAD) + var/rolefound = FALSE + play_records[EXP_TYPE_LIVING] += minutes if(announce_changes) - to_chat(mob,"You got: [minutes] [mob.mind.special_role] EXP!") + to_chat(src,"You got: [minutes] Living EXP!") + if(mob.mind.assigned_role) + for(var/job in SSjob.name_occupations) + if(mob.mind.assigned_role == job) + rolefound = TRUE + play_records[job] += minutes + if(announce_changes) + to_chat(src,"You got: [minutes] [job] EXP!") + if(!rolefound) + for(var/role in GLOB.exp_specialmap[EXP_TYPE_SPECIAL]) + if(mob.mind.assigned_role == role) + rolefound = TRUE + play_records[role] += minutes + if(announce_changes) + to_chat(mob,"You got: [minutes] [role] EXP!") + if(mob.mind.special_role && !mob.mind.var_edited) + var/trackedrole = mob.mind.special_role + var/gangrole = lookforgangrole(mob.mind.special_role) + if(gangrole) + trackedrole = gangrole + play_records[trackedrole] += minutes + if(announce_changes) + to_chat(src,"You got: [minutes] [trackedrole] EXP!") + if(!rolefound) + play_records["Unknown"] += minutes + else + play_records[EXP_TYPE_GHOST] += minutes + if(announce_changes) + to_chat(src,"You got: [minutes] Ghost EXP!") else if(isobserver(mob)) play_records[EXP_TYPE_GHOST] += minutes if(announce_changes) - to_chat(mob,"You got: [minutes] Ghost EXP!") + to_chat(src,"You got: [minutes] Ghost EXP!") else if(minutes) //Let "refresh" checks go through return prefs.exp = play_records for(var/jtype in play_records) - var jobname = jtype - var time = play_records[jtype] - var/datum/DBQuery/update_query = SSdbcore.NewQuery("INSERT INTO [format_table_name("role_time")] (`ckey`, `job`, `minutes`) VALUES ('[sanitizeSQL(ckey)]', '[jobname]', '[time]') ON DUPLICATE KEY UPDATE time = '[time]'") - if(!update_query.Execute()) - var/err = update_queryd.ErrorMsg() - log_game("SQL ERROR during exp_update_client update. Error : \[[err]\]\n") - message_admins("SQL ERROR during exp_update_client update. Error : \[[err]\]\n") - return \ No newline at end of file + if(play_records[jtype] != old_records[jtype]) + LAZYINITLIST(GLOB.exp_to_update) + GLOB.exp_to_update.Add(list(list( + "job" = "'[sanitizeSQL(jtype)]'", + "ckey" = "'[sanitizeSQL(ckey)]'", + "minutes" = play_records[jtype]))) + addtimer(CALLBACK(SSblackbox,/datum/controller/subsystem/blackbox/proc/update_exp_db),20,TIMER_OVERRIDE|TIMER_UNIQUE) + + +//ALWAYS call this at beginning to any proc touching player flags, or your database admin will probably be mad +/client/proc/set_db_player_flags() + if(!SSdbcore.Connect()) + return FALSE + + var/datum/DBQuery/flags_read = SSdbcore.NewQuery("SELECT flags FROM [format_table_name("player")] WHERE ckey='[ckey]'") + + if(!flags_read.Execute()) + return FALSE + + if(flags_read.NextRow()) + prefs.db_flags = text2num(flags_read.item[1]) + else if(isnull(prefs.db_flags)) + prefs.db_flags = 0 //This PROBABLY won't happen, but better safe than sorry. + return TRUE + +//Since each gang is tracked as a different antag type, records need to be generalized or you get up to 57 different possible records +/proc/lookforgangrole(rolecheck) + if(findtext(rolecheck,"Gangster")) + return "Gangster" + else if(findtext(rolecheck,"Gang Boss")) + return "Gang Boss" + else if(findtext(rolecheck,"Gang Lieutenant")) + return "Gang Lieutenant" + else + return FALSE From 8f7368bc5763d74257783e90a7967814a584183e Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 2 Sep 2017 06:58:30 -0500 Subject: [PATCH 061/262] Update config.txt --- config/config.txt | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/config/config.txt b/config/config.txt index 7497404a89..f9ffc880b3 100644 --- a/config/config.txt +++ b/config/config.txt @@ -32,6 +32,19 @@ BAN_LEGACY_SYSTEM ## Uncomment this to have the job system use the player's account creation date, rather than the when they first joined the server for job timers. #USE_ACCOUNT_AGE_FOR_JOBS +## Unhash this to track player playtime in the database. Requires database to be enabled. +#USE_EXP_TRACKING +## Unhash this to enable playtime requirements for head jobs. +#USE_EXP_RESTRICTIONS_HEADS +## Unhash this to override head jobs' playtime requirements with this number of hours. +#USE_EXP_RESTRICTIONS_HEADS_HOURS 15 +## Unhash this to change head jobs' playtime requirements so that they're based on department playtime, rather than crew playtime. +#USE_EXP_RESTRICTIONS_HEADS_DEPARTMENT +## Unhash this to enable playtime requirements for certain non-head jobs, like Engineer and Scientist. +#USE_EXP_RESTRICTIONS_OTHER +## Allows admins to bypass job playtime requirements. +#USE_EXP_RESTRICTIONS_ADMIN_BYPASS + ## log OOC channel LOG_OOC @@ -331,4 +344,4 @@ MINUTE_TOPIC_LIMIT 100 #ERROR_MSG_DELAY 50 ## Send a message to IRC when starting a new game -#IRC_ANNOUNCE_NEW_GAME \ No newline at end of file +#IRC_ANNOUNCE_NEW_GAME From 2161084ba1449a05f47108ef820bd986bc80c840 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 2 Sep 2017 06:59:47 -0500 Subject: [PATCH 062/262] Update database_changelog.txt --- SQL/database_changelog.txt | 144 ++++++++++++++++++++++++++++++------- 1 file changed, 120 insertions(+), 24 deletions(-) diff --git a/SQL/database_changelog.txt b/SQL/database_changelog.txt index 5d3c3ccec2..ce5c2c654d 100644 --- a/SQL/database_changelog.txt +++ b/SQL/database_changelog.txt @@ -1,17 +1,114 @@ + +20th July 2017, by Shadowlight213 +Added role_time table to track time spent playing departments. +Also, added flags column to the player table. + +CREATE TABLE `role_time` ( `ckey` VARCHAR(32) NOT NULL , `job` VARCHAR(128) NOT NULL , `minutes` INT UNSIGNED NOT NULL, PRIMARY KEY (`ckey`, `job`) ) ENGINE = InnoDB; + +ALTER TABLE `player` ADD `flags` INT NOT NULL default '0' AFTER `accountjoindate`; + +UPDATE `schema_revision` SET minor = 1; + +Remember to add a prefix to the table name if you use them. + +---------------------------------------------------- + +Any time you make a change to the schema files, remember to increment the database schema version. Generally increment the minor number, major should be reserved for significant changes to the schema. Both values go up to 255. + +The latest database version is 3.0; The query to update the schema revision table is: + +INSERT INTO `schema_revision` (`major`, `minor`) VALUES (3, 0); +or +INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (3, 0); + +---------------------------------------------------- +28 June 2017, by oranges +Added schema_revision to store the current db revision, why start at 3.0? + +because: +15:09 <+MrStonedOne> 1.0 was erro, 2.0 was when i removed erro_, 3.0 was when jordie made all the strings that hold numbers numbers + +CREATE TABLE `schema_revision` ( +`major` TINYINT(3) UNSIGNED NOT NULL , +`minor` TINYINT(3) UNSIGNED NOT NULL , +`date` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL, +PRIMARY KEY ( `major`,`minor` ) +) ENGINE = INNODB; + +INSERT INTO `schema_revision` (`major`, `minor`) VALUES (3, 0); + +Remember to add a prefix to the table name if you use them. + +---------------------------------------------------- + +26 June 2017, by Jordie0608 + +Modified table 'poll_option', adding the column 'default_percentage_calc'. + +ALTER TABLE `poll_option` ADD COLUMN `default_percentage_calc` TINYINT(1) UNSIGNED NOT NULL DEFAULT '1' AFTER `descmax` + +Remember to add a prefix to the table name if you use them. + +---------------------------------------------------- + +22 June 2017, by Jordie0608 + +Modified table 'poll_option', removing the column 'percentagecalc'. + +ALTER TABLE `poll_option` DROP COLUMN `percentagecalc` + +Remember to add a prefix to the table name if you use them. + +---------------------------------------------------- + +8 June 2017, by Jordie0608 + +Modified table 'death', adding column 'round_id', removing column 'gender' and replacing column 'coord' with the columns 'x_coord', 'y_coord' and 'z_coord'. + +START TRANSACTION; +ALTER TABLE `death` DROP COLUMN `gender`, ADD COLUMN `x_coord` SMALLINT(5) UNSIGNED NOT NULL AFTER `coord`, ADD COLUMN `y_coord` SMALLINT(5) UNSIGNED NOT NULL AFTER `x_coord`, ADD COLUMN `z_coord` SMALLINT(5) UNSIGNED NOT NULL AFTER `y_coord`, ADD COLUMN `round_id` INT(11) NOT NULL AFTER `server_port`; +SET SQL_SAFE_UPDATES = 0; +UPDATE `death` SET `x_coord` = SUBSTRING_INDEX(`coord`, ',', 1), `y_coord` = SUBSTRING_INDEX(SUBSTRING_INDEX(`coord`, ',', 2), ',', -1), `z_coord` = SUBSTRING_INDEX(`coord`, ',', -1); +SET SQL_SAFE_UPDATES = 1; +ALTER TABLE `death` DROP COLUMN `coord`; +COMMIT; + +Remember to add a prefix to the table name if you use them. + +--------------------------------------------------- + +30 May 2017, by MrStonedOne + +Z levels changed, this query allows you to convert old ss13 death records: + +UPDATE death SET coord = CONCAT(SUBSTRING_INDEX(coord, ',', 2), ', ', CASE TRIM(SUBSTRING_INDEX(coord, ',', -1)) WHEN 1 THEN 2 WHEN 2 THEN 1 ELSE TRIMSUBSTRING_INDEX(coord, ',', -1) END) + +--------------------------------------------------- + +26 May 2017, by Jordie0608 + +Modified table 'ban', adding the column 'round_id'. + +ALTER TABLE `ban` ADD COLUMN `round_id` INT(11) NOT NULL AFTER `server_port` + +Remember to add a prefix to the table name if you use them. + +---------------------------------------------------- + 20 May 2017, by Jordie0608 Created table `round` to replace tracking of the datapoints 'round_start', 'round_end', 'server_ip', 'game_mode', 'round_end_results', 'end_error', 'end_proper', 'emergency_shuttle', 'map_name' and 'station_renames' in the `feedback` table. Once created this table is populated with rows from the `feedback` table. START TRANSACTION; -CREATE TABLE `feedback`.`round` (`id` INT(11) NOT NULL AUTO_INCREMENT, `start_datetime` DATETIME NOT NULL, `end_datetime` DATETIME NULL, `server_ip` INT(10) UNSIGNED NOT NULL, `server_port` SMALLINT(5) UNSIGNED NOT NULL, `commit_hash` CHAR(40) NULL, `game_mode` VARCHAR(32) NULL, `game_mode_result` VARCHAR(64) NULL, `end_state` VARCHAR(64) NULL, `shuttle_name` VARCHAR(64) NULL, `map_name` VARCHAR(32) NULL, `station_name` VARCHAR(80) NULL, PRIMARY KEY (`id`)); -ALTER TABLE `feedback`.`feedback` ADD INDEX `tmp` (`round_id` ASC, `var_name` ASC); -INSERT INTO `feedback`.`round` +CREATE TABLE `round` (`id` INT(11) NOT NULL AUTO_INCREMENT, `start_datetime` DATETIME NOT NULL, `end_datetime` DATETIME NULL, `server_ip` INT(10) UNSIGNED NOT NULL, `server_port` SMALLINT(5) UNSIGNED NOT NULL, `commit_hash` CHAR(40) NULL, `game_mode` VARCHAR(32) NULL, `game_mode_result` VARCHAR(64) NULL, `end_state` VARCHAR(64) NULL, `shuttle_name` VARCHAR(64) NULL, `map_name` VARCHAR(32) NULL, `station_name` VARCHAR(80) NULL, PRIMARY KEY (`id`)); +ALTER TABLE `feedback` ADD INDEX `tmp` (`round_id` ASC, `var_name` ASC); +INSERT INTO `round` (`id`, `start_datetime`, `end_datetime`, `server_ip`, `server_port`, `commit_hash`, `game_mode`, `game_mode_result`, `end_state`, `shuttle_name`, `map_name`, `station_name`) SELECT DISTINCT ri.round_id, IFNULL(STR_TO_DATE(st.details,'%a %b %e %H:%i:%s %Y'), TIMESTAMP(0)), STR_TO_DATE(et.details,'%a %b %e %H:%i:%s %Y'), IFNULL(INET_ATON(SUBSTRING_INDEX(IF(si.details = '', '0', IF(SUBSTRING_INDEX(si.details, ':', 1) LIKE '%_._%', si.details, '0')), ':', 1)), INET_ATON(0)), IFNULL(IF(si.details LIKE '%:_%', CAST(SUBSTRING_INDEX(si.details, ':', -1) AS UNSIGNED), '0'), '0'), ch.details, gm.details, mr.details, IFNULL(es.details, ep.details), ss.details, mn.details, sn.details -FROM `feedback`.`feedback`AS ri -LEFT JOIN `feedback`.`feedback` AS st ON ri.round_id = st.round_id AND st.var_name = "round_start" LEFT JOIN `feedback`.`feedback` AS et ON ri.round_id = et.round_id AND et.var_name = "round_end" LEFT JOIN `feedback`.`feedback` AS si ON ri.round_id = si.round_id AND si.var_name = "server_ip" LEFT JOIN `feedback`.`feedback` AS ch ON ri.round_id = ch.round_id AND ch.var_name = "revision" LEFT JOIN `feedback`.`feedback` AS gm ON ri.round_id = gm.round_id AND gm.var_name = "game_mode" LEFT JOIN `feedback`.`feedback` AS mr ON ri.round_id = mr.round_id AND mr.var_name = "round_end_result" LEFT JOIN `feedback`.`feedback` AS es ON ri.round_id = es.round_id AND es.var_name = "end_state" LEFT JOIN `feedback`.`feedback` AS ep ON ri.round_id = ep.round_id AND ep.var_name = "end_proper" LEFT JOIN `feedback`.`feedback` AS ss ON ri.round_id = ss.round_id AND ss.var_name = "emergency_shuttle" LEFT JOIN `feedback`.`feedback` AS mn ON ri.round_id = mn.round_id AND mn.var_name = "map_name" LEFT JOIN `feedback`.`feedback` AS sn ON ri.round_id = sn.round_id AND sn.var_name = "station_renames"; -ALTER TABLE `feedback`.`feedback` DROP INDEX `tmp`; +FROM `feedback`AS ri +LEFT JOIN `feedback` AS st ON ri.round_id = st.round_id AND st.var_name = "round_start" LEFT JOIN `feedback` AS et ON ri.round_id = et.round_id AND et.var_name = "round_end" LEFT JOIN `feedback` AS si ON ri.round_id = si.round_id AND si.var_name = "server_ip" LEFT JOIN `feedback` AS ch ON ri.round_id = ch.round_id AND ch.var_name = "revision" LEFT JOIN `feedback` AS gm ON ri.round_id = gm.round_id AND gm.var_name = "game_mode" LEFT JOIN `feedback` AS mr ON ri.round_id = mr.round_id AND mr.var_name = "round_end_result" LEFT JOIN `feedback` AS es ON ri.round_id = es.round_id AND es.var_name = "end_state" LEFT JOIN `feedback` AS ep ON ri.round_id = ep.round_id AND ep.var_name = "end_proper" LEFT JOIN `feedback` AS ss ON ri.round_id = ss.round_id AND ss.var_name = "emergency_shuttle" LEFT JOIN `feedback` AS mn ON ri.round_id = mn.round_id AND mn.var_name = "map_name" LEFT JOIN `feedback` AS sn ON ri.round_id = sn.round_id AND sn.var_name = "station_renames"; +ALTER TABLE `feedback` DROP INDEX `tmp`; COMMIT; It's not necessary to delete the rows from the `feedback` table but henceforth these datapoints will be in the `round` table. @@ -24,19 +121,18 @@ Remember to add a prefix to the table names if you use them Modified table 'player', adding the column 'accountjoindate', removing the column 'id' and making the column 'ckey' the primary key. -ALTER TABLE `feedback`.`player` DROP COLUMN `id`, ADD COLUMN `accountjoindate` DATE NULL AFTER `lastadminrank`, DROP PRIMARY KEY, ADD PRIMARY KEY (`ckey`), DROP INDEX `ckey`; +ALTER TABLE `player` DROP COLUMN `id`, ADD COLUMN `accountjoindate` DATE NULL AFTER `lastadminrank`, DROP PRIMARY KEY, ADD PRIMARY KEY (`ckey`), DROP INDEX `ckey`; Remember to add a prefix to the table name if you use them. ---------------------------------------------------- - 10 March 2017, by Jordie0608 Modified table 'death', adding the columns 'toxloss', 'cloneloss', and 'staminaloss' and table 'legacy_population', adding the columns 'server_ip' and 'server_port'. -ALTER TABLE `feedback`.`death` ADD COLUMN `toxloss` SMALLINT(5) UNSIGNED NOT NULL AFTER `oxyloss`, ADD COLUMN `cloneloss` SMALLINT(5) UNSIGNED NOT NULL AFTER `toxloss`, ADD COLUMN `staminaloss` SMALLINT(5) UNSIGNED NOT NULL AFTER `cloneloss`; +ALTER TABLE `death` ADD COLUMN `toxloss` SMALLINT(5) UNSIGNED NOT NULL AFTER `oxyloss`, ADD COLUMN `cloneloss` SMALLINT(5) UNSIGNED NOT NULL AFTER `toxloss`, ADD COLUMN `staminaloss` SMALLINT(5) UNSIGNED NOT NULL AFTER `cloneloss`; -ALTER TABLE `feedback`.`legacy_population` ADD COLUMN `server_ip` INT(10) UNSIGNED NOT NULL AFTER `time`, ADD COLUMN `server_port` SMALLINT(5) UNSIGNED NOT NULL AFTER `server_ip`; +ALTER TABLE `legacy_population` ADD COLUMN `server_ip` INT(10) UNSIGNED NOT NULL AFTER `time`, ADD COLUMN `server_port` SMALLINT(5) UNSIGNED NOT NULL AFTER `server_ip`; Remember to add a prefix to the table name if you use them. @@ -68,18 +164,18 @@ Created table 'messages' to supersede the 'notes', 'memos', and 'watchlist' tabl To create this new table run the following command: -CREATE TABLE `feedback`.`messages` (`id` INT(11) NOT NULL AUTO_INCREMENT , `type` VARCHAR(32) NOT NULL , `targetckey` VARCHAR(32) NOT NULL , `adminckey` VARCHAR(32) NOT NULL , `text` TEXT NOT NULL , `timestamp` DATETIME NOT NULL , `server` VARCHAR(32) NULL , `secret` TINYINT(1) NULL DEFAULT 1 , `lasteditor` VARCHAR(32) NULL , `edits` TEXT NULL , PRIMARY KEY (`id`) ) +CREATE TABLE `messages` (`id` INT(11) NOT NULL AUTO_INCREMENT , `type` VARCHAR(32) NOT NULL , `targetckey` VARCHAR(32) NOT NULL , `adminckey` VARCHAR(32) NOT NULL , `text` TEXT NOT NULL , `timestamp` DATETIME NOT NULL , `server` VARCHAR(32) NULL , `secret` TINYINT(1) NULL DEFAULT 1 , `lasteditor` VARCHAR(32) NULL , `edits` TEXT NULL , PRIMARY KEY (`id`) ) To copy the contents of the 'notes', 'memos', and 'watchlist' tables to this new table run the following commands: -INSERT INTO `feedback`.`messages` -(`id`,`type`,`targetckey`,`adminckey`,`text`,`timestamp`,`server`,`secret`,`lasteditor`,`edits`) SELECT `id`, "note", `ckey`, `adminckey`, `notetext`, `timestamp`, `server`, `secret`, `last_editor`, `edits` FROM `feedback`.`notes` +INSERT INTO `messages` +(`id`,`type`,`targetckey`,`adminckey`,`text`,`timestamp`,`server`,`secret`,`lasteditor`,`edits`) SELECT `id`, "note", `ckey`, `adminckey`, `notetext`, `timestamp`, `server`, `secret`, `last_editor`, `edits` FROM `notes` -INSERT INTO `feedback`.`messages` -(`type`,`targetckey`,`adminckey`,`text`,`timestamp`,`lasteditor`,`edits`) SELECT "memo", `ckey`, `ckey`, `memotext`, `timestamp`, `last_editor`, `edits` FROM `feedback`.`memo` +INSERT INTO `messages` +(`type`,`targetckey`,`adminckey`,`text`,`timestamp`,`lasteditor`,`edits`) SELECT "memo", `ckey`, `ckey`, `memotext`, `timestamp`, `last_editor`, `edits` FROM `memo` -INSERT INTO `feedback`.`messages` -(`type`,`targetckey`,`adminckey`,`text`,`timestamp`,`lasteditor`,`edits`) SELECT "watchlist entry", `ckey`, `adminckey`, `reason`, `timestamp`, `last_editor`, `edits` FROM `feedback`.`watch` +INSERT INTO `messages` +(`type`,`targetckey`,`adminckey`,`text`,`timestamp`,`lasteditor`,`edits`) SELECT "watchlist entry", `ckey`, `adminckey`, `reason`, `timestamp`, `last_editor`, `edits` FROM `watch` It's not necessary to delete the 'notes', 'memos', and 'watchlist' tables but they will no longer be used. @@ -91,7 +187,7 @@ Remember to add a prefix to the table names if you use them Modified table 'notes', adding column 'secret'. -ALTER TABLE `feedback`.`notes` ADD COLUMN `secret` TINYINT(1) NOT NULL DEFAULT '1' AFTER `server` +ALTER TABLE `notes` ADD COLUMN `secret` TINYINT(1) NOT NULL DEFAULT '1' AFTER `server` Remember to add a prefix to the table name if you use them @@ -101,7 +197,7 @@ Remember to add a prefix to the table name if you use them Changed appearance bans to be jobbans. -UPDATE 'feedback'.`ban` SET `job` = "appearance", `bantype` = "JOB_PERMABAN" WHERE `bantype` = "APPEARANCE_PERMABAN" +UPDATE `ban` SET `job` = "appearance", `bantype` = "JOB_PERMABAN" WHERE `bantype` = "APPEARANCE_PERMABAN" Remember to add a prefix to the table name if you use them @@ -111,7 +207,7 @@ Remember to add a prefix to the table name if you use them Modified table 'poll_question', adding column 'dontshow' which was recently added to the server schema. -ALTER TABLE `feedback`.`poll_question` ADD COLUMN `dontshow` TINYINT(1) NOT NULL DEFAULT '0' AFTER `for_trialmin` +ALTER TABLE `poll_question` ADD COLUMN `dontshow` TINYINT(1) NOT NULL DEFAULT '0' AFTER `for_trialmin` Remember to add a prefix to the table name if you use them @@ -121,7 +217,7 @@ Remember to add a prefix to the table name if you use them Added ipintel table, only required if ip intel is enabled in the config -CREATE TABLE `ipintel` ( +CREATE TABLE `ipintel` ( `ip` INT UNSIGNED NOT NULL , `date` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL , `intel` REAL NOT NULL DEFAULT '0', @@ -134,7 +230,7 @@ PRIMARY KEY ( `ip` ) Modified table 'poll_question', adding columns 'createdby_ckey', 'createdby_ip' and 'for_trialmin' to bring it inline with the schema used by the tg servers. -ALTER TABLE `feedback`.`poll_question` ADD COLUMN `createdby_ckey` VARCHAR(45) NULL DEFAULT NULL AFTER `multiplechoiceoptions`, ADD COLUMN `createdby_ip` VARCHAR(45) NULL DEFAULT NULL AFTER `createdby_ckey`, ADD COLUMN `for_trialmin` VARCHAR(45) NULL DEFAULT NULL AFTER `createdby_ip` +ALTER TABLE `poll_question` ADD COLUMN `createdby_ckey` VARCHAR(45) NULL DEFAULT NULL AFTER `multiplechoiceoptions`, ADD COLUMN `createdby_ip` VARCHAR(45) NULL DEFAULT NULL AFTER `createdby_ckey`, ADD COLUMN `for_trialmin` VARCHAR(45) NULL DEFAULT NULL AFTER `createdby_ip` Remember to add a prefix to the table name if you use them @@ -144,7 +240,7 @@ Remember to add a prefix to the table name if you use them Modified table 'watch', removing 'id' column, making 'ckey' primary and adding the columns 'timestamp', 'adminckey', 'last_editor' and 'edits'. -ALTER TABLE `feedback`.`watch` DROP COLUMN `id`, ADD COLUMN `timestamp` datetime NOT NULL AFTER `reason`, ADD COLUMN `adminckey` varchar(32) NOT NULL AFTER `timestamp`, ADD COLUMN `last_editor` varchar(32) NULL AFTER `adminckey`, ADD COLUMN `edits` text NULL AFTER `last_editor`, DROP PRIMARY KEY, ADD PRIMARY KEY (`ckey`) +ALTER TABLE `watch` DROP COLUMN `id`, ADD COLUMN `timestamp` datetime NOT NULL AFTER `reason`, ADD COLUMN `adminckey` varchar(32) NOT NULL AFTER `timestamp`, ADD COLUMN `last_editor` varchar(32) NULL AFTER `adminckey`, ADD COLUMN `edits` text NULL AFTER `last_editor`, DROP PRIMARY KEY, ADD PRIMARY KEY (`ckey`) Remember to add a prefix to the table name if you use them. @@ -166,7 +262,7 @@ Remember to add prefix to the table name if you use them. Modified table 'memo', removing 'id' column and making 'ckey' primary. -ALTER TABLE `feedback`.`memo` DROP COLUMN `id`, DROP PRIMARY KEY, ADD PRIMARY KEY (`ckey`) +ALTER TABLE `memo` DROP COLUMN `id`, DROP PRIMARY KEY, ADD PRIMARY KEY (`ckey`) Remember to add prefix to the table name if you use them. From ea0f489f95eb4cc73837ddd66ca696fc69bc3bd1 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 2 Sep 2017 07:01:01 -0500 Subject: [PATCH 063/262] Update tgstation_schema_prefixed.sql --- SQL/tgstation_schema_prefixed.sql | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql index 094485df59..b810a82ca3 100644 --- a/SQL/tgstation_schema_prefixed.sql +++ b/SQL/tgstation_schema_prefixed.sql @@ -1,6 +1,3 @@ -CREATE DATABASE IF NOT EXISTS `feedback` /*!40100 DEFAULT CHARACTER SET latin1 */; -USE `feedback`; - /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; @@ -74,6 +71,7 @@ CREATE TABLE `SS13_ban` ( `bantime` datetime NOT NULL, `server_ip` int(10) unsigned NOT NULL, `server_port` smallint(5) unsigned NOT NULL, + `round_id` int(11) NOT NULL, `bantype` enum('PERMABAN','TEMPBAN','JOB_PERMABAN','JOB_TEMPBAN','ADMIN_PERMABAN','ADMIN_TEMPBAN') NOT NULL, `reason` varchar(2048) NOT NULL, `job` varchar(32) DEFAULT NULL, @@ -129,10 +127,13 @@ DROP TABLE IF EXISTS `SS13_death`; CREATE TABLE `SS13_death` ( `id` int(11) NOT NULL AUTO_INCREMENT, `pod` varchar(50) NOT NULL, - `coord` varchar(32) NOT NULL, + `x_coord` smallint(5) unsigned NOT NULL, + `y_coord` smallint(5) unsigned NOT NULL, + `z_coord` smallint(5) unsigned NOT NULL, `mapname` varchar(32) NOT NULL, `server_ip` int(10) unsigned NOT NULL, `server_port` smallint(5) unsigned NOT NULL, + `round_id` int(11) NOT NULL, `tod` datetime NOT NULL COMMENT 'Time of death', `job` varchar(32) NOT NULL, `special` varchar(32) DEFAULT NULL, @@ -140,7 +141,6 @@ CREATE TABLE `SS13_death` ( `byondkey` varchar(32) NOT NULL, `laname` varchar(96) DEFAULT NULL, `lakey` varchar(32) DEFAULT NULL, - `gender` enum('neuter','male','female','plural') NOT NULL, `bruteloss` smallint(5) unsigned NOT NULL, `brainloss` smallint(5) unsigned NOT NULL, `fireloss` smallint(5) unsigned NOT NULL, @@ -301,12 +301,12 @@ CREATE TABLE `SS13_poll_option` ( `id` int(11) NOT NULL AUTO_INCREMENT, `pollid` int(11) NOT NULL, `text` varchar(255) NOT NULL, - `percentagecalc` tinyint(1) NOT NULL DEFAULT '1', `minval` int(3) DEFAULT NULL, `maxval` int(3) DEFAULT NULL, `descmin` varchar(32) DEFAULT NULL, `descmid` varchar(32) DEFAULT NULL, `descmax` varchar(32) DEFAULT NULL, + `default_percentage_calc` tinyint(1) unsigned NOT NULL DEFAULT '1', PRIMARY KEY (`id`), KEY `idx_pop_pollid` (`pollid`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; @@ -403,6 +403,17 @@ CREATE TABLE `SS13_round` ( /*!40101 SET character_set_client = @saved_cs_client */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; +-- +-- Table structure for table `SS13_schema_revision` +-- +DROP TABLE IF EXISTS `SS13_schema_revision`; +CREATE TABLE `SS13_schema_revision` ( + `major` TINYINT(3) unsigned NOT NULL, + `minor` TINYINT(3) unsigned NOT NULL, + `date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`major`,`minor`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; From 31e3f6135a4711c6b7aa699217a5b835bc611cd7 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 2 Sep 2017 07:01:05 -0500 Subject: [PATCH 064/262] Update tgstation_schema.sql --- SQL/tgstation_schema.sql | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql index 4c19d0bd20..9795b90672 100644 --- a/SQL/tgstation_schema.sql +++ b/SQL/tgstation_schema.sql @@ -1,6 +1,3 @@ -CREATE DATABASE IF NOT EXISTS `feedback` /*!40100 DEFAULT CHARACTER SET latin1 */; -USE `feedback`; - /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; @@ -74,6 +71,7 @@ CREATE TABLE `ban` ( `bantime` datetime NOT NULL, `server_ip` int(10) unsigned NOT NULL, `server_port` smallint(5) unsigned NOT NULL, + `round_id` int(11) NOT NULL, `bantype` enum('PERMABAN','TEMPBAN','JOB_PERMABAN','JOB_TEMPBAN','ADMIN_PERMABAN','ADMIN_TEMPBAN') NOT NULL, `reason` varchar(2048) NOT NULL, `job` varchar(32) DEFAULT NULL, @@ -119,7 +117,6 @@ CREATE TABLE `connection_log` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; - -- -- Table structure for table `death` -- @@ -136,7 +133,7 @@ CREATE TABLE `death` ( `mapname` varchar(32) NOT NULL, `server_ip` int(10) unsigned NOT NULL, `server_port` smallint(5) unsigned NOT NULL, - `round_id` int(11) NOT NULL + `round_id` int(11) NOT NULL, `tod` datetime NOT NULL COMMENT 'Time of death', `job` varchar(32) NOT NULL, `special` varchar(32) DEFAULT NULL, @@ -155,7 +152,6 @@ CREATE TABLE `death` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; - -- -- Table structure for table `feedback` -- @@ -305,12 +301,12 @@ CREATE TABLE `poll_option` ( `id` int(11) NOT NULL AUTO_INCREMENT, `pollid` int(11) NOT NULL, `text` varchar(255) NOT NULL, - `percentagecalc` tinyint(1) NOT NULL DEFAULT '1', `minval` int(3) DEFAULT NULL, `maxval` int(3) DEFAULT NULL, `descmin` varchar(32) DEFAULT NULL, `descmid` varchar(32) DEFAULT NULL, `descmax` varchar(32) DEFAULT NULL, + `default_percentage_calc` tinyint(1) unsigned NOT NULL DEFAULT '1', PRIMARY KEY (`id`), KEY `idx_pop_pollid` (`pollid`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; @@ -407,6 +403,17 @@ CREATE TABLE `round` ( /*!40101 SET character_set_client = @saved_cs_client */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; +-- +-- Table structure for table `schema_revision` +-- +DROP TABLE IF EXISTS `schema_revision`; +CREATE TABLE `schema_revision` ( + `major` TINYINT(3) unsigned NOT NULL, + `minor` TINYINT(3) unsigned NOT NULL, + `date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`major`, `minor`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; From 2bfc7872faef501985bfb3b62b7a2f66312e657c Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 2 Sep 2017 07:06:37 -0500 Subject: [PATCH 065/262] cleanup --- code/game/objects/items/storage/boxes.dm.rej | 9 --------- code/modules/admin/verbs/randomverbs.dm.rej | 10 ---------- config/custom_roundstart_items.txt | 1 + tgstation.dme.rej | 13 ------------- 4 files changed, 1 insertion(+), 32 deletions(-) delete mode 100644 code/game/objects/items/storage/boxes.dm.rej delete mode 100644 code/modules/admin/verbs/randomverbs.dm.rej delete mode 100644 tgstation.dme.rej diff --git a/code/game/objects/items/storage/boxes.dm.rej b/code/game/objects/items/storage/boxes.dm.rej deleted file mode 100644 index c7e13676db..0000000000 --- a/code/game/objects/items/storage/boxes.dm.rej +++ /dev/null @@ -1,9 +0,0 @@ -diff a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm (rejected hunks) -@@ -732,7 +732,6 @@ - /obj/item/storage/box/ingredients //This box is for the randomely chosen version the chef spawns with, it shouldn't actually exist. - name = "ingredients box" - illustration = "donk_kit" -- icon_state = null - - /obj/item/storage/box/ingredients/Initialize() - ..() diff --git a/code/modules/admin/verbs/randomverbs.dm.rej b/code/modules/admin/verbs/randomverbs.dm.rej deleted file mode 100644 index 24b4116032..0000000000 --- a/code/modules/admin/verbs/randomverbs.dm.rej +++ /dev/null @@ -1,10 +0,0 @@ -diff a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm (rejected hunks) -@@ -1214,7 +1214,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits - - /client/proc/cmd_admin_check_player_exp() //Allows admins to determine who the newer players are. - set category = "Admin" -- set name = "Check Player Playtime" -+ set name = "Player Playtime" - if(!check_rights(R_ADMIN)) - return - diff --git a/config/custom_roundstart_items.txt b/config/custom_roundstart_items.txt index dd3ed5f2c3..1b2952615f 100644 --- a/config/custom_roundstart_items.txt +++ b/config/custom_roundstart_items.txt @@ -7,3 +7,4 @@ //test1|Memename Lastname|testjob1|/obj/item/device/aicard=3;/obj/item/device/flightpack=1;/obj/item/gun/energy=3 //kevinz000|Skylar Lineman|ALL|/obj/item/bikehorn/airhorn=1 //kevinz000|ALL|Clown|/obj/item/bikehorn=1 +JayEhh|ALL|ALL|/obj/item/bikehorn=1 diff --git a/tgstation.dme.rej b/tgstation.dme.rej deleted file mode 100644 index a5ff4dc3cb..0000000000 --- a/tgstation.dme.rej +++ /dev/null @@ -1,13 +0,0 @@ -diff a/tgstation.dme b/tgstation.dme (rejected hunks) -@@ -1746,6 +1745,11 @@ - #include "code\modules\mob\living\simple_animal\hostile\gorilla\emotes.dm" - #include "code\modules\mob\living\simple_animal\hostile\gorilla\gorilla.dm" - #include "code\modules\mob\living\simple_animal\hostile\gorilla\visuals_icons.dm" -+#include "code\modules\mob\living\simple_animal\hostile\jungle\_jungle_mobs.dm" -+#include "code\modules\mob\living\simple_animal\hostile\jungle\leaper.dm" -+#include "code\modules\mob\living\simple_animal\hostile\jungle\mega_arachnid.dm" -+#include "code\modules\mob\living\simple_animal\hostile\jungle\mook.dm" -+#include "code\modules\mob\living\simple_animal\hostile\jungle\seedling.dm" - #include "code\modules\mob\living\simple_animal\hostile\megafauna\blood_drunk_miner.dm" - #include "code\modules\mob\living\simple_animal\hostile\megafauna\bubblegum.dm" - #include "code\modules\mob\living\simple_animal\hostile\megafauna\colossus.dm" From 8731fb7e1c89cf1031001509024ec058fbb48a1f Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 2 Sep 2017 07:07:39 -0500 Subject: [PATCH 066/262] Delete database_changelog.txt.rej --- SQL/database_changelog.txt.rej | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 SQL/database_changelog.txt.rej diff --git a/SQL/database_changelog.txt.rej b/SQL/database_changelog.txt.rej deleted file mode 100644 index f65c192173..0000000000 --- a/SQL/database_changelog.txt.rej +++ /dev/null @@ -1,10 +0,0 @@ -diff a/SQL/database_changelog.txt b/SQL/database_changelog.txt (rejected hunks) -@@ -5,7 +5,7 @@ Also, added flags column to the player table. - - CREATE TABLE `role_time` ( `ckey` VARCHAR(32) NOT NULL , `job` VARCHAR(128) NOT NULL , `minutes` INT UNSIGNED NOT NULL, PRIMARY KEY (`ckey`, `job`) ) ENGINE = InnoDB; - --ALTER TABLE `player` ADD `flags` INT NOT NULL AFTER `accountjoindate`; -+ALTER TABLE `player` ADD `flags` INT NOT NULL default '0' AFTER `accountjoindate`; - - UPDATE `schema_revision` SET minor = 1; - From f4b08d32a716e2cb55fba4c9527c782d08ec1a97 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 2 Sep 2017 07:26:16 -0500 Subject: [PATCH 067/262] Update admin.dm --- code/modules/admin/admin.dm | 51 +++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index e6a1b3d383..358465ffc0 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -444,7 +444,7 @@ if("Hard Restart (No Delay, No Feeback Reason)") world.Reboot() if("Hardest Restart (No actions, just reboot)") - world.Reboot(fast_track = TRUE) + world.Reboot(fast_track = TRUE) if("Service Restart (Force restart DD)") GLOB.reboot_mode = REBOOT_MODE_HARD world.ServiceReboot() @@ -597,7 +597,7 @@ log_admin("[key_name(usr)] delayed the round start.") else to_chat(world, "The game will start in [newtime] seconds.") - SEND_SOUND(world, sound('sound/ai/attention.ogg')) + world << 'sound/ai/attention.ogg' log_admin("[key_name(usr)] set the pre-game delay to [newtime] seconds.") SSblackbox.add_details("admin_verb","Delay Game Start") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -737,33 +737,34 @@ var/dat = "Manage Free Slots" var/count = 0 - if(!SSticker.HasRoundStarted()) + if(SSticker && !SSticker.mode) alert(usr, "You cannot manage jobs before the round starts!") return - for(var/datum/job/job in SSjob.occupations) - count++ - var/J_title = html_encode(job.title) - var/J_opPos = html_encode(job.total_positions - (job.total_positions - job.current_positions)) - var/J_totPos = html_encode(job.total_positions) - if(job.total_positions < 0) - dat += "[J_title]: [J_opPos] (unlimited)" - else - dat += "[J_title]: [J_opPos]/[J_totPos]" - - if(job.title == "AI" || job.title == "Cyborg") - dat += " (Cannot Late Join)
" - continue - if(job.total_positions >= 0) - dat += " Add | " - if(job.total_positions > job.current_positions) - dat += "Remove | " + if(SSjob) + for(var/datum/job/job in SSjob.occupations) + count++ + var/J_title = html_encode(job.title) + var/J_opPos = html_encode(job.total_positions - (job.total_positions - job.current_positions)) + var/J_totPos = html_encode(job.total_positions) + if(job.total_positions < 0) + dat += "[J_title]: [J_opPos] (unlimited)" else - dat += "Remove | " - dat += "Unlimit" - else - dat += " Limit" - dat += "
" + dat += "[J_title]: [J_opPos]/[J_totPos]" + + if(job.title == "AI" || job.title == "Cyborg") + dat += " (Cannot Late Join)
" + continue + if(job.total_positions >= 0) + dat += " Add | " + if(job.total_positions > job.current_positions) + dat += "Remove | " + else + dat += "Remove | " + dat += "Unlimit" + else + dat += " Limit" + dat += "
" dat += "" var/winheight = 100 + (count * 20) From a94ffca643dc841c043a60c2e5615fd522e0621b Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 2 Sep 2017 07:28:33 -0500 Subject: [PATCH 068/262] Update admin.dm --- code/modules/admin/admin.dm | 47 ++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 358465ffc0..b88451b724 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -597,7 +597,7 @@ log_admin("[key_name(usr)] delayed the round start.") else to_chat(world, "The game will start in [newtime] seconds.") - world << 'sound/ai/attention.ogg' + SEND_SOUND(world, sound('sound/ai/attention.ogg')) log_admin("[key_name(usr)] set the pre-game delay to [newtime] seconds.") SSblackbox.add_details("admin_verb","Delay Game Start") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -737,34 +737,33 @@ var/dat = "Manage Free Slots" var/count = 0 - if(SSticker && !SSticker.mode) + if(!SSticker.HasRoundStarted()) alert(usr, "You cannot manage jobs before the round starts!") return - if(SSjob) - for(var/datum/job/job in SSjob.occupations) - count++ - var/J_title = html_encode(job.title) - var/J_opPos = html_encode(job.total_positions - (job.total_positions - job.current_positions)) - var/J_totPos = html_encode(job.total_positions) - if(job.total_positions < 0) - dat += "[J_title]: [J_opPos] (unlimited)" - else - dat += "[J_title]: [J_opPos]/[J_totPos]" + for(var/datum/job/job in SSjob.occupations) + count++ + var/J_title = html_encode(job.title) + var/J_opPos = html_encode(job.total_positions - (job.total_positions - job.current_positions)) + var/J_totPos = html_encode(job.total_positions) + if(job.total_positions < 0) + dat += "[J_title]: [J_opPos] (unlimited)" + else + dat += "[J_title]: [J_opPos]/[J_totPos]" - if(job.title == "AI" || job.title == "Cyborg") - dat += " (Cannot Late Join)
" - continue - if(job.total_positions >= 0) - dat += " Add | " - if(job.total_positions > job.current_positions) - dat += "Remove | " - else - dat += "Remove | " - dat += "Unlimit" + if(job.title == "AI" || job.title == "Cyborg") + dat += " (Cannot Late Join)
" + continue + if(job.total_positions >= 0) + dat += " Add | " + if(job.total_positions > job.current_positions) + dat += "Remove | " else - dat += " Limit" - dat += "
" + dat += "Remove | " + dat += "Unlimit" + else + dat += " Limit" + dat += "
" dat += "" var/winheight = 100 + (count * 20) From 7711b73ca790a2fb3f4fc9ac81379af585533cc6 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sat, 2 Sep 2017 07:31:52 -0500 Subject: [PATCH 069/262] Update randomverbs.dm --- code/modules/admin/verbs/randomverbs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index ca386ce110..dc7fda7a31 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -799,7 +799,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits 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/weapon/card/id) + var/list/ids = typesof(/obj/item/card/id) var/uniform_select = " + + [dropdownoptions_html.Join()] + + + + + + + +
+ + E - Edit, tries to determine the variable type by itself.
+ C - Change, asks you for the var type first.
+ M - Mass modify: changes this variable for all objects of this type.
+
+
+ + + + + +
+
+ Search: +
+
+ +
+
+
    + [variable_html.Join()] +
+ + + +"} + src << browse(html, "window=variables[refid];size=475x650") + + +#define VV_HTML_ENCODE(thing) ( sanitize ? html_encode(thing) : thing ) +/proc/debug_variable(name, value, level, datum/DA = null, sanitize = TRUE) + var/header + if(DA) + if (islist(DA)) + var/index = name + if (value) + name = DA[name] //name is really the index until this line + else + value = DA[name] + header = "
  • (E) (C) (-) " + else + header = "
  • (E) (C) (M) " + else + header = "
  • " + + var/item + if (isnull(value)) + item = "[VV_HTML_ENCODE(name)] = null" + + else if (istext(value)) + item = "[VV_HTML_ENCODE(name)] = \"[VV_HTML_ENCODE(value)]\"" + + else if (isicon(value)) + #ifdef VARSICON + var/icon/I = new/icon(value) + var/rnd = rand(1,10000) + var/rname = "tmp\ref[I][rnd].png" + usr << browse_rsc(I, rname) + item = "[VV_HTML_ENCODE(name)] = ([value]) " + #else + item = "[VV_HTML_ENCODE(name)] = /icon ([value])" + #endif + +/* else if (istype(value, /image)) + #ifdef VARSICON + var/rnd = rand(1, 10000) + var/image/I = value + + src << browse_rsc(I.icon, "tmp\ref[value][rnd].png") + html += "[name] = " + #else + html += "[name] = /image ([value])" + #endif +*/ + else if (isfile(value)) + item = "[VV_HTML_ENCODE(name)] = '[value]'" + + //else if (istype(value, /client)) + // var/client/C = value + // item = "[VV_HTML_ENCODE(name)] \ref[value] = [C] [C.type]" + + else if (istype(value, /datum)) + var/datum/D = value + if ("[D]" != "[D.type]") //if the thing as a name var, lets use it. + item = "[VV_HTML_ENCODE(name)] \ref[value] = [D] [D.type]" + else + item = "[VV_HTML_ENCODE(name)] \ref[value] = [D.type]" + + else if (islist(value)) + var/list/L = value + var/list/items = list() + + if (L.len > 0 && !(name == "underlays" || name == "overlays" || L.len > (IS_NORMAL_LIST(L) ? 50 : 150))) + for (var/i in 1 to L.len) + var/key = L[i] + var/val + if (IS_NORMAL_LIST(L) && !isnum(key)) + val = L[key] + if (!val) + val = key + key = i + + items += debug_variable(key, val, level + 1, sanitize = sanitize) + + item = "[VV_HTML_ENCODE(name)] = /list ([L.len])
      [items.Join()]
    " + else + item = "[VV_HTML_ENCODE(name)] = /list ([L.len])" + + else + item = "[VV_HTML_ENCODE(name)] = [VV_HTML_ENCODE(value)]" + + return "[header][item]
  • " + +#undef VV_HTML_ENCODE + +/client/proc/view_var_Topic(href, href_list, hsrc) + if( (usr.client != src) || !src.holder ) + return + if(href_list["Vars"]) + debug_variables(locate(href_list["Vars"])) + + else if(href_list["datumrefresh"]) + var/datum/DAT = locate(href_list["datumrefresh"]) + if(!DAT) //can't be an istype() because /client etc aren't datums + return + src.debug_variables(DAT) + + else if(href_list["mob_player_panel"]) + if(!check_rights(0)) + return + +>>>>>>> 6656ce6... Gives admins the ability to show a read only vv window to a player (#30463) var/mob/M = locate(href_list["mob_player_panel"]) in GLOB.mob_list if(!istype(M)) to_chat(usr, "This can only be used on instances of type /mob") @@ -541,6 +1008,7 @@ return var/mob/M = locate(href_list["regenerateicons"]) in GLOB.mob_list +<<<<<<< HEAD if(!ismob(M)) to_chat(usr, "This can only be done to instances of type /mob") return @@ -557,6 +1025,44 @@ if(!check_rights(0)) return +======= + if(!ismob(M)) + to_chat(usr, "This can only be done to instances of type /mob") + return + M.regenerate_icons() + else if(href_list["expose"]) + if(!check_rights(R_ADMIN, FALSE)) + return + var/thing = locate(href_list["expose"]) + if (!thing) + return + var/value = vv_get_value(VV_CLIENT) + if (value["class"] != VV_CLIENT) + return + var/client/C = value["value"] + if (!C) + return + var/prompt = alert("Do you want to grant [C] access to view this VV window? (they will not be able to edit or change anything nor open nested vv windows unless they themselves are an admin)", "Confirm", "Yes", "No") + if (prompt != "Yes" || !usr.client) + return + message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a VV window") + log_admin("Admin [key_name(usr)] Showed [key_name(C)] a VV window of a [thing]") + to_chat(C, "[usr.client.holder.fakekey ? "an Administrator" : "[usr.client.key]"] has granted you access to view a View Variables window") + C.debug_variables(thing) + + +//Needs +VAREDIT past this point + + else if(check_rights(R_VAREDIT)) + + + //~CARN: for renaming mobs (updates their name, real_name, mind.name, their ID/PDA and datacore records). + + if(href_list["rename"]) + if(!check_rights(0)) + return + +>>>>>>> 6656ce6... Gives admins the ability to show a read only vv window to a player (#30463) var/mob/M = locate(href_list["rename"]) in GLOB.mob_list if(!istype(M)) to_chat(usr, "This can only be used on instances of type /mob") From 938c10ad1cf0970693faa8996e6b5c376fb3b4eb Mon Sep 17 00:00:00 2001 From: Ashe Higgs Date: Thu, 7 Sep 2017 11:00:38 -0400 Subject: [PATCH 172/262] Adds a unique suicide to the hierophant club, plus some attack verbs (#30400) * Adds a suicide to the hierophant club * Above * good point * Removes the delay --- .../mining/lavaland/necropolis_chests.dm | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 4684c3039d..bf32c94058 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -481,7 +481,7 @@ icon_state = "oar" item_state = "oar" lefthand_file = 'icons/mob/inhands/misc/lavaland_lefthand.dmi' - righthand_file = 'icons/mob/inhands/misc/lavaland_righthand.dmi' + righthand_file = 'icons/mob/inhands/misc/lavaland_righthand.dmi' desc = "Not to be confused with the kind Research hassles you for." force = 12 w_class = WEIGHT_CLASS_NORMAL @@ -1012,6 +1012,7 @@ slot_flags = SLOT_BACK w_class = WEIGHT_CLASS_BULKY force = 15 + attack_verb = list("clubbed", "beat", "pummeled") hitsound = 'sound/weapons/sonic_jackhammer.ogg' actions_types = list(/datum/action/item_action/vortex_recall, /datum/action/item_action/toggle_unfriendly_fire) var/cooldown_time = 20 //how long the cooldown between non-melee ranged attacks is @@ -1028,6 +1029,21 @@ ..() to_chat(user, "The[beacon ? " beacon is not currently":"re is a beacon"] attached.") +/obj/item/hierophant_club/suicide_act(mob/living/user) + say("Xverwpsgexmrk...") + user.visible_message("[user] holds [src] into the air! It looks like [user.p_theyre()] trying to commit suicide!") + new/obj/effect/temp_visual/hierophant/telegraph(get_turf(user)) + playsound(user,'sound/machines/airlockopen.ogg', 75, TRUE) + user.visible_message("[user] fades out, leaving their belongings behind!") + for(var/obj/item/I in user) + if(I != src) + user.dropItemToGround(I) + for(var/turf/T in RANGE_TURFS(1, user)) + var/obj/effect/temp_visual/hierophant/blast/B = new(T, user, TRUE) + B.damage = 0 + user.dropItemToGround(src) //Drop us last, so it goes on top of their stuff + qdel(user) + /obj/item/hierophant_club/afterattack(atom/target, mob/user, proximity_flag, click_parameters) ..() var/turf/T = get_turf(target) From dd27a1850a0986c41b65d4961cf45c34fb83c4a8 Mon Sep 17 00:00:00 2001 From: kingofkosmos Date: Thu, 7 Sep 2017 18:11:41 +0300 Subject: [PATCH 174/262] Adds a message when trying to move while buckled --- code/_onclick/hud/alert.dm | 2 +- code/game/atoms.dm | 6 +++++- code/game/objects/buckling.dm | 4 +--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 69deb2cb58..638b4a31cf 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -633,6 +633,7 @@ so as to remain in compliance with the most up-to-date laws." /obj/screen/alert/restrained/buckled name = "Buckled" desc = "You've been buckled to something. Click the alert to unbuckle unless you're handcuffed." + icon_state = "buckled" /obj/screen/alert/restrained/handcuffed name = "Handcuffed" @@ -698,4 +699,3 @@ so as to remain in compliance with the most up-to-date laws." severity = 0 master = null screen_loc = "" - diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 272ec34d94..77bcefeddf 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -29,6 +29,7 @@ var/list/priority_overlays //overlays that should remain on top and not normally removed when using cut_overlay functions, like c4. var/datum/proximity_monitor/proximity_monitor + var/buckle_message_cooldown = 0 /atom/New(loc, ...) //atom creation method that preloads variables at creation @@ -291,7 +292,10 @@ else to_chat(user, "Nothing.") -/atom/proc/relaymove() +/atom/proc/relaymove(mob/user) + if(buckle_message_cooldown <= world.time) + buckle_message_cooldown = world.time + 50 + to_chat(user, "You can't move while buckled to [src]!") return /atom/proc/contents_explosion(severity, target) diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index 0648300147..ac54647468 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -62,7 +62,7 @@ M.setDir(dir) buckled_mobs |= M M.update_canmove() - M.throw_alert("buckled", /obj/screen/alert/restrained/buckled, new_master = src) + M.throw_alert("buckled", /obj/screen/alert/restrained/buckled) post_buckle_mob(M) return TRUE @@ -131,5 +131,3 @@ "You hear metal clanking.") add_fingerprint(user) return M - - From c1ccc985131c50c90f32766547a1f9556160c5db Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Thu, 7 Sep 2017 10:22:19 -0500 Subject: [PATCH 175/262] Automatic changelog generation for PR #2642 [ci skip] --- html/changelogs/AutoChangeLog-pr-2642.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-2642.yml diff --git a/html/changelogs/AutoChangeLog-pr-2642.yml b/html/changelogs/AutoChangeLog-pr-2642.yml new file mode 100644 index 0000000000..eb2a9a86cc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2642.yml @@ -0,0 +1,4 @@ +author: "Xhuis" +delete-after: True +changes: + - rscadd: "You can now kill yourself in fun and creative ways with the hierophant club." From df3b4c10bc7dd29c5c679699939013b69955f2c3 Mon Sep 17 00:00:00 2001 From: AnturK Date: Wed, 6 Sep 2017 14:56:56 +0200 Subject: [PATCH 176/262] Fixes containment field CanPass --- .../power/singularity/containment_field.dm | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm index ca25ce708f..f819b35d75 100644 --- a/code/modules/power/singularity/containment_field.dm +++ b/code/modules/power/singularity/containment_field.dm @@ -57,8 +57,7 @@ /obj/machinery/field/containment/Crossed(mob/mover) if(isliving(mover)) shock(mover) - -/obj/machinery/field/containment/Crossed(obj/mover) + if(istype(mover, /obj/machinery) || istype(mover, /obj/structure) || istype(mover, /obj/mecha)) bump_field(mover) @@ -79,21 +78,25 @@ qdel(src) - // Abstract Field Class // Used for overriding certain procs /obj/machinery/field var/hasShocked = FALSE //Used to add a delay between shocks. In some cases this used to crash servers by spawning hundreds of sparks every second. -/obj/machinery/field/CanPass(atom/movable/mover, turf/target) +/obj/machinery/field/CollidedWith(atom/movable/mover) if(hasShocked) - return FALSE - if(isliving(mover)) // Don't let mobs through + return + if(isliving(mover)) shock(mover) - return FALSE + return if(istype(mover, /obj/machinery) || istype(mover, /obj/structure) || istype(mover, /obj/mecha)) bump_field(mover) + return + + +/obj/machinery/field/CanPass(atom/movable/mover, turf/target) + if(hasShocked || isliving(mover) || istype(mover, /obj/machinery) || istype(mover, /obj/structure) || istype(mover, /obj/mecha)) return FALSE return ..() From f4dbb6dc365138669b10853682b4e1a690211a3c Mon Sep 17 00:00:00 2001 From: kingofkosmos Date: Wed, 6 Sep 2017 12:35:58 +0300 Subject: [PATCH 178/262] Fixes drone light toggle while dead --- .../mob/living/simple_animal/friendly/drone/verbs.dm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm b/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm index 18bd4cc3b0..2b35ba1b55 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm @@ -15,6 +15,12 @@ /mob/living/simple_animal/drone/verb/toggle_light() set category = "Drone" set name = "Toggle drone light" +<<<<<<< HEAD +======= + if(stat == DEAD) + to_chat(src, "There's no light in your life... by that I mean you're dead.") + return +>>>>>>> a2511ab... Makes things worse for someone who's already having a difficult time. if(light_on) set_light(0) else From c2c69d359f1255e1869d9a9b69bc8633cee9dd38 Mon Sep 17 00:00:00 2001 From: AnturK Date: Wed, 6 Sep 2017 10:44:38 +0200 Subject: [PATCH 179/262] Fixes shuttle name on ramming. --- code/modules/shuttle/on_move.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 59a0a46ae8..e80b690737 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -14,7 +14,12 @@ All ShuttleMove procs go here // Called from the new turf before anything has been moved // Only gets called if fromShuttleMove returns true first // returns the new move_mode (based on the old) +<<<<<<< HEAD /turf/proc/toShuttleMove(turf/oldT, shuttle_dir, move_mode) +======= +/turf/proc/toShuttleMove(turf/oldT, move_mode, obj/docking_port/mobile/shuttle) + var/shuttle_dir = shuttle.dir +>>>>>>> 9ac60a8... Typo for(var/i in contents) var/atom/movable/thing = i if(ismob(thing)) From b6eddd8845223d4a6b428c0492225e12517e8c9b Mon Sep 17 00:00:00 2001 From: ExcessiveUseOfCobblestone <11748095+ExcessiveUseOfCobblestone@users.noreply.github.com> Date: Tue, 5 Sep 2017 21:57:02 -0400 Subject: [PATCH 180/262] ok --- code/modules/clothing/suits/miscellaneous.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index 9e1f1de829..fe6fe67b83 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -280,6 +280,7 @@ body_parts_covered = HEAD flags_1 = THICKMATERIAL_1 flags_inv = HIDEHAIR|HIDEEARS + dynamic_hair_suffix = "" /obj/item/clothing/suit/hooded/bloated_human //OH MY GOD WHAT HAVE YOU DONE!?!?!? name = "bloated human suit" From b172025e960f7a885de0b48ddcf66a0a702fb369 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Tue, 5 Sep 2017 14:41:36 -0500 Subject: [PATCH 182/262] Disablers and ions wont burn statues --- code/game/objects/structures/statues.dm | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index d2e008f4f8..63333ba07b 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -155,12 +155,9 @@ /obj/structure/statue/plasma/bullet_act(obj/item/projectile/Proj) var/burn = FALSE - if(istype(Proj, /obj/item/projectile/beam)) + if(!(Proj.nodamage) && Proj.damage_type == BURN) PlasmaBurn(2500) burn = TRUE - else if(istype(Proj, /obj/item/projectile/ion)) - PlasmaBurn(500) - burn = TRUE if(burn) var/turf/T = get_turf(src) if(Proj.firer) From ff219f365e865d16f121dc088a9c0e5e4b21d9f1 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Thu, 7 Sep 2017 11:57:51 -0500 Subject: [PATCH 185/262] Update goliath.dm (#30486) --- .../mob/living/simple_animal/hostile/mining_mobs/goliath.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm index 427628984c..598b6c8ff0 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/goliath.dm @@ -31,6 +31,7 @@ var/pre_attack = 0 var/pre_attack_icon = "Goliath_preattack" loot = list(/obj/item/stack/sheet/animalhide/goliath_hide) + butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/goliath = 2, /obj/item/stack/sheet/animalhide/goliath_hide = 1, /obj/item/stack/sheet/bone = 2) /mob/living/simple_animal/hostile/asteroid/goliath/Life() ..() @@ -101,7 +102,6 @@ pre_attack_icon = "Goliath_preattack" throw_message = "does nothing to the rocky hide of the" loot = list(/obj/item/stack/sheet/animalhide/goliath_hide) //A throwback to the asteroid days - butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/goliath = 2, /obj/item/stack/sheet/bone = 2) /mob/living/simple_animal/hostile/asteroid/goliath/beast/tendril fromtendril = TRUE From b9bbd348df9963cc1ec65340f92b7434ee2a8822 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Thu, 7 Sep 2017 12:48:26 -0500 Subject: [PATCH 187/262] You can now drag things up and down ladders (#30202) * Can drag things up and down ladders * Somehow left out this line * Icon update, auto_connect * Uses the proper pulling proc --- code/game/objects/structures/ladders.dm | 40 ++++++++++++++++--------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm index 84d9481464..c1a45ad20e 100644 --- a/code/game/objects/structures/ladders.dm +++ b/code/game/objects/structures/ladders.dm @@ -7,6 +7,7 @@ var/height = 0 //the 'height' of the ladder. higher numbers are considered physically higher var/obj/structure/ladder/down = null //the ladder below this one var/obj/structure/ladder/up = null //the ladder above this one + var/auto_connect = FALSE /obj/structure/ladder/unbreakable //mostly useful for awaymissions to prevent halting progress in a mission name = "sturdy ladder" @@ -19,12 +20,18 @@ return INITIALIZE_HINT_LATELOAD /obj/structure/ladder/Destroy() + if(up && up.down == src) + up.down = null + up.update_icon() + if(down && down.up == src) + down.up = null + down.update_icon() GLOB.ladders -= src . = ..() /obj/structure/ladder/LateInitialize() for(var/obj/structure/ladder/L in GLOB.ladders) - if(L.id == id) + if(L.id == id || (auto_connect && L.auto_connect && L.x == x && L.y == y)) if(L.height == (height - 1)) down = L continue @@ -50,31 +57,33 @@ else //wtf make your ladders properly assholes icon_state = "ladder00" -/obj/structure/ladder/proc/go_up(mob/user,is_ghost) +/obj/structure/ladder/proc/travel(going_up, mob/user, is_ghost, obj/structure/ladder/ladder) if(!is_ghost) - show_fluff_message(1,user) - up.add_fingerprint(user) - user.loc = get_turf(up) + show_fluff_message(going_up,user) + ladder.add_fingerprint(user) + + var/atom/movable/AM + if(user.pulling) + AM = user.pulling + user.pulling.forceMove(get_turf(ladder)) + user.forceMove(get_turf(ladder)) + if(AM) + user.start_pulling(AM) -/obj/structure/ladder/proc/go_down(mob/user,is_ghost) - if(!is_ghost) - show_fluff_message(0,user) - down.add_fingerprint(user) - user.loc = get_turf(down) /obj/structure/ladder/proc/use(mob/user,is_ghost=0) if(up && down) switch( alert("Go up or down the ladder?", "Ladder", "Up", "Down", "Cancel") ) if("Up") - go_up(user,is_ghost) + travel(TRUE, user, is_ghost, up) if("Down") - go_down(user,is_ghost) + travel(FALSE, user, is_ghost, down) if("Cancel") return else if(up) - go_up(user,is_ghost) + travel(TRUE, user, is_ghost, up) else if(down) - go_down(user,is_ghost) + travel(FALSE, user,is_ghost, down) else to_chat(user, "[src] doesn't seem to lead anywhere!") @@ -108,3 +117,6 @@ . = ..() else return QDEL_HINT_LETMELIVE + +/obj/structure/ladder/auto_connect //They will connect to ladders with the same X and Y without needing to share an ID + auto_connect = TRUE \ No newline at end of file From 7155e1c63157cd55fc16f5101563a8627bf0bef9 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Thu, 7 Sep 2017 16:17:35 -0500 Subject: [PATCH 189/262] Automatic changelog generation for PR #2651 [ci skip] --- html/changelogs/AutoChangeLog-pr-2651.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-2651.yml diff --git a/html/changelogs/AutoChangeLog-pr-2651.yml b/html/changelogs/AutoChangeLog-pr-2651.yml new file mode 100644 index 0000000000..18dfe3ec3d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2651.yml @@ -0,0 +1,4 @@ +author: "Jay" +delete-after: True +changes: + - bugfix: "Goliaths can be butchered again" From 50cd75df7d8518d6fca3d1b3403c650e8a3c39e6 Mon Sep 17 00:00:00 2001 From: Poojawa Date: Fri, 8 Sep 2017 06:55:19 -0500 Subject: [PATCH 190/262] Actually makes Citadel reagents process (#2653) --- code/citadel/cit_reagents.dm | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/code/citadel/cit_reagents.dm b/code/citadel/cit_reagents.dm index 4a0e91479b..30b4da7ccf 100644 --- a/code/citadel/cit_reagents.dm +++ b/code/citadel/cit_reagents.dm @@ -46,7 +46,7 @@ name = "Female Ejaculate" id = "femcum" description = "Vaginal lubricant found in most mammals and other animals of similar nature. Where you found this is your own business." - taste_description = "female arousal" + taste_description = "something with a tang" // wew coders who haven't eaten out a girl. taste_mult = 2 data = list("donor"=null,"viruses"=null,"donor_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null) reagent_state = LIQUID @@ -90,7 +90,7 @@ //aphrodisiac & anaphrodisiac -/datum/reagent/aphrodisiac +/datum/reagent/drug/aphrodisiac name = "Crocin" id = "aphro" description = "Naturally found in the crocus and gardenia flowers, this drug acts as a natural and safe aphrodisiac." @@ -98,7 +98,7 @@ taste_mult = 2 //Hide the roofies in stronger flavors color = "#FFADFF"//PINK, rgb(255, 173, 255) -/datum/reagent/aphrodisiac/on_mob_life(mob/living/M) +/datum/reagent/drug/aphrodisiac/on_mob_life(mob/living/M) if(prob(33)) M.adjustArousalLoss(2) if(prob(5)) @@ -108,7 +108,7 @@ to_chat(M, "[aroused_message]") ..() -/datum/reagent/aphrodisiacplus +/datum/reagent/drug/aphrodisiacplus name = "Hexacrocin" id = "aphro+" description = "Chemically condensed form of basic crocin. This aphrodisiac is extremely powerful and addictive in most animals.\ @@ -119,7 +119,7 @@ addiction_threshold = 20 overdose_threshold = 20 -/datum/reagent/aphrodisiacplus/on_mob_life(mob/living/M) +/datum/reagent/drug/aphrodisiacplus/on_mob_life(mob/living/M) if(prob(33)) M.adjustArousalLoss(6)//not quite six times as powerful, but still considerably more powerful. if(prob(5)) @@ -135,21 +135,21 @@ aroused_message = pick("You feel a bit hot.", "You feel strong sexual urges.", "You feel in the mood.", "You're ready to go down on someone.") to_chat(M, "[aroused_message]") -/datum/reagent/aphrodisiacplus/addiction_act_stage2(mob/living/M) +/datum/reagent/drug/aphrodisiacplus/addiction_act_stage2(mob/living/M) if(prob(30)) M.adjustBrainLoss(2) ..() -/datum/reagent/aphrodisiacplus/addiction_act_stage3(mob/living/M) +/datum/reagent/drug/aphrodisiacplus/addiction_act_stage3(mob/living/M) if(prob(30)) M.adjustBrainLoss(3) ..() -/datum/reagent/aphrodisiacplus/addiction_act_stage4(mob/living/M) +/datum/reagent/drug/aphrodisiacplus/addiction_act_stage4(mob/living/M) if(prob(30)) M.adjustBrainLoss(4) ..() -/datum/reagent/aphrodisiacplus/overdose_process(mob/living/M) +/datum/reagent/drug/aphrodisiacplus/overdose_process(mob/living/M) if(prob(33)) if(M.getArousalLoss() >= 100 && ishuman(M) && M.has_dna()) var/mob/living/carbon/human/H = M @@ -163,7 +163,7 @@ M.adjustArousalLoss(2) ..() -/datum/reagent/anaphrodisiac +/datum/reagent/drug/anaphrodisiac name = "Camphor" id = "anaphro" description = "Naturally found in some species of evergreen trees, camphor is a waxy substance. When injested by most animals, it acts as an anaphrodisiac\ @@ -173,12 +173,12 @@ color = "#D9D9D9"//rgb(217, 217, 217) reagent_state = SOLID -/datum/reagent/anaphrodisiac/on_mob_life(mob/living/M) +/datum/reagent/drug/anaphrodisiac/on_mob_life(mob/living/M) if(prob(33)) M.adjustArousalLoss(-2) ..() -/datum/reagent/anaphrodisiacplus +/datum/reagent/drug/anaphrodisiacplus name = "Hexacamphor" id = "anaphro+" description = "Chemically condensed camphor. Causes an extreme reduction in libido and a permanent one if overdosed. Non-addictive." @@ -187,12 +187,12 @@ reagent_state = SOLID overdose_threshold = 20 -/datum/reagent/anaphrodisiacplus/on_mob_life(mob/living/M) +/datum/reagent/drug/anaphrodisiacplus/on_mob_life(mob/living/M) if(prob(33)) M.adjustArousalLoss(-4) ..() -/datum/reagent/anaphrodisiacplus/overdose_process(mob/living/M) +/datum/reagent/drug/anaphrodisiacplus/overdose_process(mob/living/M) if(prob(33)) if(M.min_arousal > 0) M.min_arousal -= 1 From ed4488bd1dc74b82ea544a3fe472b8659b52a298 Mon Sep 17 00:00:00 2001 From: Poojawa Date: Fri, 8 Sep 2017 06:55:51 -0500 Subject: [PATCH 191/262] cleans merge conflict mess of #2638 (#2639) --- tools/github_webhook_processor.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tools/github_webhook_processor.php b/tools/github_webhook_processor.php index 3f1120fad8..6113714566 100644 --- a/tools/github_webhook_processor.php +++ b/tools/github_webhook_processor.php @@ -138,11 +138,7 @@ function tag_pr($payload, $opened) { if(strpos($lowertitle, 'refactor') !== FALSE) $tags[] = 'Refactor'; -<<<<<<< HEAD - if(strpos($lowertitle, 'revert') !== FALSE || strpos($lowertitle, 'removes') !== FALSE) -======= if(strpos(strtolower($title), 'revert') !== FALSE || strpos(strtolower($title), 'removes') !== FALSE) ->>>>>>> 6d41d71... Another fix (#30441) $tags[] = 'Revert/Removal'; } From 62225acc2b91c17ea74f67a405ffc5af658e5608 Mon Sep 17 00:00:00 2001 From: Poojawa Date: Fri, 8 Sep 2017 06:56:31 -0500 Subject: [PATCH 192/262] Update verbs.dm --- code/modules/mob/living/simple_animal/friendly/drone/verbs.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm b/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm index 2b35ba1b55..49faea14b3 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/verbs.dm @@ -15,12 +15,10 @@ /mob/living/simple_animal/drone/verb/toggle_light() set category = "Drone" set name = "Toggle drone light" -<<<<<<< HEAD -======= + if(stat == DEAD) to_chat(src, "There's no light in your life... by that I mean you're dead.") return ->>>>>>> a2511ab... Makes things worse for someone who's already having a difficult time. if(light_on) set_light(0) else From ce787e7726416e68b03389fbbb2558c197848f0b Mon Sep 17 00:00:00 2001 From: Poojawa Date: Fri, 8 Sep 2017 06:58:08 -0500 Subject: [PATCH 193/262] Reverts sav file persistance for poly/pun-pun (#2654) * Reverts sav file persistance for poly/pun-pun * makes sure poly writes to poly --- code/controllers/subsystem/persistence.dm | 133 +++++++----------- .../mob/living/carbon/human/interactive.dm | 33 ++--- .../mob/living/carbon/monkey/punpun.dm | 28 ++-- .../mob/living/simple_animal/friendly/cat.dm | 19 +-- .../mob/living/simple_animal/friendly/dog.dm | 25 ++-- .../hostile/megafauna/colossus.dm | 19 +-- .../mob/living/simple_animal/parrot.dm | 28 ++-- 7 files changed, 108 insertions(+), 177 deletions(-) diff --git a/code/controllers/subsystem/persistence.dm b/code/controllers/subsystem/persistence.dm index 0137953a65..8b8bc81ad2 100644 --- a/code/controllers/subsystem/persistence.dm +++ b/code/controllers/subsystem/persistence.dm @@ -2,13 +2,15 @@ SUBSYSTEM_DEF(persistence) name = "Persistence" init_order = INIT_ORDER_PERSISTENCE flags = SS_NO_FIRE + var/secret_satchels var/list/satchel_blacklist = list() //this is a typecache var/list/new_secret_satchels = list() //these are objects - var/list/old_secret_satchels = list() + var/list/old_secret_satchels = "" var/list/obj/structure/chisel_message/chisel_messages = list() var/list/saved_messages = list() + var/trophy_sav var/list/saved_trophies = list() /datum/controller/subsystem/persistence/Initialize() @@ -19,45 +21,30 @@ SUBSYSTEM_DEF(persistence) ..() /datum/controller/subsystem/persistence/proc/LoadSatchels() - var/placed_satchel = 0 - var/path - var/obj/item/storage/backpack/satchel/flat/F = new() - if(fexists("data/npc_saves/SecretSatchels.sav")) //legacy compatability to convert old format to new - var/savefile/secret_satchels = new /savefile("data/npc_saves/SecretSatchels.sav") - var/sav_text - secret_satchels[SSmapping.config.map_name] >> sav_text - fdel("data/npc_saves/SecretSatchels.sav") - if(sav_text) - old_secret_satchels = splittext(sav_text,"#") - if(old_secret_satchels.len >= 20) - var/satchel_string = pick_n_take(old_secret_satchels) - var/list/chosen_satchel = splittext(satchel_string,"|") - if(chosen_satchel.len == 3) - F.x = text2num(chosen_satchel[1]) - F.y = text2num(chosen_satchel[2]) - F.z = ZLEVEL_STATION - path = text2path(chosen_satchel[3]) - else - var/json_file = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json") - if(!fexists(json_file)) - return - var/list/json = list() - json = json_decode(file2text(json_file)) - old_secret_satchels = json["data"] - if(old_secret_satchels.len) - if(old_secret_satchels.len >= 20) //guards against low drop pools assuring that one player cannot reliably find his own gear. - var/pos = rand(1, old_secret_satchels.len) - old_secret_satchels.Cut(pos, pos+1) - F.x = old_secret_satchels[pos]["x"] - F.y = old_secret_satchels[pos]["y"] - F.z = ZLEVEL_STATION - path = text2path(old_secret_satchels[pos]["saved_obj"]) - if(!ispath(path)) + secret_satchels = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json") + if(!fexists(secret_satchels)) return - if(isfloorturf(F.loc) && !istype(F.loc, /turf/open/floor/plating/)) - F.hide(1) - new path(F) - placed_satchel++ + satchel_blacklist = typecacheof(list(/obj/item/stack/tile/plasteel, /obj/item/crowbar)) + var/list/json = list() + json = json_decode(file2text(secret_satchels)) + old_secret_satchels = json["data"] + var/placed_satchel = 0 + if(old_secret_satchels.len) + if(old_secret_satchels.len >= 20) //guards against low drop pools assuring that one player cannot reliably find his own gear. + var/pos = rand(1, old_secret_satchels.len) + old_secret_satchels.Cut(pos, pos+1) + var/obj/item/storage/backpack/satchel/flat/F = new() + F.x = old_secret_satchels[pos]["x"] + F.y = old_secret_satchels[pos]["y"] + F.z = ZLEVEL_STATION + var/path = text2path(old_secret_satchels[pos]["saved_obj"]) + if(!ispath(path)) + return + if(isfloorturf(F.loc) && !istype(F.loc, /turf/open/floor/plating/)) + F.hide(1) + new path(F) + placed_satchel++ + var/list/free_satchels = list() for(var/turf/T in shuffle(block(locate(TRANSITIONEDGE,TRANSITIONEDGE,ZLEVEL_STATION), locate(world.maxx-TRANSITIONEDGE,world.maxy-TRANSITIONEDGE,ZLEVEL_STATION)))) //Nontrivially expensive but it's roundstart only if(isfloorturf(T) && !istype(T, /turf/open/floor/plating/)) @@ -71,25 +58,16 @@ SUBSYSTEM_DEF(persistence) break //Who's been duping the bird?! /datum/controller/subsystem/persistence/proc/LoadChiselMessages() - var/list/saved_messages = list() - if(fexists("data/npc_saves/ChiselMessages.sav")) //legacy compatability to convert old format to new - var/savefile/chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav") - var/saved_json - chisel_messages_sav[SSmapping.config.map_name] >> saved_json - if(!saved_json) - return - saved_messages = json_decode(saved_json) - fdel("data/npc_saves/ChiselMessages.sav") - else - var/json_file = file("data/npc_saves/ChiselMessages[SSmapping.config.map_name].json") - if(!fexists(json_file)) - return - var/list/json - json = json_decode(file2text(json_file)) + var/json_file = file("data/npc_saves/ChiselMessages[SSmapping.config.map_name].json") + if(!fexists(json_file)) + return + var/list/json + json = json_decode(file2text(json_file)) - if(!json) - return - saved_messages = json["data"] + if(!json) + return + + var/list/saved_messages = json["data"] for(var/item in saved_messages) if(!islist(item)) @@ -117,23 +95,17 @@ SUBSYSTEM_DEF(persistence) log_world("Loaded [saved_messages.len] engraved messages on map [SSmapping.config.map_name]") /datum/controller/subsystem/persistence/proc/LoadTrophies() - if(fexists("data/npc_saves/TrophyItems.sav")) //legacy compatability to convert old format to new - var/savefile/S = new /savefile("data/npc_saves/TrophyItems.sav") - var/saved_json - S >> saved_json - if(!saved_json) - return - saved_trophies = json_decode(saved_json) - fdel("data/npc_saves/TrophyItems.sav") - else - var/json_file = file("data/npc_saves/TrophyItems.json") - if(!fexists(json_file)) - return - var/list/json = list() - json = json_decode(file2text(json_file)) - if(!json) - return - saved_trophies = json["data"] + trophy_sav = file("data/npc_saves/TrophyItems.json") + if(!fexists(trophy_sav)) + return + var/list/json = list() + json = json_decode(file2text(trophy_sav)) + + if(!json) + return + + saved_trophies = json["data"] + SetUpTrophies(saved_trophies.Copy()) /datum/controller/subsystem/persistence/proc/SetUpTrophies(list/trophy_items) @@ -168,7 +140,6 @@ SUBSYSTEM_DEF(persistence) /datum/controller/subsystem/persistence/proc/CollectSecretSatchels() var/list/satchels = list() - satchel_blacklist = typecacheof(list(/obj/item/stack/tile/plasteel, /obj/item/crowbar)) for(var/A in new_secret_satchels) var/obj/item/storage/backpack/satchel/flat/F = A if(QDELETED(F) || F.z != ZLEVEL_STATION || F.invisibility != INVISIBILITY_MAXIMUM) @@ -188,11 +159,10 @@ SUBSYSTEM_DEF(persistence) data["y"] = F.y data["saved_obj"] = pick(savable_obj) satchels += list(data) - var/json_file = file("data/npc_saves/SecretSatchels[SSmapping.config.map_name].json") var/list/file_data = list() file_data["data"] = satchels - fdel(json_file) - WRITE_FILE(json_file, json_encode(file_data)) + fdel(secret_satchels) + WRITE_FILE(secret_satchels, json_encode(file_data)) /datum/controller/subsystem/persistence/proc/CollectChiselMessages() var/json_file = file("data/npc_saves/ChiselMessages[SSmapping.config.map_name].json") @@ -211,11 +181,10 @@ SUBSYSTEM_DEF(persistence) /datum/controller/subsystem/persistence/proc/CollectTrophies() - var/json_file = file("data/npc_saves/TrophyItems.json") var/list/file_data = list() file_data["data"] = saved_trophies - fdel(json_file) - WRITE_FILE(json_file, json_encode(file_data)) + fdel(trophy_sav) + WRITE_FILE(trophy_sav, json_encode(file_data)) /datum/controller/subsystem/persistence/proc/SaveTrophy(obj/structure/displaycase/trophy/T) if(!T.added_roundstart && T.showpiece) @@ -223,4 +192,4 @@ SUBSYSTEM_DEF(persistence) data["path"] = T.showpiece.type data["message"] = T.trophy_message data["placer_key"] = T.placer_key - saved_trophies += list(data) + saved_trophies += list(data) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/interactive.dm b/code/modules/mob/living/carbon/human/interactive.dm index b1eaa5349b..7a80758eae 100644 --- a/code/modules/mob/living/carbon/human/interactive.dm +++ b/code/modules/mob/living/carbon/human/interactive.dm @@ -87,17 +87,12 @@ /// SNPC voice handling /mob/living/carbon/human/interactive/proc/loadVoice() - if(fexists("data/npc_saves/snpc.sav")) - var/savefile/S = new /savefile("data/npc_saves/snpc.sav") - S["knownStrings"] >> knownStrings - fdel(S) - else - var/json_file = file("data/npc_saves/snpc.json") - if(!fexists(json_file)) - return - var/list/json = list() - json = json_decode(file2text(json_file)) - knownStrings = json["knownStrings"] + var/json_file = file("data/npc_saves/snpc.json") + if(!fexists(json_file)) + return + var/list/json = list() + json = json_decode(file2text(json_file)) + knownStrings = json["knownStrings"] if(isnull(knownStrings)) knownStrings = list() @@ -295,7 +290,7 @@ //job specific favours switch(myjob.title) if("Assistant") - favoured_types = list(/obj/item/clothing, /obj/item/weapon) + favoured_types = list(/obj/item/clothing, /obj/item) if("Captain","Head of Personnel") favoured_types = list(/obj/item/clothing, /obj/item/stamp/captain, /obj/item/disk/nuclear) if("Cook") @@ -307,14 +302,14 @@ functions += "bartend" restrictedJob = 1 if("Station Engineer","Chief Engineer","Atmospheric Technician") - favoured_types = list(/obj/item/stack, /obj/item/weapon, /obj/item/clothing) + favoured_types = list(/obj/item/stack, /obj/item, /obj/item/clothing) if("Chief Medical Officer","Medical Doctor","Chemist","Virologist","Geneticist") favoured_types = list(/obj/item/reagent_containers/glass/beaker, /obj/item/storage/firstaid, /obj/item/stack/medical, /obj/item/reagent_containers/syringe) functions += "healpeople" if("Research Director","Scientist","Roboticist") favoured_types = list(/obj/item/reagent_containers/glass/beaker, /obj/item/stack, /obj/item/reagent_containers) if("Head of Security","Warden","Security Officer","Detective") - favoured_types = list(/obj/item/clothing, /obj/item/weapon, /obj/item/restraints) + favoured_types = list(/obj/item/clothing, /obj/item, /obj/item/restraints) if("Janitor") favoured_types = list(/obj/item/mop, /obj/item/reagent_containers/glass/bucket, /obj/item/reagent_containers/spray/cleaner, /obj/effect/decal/cleanable) functions += "dojanitor" @@ -324,7 +319,7 @@ if("Mime") functions -= "chatter" if("Botanist") - favoured_types = list(/obj/machinery/hydroponics, /obj/item/reagent_containers, /obj/item/weapon) + favoured_types = list(/obj/machinery/hydroponics, /obj/item/reagent_containers, /obj/item) functions += "botany" restrictedJob = 1 else @@ -644,7 +639,7 @@ insert_into_backpack() // dump random item into backpack to make space //---------ITEMS if(isitem(TARGET)) - if(istype(TARGET, /obj/item/weapon)) + if(istype(TARGET, /obj/item)) var/obj/item/W = TARGET if(W.force >= best_force || prob((FUZZY_CHANCE_LOW+FUZZY_CHANCE_HIGH)/2)) if(!get_item_for_held_index(1) || !get_item_for_held_index(2)) @@ -1484,7 +1479,7 @@ foundFav = 1 return if(!foundFav) - if(istype(test, /obj/item/weapon)) + if(istype(test, /obj/item)) var/obj/item/R = test if(R.force > 2) // make sure we don't equip any non-weaponlike items, ie bags and stuff if(!best) @@ -1509,7 +1504,7 @@ if(istype(A, /obj/item/gun)) // guns are for shooting, not throwing. continue if(prob(robustness)) - if(istype(A, /obj/item/weapon)) + if(istype(A, /obj/item)) var/obj/item/W = A if(W.throwforce > 19) // Only throw worthwile stuff, no more lobbing wrenches at wenches npcDrop(W,1) @@ -1623,4 +1618,4 @@ TRAITS |= TRAIT_ROBUST TRAITS |= TRAIT_SMART faction += "bot_power" - ..() + ..() \ No newline at end of file diff --git a/code/modules/mob/living/carbon/monkey/punpun.dm b/code/modules/mob/living/carbon/monkey/punpun.dm index 2cf821093d..711e771074 100644 --- a/code/modules/mob/living/carbon/monkey/punpun.dm +++ b/code/modules/mob/living/carbon/monkey/punpun.dm @@ -42,23 +42,15 @@ ..() /mob/living/carbon/monkey/punpun/proc/Read_Memory() - if(fexists("data/npc_saves/Punpun.sav")) //legacy compatability to convert old format to new - var/savefile/S = new /savefile("data/npc_saves/Punpun.sav") - S["ancestor_name"] >> ancestor_name - S["ancestor_chain"] >> ancestor_chain - S["relic_hat"] >> relic_hat - S["relic_mask"] >> relic_mask - fdel("data/npc_saves/Punpun.sav") - else - var/json_file = file("data/npc_saves/Punpun.json") - if(!fexists(json_file)) - return - var/list/json = list() - json = json_decode(file2text(json_file)) - ancestor_name = json["ancestor_name"] - ancestor_chain = json["ancestor_chain"] - relic_hat = json["relic_hat"] - relic_mask = json["relic_hat"] + var/json_file = file("data/npc_saves/Punpun.json") + if(!fexists(json_file)) + return + var/list/json = list() + json = json_decode(file2text(json_file)) + ancestor_name = json["ancestor_name"] + ancestor_chain = json["ancestor_chain"] + relic_hat = json["relic_hat"] + relic_mask = json["relic_hat"] /mob/living/carbon/monkey/punpun/proc/Write_Memory(dead, gibbed) var/json_file = file("data/npc_saves/Punpun.json") @@ -78,4 +70,4 @@ fdel(json_file) WRITE_FILE(json_file, json_encode(json_file)) if(!dead) - memory_saved = 1 + memory_saved = 1 \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 0e0b811810..ee8a25b679 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -113,17 +113,12 @@ ..() /mob/living/simple_animal/pet/cat/Runtime/proc/Read_Memory() - if(fexists("data/npc_saves/Runtime.sav")) //legacy compatability to convert old format to new - var/savefile/S = new /savefile("data/npc_saves/Runtime.sav") - S["family"] >> family - fdel("data/npc_saves/Runtime.sav") - else - var/json_file = file("data/npc_saves/Runtime.json") - if(!fexists(json_file)) - return - var/list/json = list() - json = json_decode(file2text(json_file)) - family = json["family"] + var/json_file = file("data/npc_saves/Runtime.json") + if(!fexists(json_file)) + return + var/list/json = list() + json = json_decode(file2text(json_file)) + family = json["family"] if(isnull(family)) family = list() @@ -280,4 +275,4 @@ ..() if(L.a_intent == INTENT_HARM && L.reagents && !stat) L.reagents.add_reagent("nutriment", 0.4) - L.reagents.add_reagent("vitamin", 0.4) + L.reagents.add_reagent("vitamin", 0.4) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 244e77d33a..a6db2dc0b5 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -328,21 +328,14 @@ ..() /mob/living/simple_animal/pet/dog/corgi/Ian/proc/Read_Memory() - if(fexists("data/npc_saves/Ian.sav")) //legacy compatability to convert old format to new - var/savefile/S = new /savefile("data/npc_saves/Ian.sav") - S["age"] >> age - S["record_age"] >> record_age - S["saved_head"] >> saved_head - fdel("data/npc_saves/Ian.sav") - else - var/json_file = file("data/npc_saves/Ian.json") - if(!fexists(json_file)) - return - var/list/json = list() - json = json_decode(file2text(json_file)) - age = json["age"] - record_age = json["record_age"] - saved_head = json["saved_head"] + var/json_file = file("data/npc_saves/Ian.json") + if(!fexists(json_file)) + return + var/list/json = list() + json = json_decode(file2text(json_file)) + age = json["age"] + record_age = json["record_age"] + saved_head = json["saved_head"] if(isnull(age)) age = 0 if(isnull(record_age)) @@ -576,4 +569,4 @@ emote("me", 1, "yaps happily!") else if(M && stat != DEAD) // Same check here, even though emote checks it as well (poor form to check it only in the help case) - emote("me", 1, "growls!") + emote("me", 1, "growls!") \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm index 66fd219358..ab39c35413 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -289,17 +289,12 @@ Difficulty: Very Hard memory_saved = TRUE /obj/machinery/smartfridge/black_box/proc/ReadMemory() - if(fexists("data/npc_saves/Blackbox.sav")) //legacy compatability to convert old format to new - var/savefile/S = new /savefile("data/npc_saves/Blackbox.sav") - S["stored_items"] >> stored_items - fdel("data/npc_saves/Blackbox.sav") - else - var/json_file = file("data/npc_saves/Blackbox.json") - if(!fexists(json_file)) - return - var/list/json = list() - json = json_decode(file2text(json_file)) - stored_items = json["data"] + var/json_file = file("data/npc_saves/Blackbox.json") + if(!fexists(json_file)) + return + var/list/json = list() + json = json_decode(file2text(json_file)) + stored_items = json["data"] if(isnull(stored_items)) stored_items = list() @@ -792,4 +787,4 @@ Difficulty: Very Hard #undef ACTIVATE_WEAPON #undef ACTIVATE_MAGIC -#undef MEDAL_PREFIX +#undef MEDAL_PREFIX \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index aa96494745..9e347e3b7a 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -296,7 +296,7 @@ else parrot_state |= PARROT_FLEE //Otherwise, fly like a bat out of hell! drop_held_item(0) - if(stat != DEAD && M.a_intent == INTENT_HELP) + if(!stat && M.a_intent == INTENT_HELP) handle_automated_speech(1) //assured speak/emote return @@ -924,23 +924,15 @@ ..(gibbed) /mob/living/simple_animal/parrot/Poly/proc/Read_Memory() - if(fexists("data/npc_saves/Poly.sav")) //legacy compatability to convert old format to new - var/savefile/S = new /savefile("data/npc_saves/Poly.sav") - S["phrases"] >> speech_buffer - S["roundssurvived"] >> rounds_survived - S["longestsurvival"] >> longest_survival - S["longestdeathstreak"] >> longest_deathstreak - fdel("data/npc_saves/Poly.sav") - else - var/json_file = file("data/npc_saves/Poly.json") - if(!fexists(json_file)) - return - var/list/json = list() - json = json_decode(file2text(json_file)) - speech_buffer = json["phrases"] - rounds_survived = json["roundssurvived"] - longest_survival = json["longestsurvival"] - longest_deathstreak = json["longestdeathstreak"] + var/json_file = file("data/npc_saves/Poly.json") + if(!fexists(json_file)) + return + var/list/json = list() + json = json_decode(file2text(json_file)) + speech_buffer = json["phrases"] + rounds_survived = json["roundssurvived"] + longest_survival = json["longestsurvival"] + longest_deathstreak = json["longestdeathstreak"] if(!islist(speech_buffer)) speech_buffer = list() From 17b5eecf833d0319e8bd9a836e1d934f76c3a5d9 Mon Sep 17 00:00:00 2001 From: erwgd Date: Fri, 8 Sep 2017 04:58:03 +0100 Subject: [PATCH 194/262] Updated metadata on title1.ogg (#30477) --- sound/ambience/title1.ogg | Bin 801075 -> 801075 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/sound/ambience/title1.ogg b/sound/ambience/title1.ogg index 1858f38e338af753c010c815b60424734a1d3245..560fb6342f44310f5289257a93fb5a7e568431d7 100644 GIT binary patch delta 261 zcmdn|$zby*g9!mF*H<>>P7Fz?=Vf4Ea4agxEH1H)&~;8tP3Z>;IOpf)rskE{2IrR+ zC8ri!DP)wC6jr4i%iK*n75<}V!WUpN?nm}HO delta 182 zcmdn|$zby*g9!mF*YZ5HCx#^0OEEAoBo>uq7MIwDr52SG<>zE3C*}kv7bTV?XV`NA zWz$phic)R86052_fV|}V+}zZ>65HVX(xT*4tH~0KmdXM^@siAvoK)MK)UwnZW4+w` z6p&6A#}HRrBLf2yd&bQZ8I##3FJN?P{=(7zg@X}@nShuXh*^M`6^Pk@m>q~g@|-}- O1;pIjzi{x_8vp<*20gF< From 00dd2f283befbd73a1c8d253203e1e1e0299e7aa Mon Sep 17 00:00:00 2001 From: JJRcop Date: Fri, 8 Sep 2017 10:31:33 -0400 Subject: [PATCH 196/262] Adds Internet admin midi (#30457) * Adds Internet admin midi * Moves global regex into proc (shell_url_scrub) * Moves shelleo to world Adds quotes around the command in shelleo, to encapsulate it * Admins can stop playing web sounds * Revised internet midi extension order Moved m4a to least preferred, as it can potentially carry non-aac or non-mpeg-3 audio * Kills \n in web sound * play_web_sound availability based on config * play web sound and shelleo tweaks istypeless for in play web sound & readability parenthesis around binary AND add return index defines for shelleo proc * Security fix for play web sound --- code/__DEFINES/misc.dm | 5 ++ code/__HELPERS/shell.dm | 57 ++++++++++++++ code/controllers/configuration.dm | 6 +- code/modules/admin/admin_verbs.dm | 3 + code/modules/admin/verbs/playsound.dm | 60 +++++++++++++++ code/modules/client/preferences_toggles.dm | 3 + code/modules/goonchat/browserOutput.dm | 14 ++++ .../browserassets/css/browserOutput.css | 13 +++- .../browserassets/html/browserOutput.html | 16 ++-- .../browserassets/js/browserOutput.js | 77 +++++++++++++++++-- config/config.txt | 8 ++ tgstation.dme | 1 + 12 files changed, 246 insertions(+), 17 deletions(-) create mode 100644 code/__HELPERS/shell.dm diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 6ccebf83b0..209a33e0c5 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -453,3 +453,8 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE #define MOUSE_OPACITY_TRANSPARENT 0 #define MOUSE_OPACITY_ICON 1 #define MOUSE_OPACITY_OPAQUE 2 + +//world/proc/shelleo +#define SHELLEO_ERRORLEVEL 1 +#define SHELLEO_STDOUT 2 +#define SHELLEO_STDERR 3 diff --git a/code/__HELPERS/shell.dm b/code/__HELPERS/shell.dm new file mode 100644 index 0000000000..8b615eac0a --- /dev/null +++ b/code/__HELPERS/shell.dm @@ -0,0 +1,57 @@ +//Runs the command in the system's shell, returns a list of (error code, stdout, stderr) + +#define SHELLEO_NAME "data/shelleo." +#define SHELLEO_ERR ".err" +#define SHELLEO_OUT ".out" +/world/proc/shelleo(command) + var/static/list/shelleo_ids = list() + var/stdout = "" + var/stderr = "" + var/errorcode = 1 + var/shelleo_id + var/out_file = "" + var/err_file = "" + var/static/list/interpreters = list("[MS_WINDOWS]" = "cmd /c", "[UNIX]" = "sh -c") + var/interpreter = interpreters["[world.system_type]"] + if(interpreter) + for(var/seo_id in shelleo_ids) + if(!shelleo_ids[seo_id]) + shelleo_ids[seo_id] = TRUE + shelleo_id = "[seo_id]" + break + if(!shelleo_id) + shelleo_id = "[shelleo_ids.len + 1]" + shelleo_ids += shelleo_id + shelleo_ids[shelleo_id] = TRUE + out_file = "[SHELLEO_NAME][shelleo_id][SHELLEO_OUT]" + err_file = "[SHELLEO_NAME][shelleo_id][SHELLEO_ERR]" + errorcode = shell("[interpreter] \"[command]\" > [out_file] 2> [err_file]") + if(fexists(out_file)) + stdout = file2text(out_file) + fdel(out_file) + if(fexists(err_file)) + stderr = file2text(err_file) + fdel(err_file) + shelleo_ids[shelleo_id] = FALSE + else + CRASH("Operating System: [world.system_type] not supported") // If you encounter this error, you are encouraged to update this proc with support for the new operating system + . = list(errorcode, stdout, stderr) +#undef SHELLEO_NAME +#undef SHELLEO_ERR +#undef SHELLEO_OUT + +/proc/shell_url_scrub(url) + var/static/regex/bad_chars_regex = regex("\[^#%&./:=?\\w]*", "g") + var/scrubbed_url = "" + var/bad_match = "" + var/last_good = 1 + var/bad_chars = 1 + do + bad_chars = bad_chars_regex.Find(url) + scrubbed_url += copytext(url, last_good, bad_chars) + if(bad_chars) + bad_match = url_encode(bad_chars_regex.match) + scrubbed_url += bad_match + last_good = bad_chars + length(bad_match) + while(bad_chars) + . = scrubbed_url diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 1d853c332b..bba82e6c8a 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -16,7 +16,7 @@ GLOBAL_PROTECT(config_dir) return ..() /datum/configuration/vv_edit_var(var_name, var_value) - var/static/list/banned_edits = list("cross_address", "cross_allowed", "autoadmin", "autoadmin_rank") + var/static/list/banned_edits = list("cross_address", "cross_allowed", "autoadmin", "autoadmin_rank", "invoke_youtubedl") if(var_name in banned_edits) return FALSE return ..() @@ -94,6 +94,8 @@ GLOBAL_PROTECT(config_dir) var/panic_server_name var/panic_address //Reconnect a player this linked server if this server isn't accepting new players + var/invoke_youtubedl + //IP Intel vars var/ipintel_email var/ipintel_rating_bad = 1 @@ -476,6 +478,8 @@ GLOBAL_PROTECT(config_dir) 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") diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index f8e5c31687..343e954a8d 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -261,6 +261,8 @@ 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) + verbs += /client/proc/play_web_sound if(rights & R_SPAWN) verbs += GLOB.admin_verbs_spawn @@ -283,6 +285,7 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( /client/proc/stealth, GLOB.admin_verbs_poll, GLOB.admin_verbs_sounds, + /client/proc/play_web_sound, GLOB.admin_verbs_spawn, /*Debug verbs added by "show debug verbs"*/ /client/proc/Cell, diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm index 84a29d9c01..20c1d91fd2 100644 --- a/code/modules/admin/verbs/playsound.dm +++ b/code/modules/admin/verbs/playsound.dm @@ -36,7 +36,11 @@ for(var/mob/M in GLOB.player_list) if(M.client.prefs.toggles & SOUND_MIDI) + var/user_vol = M.client.chatOutput.adminMusicVolume + if(user_vol) + admin_sound.volume = vol * (user_vol / 100) SEND_SOUND(M, admin_sound) + admin_sound.volume = vol SSblackbox.add_details("admin_verb","Play Global Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -52,6 +56,62 @@ playsound(get_turf(src.mob), S, 50, 0, 0) SSblackbox.add_details("admin_verb","Play Local Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/client/proc/play_web_sound() + set category = "Fun" + set name = "Play Internet Sound" + if(!check_rights(R_SOUNDS)) + return + + if(!config.invoke_youtubedl) + to_chat(src, "Youtube-dl was not configured, action unavailable") //Check config.txt for the INVOKE_YOUTUBEDL value + return + + var/web_sound_input = input("Enter content URL (supported sites only, leave blank to stop playing)", "Play Internet Sound via youtube-dl") as text|null + if(istext(web_sound_input)) + var/web_sound_url = "" + var/pitch + if(length(web_sound_input)) + + web_sound_input = trim(web_sound_input) + var/static/regex/html_protocol_regex = regex("https?://") + if(findtext(web_sound_input, ":") && !findtext(web_sound_input, html_protocol_regex)) + to_chat(src, "Non-http(s) URIs are not allowed.") + 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=aac]/bestaudio\[ext=mp3]/bestaudio\[ext=m4a]\" --get-url \"[shell_scrubbed_input]\"") + var/errorlevel = output[SHELLEO_ERRORLEVEL] + var/stdout = output[SHELLEO_STDOUT] + var/stderr = output[SHELLEO_STDERR] + if(!errorlevel) + var/static/regex/content_url_regex = regex("https?://\\S+") + if(content_url_regex.Find(stdout)) + web_sound_url = content_url_regex.match + + if(SSevents.holidays && SSevents.holidays[APRIL_FOOLS]) + pitch = pick(0.5, 0.7, 0.8, 0.85, 0.9, 0.95, 1.1, 1.2, 1.4, 1.6, 2.0, 2.5) + to_chat(src, "You feel the Honkmother messing with your song...") + + log_admin("[key_name(src)] played web sound: [web_sound_input]") + message_admins("[key_name(src)] played web sound: [web_sound_input]") + else + to_chat(src, "Youtube-dl URL retrieval FAILED:") + to_chat(src, "[stderr]") + + else //pressed ok with blank + log_admin("[key_name(src)] stopped web sound") + message_admins("[key_name(src)] stopped web sound") + web_sound_url = " " + + if(web_sound_url) + for(var/m in GLOB.player_list) + var/mob/M = m + var/client/C = M.client + if((C.prefs.toggles & SOUND_MIDI) && C.chatOutput && !C.chatOutput.broken && C.chatOutput.loaded) + C.chatOutput.sendMusic(web_sound_url, pitch) + + SSblackbox.add_details("admin_verb","Play Internet Sound") + /client/proc/set_round_end_sound(S as sound) set category = "Fun" set name = "Set Round End Sound" diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index 1d04964a8b..8e8690bde3 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -144,6 +144,9 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, togglemidis)() else to_chat(usr, "You will no longer hear sounds uploaded by admins") usr.stop_sound_channel(CHANNEL_ADMIN) + var/client/C = usr.client + if(C && C.chatOutput && !C.chatOutput.broken && C.chatOutput.loaded) + C.chatOutput.sendMusic(" ") SSblackbox.add_details("preferences_verb","Toggle Hearing Midis|[usr.client.prefs.toggles & SOUND_MIDI]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/verbs/menu/Settings/Sound/togglemidis/Get_checked(client/C) return C.prefs.toggles & SOUND_MIDI diff --git a/code/modules/goonchat/browserOutput.dm b/code/modules/goonchat/browserOutput.dm index 85770f618a..408da4c401 100644 --- a/code/modules/goonchat/browserOutput.dm +++ b/code/modules/goonchat/browserOutput.dm @@ -13,6 +13,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic var/cookieSent = FALSE // Has the client sent a cookie for analysis var/broken = FALSE var/list/connectionHistory //Contains the connection history passed from chat cookie + var/adminMusicVolume = 100 //This is for the Play Global Sound verb /datum/chatOutput/New(client/C) owner = C @@ -79,6 +80,9 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic if("analyzeClientData") data = analyzeClientData(arglist(params)) + if("setMusicVolume") + data = setMusicVolume(arglist(params)) + if(data) ehjax_send(data = data) @@ -120,6 +124,16 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("data/iconCache.sav")) //Cache of ic data = json_encode(data) C << output("[data]", "[window]:ehjaxCallback") +/datum/chatOutput/proc/sendMusic(music, pitch) + var/list/music_data = list("adminMusic" = url_encode(url_encode(music))) + if(pitch) + music_data["musicRate"] = pitch + ehjax_send(data = music_data) + +/datum/chatOutput/proc/setMusicVolume(volume = "") + if(volume) + adminMusicVolume = Clamp(text2num(volume), 0, 100) + //Sends client connection details to the chat to handle and save /datum/chatOutput/proc/sendClientData() //Get dem deets diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css index 36640db74e..fa2c5d056c 100644 --- a/code/modules/goonchat/browserassets/css/browserOutput.css +++ b/code/modules/goonchat/browserassets/css/browserOutput.css @@ -101,7 +101,7 @@ a.popt {text-decoration: none;} top: 0; right: 0; } -#options a { +#options .optionsCell { background: #ddd; height: 30px; padding: 5px 0; @@ -111,7 +111,7 @@ a.popt {text-decoration: none;} line-height: 28px; border-top: 1px solid #b4b4b4; } -#options a:hover {background: #ccc;} +#options .optionsCell:hover {background: #ccc;} #options .toggle { width: 40px; background: #ccc; @@ -121,7 +121,7 @@ a.popt {text-decoration: none;} } #options .sub {clear: both; display: none; width: 160px;} #options .sub.scroll {overflow-y: scroll;} -#options .sub a {padding: 3px 0 3px 8px; line-height: 30px; font-size: 0.9em; clear: both;} +#options .sub.optionsCell {padding: 3px 0 3px 8px; line-height: 30px; font-size: 0.9em; clear: both;} #options .sub span { display: block; line-height: 30px; @@ -136,6 +136,13 @@ a.popt {text-decoration: none;} line-height: 30px; float: right; } +#options .sub input { + position: absolute; + padding: 7px 5px; + width: 121px; + line-height: 30px; + float: left; +} #options .decreaseFont {border-top: 0;} /* POPUPS */ diff --git a/code/modules/goonchat/browserassets/html/browserOutput.html b/code/modules/goonchat/browserassets/html/browserOutput.html index f55e69ecd1..a9e30b6b51 100644 --- a/code/modules/goonchat/browserassets/html/browserOutput.html +++ b/code/modules/goonchat/browserassets/html/browserOutput.html @@ -28,17 +28,19 @@ --ms + \ No newline at end of file diff --git a/code/modules/goonchat/browserassets/js/browserOutput.js b/code/modules/goonchat/browserassets/js/browserOutput.js index c7eff15913..eccb0dd2b6 100644 --- a/code/modules/goonchat/browserassets/js/browserOutput.js +++ b/code/modules/goonchat/browserassets/js/browserOutput.js @@ -61,8 +61,17 @@ var opts = { 'clientDataLimit': 5, 'clientData': [], + //Admin music volume update + 'volumeUpdateDelay': 5000, //Time from when the volume updates to data being sent to the server + 'volumeUpdating': false, //True if volume update function set to fire + 'updatedVolume': 0, //The volume level that is sent to the server + }; +function clamp(val, min, max) { + return Math.max(min, Math.min(val, max)) +} + function outerHTML(el) { var wrap = document.createElement('div'); wrap.appendChild(el.cloneNode(true)); @@ -95,6 +104,15 @@ function linkify(text) { }); } +function byondDecode(message) { + // Basically we url_encode twice server side so we can manually read the encoded version and actually do UTF-8. + // The replace for + is because FOR SOME REASON, BYOND replaces spaces with a + instead of %20, and a plus with %2b. + // Marvelous. + message = message.replace(/\+/g, "%20"); + message = decoder(message); + return message; +} + //Actually turns the highlight term match into appropriate html function addHighlightMarkup(match) { var extra = ''; @@ -176,11 +194,7 @@ function output(message, flag) { if (flag !== 'internal') opts.lastPang = Date.now(); - // Basically we url_encode twice server side so we can manually read the encoded version and actually do UTF-8. - // The replace for + is because FOR SOME REASON, BYOND replaces spaces with a + instead of %20, and a plus with %2b. - // Marvelous. - message = message.replace(/\+/g, "%20") - message = decoder(message) + message = byondDecode(message) //The behemoth of filter-code (for Admin message filters) //Note: This is proooobably hella inefficient @@ -423,7 +437,22 @@ function ehjaxCallback(data) { var firebugEl = document.createElement('script'); firebugEl.src = 'https://getfirebug.com/firebug-lite-debug.js'; document.body.appendChild(firebugEl); - } + } else if (data.adminMusic) { + if (typeof data.adminMusic === 'string') { + var adminMusic = byondDecode(data.adminMusic); + adminMusic = adminMusic.match(/https?:\/\/\S+/) || ''; + if (data.musicRate) { + var newRate = Number(data.musicRate); + if(newRate) { + $('#adminMusic').prop('defaultPlaybackRate', newRate); + } + } else { + $('#adminMusic').prop('defaultPlaybackRate', 1.0); + } + $('#adminMusic').prop('src', adminMusic); + $('#adminMusic').trigger("play"); + } + } } } @@ -446,6 +475,13 @@ function toggleWasd(state) { opts.wasd = (state == 'on' ? true : false); } +function sendVolumeUpdate() { + opts.volumeUpdating = false; + if(opts.updatedVolume) { + runByond('?_src_=chat&proc=setMusicVolume¶m[volume]='+opts.updatedVolume); + } +} + /***************************************** * * DOM READY @@ -486,6 +522,7 @@ $(function() { 'spingDisabled': getCookie('pingdisabled'), 'shighlightTerms': getCookie('highlightterms'), 'shighlightColor': getCookie('highlightcolor'), + 'smusicVolume': getCookie('musicVolume'), }; if (savedConfig.sfontSize) { @@ -517,6 +554,14 @@ $(function() { opts.highlightColor = savedConfig.shighlightColor; internalOutput('Loaded highlight color of: '+savedConfig.shighlightColor+'', 'internal'); } + if (savedConfig.smusicVolume) { + var newVolume = clamp(savedConfig.smusicVolume, 0, 100); + $('#adminMusic').prop('volume', newVolume / 100); + $('#musicVolume').val(newVolume); + opts.updatedVolume = newVolume; + sendVolumeUpdate(); + internalOutput('Loaded music volume of: '+savedConfig.smusicVolume+'', 'internal'); + } (function() { var dataCookie = getCookie('connData'); @@ -835,6 +880,26 @@ $(function() { opts.messageCount = 0; }); + $('#musicVolumeSpan').hover(function() { + $('#musicVolumeText').addClass('hidden'); + $('#musicVolume').removeClass('hidden'); + }, function() { + $('#musicVolume').addClass('hidden'); + $('#musicVolumeText').removeClass('hidden'); + }); + + $('#musicVolume').change(function() { + var newVolume = $('#musicVolume').val(); + newVolume = clamp(newVolume, 0, 100); + $('#adminMusic').prop('volume', newVolume / 100); + setCookie('musicVolume', newVolume, 365); + opts.updatedVolume = newVolume; + if(!opts.volumeUpdating) { + setTimeout(sendVolumeUpdate, opts.volumeUpdateDelay); + opts.volumeUpdating = true; + } + }); + $('img.icon').error(iconError); diff --git a/config/config.txt b/config/config.txt index ae2cc1e43a..70fe7812b2 100644 --- a/config/config.txt +++ b/config/config.txt @@ -191,6 +191,14 @@ CHECK_RANDOMIZER ## Ban appeals URL - usually for a forum or wherever people should go to contact your admins. # BANAPPEALS http://justanotherday.example.com +## System command that invokes youtube-dl, used by Play Internet Sound. +## You can install youtube-dl with +## "pip install youtube-dl" if you have pip installed +## from https://github.com/rg3/youtube-dl/releases +## or your package manager +## The default value assumes youtube-dl is in your system PATH +# INVOKE_YOUTUBEDL youtube-dl + ## In-game features ##Toggle for having jobs load up from the .txt # LOAD_JOBS_FROM_TXT diff --git a/tgstation.dme b/tgstation.dme index df879e0b4d..961b2f163c 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -95,6 +95,7 @@ #include "code\__HELPERS\pronouns.dm" #include "code\__HELPERS\radio.dm" #include "code\__HELPERS\sanitize_values.dm" +#include "code\__HELPERS\shell.dm" #include "code\__HELPERS\text.dm" #include "code\__HELPERS\text_vr.dm" #include "code\__HELPERS\time.dm" From cf07ead653fbc0cfd3b3195e69b133e0c17185b6 Mon Sep 17 00:00:00 2001 From: kingofkosmos Date: Fri, 8 Sep 2017 17:57:51 +0300 Subject: [PATCH 198/262] Regularizes resisting out of containers --- .../abduction/machinery/experiment.dm | 22 +- code/game/machinery/cloning.dm | 3 + code/game/machinery/dna_scanner.dm | 24 +- code/game/machinery/gulag_teleporter.dm | 23 +- code/game/machinery/suit_storage_unit.dm | 278 ++++++++++++++++++ .../objects/items/implants/implantchair.dm | 191 ++++++++++++ .../structures/crates_lockers/closets.dm | 25 +- code/game/objects/structures/morgue.dm | 26 +- .../transit_tubes/transit_tube_pod.dm | 3 + code/modules/VR/vr_sleeper.dm | 4 + .../components/unary_devices/cryo.dm | 27 +- .../kitchen_machinery/gibber.dm | 5 +- 12 files changed, 567 insertions(+), 64 deletions(-) diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm index 58ca8bbea9..182b7e2756 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm @@ -12,6 +12,8 @@ var/list/abductee_minds var/flash = " - || - " var/obj/machinery/abductor/console/console + var/message_cooldown = 0 + var/breakout_time = 0.75 /obj/machinery/abductor/experiment/MouseDrop_T(mob/target, mob/user) if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user) || !ishuman(target)) @@ -40,25 +42,23 @@ /obj/machinery/abductor/experiment/relaymove(mob/user) if(user.stat != CONSCIOUS) return - container_resist(user) + if(message_cooldown <= world.time) + message_cooldown = world.time + 50 + to_chat(user, "[src]'s door won't budge!") /obj/machinery/abductor/experiment/container_resist(mob/living/user) - var/breakout_time = 600 user.changeNext_move(CLICK_CD_BREAKOUT) user.last_special = world.time + CLICK_CD_BREAKOUT - to_chat(user, "You lean on the back of [src] and start pushing the door open... (this will take about a minute.)") - user.visible_message("You hear a metallic creaking from [src]!") - - if(do_after(user,(breakout_time), target = src)) + user.visible_message("You see [user] kicking against the door of [src]!", \ + "You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)", \ + "You hear a metallic creaking from [src].") + if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds if(!user || user.stat != CONSCIOUS || user.loc != src || state_open) return - - visible_message("[user] successfully broke out of [src]!") - to_chat(user, "You successfully break out of [src]!") - + user.visible_message("[user] successfully broke out of [src]!", \ + "You successfully break out of [src]!") open_machine() - /obj/machinery/abductor/experiment/proc/dissection_icon(mob/living/carbon/human/H) var/icon/photo = null var/g = (H.gender == FEMALE) ? "f" : "m" diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 7ea954a671..2276b5154b 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -392,6 +392,9 @@ QDEL_IN(mob_occupant, 40) /obj/machinery/clonepod/relaymove(mob/user) + container_resist() + +/obj/machinery/clonepod/container_resist(mob/living/user) if(user.stat == CONSCIOUS) go_out() diff --git a/code/game/machinery/dna_scanner.dm b/code/game/machinery/dna_scanner.dm index 65a6088721..4085b4edb4 100644 --- a/code/game/machinery/dna_scanner.dm +++ b/code/game/machinery/dna_scanner.dm @@ -14,6 +14,8 @@ var/damage_coeff var/scan_level var/precision_coeff + var/message_cooldown + var/breakout_time = 2 /obj/machinery/dna_scannernew/RefreshParts() scan_level = 0 @@ -65,23 +67,20 @@ open_machine() /obj/machinery/dna_scannernew/container_resist(mob/living/user) - var/breakout_time = 2 - if(state_open || !locked) //Open and unlocked, no need to escape - state_open = TRUE + if(!locked) + open_machine() return user.changeNext_move(CLICK_CD_BREAKOUT) user.last_special = world.time + CLICK_CD_BREAKOUT - to_chat(user, "You lean on the back of [src] and start pushing the door open... (this will take about [breakout_time] minutes.)") - user.visible_message("You hear a metallic creaking from [src]!") - + user.visible_message("You see [user] kicking against the door of [src]!", \ + "You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)", \ + "You hear a metallic creaking from [src].") if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds if(!user || user.stat != CONSCIOUS || user.loc != src || state_open || !locked) return - locked = FALSE - visible_message("[user] successfully broke out of [src]!") - to_chat(user, "You successfully break out of [src]!") - + user.visible_message("[user] successfully broke out of [src]!", \ + "You successfully break out of [src]!") open_machine() /obj/machinery/dna_scannernew/proc/locate_computer(type_) @@ -122,10 +121,11 @@ /obj/machinery/dna_scannernew/relaymove(mob/user as mob) if(user.stat || locked) + if(message_cooldown <= world.time) + message_cooldown = world.time + 50 + to_chat(user, "[src]'s door won't budge!") return - open_machine() - return /obj/machinery/dna_scannernew/attackby(obj/item/I, mob/user, params) diff --git a/code/game/machinery/gulag_teleporter.dm b/code/game/machinery/gulag_teleporter.dm index b37c5a10a7..d77e91af90 100644 --- a/code/game/machinery/gulag_teleporter.dm +++ b/code/game/machinery/gulag_teleporter.dm @@ -19,6 +19,8 @@ The console is located at computer/gulag_teleporter.dm active_power_usage = 5000 circuit = /obj/item/circuitboard/machine/gulag_teleporter var/locked = FALSE + var/message_cooldown + var/breakout_time = 1 var/jumpsuit_type = /obj/item/clothing/under/rank/prisoner var/shoes_type = /obj/item/clothing/shoes/sneakers/orange var/obj/machinery/gulag_item_reclaimer/linked_reclaimer @@ -46,7 +48,7 @@ The console is located at computer/gulag_teleporter.dm /obj/machinery/gulag_teleporter/interact(mob/user) if(locked) - to_chat(user, "[src] is locked.") + to_chat(user, "[src] is locked!") return toggle_open() @@ -89,28 +91,27 @@ The console is located at computer/gulag_teleporter.dm if(user.stat != CONSCIOUS) return if(locked) - to_chat(user, "[src] is locked!") + if(message_cooldown <= world.time) + message_cooldown = world.time + 50 + to_chat(user, "[src]'s door won't budge!") return open_machine() /obj/machinery/gulag_teleporter/container_resist(mob/living/user) - var/breakout_time = 600 if(!locked) open_machine() return user.changeNext_move(CLICK_CD_BREAKOUT) user.last_special = world.time + CLICK_CD_BREAKOUT - to_chat(user, "You lean on the back of [src] and start pushing the door open... (this will take about a minute.)") - user.visible_message("You hear a metallic creaking from [src]!") - - if(do_after(user,(breakout_time), target = src)) + user.visible_message("You see [user] kicking against the door of [src]!", \ + "You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)", \ + "You hear a metallic creaking from [src].") + if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds if(!user || user.stat != CONSCIOUS || user.loc != src || state_open || !locked) return - locked = FALSE - visible_message("[user] successfully broke out of [src]!") - to_chat(user, "You successfully break out of [src]!") - + user.visible_message("[user] successfully broke out of [src]!", \ + "You successfully break out of [src]!") open_machine() /obj/machinery/gulag_teleporter/proc/locate_reclaimer() diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index cd2a5bd3b5..6ab0cbf17b 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -6,6 +6,7 @@ icon_state = "close" anchored = TRUE density = TRUE +<<<<<<< HEAD max_integrity = 250 var/obj/item/clothing/suit/space/suit = null @@ -101,6 +102,105 @@ mask_type = /obj/item/clothing/mask/breath storage_type = /obj/item/tank/internals/emergency_oxygen/double +======= + max_integrity = 250 + + var/obj/item/clothing/suit/space/suit = null + var/obj/item/clothing/head/helmet/space/helmet = null + var/obj/item/clothing/mask/mask = null + var/obj/item/storage = null + + var/suit_type = null + var/helmet_type = null + var/mask_type = null + var/storage_type = null + + state_open = FALSE + var/locked = FALSE + panel_open = FALSE + var/safeties = TRUE + + var/uv = FALSE + var/uv_super = FALSE + var/uv_cycles = 6 + var/message_cooldown + var/breakout_time = 0.5 + +/obj/machinery/suit_storage_unit/standard_unit + suit_type = /obj/item/clothing/suit/space/eva + helmet_type = /obj/item/clothing/head/helmet/space/eva + mask_type = /obj/item/clothing/mask/breath + +/obj/machinery/suit_storage_unit/captain + suit_type = /obj/item/clothing/suit/space/hardsuit/captain + mask_type = /obj/item/clothing/mask/gas/sechailer + storage_type = /obj/item/tank/jetpack/oxygen/captain + +/obj/machinery/suit_storage_unit/engine + suit_type = /obj/item/clothing/suit/space/hardsuit/engine + mask_type = /obj/item/clothing/mask/breath + +/obj/machinery/suit_storage_unit/ce + suit_type = /obj/item/clothing/suit/space/hardsuit/engine/elite + mask_type = /obj/item/clothing/mask/breath + storage_type= /obj/item/clothing/shoes/magboots/advance + +/obj/machinery/suit_storage_unit/security + suit_type = /obj/item/clothing/suit/space/hardsuit/security + mask_type = /obj/item/clothing/mask/gas/sechailer + +/obj/machinery/suit_storage_unit/hos + suit_type = /obj/item/clothing/suit/space/hardsuit/security/hos + mask_type = /obj/item/clothing/mask/gas/sechailer + storage_type = /obj/item/tank/internals/oxygen + +/obj/machinery/suit_storage_unit/atmos + suit_type = /obj/item/clothing/suit/space/hardsuit/engine/atmos + mask_type = /obj/item/clothing/mask/gas + storage_type = /obj/item/watertank/atmos + +/obj/machinery/suit_storage_unit/mining + suit_type = /obj/item/clothing/suit/hooded/explorer + mask_type = /obj/item/clothing/mask/gas/explorer + +/obj/machinery/suit_storage_unit/mining/eva + suit_type = /obj/item/clothing/suit/space/hardsuit/mining + mask_type = /obj/item/clothing/mask/breath + +/obj/machinery/suit_storage_unit/cmo + suit_type = /obj/item/clothing/suit/space/hardsuit/medical + mask_type = /obj/item/clothing/mask/breath + +/obj/machinery/suit_storage_unit/rd + suit_type = /obj/item/clothing/suit/space/hardsuit/rd + mask_type = /obj/item/clothing/mask/breath + +/obj/machinery/suit_storage_unit/syndicate + suit_type = /obj/item/clothing/suit/space/hardsuit/syndi + mask_type = /obj/item/clothing/mask/gas/syndicate + storage_type = /obj/item/tank/jetpack/oxygen/harness + +/obj/machinery/suit_storage_unit/ert/command + suit_type = /obj/item/clothing/suit/space/hardsuit/ert + mask_type = /obj/item/clothing/mask/breath + storage_type = /obj/item/tank/internals/emergency_oxygen/double + +/obj/machinery/suit_storage_unit/ert/security + suit_type = /obj/item/clothing/suit/space/hardsuit/ert/sec + mask_type = /obj/item/clothing/mask/breath + storage_type = /obj/item/tank/internals/emergency_oxygen/double + +/obj/machinery/suit_storage_unit/ert/engineer + suit_type = /obj/item/clothing/suit/space/hardsuit/ert/engi + mask_type = /obj/item/clothing/mask/breath + storage_type = /obj/item/tank/internals/emergency_oxygen/double + +/obj/machinery/suit_storage_unit/ert/medical + suit_type = /obj/item/clothing/suit/space/hardsuit/ert/med + mask_type = /obj/item/clothing/mask/breath + storage_type = /obj/item/tank/internals/emergency_oxygen/double + +>>>>>>> d4d898f... Regularizes resisting out of containers (#30412) /obj/machinery/suit_storage_unit/Initialize() . = ..() wires = new /datum/wires/suit_storage_unit(src) @@ -162,6 +262,7 @@ /obj/machinery/suit_storage_unit/deconstruct(disassembled = TRUE) if(!(flags_1 & NODECONSTRUCT_1)) +<<<<<<< HEAD open_machine() dump_contents() new /obj/item/stack/sheet/metal (loc, 2) @@ -312,6 +413,183 @@ return ..() +======= + open_machine() + dump_contents() + new /obj/item/stack/sheet/metal (loc, 2) + qdel(src) + +/obj/machinery/suit_storage_unit/MouseDrop_T(atom/A, mob/user) + if(user.stat || user.lying || !Adjacent(user) || !Adjacent(A) || !isliving(A)) + return + var/mob/living/target = A + if(!state_open) + to_chat(user, "The unit's doors are shut!") + return + if(!is_operational()) + to_chat(user, "The unit is not operational!") + return + if(occupant || helmet || suit || storage) + to_chat(user, "It's too cluttered inside to fit in!") + return + + if(target == user) + user.visible_message("[user] starts squeezing into [src]!", "You start working your way into [src]...") + else + target.visible_message("[user] starts shoving [target] into [src]!", "[user] starts shoving you into [src]!") + + if(do_mob(user, target, 30)) + if(occupant || helmet || suit || storage) + return + if(target == user) + user.visible_message("[user] slips into [src] and closes the door behind them!", "You slip into [src]'s cramped space and shut its door.") + else + target.visible_message("[user] pushes [target] into [src] and shuts its door!", "[user] shoves you into [src] and shuts the door!") + close_machine(target) + add_fingerprint(user) + +/obj/machinery/suit_storage_unit/proc/cook() + if(uv_cycles) + uv_cycles-- + uv = TRUE + locked = TRUE + update_icon() + if(occupant) + var/mob/living/mob_occupant = occupant + if(uv_super) + mob_occupant.adjustFireLoss(rand(20, 36)) + else + mob_occupant.adjustFireLoss(rand(10, 16)) + mob_occupant.emote("scream") + addtimer(CALLBACK(src, .proc/cook), 50) + else + uv_cycles = initial(uv_cycles) + uv = FALSE + locked = FALSE + if(uv_super) + visible_message("[src]'s door creaks open with a loud whining noise. A cloud of foul black smoke escapes from its chamber.") + playsound(src, 'sound/machines/airlock_alien_prying.ogg', 50, 1) + helmet = null + qdel(helmet) + suit = null + qdel(suit) // Delete everything but the occupant. + mask = null + qdel(mask) + storage = null + qdel(storage) + // The wires get damaged too. + wires.cut_all() + else + if(!occupant) + visible_message("[src]'s door slides open. The glowing yellow lights dim to a gentle green.") + else + visible_message("[src]'s door slides open, barraging you with the nauseating smell of charred flesh.") + playsound(src, 'sound/machines/airlockclose.ogg', 25, 1) + for(var/obj/item/I in src) //Scorches away blood and forensic evidence, although the SSU itself is unaffected + I.clean_blood() + I.fingerprints = list() + open_machine(FALSE) + if(occupant) + dump_contents() + +/obj/machinery/suit_storage_unit/proc/shock(mob/user, prb) + if(!prob(prb)) + var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread + s.set_up(5, 1, src) + s.start() + if(electrocute_mob(user, src, src, 1, TRUE)) + return 1 + +/obj/machinery/suit_storage_unit/relaymove(mob/user) + if(locked) + if(message_cooldown <= world.time) + message_cooldown = world.time + 50 + to_chat(user, "[src]'s door won't budge!") + return + open_machine() + dump_contents() + +/obj/machinery/suit_storage_unit/container_resist(mob/living/user) + if(!locked) + open_machine() + dump_contents() + return + user.changeNext_move(CLICK_CD_BREAKOUT) + user.last_special = world.time + CLICK_CD_BREAKOUT + user.visible_message("You see [user] kicking against the doors of [src]!", \ + "You start kicking against the doors... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)", \ + "You hear a thump from [src].") + if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds + if(!user || user.stat != CONSCIOUS || user.loc != src ) + return + user.visible_message("[user] successfully broke out of [src]!", \ + "You successfully break out of [src]!") + open_machine() + dump_contents() + + add_fingerprint(user) + if(locked) + visible_message("You see [user] kicking against the doors of [src]!", \ + "You start kicking against the doors...") + addtimer(CALLBACK(src, .proc/resist_open, user), 300) + else + open_machine() + dump_contents() + +/obj/machinery/suit_storage_unit/proc/resist_open(mob/user) + if(!state_open && occupant && (user in src) && user.stat == 0) // Check they're still here. + visible_message("You see [user] bursts out of [src]!", \ + "You escape the cramped confines of [src]!") + open_machine() + +/obj/machinery/suit_storage_unit/attackby(obj/item/I, mob/user, params) + if(state_open && is_operational()) + if(istype(I, /obj/item/clothing/suit/space)) + if(suit) + to_chat(user, "The unit already contains a suit!.") + return + if(!user.drop_item()) + return + suit = I + else if(istype(I, /obj/item/clothing/head/helmet)) + if(helmet) + to_chat(user, "The unit already contains a helmet!") + return + if(!user.drop_item()) + return + helmet = I + else if(istype(I, /obj/item/clothing/mask)) + if(mask) + to_chat(user, "The unit already contains a mask!") + return + if(!user.drop_item()) + return + mask = I + else + if(storage) + to_chat(user, "The auxiliary storage compartment is full!") + return + if(!user.drop_item()) + return + storage = I + + I.loc = src + visible_message("[user] inserts [I] into [src]", "You load [I] into [src].") + update_icon() + return + + if(panel_open && is_wire_tool(I)) + wires.interact(user) + if(!state_open) + if(default_deconstruction_screwdriver(user, "panel", "close", I)) + return + if(default_pry_open(I)) + dump_contents() + return + + return ..() + +>>>>>>> d4d898f... Regularizes resisting out of containers (#30412) /obj/machinery/suit_storage_unit/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) diff --git a/code/game/objects/items/implants/implantchair.dm b/code/game/objects/items/implants/implantchair.dm index 55a35960cf..c7035f748e 100644 --- a/code/game/objects/items/implants/implantchair.dm +++ b/code/game/objects/items/implants/implantchair.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD /obj/machinery/implantchair name = "mindshield implanter" desc = "Used to implant occupants with mindshield implants." @@ -185,3 +186,193 @@ log_game("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.") return 1 +======= +/obj/machinery/implantchair + name = "mindshield implanter" + desc = "Used to implant occupants with mindshield implants." + icon = 'icons/obj/machines/implantchair.dmi' + icon_state = "implantchair" + density = TRUE + opacity = 0 + anchored = TRUE + + var/ready = TRUE + var/replenishing = FALSE + + var/ready_implants = 5 + var/max_implants = 5 + var/injection_cooldown = 600 + var/replenish_cooldown = 6000 + var/implant_type = /obj/item/implant/mindshield + var/auto_inject = FALSE + var/auto_replenish = TRUE + var/special = FALSE + var/special_name = "special function" + var/message_cooldown + var/breakout_time = 1 + +/obj/machinery/implantchair/Initialize() + . = ..() + open_machine() + update_icon() + + +/obj/machinery/implantchair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "implantchair", name, 375, 280, master_ui, state) + ui.open() + + +/obj/machinery/implantchair/ui_data() + var/list/data = list() + data["occupied"] = occupant ? 1 : 0 + data["open"] = state_open + + data["occupant"] = list() + if(occupant) + var/mob/living/mob_occupant = occupant + data["occupant"]["name"] = mob_occupant.name + data["occupant"]["stat"] = mob_occupant.stat + + data["special_name"] = special ? special_name : null + data["ready_implants"] = ready_implants + data["ready"] = ready + data["replenishing"] = replenishing + + return data + +/obj/machinery/implantchair/ui_act(action, params) + if(..()) + return + switch(action) + if("door") + if(state_open) + close_machine() + else + open_machine() + . = TRUE + if("implant") + implant(occupant,usr) + . = TRUE + +/obj/machinery/implantchair/proc/implant(mob/living/M,mob/user) + if (!istype(M)) + return + if(!ready_implants || !ready) + return + if(implant_action(M,user)) + ready_implants-- + if(!replenishing && auto_replenish) + replenishing = TRUE + addtimer(CALLBACK(src,"replenish"),replenish_cooldown) + if(injection_cooldown > 0) + ready = FALSE + addtimer(CALLBACK(src,"set_ready"),injection_cooldown) + else + playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, 1) + update_icon() + +/obj/machinery/implantchair/proc/implant_action(mob/living/M) + var/obj/item/implant/I = new implant_type + if(I.implant(M)) + visible_message("[M] has been implanted by the [name].") + return 1 + +/obj/machinery/implantchair/update_icon() + icon_state = initial(icon_state) + if(state_open) + icon_state += "_open" + if(occupant) + icon_state += "_occupied" + if(ready) + add_overlay("ready") + else + cut_overlays() + +/obj/machinery/implantchair/proc/replenish() + if(ready_implants < max_implants) + ready_implants++ + if(ready_implants < max_implants) + addtimer(CALLBACK(src,"replenish"),replenish_cooldown) + else + replenishing = FALSE + +/obj/machinery/implantchair/proc/set_ready() + ready = TRUE + update_icon() + +/obj/machinery/implantchair/container_resist(mob/living/user) + user.changeNext_move(CLICK_CD_BREAKOUT) + user.last_special = world.time + CLICK_CD_BREAKOUT + user.visible_message("You see [user] kicking against the door of [src]!", \ + "You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)", \ + "You hear a metallic creaking from [src].") + if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds + if(!user || user.stat != CONSCIOUS || user.loc != src || state_open) + return + user.visible_message("[user] successfully broke out of [src]!", \ + "You successfully break out of [src]!") + open_machine() + +/obj/machinery/implantchair/relaymove(mob/user) + if(message_cooldown <= world.time) + message_cooldown = world.time + 50 + to_chat(user, "[src]'s door won't budge!") + +/obj/machinery/implantchair/MouseDrop_T(mob/target, mob/user) + if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !isliving(target) || !user.IsAdvancedToolUser()) + return + close_machine(target) + +/obj/machinery/implantchair/close_machine(mob/living/user) + if((isnull(user) || istype(user)) && state_open) + ..(user) + if(auto_inject && ready && ready_implants > 0) + implant(user,null) + +/obj/machinery/implantchair/genepurge + name = "Genetic purifier" + desc = "Used to purge human genome of foreign influences" + special = TRUE + special_name = "Purge genome" + injection_cooldown = 0 + replenish_cooldown = 300 + +/obj/machinery/implantchair/genepurge/implant_action(mob/living/carbon/human/H,mob/user) + if(!istype(H)) + return 0 + H.set_species(/datum/species/human, 1)//lizards go home + purrbation_remove(H)//remove cats + H.dna.remove_all_mutations()//hulks out + return 1 + + +/obj/machinery/implantchair/brainwash + name = "Neural Imprinter" + desc = "Used to indoctrinate rehabilitate hardened recidivists." + special_name = "Imprint" + injection_cooldown = 3000 + auto_inject = FALSE + auto_replenish = FALSE + special = TRUE + var/objective = "Obey the law. Praise Nanotrasen." + var/custom = FALSE + +/obj/machinery/implantchair/brainwash/implant_action(mob/living/C,mob/user) + if(!istype(C) || !C.mind) // I don't know how this makes any sense for silicons but laws trump objectives anyway. + return 0 + if(custom) + if(!user || !user.Adjacent(src)) + return 0 + objective = stripped_input(usr,"What order do you want to imprint on [C]?","Enter the order","",120) + message_admins("[key_name_admin(user)] set brainwash machine objective to '[objective]'.") + log_game("[key_name_admin(user)] set brainwash machine objective to '[objective]'.") + var/datum/objective/custom_objective = new/datum/objective(objective) + custom_objective.owner = C.mind + C.mind.objectives += custom_objective + C.mind.announce_objectives() + message_admins("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.") + log_game("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.") + return 1 +>>>>>>> d4d898f... Regularizes resisting out of containers (#30412) diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 78e672e49d..4f8705aa71 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -16,7 +16,7 @@ integrity_failure = 50 armor = list(melee = 20, bullet = 10, laser = 10, energy = 0, bomb = 10, bio = 0, rad = 0, fire = 70, acid = 60) var/breakout_time = 2 - var/lastbang + var/message_cooldown var/can_weld_shut = TRUE var/horizontal = FALSE var/allow_objects = FALSE @@ -300,14 +300,12 @@ /obj/structure/closet/relaymove(mob/user) if(user.stat || !isturf(loc) || !isliving(user)) return - var/mob/living/L = user - if(!open()) - if(L.last_special <= world.time) - container_resist(L) - if(world.time > lastbang+5) - lastbang = world.time - for(var/mob/M in get_hearers_in_view(src, null)) - M.show_message("BANG, bang!", 2) + if(locked) + if(message_cooldown <= world.time) + message_cooldown = world.time + 50 + to_chat(user, "[src]'s door won't budge!") + return + container_resist() /obj/structure/closet/attack_hand(mob/user) ..() @@ -367,9 +365,10 @@ //okay, so the closet is either welded or locked... resist!!! user.changeNext_move(CLICK_CD_BREAKOUT) user.last_special = world.time + CLICK_CD_BREAKOUT - to_chat(user, "You lean on the back of [src] and start pushing the door open.") - visible_message("[src] begins to shake violently!") - if(do_after(user,(breakout_time * 60 * 10), target = src)) //minutes * 60seconds * 10deciseconds + user.visible_message("[src] begins to shake violently!", \ + "You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)", \ + "You hear banging from [src].") + if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds if(!user || user.stat != CONSCIOUS || user.loc != src || opened || (!locked && !welded) ) return //we check after a while whether there is a point of resisting anymore and whether the user is capable of resisting @@ -388,7 +387,7 @@ /obj/structure/closet/AltClick(mob/user) ..() - if(!user.canUseTopic(src, be_close=TRUE)) + if(!user.canUseTopic(src, be_close=TRUE) || isturf(loc)) to_chat(user, "You can't do that right now!") return if(opened || !secure) diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 600e15201d..f4a98811c0 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -23,6 +23,8 @@ var/obj/structure/tray/connected = null var/locked = FALSE var/opendir = SOUTH + var/message_cooldown + var/breakout_time = 1 /obj/structure/bodycontainer/Destroy() open() @@ -41,6 +43,11 @@ /obj/structure/bodycontainer/relaymove(mob/user) if(user.stat || !isturf(loc)) return + if(locked) + if(message_cooldown <= world.time) + message_cooldown = world.time + 50 + to_chat(user, "[src]'s door won't budge!") + return open() /obj/structure/bodycontainer/attack_paw(mob/user) @@ -84,11 +91,20 @@ qdel(src) /obj/structure/bodycontainer/container_resist(mob/living/user) - open() - -/obj/structure/bodycontainer/relay_container_resist(mob/living/user, obj/O) - to_chat(user, "You slam yourself into the side of [O].") - container_resist(user) + if(!locked) + open() + return + user.changeNext_move(CLICK_CD_BREAKOUT) + user.last_special = world.time + CLICK_CD_BREAKOUT + user.visible_message(null, \ + "You lean on the back of [src] and start pushing the tray open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)", \ + "You hear a metallic creaking from [src].") + if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds + if(!user || user.stat != CONSCIOUS || user.loc != src ) + return + user.visible_message("[user] successfully broke out of [src]!", \ + "You successfully break out of [src]!") + open() /obj/structure/bodycontainer/proc/open() playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm index 89f02b13af..fcd9ead2a7 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm @@ -66,6 +66,9 @@ deconstruct(FALSE) /obj/structure/transit_tube_pod/container_resist(mob/living/user) + if(!user.incapacitated()) + empty_pod() + return if(!moving) user.changeNext_move(CLICK_CD_BREAKOUT) user.last_special = world.time + CLICK_CD_BREAKOUT diff --git a/code/modules/VR/vr_sleeper.dm b/code/modules/VR/vr_sleeper.dm index a83ced850e..f447b2f3e9 100644 --- a/code/modules/VR/vr_sleeper.dm +++ b/code/modules/VR/vr_sleeper.dm @@ -49,6 +49,10 @@ open_machine() +/obj/machinery/vr_sleeper/container_resist(mob/living/user) + open_machine() + + /obj/machinery/vr_sleeper/Destroy() open_machine() cleanup_vr_human() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index f0f41e375a..89e6538b07 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -32,6 +32,8 @@ var/running_bob_anim = FALSE var/escape_in_progress = FALSE + var/message_cooldown + var/breakout_time = 0.5 /obj/machinery/atmospherics/components/unary/cryo_cell/Initialize() . = ..() @@ -219,7 +221,9 @@ update_icon() /obj/machinery/atmospherics/components/unary/cryo_cell/relaymove(mob/user) - container_resist(user) + if(message_cooldown <= world.time) + message_cooldown = world.time + 50 + to_chat(user, "[src]'s door won't budge!") /obj/machinery/atmospherics/components/unary/cryo_cell/open_machine(drop = 0) if(!state_open && !panel_open) @@ -239,16 +243,17 @@ return occupant /obj/machinery/atmospherics/components/unary/cryo_cell/container_resist(mob/living/user) - if(escape_in_progress) - to_chat(user, "You are already trying to exit (This will take around 30 seconds)") - return - escape_in_progress = TRUE - to_chat(user, "You struggle inside the cryotube, kicking the release with your foot... (This will take around 30 seconds.)") - audible_message("You hear a thump from [src].") - if(do_after(user, 300)) - if(occupant == user) // Check they're still here. - open_machine() - escape_in_progress = FALSE + user.changeNext_move(CLICK_CD_BREAKOUT) + user.last_special = world.time + CLICK_CD_BREAKOUT + user.visible_message("You see [user] kicking against the glass of [src]!", \ + "You struggle inside [src], kicking the release with your foot... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)", \ + "You hear a thump from [src].") + if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds + if(!user || user.stat != CONSCIOUS || user.loc != src ) + return + user.visible_message("[user] successfully broke out of [src]!", \ + "You successfully break out of [src]!") + open_machine() /obj/machinery/atmospherics/components/unary/cryo_cell/examine(mob/user) ..() diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index d9f70160a4..978e8af62d 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -51,6 +51,9 @@ /obj/machinery/gibber/container_resist(mob/living/user) go_out() +/obj/machinery/gibber/relaymove(mob/living/user) + go_out() + /obj/machinery/gibber/attack_hand(mob/user) if(stat & (NOPOWER|BROKEN)) return @@ -225,4 +228,4 @@ if(M.loc == input_plate) M.forceMove(src) - M.gib() \ No newline at end of file + M.gib() From 33f36fd0de5d8dfa880ca0380f3f329ed5da6c9a Mon Sep 17 00:00:00 2001 From: ExcessiveUseOfCobblestone <11748095+ExcessiveUseOfCobblestone@users.noreply.github.com> Date: Fri, 8 Sep 2017 11:01:30 -0400 Subject: [PATCH 199/262] Adds Archaeology Component --- code/__DEFINES/components.dm | 11 ++- code/__DEFINES/is_helpers.dm | 2 + code/datums/components/archaeology.dm | 92 +++++++++++++++++++ code/game/atoms.dm | 5 +- .../mecha/equipment/tools/mining_tools.dm | 4 +- code/game/objects/items.dm | 3 +- code/game/objects/objs.dm | 1 + code/game/objects/structures/lattice.dm | 1 + .../structures/transit_tubes/transit_tube.dm | 1 + .../transit_tubes/transit_tube_pod.dm | 1 + code/game/objects/structures/window.dm | 1 + code/game/turfs/open.dm | 3 + code/game/turfs/simulated/floor.dm | 1 + code/game/turfs/simulated/floor/misc_floor.dm | 1 + .../turfs/simulated/floor/plating/asteroid.dm | 83 +++-------------- .../game/turfs/simulated/floor/reinf_floor.dm | 1 + code/game/turfs/simulated/wall/reinf_walls.dm | 1 + code/game/turfs/simulated/walls.dm | 1 + .../atmospherics/machinery/atmosmachinery.dm | 1 + .../atmospherics/machinery/other/meter.dm | 1 + code/modules/mob/living/carbon/human/human.dm | 2 +- code/modules/mob/living/living.dm | 1 + code/modules/power/cable.dm | 1 + code/modules/recycling/disposal-structures.dm | 1 + code/modules/recycling/disposal-unit.dm | 1 + tgstation.dme | 1 + 26 files changed, 146 insertions(+), 76 deletions(-) create mode 100644 code/datums/components/archaeology.dm diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index 0225dad669..37af346a88 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -5,7 +5,7 @@ // How multiple components of the exact same type are handled in the same datum #define COMPONENT_DUPE_HIGHLANDER 0 //old component is deleted (default) -#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed +#define COMPONENT_DUPE_ALLOWED 1 //duplicates allowed #define COMPONENT_DUPE_UNIQUE 2 //new component is deleted // All signals. Format: @@ -14,5 +14,14 @@ #define COMSIG_COMPONENT_ADDED "component_added" //when a component is added to a datum: (datum/component) #define COMSIG_COMPONENT_REMOVING "component_removing" //before a component is removed from a datum because of RemoveComponent: (datum/component) #define COMSIG_PARENT_QDELETED "parent_qdeleted" //before a datum's Destroy() is called: () +<<<<<<< HEAD #define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable, atom) #define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (atom/movable) +======= +#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from the base of atom/attackby: (obj/item, mob/living, params) +#define COMSIG_PARENT_EXAMINE "atom_examine" //from the base of atom/examine: (mob) +#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable, atom) +#define COMSIG_ATOM_EX_ACT "atom_ex_act" //from base of atom/ex_act(): (severity, target) +#define COMSIG_ATOM_SING_PULL "atom_sing_pull" //from base of atom/singularity_pull(): (S, current_size) +#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (atom/movable) +>>>>>>> 1e17bb7... Adds Archaeology Component (#30220) diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 16b2a8f4fb..2c18e51f01 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -25,6 +25,8 @@ #define islava(A) (istype(A, /turf/open/lava)) +#define isplatingturf(A) (istype(A, /turf/open/floor/plating)) + //Mobs #define isliving(A) (istype(A, /mob/living)) diff --git a/code/datums/components/archaeology.dm b/code/datums/components/archaeology.dm new file mode 100644 index 0000000000..22a6b24bc4 --- /dev/null +++ b/code/datums/components/archaeology.dm @@ -0,0 +1,92 @@ +/datum/component/archaeology + dupe_type = COMPONENT_DUPE_UNIQUE + var/list/archdrops + var/prob2drop + var/dug + +/datum/component/archaeology/Initialize(_prob2drop, list/_archdrops = list()) + prob2drop = Clamp(_prob2drop, 0, 100) + archdrops = _archdrops + RegisterSignal(COMSIG_PARENT_ATTACKBY,.proc/Dig) + RegisterSignal(COMSIG_ATOM_EX_ACT, .proc/BombDig) + RegisterSignal(COMSIG_ATOM_SING_PULL, .proc/SingDig) + +/datum/component/archaeology/InheritComponent(datum/component/archaeology/A, i_am_original) + var/list/other_archdrops = A.archdrops + var/list/_archdrops = archdrops + for(var/I in other_archdrops) + _archdrops[I] += other_archdrops[I] + +/datum/component/archaeology/proc/Dig(mob/user, obj/item/W) + if(dug) + to_chat(user, "Looks like someone has dug here already.") + return FALSE + else + var/digging_speed + if (istype(W, /obj/item/shovel)) + var/obj/item/shovel/S = W + digging_speed = S.digspeed + else if (istype(W, /obj/item/pickaxe)) + var/obj/item/pickaxe/P = W + digging_speed = P.digspeed + + if (digging_speed && isturf(user.loc)) + to_chat(user, "You start digging...") + playsound(parent, 'sound/effects/shovel_dig.ogg', 50, 1) + + if(do_after(user, digging_speed, target = parent)) + to_chat(user, "You dig a hole.") + gets_dug() + dug = TRUE + SSblackbox.add_details("pick_used_mining",W.type) + return TRUE + return FALSE + +/datum/component/archaeology/proc/gets_dug() + if(dug) + return + else + var/turf/open/OT = get_turf(parent) + for(var/thing in archdrops) + var/maxtodrop = archdrops[thing] + for(var/i in 1 to maxtodrop) + if(prob(prob2drop)) // can't win them all! + new thing(OT) + + if(isopenturf(OT)) + if(OT.postdig_icon_change) + if(istype(OT, /turf/open/floor/plating/asteroid/) && !OT.postdig_icon) + var/turf/open/floor/plating/asteroid/AOT = parent + AOT.icon_plating = "[AOT.environment_type]_dug" + AOT.icon_state = "[AOT.environment_type]_dug" + else + if(isplatingturf(OT)) + var/turf/open/floor/plating/POT = parent + POT.icon_plating = "[POT.postdig_icon]" + OT.icon_state = "[OT.postdig_icon]" + + if(OT.slowdown) //Things like snow slow you down until you dig them. + OT.slowdown = 0 + dug = TRUE + +/datum/component/archaeology/proc/SingDig(S, current_size) + switch(current_size) + if(STAGE_THREE) + if(prob(30)) + gets_dug() + if(STAGE_FOUR) + if(prob(50)) + gets_dug() + else + if(current_size >= STAGE_FIVE && prob(70)) + gets_dug() + +/datum/component/archaeology/proc/BombDig(severity, target) + switch(severity) + if(3) + return + if(2) + if(prob(20)) + gets_dug() + if(1) + gets_dug() diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 77bcefeddf..1e8ef4c5e2 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -304,6 +304,7 @@ /atom/proc/ex_act(severity, target) set waitfor = FALSE contents_explosion(severity, target) + SendSignal(COMSIG_ATOM_EX_ACT, severity, target) /atom/proc/blob_act(obj/structure/blob/B) return @@ -468,8 +469,8 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons) /atom/proc/singularity_act() return -/atom/proc/singularity_pull() - return +/atom/proc/singularity_pull(obj/singularity/S, current_size) + SendSignal(COMSIG_ATOM_SING_PULL, S, current_size) /atom/proc/acid_act(acidpwr, acid_volume) return diff --git a/code/game/mecha/equipment/tools/mining_tools.dm b/code/game/mecha/equipment/tools/mining_tools.dm index 6d15716941..d0a1310e8e 100644 --- a/code/game/mecha/equipment/tools/mining_tools.dm +++ b/code/game/mecha/equipment/tools/mining_tools.dm @@ -58,7 +58,9 @@ /turf/open/floor/plating/asteroid/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill) for(var/turf/open/floor/plating/asteroid/M in range(1, drill.chassis)) if(get_dir(drill.chassis,M)&drill.chassis.dir) - M.gets_dug() + for(var/I in GetComponents(/datum/component/archaeology)) + var/datum/component/archaeology/archy = I + archy.gets_dug() drill.log_message("Drilled through [src]") drill.move_ores() diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 96dcba36cf..f640e0f90b 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -549,9 +549,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) transfer_blood = 0 /obj/item/singularity_pull(S, current_size) + ..() if(current_size >= STAGE_FOUR) throw_at(S,14,3, spin=0) - else ..() + else return /obj/item/throw_impact(atom/A) if(A && !QDELETED(A)) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 1f3668f283..c8f105dfbe 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -169,6 +169,7 @@ return /obj/singularity_pull(S, current_size) + ..() if(!anchored || current_size >= STAGE_FIVE) step_towards(src,S) diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index 8a24b0271f..081cf186a3 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -45,6 +45,7 @@ qdel(src) /obj/structure/lattice/singularity_pull(S, current_size) + ..() if(current_size >= STAGE_FOUR) deconstruct() diff --git a/code/game/objects/structures/transit_tubes/transit_tube.dm b/code/game/objects/structures/transit_tubes/transit_tube.dm index 7b86cdffcc..10d883d392 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube.dm @@ -30,6 +30,7 @@ return ..() /obj/structure/transit_tube/singularity_pull(S, current_size) + ..() if(current_size >= STAGE_FIVE) deconstruct(FALSE) diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm index 89f02b13af..b885f980a2 100644 --- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm +++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm @@ -62,6 +62,7 @@ AM.ex_act(severity, target) /obj/structure/transit_tube_pod/singularity_pull(S, current_size) + ..() if(current_size >= STAGE_FIVE) deconstruct(FALSE) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index e70d5d3ddb..170a651315 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -105,6 +105,7 @@ qdel(src) /obj/structure/window/singularity_pull(S, current_size) + ..() if(current_size >= STAGE_FIVE) deconstruct(FALSE) diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm index 2622a4e74c..f97f79068d 100644 --- a/code/game/turfs/open.dm +++ b/code/game/turfs/open.dm @@ -4,6 +4,9 @@ var/wet = 0 var/wet_time = 0 // Time in seconds that this floor will be wet for. var/mutable_appearance/wet_overlay + var/postdig_icon_change = FALSE + var/postdig_icon + var/list/archdrops /turf/open/indestructible name = "floor" diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index cfc834037d..df3d2aba86 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -170,6 +170,7 @@ return make_plating() /turf/open/floor/singularity_pull(S, current_size) + ..() if(current_size == STAGE_THREE) if(prob(30)) if(floor_tile) diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm index f8d6c1da71..f2475cf997 100644 --- a/code/game/turfs/simulated/floor/misc_floor.dm +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -269,6 +269,7 @@ narsie_act(force, ignore_mobs, probability) /turf/open/floor/vines/singularity_pull(S, current_size) + ..() if(current_size >= STAGE_FIVE) if(prob(50)) ChangeTurf(src.baseturf) diff --git a/code/game/turfs/simulated/floor/plating/asteroid.dm b/code/game/turfs/simulated/floor/plating/asteroid.dm index b24b758d73..c6dd8cb2eb 100644 --- a/code/game/turfs/simulated/floor/plating/asteroid.dm +++ b/code/game/turfs/simulated/floor/plating/asteroid.dm @@ -9,11 +9,11 @@ icon = 'icons/turf/floors.dmi' icon_state = "asteroid" icon_plating = "asteroid" + postdig_icon_change = TRUE var/environment_type = "asteroid" var/turf_type = /turf/open/floor/plating/asteroid //Because caves do whacky shit to revert to normal - var/dug = 0 //0 = has not yet been dug, 1 = has already been dug - var/sand_type = /obj/item/ore/glass var/floor_variance = 20 //probability floor has a different icon state + archdrops = list(/obj/item/ore/glass = 5) /turf/open/floor/plating/asteroid/Initialize() var/proper_name = name @@ -22,6 +22,9 @@ if(prob(floor_variance)) icon_state = "[environment_type][rand(0,12)]" + if(LAZYLEN(archdrops)) + AddComponent(/datum/component/archaeology, 100, archdrops) + /turf/open/floor/plating/asteroid/burn_tile() return @@ -31,46 +34,7 @@ /turf/open/floor/plating/asteroid/MakeDry(wet_setting = TURF_WET_WATER) return -/turf/open/floor/plating/asteroid/ex_act(severity, target) - contents_explosion(severity, target) - switch(severity) - if(3) - return - if(2) - if(prob(20)) - src.gets_dug() - if(1) - src.gets_dug() - /turf/open/floor/plating/asteroid/attackby(obj/item/W, mob/user, params) - //note that this proc does not call ..() - if(!W || !user) - return 0 - var/digging_speed = 0 - if (istype(W, /obj/item/shovel)) - var/obj/item/shovel/S = W - digging_speed = S.digspeed - else if (istype(W, /obj/item/pickaxe)) - var/obj/item/pickaxe/P = W - digging_speed = P.digspeed - if (digging_speed) - var/turf/T = user.loc - if(!isturf(T)) - return - - if (dug) - to_chat(user, "This area has already been dug!") - return - - to_chat(user, "You start digging...") - playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) - - if(do_after(user, digging_speed, target = src)) - if(istype(src, /turf/open/floor/plating/asteroid)) - to_chat(user, "You dig a hole.") - gets_dug() - SSblackbox.add_details("pick_used_mining","[W.type]") - if(istype(W, /obj/item/storage/bag/ore)) var/obj/item/storage/bag/ore/S = W if(S.collection_mode == 1) @@ -88,37 +52,16 @@ var/turf/open/floor/light/F = T F.state = L.state playsound(src, 'sound/weapons/genhit.ogg', 50, 1) - -/turf/open/floor/plating/asteroid/proc/gets_dug() - if(dug) return - for(var/i in 1 to 5) - new sand_type(src) - dug = 1 - icon_plating = "[environment_type]_dug" - icon_state = "[environment_type]_dug" - slowdown = 0 - return + + return ..() + /turf/open/floor/plating/asteroid/singularity_act() if(turf_z_is_planet(src)) return ..() ChangeTurf(/turf/open/space) -/turf/open/floor/plating/asteroid/singularity_pull(S, current_size) - if(dug) - return - switch(current_size) - if(STAGE_THREE) - if(!prob(30)) - gets_dug() - if(STAGE_FOUR) - if(prob(50)) - gets_dug() - else - if(current_size >= STAGE_FIVE && prob(70)) - gets_dug() - /turf/open/floor/plating/asteroid/basalt name = "volcanic floor" @@ -127,7 +70,7 @@ icon_state = "basalt" icon_plating = "basalt" environment_type = "basalt" - sand_type = /obj/item/ore/glass/basalt + archdrops = list(/obj/item/ore/glass/basalt = 5) floor_variance = 15 /turf/open/floor/plating/asteroid/basalt/lava //lava underneath @@ -147,10 +90,10 @@ if("basalt5", "basalt9") B.set_light(1.4, 0.6, LIGHT_COLOR_LAVA) //barely anything! -/turf/open/floor/plating/asteroid/basalt/gets_dug() - if(!dug) - set_light(0) +/turf/open/floor/plating/asteroid/basalt/ComponentActivated(datum/component/C) ..() + if(istype(C, /datum/component/archaeology)) + set_light(0) ///////Surface. The surface is warm, but survivable without a suit. Internals are required. The floors break to chasms, which drop you into the underground. @@ -340,8 +283,8 @@ initial_gas_mix = "TEMP=180" slowdown = 2 environment_type = "snow" - sand_type = /obj/item/stack/sheet/mineral/snow flags_1 = NONE + archdrops = list(/obj/item/stack/sheet/mineral/snow = 5) /turf/open/floor/plating/asteroid/snow/airless initial_gas_mix = "TEMP=2.7" diff --git a/code/game/turfs/simulated/floor/reinf_floor.dm b/code/game/turfs/simulated/floor/reinf_floor.dm index df353653d7..eaf0e512f7 100644 --- a/code/game/turfs/simulated/floor/reinf_floor.dm +++ b/code/game/turfs/simulated/floor/reinf_floor.dm @@ -58,6 +58,7 @@ make_plating(1) /turf/open/floor/engine/singularity_pull(S, current_size) + ..() if(current_size >= STAGE_FIVE) if(floor_tile) if(prob(30)) diff --git a/code/game/turfs/simulated/wall/reinf_walls.dm b/code/game/turfs/simulated/wall/reinf_walls.dm index 261e856629..5ebe1d632a 100644 --- a/code/game/turfs/simulated/wall/reinf_walls.dm +++ b/code/game/turfs/simulated/wall/reinf_walls.dm @@ -247,6 +247,7 @@ icon_state = "r_wall" /turf/closed/wall/r_wall/singularity_pull(S, current_size) + ..() if(current_size >= STAGE_FIVE) if(prob(30)) dismantle_wall() diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index 57774a5754..9171c7f54c 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -245,6 +245,7 @@ QDEL_IN(O, 50) /turf/closed/wall/singularity_pull(S, current_size) + ..() if(current_size >= STAGE_FIVE) if(prob(50)) dismantle_wall() diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index e22da2f1b1..977d48fbd7 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -222,6 +222,7 @@ Pipelines + Other Objects -> Pipe network build_network() /obj/machinery/atmospherics/singularity_pull(S, current_size) + ..() if(current_size >= STAGE_FIVE) deconstruct(FALSE) diff --git a/code/modules/atmospherics/machinery/other/meter.dm b/code/modules/atmospherics/machinery/other/meter.dm index 89f8b8d2cb..b73fd986f8 100644 --- a/code/modules/atmospherics/machinery/other/meter.dm +++ b/code/modules/atmospherics/machinery/other/meter.dm @@ -120,6 +120,7 @@ return 1 /obj/machinery/meter/singularity_pull(S, current_size) + ..() if(current_size >= STAGE_FIVE) new /obj/item/pipe_meter(loc) qdel(src) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 304a745220..f93b1cc2f1 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -643,6 +643,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) update_hair() /mob/living/carbon/human/singularity_pull(S, current_size) + ..() if(current_size >= STAGE_THREE) for(var/obj/item/hand in held_items) if(prob(current_size * 5) && hand.w_class >= ((11-current_size)/2) && dropItemToGround(hand)) @@ -651,7 +652,6 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) rad_act(current_size * 3) if(mob_negates_gravity()) return - ..() /mob/living/carbon/human/proc/do_cpr(mob/living/carbon/C) CHECK_DNA_AND_SPECIES(C) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 70a8474165..522bf5cf57 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -690,6 +690,7 @@ who.equip_to_slot(what, where, TRUE) /mob/living/singularity_pull(S, current_size) + ..() if(current_size >= STAGE_SIX) throw_at(S,14,3, spin=1) else diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index ebe478a7bf..a24c0d7c57 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -170,6 +170,7 @@ By design, d1 is the smallest direction and d2 is the highest return 0 /obj/structure/cable/singularity_pull(S, current_size) + ..() if(current_size >= STAGE_FIVE) deconstruct() diff --git a/code/modules/recycling/disposal-structures.dm b/code/modules/recycling/disposal-structures.dm index efe730d1c2..9015320c56 100644 --- a/code/modules/recycling/disposal-structures.dm +++ b/code/modules/recycling/disposal-structures.dm @@ -335,6 +335,7 @@ /obj/structure/disposalpipe/singularity_pull(S, current_size) + ..() if(current_size >= STAGE_FIVE) deconstruct() diff --git a/code/modules/recycling/disposal-unit.dm b/code/modules/recycling/disposal-unit.dm index 14ebec8128..4c82605673 100644 --- a/code/modules/recycling/disposal-unit.dm +++ b/code/modules/recycling/disposal-unit.dm @@ -58,6 +58,7 @@ return ..() /obj/machinery/disposal/singularity_pull(S, current_size) + ..() if(current_size >= STAGE_FIVE) deconstruct() diff --git a/tgstation.dme b/tgstation.dme index df879e0b4d..4ecd700891 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -281,6 +281,7 @@ #include "code\datums\antagonists\datum_traitor.dm" #include "code\datums\antagonists\devil.dm" #include "code\datums\antagonists\ninja.dm" +#include "code\datums\components\archaeology.dm" #include "code\datums\components\component.dm" #include "code\datums\components\slippery.dm" #include "code\datums\diseases\_disease.dm" From 2ab29ccac45972556f0d0807f045754c942c1a6d Mon Sep 17 00:00:00 2001 From: Militaires Date: Fri, 8 Sep 2017 18:11:17 +0300 Subject: [PATCH 200/262] Adds shamebrero penguin for dumb alphonzo (#30487) --- .../living/simple_animal/friendly/penguin.dm | 8 +++++++- icons/mob/penguins.dmi | Bin 1090 -> 1721 bytes 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/friendly/penguin.dm b/code/modules/mob/living/simple_animal/friendly/penguin.dm index fdec7e7b47..1fa0fd53b8 100644 --- a/code/modules/mob/living/simple_animal/friendly/penguin.dm +++ b/code/modules/mob/living/simple_animal/friendly/penguin.dm @@ -24,11 +24,17 @@ butcher_results = list() gold_core_spawnable = 2 +/mob/living/simple_animal/pet/penguin/emperor/shamebrero + name = "Shamebrero penguin." + desc = "Shameful of all he surveys." + icon_state = "penguin_shamebrero" + icon_living = "penguin_shamebrero" + /mob/living/simple_animal/pet/penguin/baby speak = list("gah", "noot noot", "noot!", "noot", "squeee!", "noo!") name = "Penguin chick" real_name = "penguin" - desc = "Can't fly and can barely waddles, but the prince of all chicks." + desc = "Can't fly and barely waddles, yet the prince of all chicks." icon_state = "penguin_baby" icon_living = "penguin_baby" icon_dead = "penguin_baby_dead" diff --git a/icons/mob/penguins.dmi b/icons/mob/penguins.dmi index fae32b6bccaa443d13ea0b24ae5c7aef3e53a6f6..c7417f89b4a222138066ff88c4ed9ad560134be3 100644 GIT binary patch literal 1721 zcmV;q21fabP)004jp0{{R3ySI7-{{YCu3ggHTx$(Re(wt*Gki=-jIS^78Wk004#u2f)C< z`vYL~00001bW%=J06^y0W&i*Hr+QRabVOxyV{&P5bZKvH004NLm65>;0wEMd*ZLJQ zvyZ0Qwuu>H7R@h+;!CB{cv{ilrvcPcWlj8vpFR< ztD;F|xuC>=)h515h$2FY%^94&Sl3XZEQYL6vPW@(oVzcM2a|3R0e!KeK&TJg{fD_c zdS9+cA@9XwGF-RlZB)(zt!r2=(I3G5Qd%}l{qw^QBUzNb?w{q)000F@Nkl#)?+=tkZLHQeR*mK@s1OB%6wZjDCB)gL*g|pT7O`)B$c{zz@$^OL54K-@pC){g}1?AF}7udSot6r!<3} zI-h_1Jih#TdiwQp{Q2X2hGSWJS|2burD>LB&)FqEpYoU2{3Sn~^NT)^WobI#6GD)! zjnK&g0sW-=@a^p_&o39#ZMrirmps>pbpQE)f=Mt+Ckll0D~$4Mo~G&h`}^`;NuP` zHK6S9KD_#ct6m`O7s|*A({;^)zXqXG4%HbdmlHj z1R!}2xB`j;R9JmBzp1TsC)B|bLNJ7)1w;v@5s~^_ep^6Sw;3h_N)Av`fJA;*ptc{Y z0pj`F0yPRKdw9VHW&yY>13G86R!U|_O~1Z47WA5eM) z{2bB)95UFY$|%6VqlC*p8{nvUa1x+*kq!X8njG^=0HU?K6gVKA-w;T+ zKnR`T6Xt<~1Dajc56Jj)v3fKh=g-CJ(SWQ!7punuGX7kw9vz%N7pu6 z^YMF{hKX>=<3eXcwPoRFGKf?ZABqI28B`i0B{#HgoWd<*!0Uj;bXz4{9P7xw?6`4;y7;sF=7 z*ZvSd;u7cdrTxEzzYS@9Y5&hpKY-x$rTstA{#N`jTZqy6(*B=rv#69$&=ur#(|R8; zlwL3+O!$Ao2e3Am9IN|;bNhd`RZU=e7Y4$d$-N~`{|w+H|IfBs)$L908@;~XAV%aC|Yp5AL`A^*>vxEEb1P#e*hqs{HsG@ic49((Mu#~yp^vBw^N zN)YSiIdrZ%8-W*!&*@Uon{26F&?7=OAgB!Pm4oDyHTKr!#27-bwQ6doH@uLMx~Ne; zLl_HK(_;i%U{%1}yb~yXh^hB#F2H+{V6G5)P3d35b??M@Zc0 z`Z=fT5>EbGyip|7MX-2Cde;XS7mA*VmJaT9W`E(?d~AJuXnSt$VC}h;V~jPj zW{fhI)(mIQH8;YZTQ%AqY_{5iEn#D?!DeloKnQVbn%nILcQJfho5#lghK6w9P64u; P00000NkvXXu0mjfJ>FNf literal 1090 zcmV-I1ikx-P)fFDZ*Bkpc$`yKaB_9`^iy#0_2eo`Eh^5;&r`5fFwryM;w;ZhDainGjE%TB zGg33tGfE(w;*!LYR3KBSAT=+&G&4_$i!&v&s2HS;i!-e#F*g;&HpEaDpOTuGf>3No zSaEz(PJTY|T9OizDv5RsNHJ+Hg6kmBS*hviq^ONgD$37J&BLWdS;5uM1sq)fI<17D zA+HBp0009iNklf&U42CT)=s8q^_G$~Nd+wq4+S7br*Y&&@n)U~VuGd}G z{_N3qYLU!`>via%FcAcJW%AKS9FbCz%=V59mLnRDYb6@?=;bkuK;E#cHEmFkiyp=S zv_*B20W|1i03`!JIDA08qPhh5NCB%$xdy9C+Hn3E;A=+o4QQ(2{L38&e80LOLsHhm z+UHTPaRiPy!1`0DD8Po>@)!WbDgmq|prp@r?MoM`W%S=!^>y%MN@?8!mIM&W`Zz#K zKrR42yb=&7KzH%_#Q;_HfO611pnNf)=>eNT_khit0n#m?8FUY527ulN$R`2zyaxoZ zUBqh8Js`e&8mxR1D~NCI=+BsdsU^T0@+zl2AnG0v9RPL#Y=f{EPv@Ao0HPJt^l{sz zXB&idXh#9;F#?=pfD}xwnPxL+|IRtzP&E5HV-M|zYDKjIZRDP4a+x}2n{Bq)-pJHW zWjYbCTbWMV(9{MtOlvc32&y>EnYJ!JQw4c0IY7&wM(d729$aXpq>M)E3-X%6oAfG z&VaUc=yJH!`xX(4qNp+8E;Lw&ZL6GTeNU<$gMcgoQ2VGc0LzO~w_iQrcc*`Db=ReJ zhQudnUPj%Pk*2q9%@mxS8FTUUYpc5eUwYV|JXqGv0oQ*7q#_NNjO(J2fPw?8JUg?q z_$WX@fq5%>fNoGTfVcd3U$H3wX6g{LqtXsf`z+hqAOW-l>H>lve&~)DN(wNw1b8w+ z)n9Q8g&o-N<4^GH0>L;AaAsr#_k0AolK{u=4|dn!-d7jI0}BLxKY+CXkqWx_W_#!M7x7oz3k`zPwEzGB07*qo IM6N<$f?g)^1ONa4 From 2f438e5f4a21589a187a2232e78e83e303bb3f08 Mon Sep 17 00:00:00 2001 From: Ashe Higgs Date: Fri, 8 Sep 2017 11:18:14 -0400 Subject: [PATCH 202/262] Adds a short telegraph to the watcher's blasts (#30389) * Adds a telegraph to the watcher's blasts * hmm --- .../mob/living/simple_animal/hostile/hostile.dm | 12 +++++++++++- .../simple_animal/hostile/mining_mobs/basilisk.dm | 7 ++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 0f464de328..866f9c995a 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -28,6 +28,9 @@ var/ranged_message = "fires" //Fluff text for ranged mobs var/ranged_cooldown = 0 //What the current cooldown on ranged attacks is, generally world.time + ranged_cooldown_time var/ranged_cooldown_time = 30 //How long, in deciseconds, the cooldown of ranged attacks is + var/ranged_telegraph = "prepares to fire at *TARGET*!" //A message shown when the mob prepares to fire; use *TARGET* if you want to show the target's name + var/ranged_telegraph_sound //A sound played when the mob prepares to fire + var/ranged_telegraph_time = 0 //In deciseconds, how long between the telegraph and ranged shot var/ranged_ignores_vision = FALSE //if it'll fire ranged attacks even if it lacks vision on its target, only works with environment smash var/check_friendly_fire = 0 // Should the ranged mob check for friendlies when shooting var/retreat_distance = null //If our mob runs from players when they're too close, set in tile distance. By default, mobs do not retreat. @@ -232,7 +235,14 @@ var/target_distance = get_dist(targets_from,target) if(ranged) //We ranged? Shoot at em if(!target.Adjacent(targets_from) && ranged_cooldown <= world.time) //But make sure they're not in range for a melee attack and our range attack is off cooldown - OpenFire(target) + if(!ranged_telegraph_time || client) + OpenFire(target) + else + if(ranged_telegraph) + visible_message("[src] [replacetext(ranged_telegraph, "*TARGET*", "[target]")]") + if(ranged_telegraph_sound) + playsound(src, ranged_telegraph_sound, 75, FALSE) + addtimer(CALLBACK(src, .proc/OpenFire, target), ranged_telegraph_time) if(!Process_Spacemove()) //Drifting walk(src,0) return 1 diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm index f95820f87f..14b8056af6 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/basilisk.dm @@ -14,6 +14,9 @@ ranged = 1 ranged_message = "stares" ranged_cooldown_time = 30 + ranged_telegraph = "gathers energy and stares at *TARGET*!" + ranged_telegraph_sound = 'sound/magic/magic_missile.ogg' + ranged_telegraph_time = 7 throw_message = "does nothing against the hard shell of" vision_range = 2 speed = 3 @@ -70,9 +73,11 @@ melee_damage_lower = 15 melee_damage_upper = 15 attacktext = "impales" + ranged_telegraph = "fixates on *TARGET* as its eye shines blue!" + ranged_telegraph_sound = 'sound/magic/tail_swing.ogg' + ranged_telegraph_time = 5 a_intent = INTENT_HARM speak_emote = list("telepathically cries") - attack_sound = 'sound/weapons/bladeslice.ogg' stat_attack = UNCONSCIOUS movement_type = FLYING robust_searching = 1 From 71e87d851c9a943a4d864a219a0d0c715c84ae05 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 8 Sep 2017 11:27:53 -0400 Subject: [PATCH 204/262] Adds Features per Fix tracking --- tools/github_webhook_processor.php | 128 ++++++++++++++++++++++++++++- 1 file changed, 127 insertions(+), 1 deletion(-) diff --git a/tools/github_webhook_processor.php b/tools/github_webhook_processor.php index 6113714566..75cb3562b6 100644 --- a/tools/github_webhook_processor.php +++ b/tools/github_webhook_processor.php @@ -23,6 +23,12 @@ //This is required as otherwise somebody could trick the script into leaking the api key. $hookSecret = '08ajh0qj93209qj90jfq932j32r'; +$trackPRBalance = true; //set this to false to disable PR balance tracking +$prBalanceJson = ''; //Set this to the path you'd like the writable pr balance file to be stored, not setting it writes it to the working directory +$startingPRBalance = 3; //Starting balance for never before seen users +//team 133041: tgstation/commit-access +$maintainer_team_id = 133041; //org team id that is exempt from PR balance system, setting this to null will use anyone with write access to the repo. Get from https://api.github.com/orgs/:org/teams + //Api key for pushing changelogs. $apiKey = '209ab8d879c0f987d06a09b9d879c0f987d06a09b9d8787d0a089c'; @@ -168,7 +174,7 @@ function tag_pr($payload, $opened) { if(strpos($lowertitle, '[wip]') !== FALSE) $tags[] = 'Work In Progress'; - $url = $payload['pull_request']['base']['repo']['url'] . '/issues/' . $payload['pull_request']['number'] . '/labels'; + $url = $payload['pull_request']['issue_url'] . '/labels'; $existing_labels = file_get_contents($url, false, stream_context_create($scontext)); $existing_labels = json_decode($existing_labels, true); @@ -195,6 +201,12 @@ function handle_pr($payload) { switch ($payload["action"]) { case 'opened': tag_pr($payload, true); + if(get_pr_code_friendliness($payload) < 0){ + $balances = pr_balances(); + $author = $payload['pull_request']['user']['login']; + if(isset($balances[$author]) && $balances[$author] < 0) + create_comment($payload, 'You currently have a negative Fix/Feature pull request delta of ' . $balances[$author] . '. Maintainers may close this PR at will. Fixing issues or improving the codebase will improve this score.'); + } break; case 'edited': case 'synchronize': @@ -210,6 +222,11 @@ function handle_pr($payload) { else { $action = 'merged'; checkchangelog($payload, true, true); +<<<<<<< HEAD +======= + update_pr_balance($payload); + $validated = TRUE; //pr merged events always get announced. +>>>>>>> af44a7a... Adds Features per Fix tracking (#29897) } break; default: @@ -223,7 +240,116 @@ function handle_pr($payload) { $msg = '['.$payload['pull_request']['base']['repo']['full_name'].'] Pull Request '.$action.' by '.htmlSpecialChars($payload['sender']['login']).': '.htmlSpecialChars('#'.$payload['pull_request']['number'].' '.$payload['pull_request']['user']['login'].' - '.$payload['pull_request']['title']).''; sendtoallservers('?announce='.urlencode($msg), $payload); +} +//creates a comment on the payload issue +function create_comment($payload, $comment){ + apisend($payload['pull_request']['comments_url'], 'POST', json_encode(array('body' => $comment))); +} + +//returns the payload issue's labels as a flat array +function get_pr_labels_array($payload){ + $url = $payload['pull_request']['issue_url'] . '/labels'; + $issue = json_decode(apisend($url), true); + $result = array(); + foreach($issue as $l) + $result[] = $l['name']; + return $result; +} + +//helper for getting the path the the balance json file +function pr_balance_json_path(){ + global $prBalanceJson; + return $prBalanceJson != '' ? $prBalanceJson : 'pr_balances.json'; +} + +//return the assoc array of login -> balance for prs +function pr_balances(){ + $path = pr_balance_json_path(); + if(file_exists($path)) + return json_decode(file_get_contents($path), true); + else + return array(); +} + +//returns the difference in PR balance a pull request would cause +function get_pr_code_friendliness($payload, $oldbalance = null){ + global $startingPRBalance; + if($oldbalance == null) + $oldbalance = $startingPRBalance; + $labels = get_pr_labels_array($payload); + //anything not in this list defaults to 0 + $label_values = array( + 'Fix' => 2, + 'Refactor' => 2, + 'Code Improvement' => 1, + 'Priority: High' => 4, + 'Priority: CRITICAL' => 5, + 'Atmospherics' => 4, + 'Logging' => 1, + 'Feedback' => 1, + 'Performance' => 3, + 'Feature' => -1, + 'Balance/Rebalance' => -1, + 'Tweak' => -1, + 'PRB: Reset' => $startingPRBalance - $oldbalance, + ); + + $affecting = 0; + $is_neutral = FALSE; + $found_something_positive = false; + foreach($labels as $l){ + if($l == 'PRB: No Update') { //no effect on balance + $affecting = 0; + break; + } + else if(isset($label_values[$l])) { + $friendliness = $label_values[$l]; + if($friendliness > 0) + $found_something_positive = true; + $affecting = $found_something_positive ? max($affecting, $friendliness) : $friendliness; + } + } + return $affecting; +} + +function is_maintainer($payload, $author){ + global $maintainer_team_id; + $repo_is_org = $payload['pull_request']['base']['repo']['owner']['type'] == 'Organization'; + if($maintainer_team_id == null || !$repo_is_org) { + $collaburl = $payload['pull_request']['base']['repo']['collaborators_url'] . '/' . $author . '/permissions'; + $perms = json_decode(apisend($collaburl), true); + $permlevel = $perms['permission']; + return $permlevel == 'admin' || $permlevel == 'write'; + } + else { + $check_url = 'https://api.github.com/teams/' . $maintainer_team_id . '/memberships/' . $author; + $result = json_decode(apisend($check_url), true); + return isset($result['state']); //this field won't be here if they aren't a member + } +} + +//payload is a merged pull request, updates the pr balances file with the correct positive or negative balance based on comments +function update_pr_balance($payload) { + global $startingPRBalance; + global $trackPRBalance; + if(!$trackPRBalance) + return; + $author = $payload['pull_request']['user']['login']; + if(is_maintainer($payload, $author)) //immune + return; + $balances = pr_balances(); + if(!isset($balances[$author])) + $balances[$author] = $startingPRBalance; + $friendliness = get_pr_code_friendliness($payload, $balances[$author]); + $balances[$author] += $friendliness; + if($balances[$author] < 0 && $friendliness < 0) + create_comment($payload, 'Your Fix/Feature pull request delta is currently below zero (' . $balances[$author] . '). Maintainers may close future Feature/Tweak/Balance PRs. Fixing issues or helping to improve the codebase will raise this score.'); + else if($balances[$author] >= 0 && ($balances[$author] - $friendliness) < 0) + create_comment($payload, 'Your Fix/Feature pull request delta is now above zero (' . $balances[$author] . '). Feel free to make Feature/Tweak/Balance PRs.'); + $balances_file = fopen(pr_balance_json_path(), 'w'); + fwrite($balances_file, json_encode($balances)); + fclose($balances_file); } function has_tree_been_edited($payload, $tree){ From 8010c44c726fe626ebd9bc398f6b93af06b74109 Mon Sep 17 00:00:00 2001 From: Robustin Date: Fri, 8 Sep 2017 14:45:49 -0400 Subject: [PATCH 205/262] Golem shells can no longer fit in bags (#30498) * Automatic changelog generation for PR #30056 [ci skip] * RIP pocket army * Delete AutoChangeLog-pr-30056.yml --- code/modules/ruins/lavaland_ruin_code.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/ruins/lavaland_ruin_code.dm b/code/modules/ruins/lavaland_ruin_code.dm index 63861b8e35..e4927349d8 100644 --- a/code/modules/ruins/lavaland_ruin_code.dm +++ b/code/modules/ruins/lavaland_ruin_code.dm @@ -46,6 +46,7 @@ desc = "The incomplete body of a golem. Add ten sheets of any mineral to finish." var/shell_type = /obj/effect/mob_spawn/human/golem var/has_owner = FALSE //if the resulting golem obeys someone + w_class = WEIGHT_CLASS_BULKY /obj/item/golem_shell/attackby(obj/item/I, mob/user, params) ..() From d35717e1abd4f728e9c64b7494a6262a60cbfe51 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Fri, 8 Sep 2017 20:15:10 -0500 Subject: [PATCH 207/262] [MIRROR] Fixes assault pod blinking docking effects (#2667) * Fixes assault pod blinking docking effects (#30492) * Fixes assault pod blinking docking effects --- code/modules/shuttle/assault_pod.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/shuttle/assault_pod.dm b/code/modules/shuttle/assault_pod.dm index 7015192722..5b21d22d19 100644 --- a/code/modules/shuttle/assault_pod.dm +++ b/code/modules/shuttle/assault_pod.dm @@ -11,7 +11,7 @@ /obj/docking_port/mobile/assault_pod/dock(obj/docking_port/stationary/S1) - ..() + . = ..() if(!istype(S1, /obj/docking_port/stationary/transit)) playsound(get_turf(src.loc), 'sound/effects/explosion1.ogg',50,1) From 25a5325e2461e4aec66e3fa57c3f6531b35dc23f Mon Sep 17 00:00:00 2001 From: oranges Date: Sat, 9 Sep 2017 12:01:22 +1000 Subject: [PATCH 208/262] Merge pull request #30489 from Cyberboss/CompLightFix Makes computers lose their light when their screens break --- code/game/machinery/computer/_computer.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm index 85d8f02970..0c4c6c4bbe 100644 --- a/code/game/machinery/computer/_computer.dm +++ b/code/game/machinery/computer/_computer.dm @@ -90,6 +90,7 @@ playsound(loc, 'sound/effects/glassbr3.ogg', 100, 1) stat |= BROKEN update_icon() + set_light(0) /obj/machinery/computer/emp_act(severity) switch(severity) From d60a6729d30191787db93d321bea038a19c3948e Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 8 Sep 2017 22:22:05 -0400 Subject: [PATCH 210/262] Merge pull request #30504 from YPOQ/windooremagfix Windoors open when emagged again --- code/game/machinery/doors/windowdoor.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 6a1bb1ec3a..f76412199c 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -213,7 +213,7 @@ sleep(6) operating = FALSE desc += "
    Its access panel is smoking slightly." - open() + open(2) /obj/machinery/door/window/attackby(obj/item/I, mob/living/user, params) From 5b61c84df40733a1de10c693d5467226e3aa72ed Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 8 Sep 2017 22:24:40 -0400 Subject: [PATCH 212/262] Merge pull request #30481 from YPOQ/shuntfix Placing a robotics factory actually disables shunting --- code/game/gamemodes/malfunction/Malf_Modules.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 5dfd8f7396..24d5311af3 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -672,7 +672,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list( var/obj/machinery/transformer/conveyor = new(T) conveyor.masterAI = owner playsound(T, 'sound/effects/phasein.ogg', 100, 1) - owner_AI.can_shunt = TRUE + owner_AI.can_shunt = FALSE to_chat(owner, "You are no longer able to shunt your core to APCs.") adjust_uses(-1) From 80d0048ac08da17220805259cc60ad86faa82428 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 9 Sep 2017 01:02:52 -0500 Subject: [PATCH 214/262] Automatic changelog generation for PR #2662 [ci skip] --- html/changelogs/AutoChangeLog-pr-2662.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-2662.yml diff --git a/html/changelogs/AutoChangeLog-pr-2662.yml b/html/changelogs/AutoChangeLog-pr-2662.yml new file mode 100644 index 0000000000..9eb4f3020f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2662.yml @@ -0,0 +1,4 @@ +author: "basilman" +delete-after: True +changes: + - rscadd: "penguins may now have shamebreros, noot noot" From 12a30f8ec11081cb83b34bee9b695dfac243b015 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 9 Sep 2017 01:03:18 -0500 Subject: [PATCH 215/262] Automatic changelog generation for PR #2663 [ci skip] --- html/changelogs/AutoChangeLog-pr-2663.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-2663.yml diff --git a/html/changelogs/AutoChangeLog-pr-2663.yml b/html/changelogs/AutoChangeLog-pr-2663.yml new file mode 100644 index 0000000000..99d9414d41 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2663.yml @@ -0,0 +1,4 @@ +author: "Xhuis" +delete-after: True +changes: + - balance: "Watchers now have a half-second telegraph between charging and firing their freezing blasts." From a47776705a63f8da82ef995bf07f91c9dcced0be Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 9 Sep 2017 01:04:24 -0500 Subject: [PATCH 216/262] Automatic changelog generation for PR #2666 [ci skip] --- html/changelogs/AutoChangeLog-pr-2666.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-2666.yml diff --git a/html/changelogs/AutoChangeLog-pr-2666.yml b/html/changelogs/AutoChangeLog-pr-2666.yml new file mode 100644 index 0000000000..5f15eab5f6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2666.yml @@ -0,0 +1,4 @@ +author: "Robustin" +delete-after: True +changes: + - tweak: "Golem shells no longer fit in standard crew bags." From b2ffb03cef940937dc19840b028f9308e6518e17 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 9 Sep 2017 01:05:31 -0500 Subject: [PATCH 217/262] Automatic changelog generation for PR #2671 [ci skip] --- html/changelogs/AutoChangeLog-pr-2671.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-2671.yml diff --git a/html/changelogs/AutoChangeLog-pr-2671.yml b/html/changelogs/AutoChangeLog-pr-2671.yml new file mode 100644 index 0000000000..2415108e8b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2671.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Windoors open when emagged again" From 1769b0272ae8477c2716dd8f83458502f239cfb6 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 9 Sep 2017 01:07:06 -0500 Subject: [PATCH 218/262] Automatic changelog generation for PR #2656 [ci skip] --- html/changelogs/AutoChangeLog-pr-2656.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-2656.yml diff --git a/html/changelogs/AutoChangeLog-pr-2656.yml b/html/changelogs/AutoChangeLog-pr-2656.yml new file mode 100644 index 0000000000..a1be7491b7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2656.yml @@ -0,0 +1,4 @@ +author: "JJRcop" +delete-after: True +changes: + - rscadd: "Admins can now play media content from the web to players." From 8e0ef4f38f18879ebd14c0e9853c2a80481444c5 Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Sat, 9 Sep 2017 12:23:54 -0700 Subject: [PATCH 219/262] num2text the Instances number (#30509) --- code/modules/mob/mob.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 76553d17fd..a759bb89ec 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -587,7 +587,7 @@ var/turf/T = get_turf(client.eye) stat("Location:", COORD(T)) stat("CPU:", "[world.cpu]") - stat("Instances:", "[world.contents.len]") + stat("Instances:", "[num2text(world.contents.len, 10)]") GLOB.stat_entry() config.stat_entry() stat(null) From 3ceb70f84dbdd5e41d68a79a20305d764cc6415a Mon Sep 17 00:00:00 2001 From: msgerbs Date: Sat, 9 Sep 2017 16:28:53 -0500 Subject: [PATCH 221/262] Fix crit-only healing to include softcrit (#30520) With softcrit implemented, people are only unconcious in hard crit. This will no longer bring you out of crit as intended. This PR fixes that. --- code/modules/reagents/chemistry/reagents/alcohol_reagents.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 9b22236a03..5e3bf0f749 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -1072,7 +1072,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Aromatic beverage served piping hot. According to folk tales it can almost wake the dead." /datum/reagent/consumable/ethanol/hearty_punch/on_mob_life(mob/living/M) - if(M.stat == UNCONSCIOUS && M.health <= 0) + if(M.health <= 0) M.adjustBruteLoss(-7, 0) M.adjustFireLoss(-7, 0) M.adjustToxLoss(-7, 0) From eaeaae7bef957e594e2727d02a7f3accd4392567 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Sat, 9 Sep 2017 20:39:49 -0400 Subject: [PATCH 223/262] Added warnings for ultrasafe and safe security modes (#30515) --- code/__DEFINES/misc.dm | 5 +++++ code/game/world.dm | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 209a33e0c5..1c79dde65f 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -458,3 +458,8 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE #define SHELLEO_ERRORLEVEL 1 #define SHELLEO_STDOUT 2 #define SHELLEO_STDERR 3 + +//server security mode +#define SECURITY_SAFE 1 +#define SECURITY_ULTRASAFE 2 +#define SECURITY_TRUSTED 3 diff --git a/code/game/world.dm b/code/game/world.dm index a1fcc364cd..991e6230e6 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -1,3 +1,6 @@ +GLOBAL_VAR(security_mode) +GLOBAL_PROTECT(security_mode) + /world/New() log_world("World loaded at [time_stamp()]") @@ -5,6 +8,8 @@ GLOB.config_error_log = GLOB.sql_error_log = GLOB.world_href_log = GLOB.world_runtime_log = GLOB.world_attack_log = GLOB.world_game_log = file("data/logs/config_error.log") //temporary file used to record errors with loading config, moved to log directory once logging is set bl + CheckSecurityMode() + make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once) config = new @@ -94,6 +99,20 @@ if(GLOB.round_id) log_game("Round ID: [GLOB.round_id]") +/world/proc/CheckSecurityMode() + //try to write to data + if(!text2file("The world is running at least safe mode", "data/server_security_check.lock")) + GLOB.security_mode = SECURITY_ULTRASAFE + warning("/tg/station 13 is not supported in ultrasafe security mode. Everything will break!") + return + + //try to shell + if(shell("echo \"The world is running in trusted mode\"") != null) + GLOB.security_mode = SECURITY_TRUSTED + else + GLOB.security_mode = SECURITY_SAFE + warning("/tg/station 13 uses many file operations, a few shell()s, and some external call()s. Trusted mode is recommended. You can download our source code for your own browsing and compilation at https://github.com/tgstation/tgstation") + /world/Topic(T, addr, master, key) var/list/input = params2list(T) From 317958fb5ccf9503d8f8fb7db71ff04652b0eabb Mon Sep 17 00:00:00 2001 From: AnturK Date: Sun, 10 Sep 2017 02:40:23 +0200 Subject: [PATCH 225/262] Fixes more CanPass misuse (#30493) * Fixes more CanPass misuse * Let's not give wrong impression * spans --- code/game/atoms_movable.dm | 2 +- code/modules/holodeck/items.dm | 16 ++++++------ code/modules/recycling/disposal-unit.dm | 30 +++++++++++----------- code/modules/shuttle/special.dm | 33 ++++++++++++++++++------- 4 files changed, 46 insertions(+), 35 deletions(-) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index f4cbcda098..38c815ee43 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -215,7 +215,7 @@ //to differentiate it, naturally everyone forgot about this immediately and so some things //would bump twice, so now it's called Collide /atom/movable/proc/Collide(atom/A) - if((A)) + if(A) if(throwing) throwing.hit_atom(A) . = 1 diff --git a/code/modules/holodeck/items.dm b/code/modules/holodeck/items.dm index 8dfbfa7c63..86481b4c14 100644 --- a/code/modules/holodeck/items.dm +++ b/code/modules/holodeck/items.dm @@ -120,17 +120,15 @@ else ..() -/obj/structure/holohoop/CanPass(atom/movable/mover, turf/target) - if (isitem(mover) && mover.throwing) - var/obj/item/I = mover - if(istype(I, /obj/item/projectile)) - return +/obj/structure/holohoop/hitby(atom/movable/AM) + if (isitem(AM) && !istype(AM,/obj/item/projectile)) if(prob(50)) - I.forceMove(get_turf(src)) - visible_message("Swish! [I] lands in [src].") + AM.forceMove(get_turf(src)) + visible_message("Swish! [AM] lands in [src].") + return else - visible_message("[I] bounces off of [src]'s rim!") - return 0 + visible_message("[AM] bounces off of [src]'s rim!") + return ..() else return ..() diff --git a/code/modules/recycling/disposal-unit.dm b/code/modules/recycling/disposal-unit.dm index 14ebec8128..04207a8e09 100644 --- a/code/modules/recycling/disposal-unit.dm +++ b/code/modules/recycling/disposal-unit.dm @@ -335,20 +335,18 @@ eject() . = TRUE -/obj/machinery/disposal/bin/CanPass(atom/movable/mover, turf/target) - if (isitem(mover) && mover.throwing) - var/obj/item/I = mover - if(istype(I, /obj/item/projectile)) - return + +/obj/machinery/disposal/bin/hitby(atom/movable/AM) + if(isitem(AM) && AM.CanEnterDisposals()) if(prob(75)) - I.forceMove(src) - visible_message("[I] lands in [src].") + AM.forceMove(src) + visible_message("[AM] lands in [src].") update_icon() else - visible_message("[I] bounces off of [src]'s rim!") - return 0 + visible_message("[AM] bounces off of [src]'s rim!") + return ..() else - return ..(mover, target) + return ..() /obj/machinery/disposal/bin/flush() ..() @@ -457,12 +455,12 @@ trunk.linked = src // link the pipe trunk to self /obj/machinery/disposal/deliveryChute/place_item_in_disposal(obj/item/I, mob/user) - if(I.disposalEnterTry()) + if(I.CanEnterDisposals()) ..() flush() /obj/machinery/disposal/deliveryChute/CollidedWith(atom/movable/AM) //Go straight into the chute - if(!AM.disposalEnterTry()) + if(!AM.CanEnterDisposals()) return switch(dir) if(NORTH) @@ -485,16 +483,16 @@ M.forceMove(src) flush() -/atom/movable/proc/disposalEnterTry() +/atom/movable/proc/CanEnterDisposals() return 1 -/obj/item/projectile/disposalEnterTry() +/obj/item/projectile/CanEnterDisposals() return -/obj/effect/disposalEnterTry() +/obj/effect/CanEnterDisposals() return -/obj/mecha/disposalEnterTry() +/obj/mecha/CanEnterDisposals() return /obj/machinery/disposal/deliveryChute/newHolderDestination(obj/structure/disposalholder/H) diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm index 6a972bff9b..0373ea5b53 100644 --- a/code/modules/shuttle/special.dm +++ b/code/modules/shuttle/special.dm @@ -215,23 +215,37 @@ /obj/effect/forcefield/luxury_shuttle var/threshold = 500 var/static/list/approved_passengers = list() + var/static/list/check_times = list() /obj/effect/forcefield/luxury_shuttle/CanPass(atom/movable/mover, turf/target) if(mover in approved_passengers) - return 1 + return TRUE if(!isliving(mover)) //No stowaways - return 0 + return FALSE + + return FALSE + + +#define LUXURY_MESSAGE_COOLDOWN 100 +/obj/effect/forcefield/luxury_shuttle/CollidedWith(atom/movable/AM) + if(!isliving(AM)) + return ..() + + if(check_times[AM] && check_times[AM] > world.time) //Let's not spam the message + return ..() + + check_times[AM] = world.time + LUXURY_MESSAGE_COOLDOWN var/total_cash = 0 var/list/counted_money = list() - for(var/obj/item/coin/C in mover.GetAllContents()) + for(var/obj/item/coin/C in AM.GetAllContents()) total_cash += C.value counted_money += C if(total_cash >= threshold) break - for(var/obj/item/stack/spacecash/S in mover.GetAllContents()) + for(var/obj/item/stack/spacecash/S in AM.GetAllContents()) total_cash += S.value * S.amount counted_money += S if(total_cash >= threshold) @@ -241,12 +255,13 @@ for(var/obj/I in counted_money) qdel(I) - to_chat(mover, "Thank you for your payment! Please enjoy your flight.") - approved_passengers += mover - return 1 + to_chat(AM, "Thank you for your payment! Please enjoy your flight.") + approved_passengers += AM + check_times -= AM + return else - to_chat(mover, "You don't have enough money to enter the main shuttle. You'll have to fly coach.") - return 0 + to_chat(AM, "You don't have enough money to enter the main shuttle. You'll have to fly coach.") + return ..() /mob/living/simple_animal/hostile/bear/fightpit name = "fight pit bear" From 9704893614fe38f66d391257af565a842dd857b9 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 9 Sep 2017 23:50:23 -0500 Subject: [PATCH 227/262] Automatic changelog generation for PR #2674 [ci skip] --- html/changelogs/AutoChangeLog-pr-2674.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-2674.yml diff --git a/html/changelogs/AutoChangeLog-pr-2674.yml b/html/changelogs/AutoChangeLog-pr-2674.yml new file mode 100644 index 0000000000..192d444569 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2674.yml @@ -0,0 +1,4 @@ +author: "VexingRaven" +delete-after: True +changes: + - bugfix: "Hearty Punch once again pulls people out of crit." From ee4052eb61124cbfb1114e0312307ca4c2abc4d5 Mon Sep 17 00:00:00 2001 From: oranges Date: Sun, 10 Sep 2017 21:00:58 +1000 Subject: [PATCH 228/262] Merge pull request #30524 from ChangelingRain/srcremoval Removes a src. --- code/game/gamemodes/blob/theblob.dm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index c2511f2302..8443f3d6f1 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -90,8 +90,10 @@ /obj/structure/blob/proc/Life() return -/obj/structure/blob/proc/Pulse_Area(pulsing_overmind = overmind, claim_range = 10, pulse_range = 3, expand_range = 2) - src.Be_Pulsed() +/obj/structure/blob/proc/Pulse_Area(mob/camera/blob/pulsing_overmind, claim_range = 10, pulse_range = 3, expand_range = 2) + if(QDELETED(pulsing_overmind)) + pulsing_overmind = overmind + Be_Pulsed() var/expanded = FALSE if(prob(70) && expand()) expanded = TRUE From 55f9874a080ef46ae63608e1a8916d17543445c9 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Sun, 10 Sep 2017 06:05:57 -0500 Subject: [PATCH 230/262] Ladders cant be moved by the singularity (#30518) It'd be weird to have the top part of a ladder moved five tiles and then still lead to the ladder underneath its old location. Just destroys it instead. --- code/game/objects/structures/ladders.dm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm index c1a45ad20e..d0ad32113d 100644 --- a/code/game/objects/structures/ladders.dm +++ b/code/game/objects/structures/ladders.dm @@ -118,5 +118,13 @@ else return QDEL_HINT_LETMELIVE +/obj/structure/ladder/unbreakable/singularity_pull() + return + /obj/structure/ladder/auto_connect //They will connect to ladders with the same X and Y without needing to share an ID - auto_connect = TRUE \ No newline at end of file + auto_connect = TRUE + + +/obj/structure/ladder/singularity_pull() + visible_message("[src] is torn to pieces by the gravitational pull!") + qdel(src) From b363dc352fea12482775bccc8719ec7e4bc2edff Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 10 Sep 2017 09:07:18 -0500 Subject: [PATCH 232/262] [MIRROR] remove GLOB. (#2683) * Merge pull request #30540 from p440/blobglob remove GLOB. * remove GLOB. --- code/game/gamemodes/blob/powers.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index 389888ac28..6baf8b4dbe 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -363,7 +363,7 @@ to_chat(src, "Node Blobs are blobs which grow, like the core. Like the core it can activate resource and factory blobs.") to_chat(src, "In addition to the buttons on your HUD, there are a few click shortcuts to speed up expansion and defense.") to_chat(src, "Shortcuts: Click = Expand Blob | Middle Mouse Click = Rally Spores | Ctrl Click = Create Shield Blob | Alt Click = Remove Blob") - to_chat(src, "Attempting to talk will send a message to all other GLOB.overminds, allowing you to coordinate with them.") + to_chat(src, "Attempting to talk will send a message to all other overminds, allowing you to coordinate with them.") if(!placed && autoplace_max_time <= world.time) to_chat(src, "You will automatically place your blob core in [round((autoplace_max_time - world.time)/600, 0.5)] minutes.") to_chat(src, "You [manualplace_min_time ? "will be able to":"can"] manually place your blob core by pressing the Place Blob Core button in the bottom right corner of the screen.") From 863db1b7c39cd951f5050f54fd0a603dcc78af48 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 10 Sep 2017 11:44:48 -0500 Subject: [PATCH 233/262] Automatic changelog generation for PR #2633 [ci skip] --- html/changelogs/AutoChangeLog-pr-2633.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-2633.yml diff --git a/html/changelogs/AutoChangeLog-pr-2633.yml b/html/changelogs/AutoChangeLog-pr-2633.yml new file mode 100644 index 0000000000..4806cb12c5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2633.yml @@ -0,0 +1,4 @@ +author: "Xhuis" +delete-after: True +changes: + - imageadd: "The hand drill and jaws of life now have sprites on the toolbelt." From 33f35fe4d2c895ecefa4970c2d25cf303c63951d Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 10 Sep 2017 11:46:34 -0500 Subject: [PATCH 234/262] Update tools.dm --- code/game/objects/items/tools.dm | 1583 +++++++++++++++--------------- 1 file changed, 790 insertions(+), 793 deletions(-) diff --git a/code/game/objects/items/tools.dm b/code/game/objects/items/tools.dm index 0e557497c0..5c901ca4bd 100644 --- a/code/game/objects/items/tools.dm +++ b/code/game/objects/items/tools.dm @@ -1,795 +1,793 @@ -<<<<<<< HEAD -#define WELDER_FUEL_BURN_INTERVAL 13 - -/* Tools! - * Note: Multitools are /obj/item/device - * - * Contains: - * Wrench - * Screwdriver - * Wirecutters - * Welding Tool - * Crowbar - */ - -/* - * Wrench - */ -/obj/item/wrench - name = "wrench" - desc = "A wrench with common uses. Can be found in your hand." - icon = 'icons/obj/tools.dmi' - icon_state = "wrench" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 5 - throwforce = 7 - w_class = WEIGHT_CLASS_SMALL - usesound = 'sound/items/ratchet.ogg' - materials = list(MAT_METAL=150) - origin_tech = "materials=1;engineering=1" - attack_verb = list("bashed", "battered", "bludgeoned", "whacked") - toolspeed = 1 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) - -/obj/item/wrench/suicide_act(mob/user) - user.visible_message("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) - return (BRUTELOSS) - -/obj/item/wrench/cyborg - name = "automatic wrench" - desc = "An advanced robotic wrench. Can be found in construction cyborgs." - toolspeed = 0.5 - -/obj/item/wrench/brass - name = "brass wrench" - desc = "A brass wrench. It's faintly warm to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "wrench_brass" - toolspeed = 0.5 - -/obj/item/wrench/abductor - name = "alien wrench" - desc = "A polarized wrench. It causes anything placed between the jaws to turn." - icon = 'icons/obj/abductor.dmi' - icon_state = "wrench" - usesound = 'sound/effects/empulse.ogg' - toolspeed = 0.1 - origin_tech = "materials=5;engineering=5;abductor=3" - -/obj/item/wrench/power - name = "hand drill" - desc = "A simple powered hand drill. It's fitted with a bolt bit." - icon_state = "drill_bolt" - item_state = "drill" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - usesound = 'sound/items/drill_use.ogg' - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get - force = 8 //might or might not be too high, subject to change - w_class = WEIGHT_CLASS_SMALL - throwforce = 8 - attack_verb = list("drilled", "screwed", "jabbed") - toolspeed = 0.25 - -/obj/item/wrench/power/attack_self(mob/user) - playsound(get_turf(user),'sound/items/change_drill.ogg',50,1) - var/obj/item/wirecutters/power/s_drill = new /obj/item/screwdriver/power - to_chat(user, "You attach the screw driver bit to [src].") - qdel(src) - user.put_in_active_hand(s_drill) - -/obj/item/wrench/power/suicide_act(mob/user) - user.visible_message("[user] is pressing [src] against [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) - -/obj/item/wrench/medical - name = "medical wrench" - desc = "A medical wrench with common(medical?) uses. Can be found in your hand." - icon_state = "wrench_medical" - force = 2 //MEDICAL - throwforce = 4 - origin_tech = "materials=1;engineering=1;biotech=3" - attack_verb = list("wrenched", "medicaled", "tapped", "jabbed", "whacked") - -/obj/item/wrench/medical/suicide_act(mob/living/user) - user.visible_message("[user] is praying to the medical wrench to take [user.p_their()] soul. It looks like [user.p_theyre()] trying to commit suicide!") - // TODO Make them glow with the power of the M E D I C A L W R E N C H - // during their ascension - - // Stun stops them from wandering off - user.Stun(100, ignore_canstun = TRUE) - playsound(loc, 'sound/effects/pray.ogg', 50, 1, -1) - - // Let the sound effect finish playing - sleep(20) - - if(!user) - return - - for(var/obj/item/W in user) - user.dropItemToGround(W) - - var/obj/item/wrench/medical/W = new /obj/item/wrench/medical(loc) - W.add_fingerprint(user) - W.desc += " For some reason, it reminds you of [user.name]." - - if(!user) - return - - user.dust() - - return OXYLOSS - -/* - * Screwdriver - */ -/obj/item/screwdriver - name = "screwdriver" - desc = "You can be totally screwy with this." - icon = 'icons/obj/tools.dmi' - icon_state = "screwdriver" - item_state = "screwdriver" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 5 - w_class = WEIGHT_CLASS_TINY - throwforce = 5 - throw_speed = 3 - throw_range = 5 - materials = list(MAT_METAL=75) - attack_verb = list("stabbed") - hitsound = 'sound/weapons/bladeslice.ogg' - usesound = 'sound/items/screwdriver.ogg' - toolspeed = 1 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) - var/random_color = TRUE //if the screwdriver uses random coloring - var/static/list/screwdriver_colors = list(\ - "blue" = rgb(24, 97, 213), \ - "red" = rgb(149, 23, 16), \ - "pink" = rgb(213, 24, 141), \ - "brown" = rgb(160, 82, 18), \ - "green" = rgb(14, 127, 27), \ - "cyan" = rgb(24, 162, 213), \ - "yellow" = rgb(213, 140, 24), \ - ) - -/obj/item/screwdriver/suicide_act(mob/user) - user.visible_message("[user] is stabbing [src] into [user.p_their()] [pick("temple", "heart")]! It looks like [user.p_theyre()] trying to commit suicide!") - return(BRUTELOSS) - -/obj/item/screwdriver/Initialize() - . = ..() - if(random_color) //random colors! - var/our_color = pick(screwdriver_colors) - add_atom_colour(screwdriver_colors[our_color], FIXED_COLOUR_PRIORITY) - update_icon() - if(prob(75)) - pixel_y = rand(0, 16) - -/obj/item/screwdriver/update_icon() - if(!random_color) //icon override - return - cut_overlays() - var/mutable_appearance/base_overlay = mutable_appearance(icon, "screwdriver_screwybits") - base_overlay.appearance_flags = RESET_COLOR - add_overlay(base_overlay) - -/obj/item/screwdriver/worn_overlays(isinhands = FALSE, icon_file) - . = list() - if(isinhands && random_color) - var/mutable_appearance/M = mutable_appearance(icon_file, "screwdriver_head") - M.appearance_flags = RESET_COLOR - . += M - -/obj/item/screwdriver/get_belt_overlay() - if(random_color) - var/mutable_appearance/body = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver") - var/mutable_appearance/head = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver_head") - body.color = color - head.overlays += body - return head - else - return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state) - -/obj/item/screwdriver/attack(mob/living/carbon/M, mob/living/carbon/user) - if(!istype(M)) - return ..() - if(user.zone_selected != "eyes" && user.zone_selected != "head") - return ..() - if(user.disabilities & CLUMSY && prob(50)) - M = user - return eyestab(M,user) - -/obj/item/screwdriver/brass - name = "brass screwdriver" - desc = "A screwdriver made of brass. The handle feels freezing cold." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "screwdriver_brass" - item_state = "screwdriver_brass" - toolspeed = 0.5 - random_color = FALSE - -/obj/item/screwdriver/abductor - name = "alien screwdriver" - desc = "An ultrasonic screwdriver." - icon = 'icons/obj/abductor.dmi' - icon_state = "screwdriver_a" - item_state = "screwdriver_nuke" - usesound = 'sound/items/pshoom.ogg' - toolspeed = 0.1 - random_color = FALSE - -/obj/item/screwdriver/power - name = "hand drill" - desc = "A simple powered hand drill. It's fitted with a screw bit." - icon_state = "drill_screw" - item_state = "drill" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get - force = 8 //might or might not be too high, subject to change - w_class = WEIGHT_CLASS_SMALL - throwforce = 8 - throw_speed = 2 - throw_range = 3//it's heavier than a screw driver/wrench, so it does more damage, but can't be thrown as far - attack_verb = list("drilled", "screwed", "jabbed","whacked") - hitsound = 'sound/items/drill_hit.ogg' - usesound = 'sound/items/drill_use.ogg' - toolspeed = 0.25 - random_color = FALSE - -/obj/item/screwdriver/power/suicide_act(mob/user) - user.visible_message("[user] is putting [src] to [user.p_their()] temple. It looks like [user.p_theyre()] trying to commit suicide!") - return(BRUTELOSS) - -/obj/item/screwdriver/power/attack_self(mob/user) - playsound(get_turf(user),'sound/items/change_drill.ogg',50,1) - var/obj/item/wrench/power/b_drill = new /obj/item/wrench/power - to_chat(user, "You attach the bolt driver bit to [src].") - qdel(src) - user.put_in_active_hand(b_drill) - -/obj/item/screwdriver/cyborg - name = "powered screwdriver" - desc = "An electrical screwdriver, designed to be both precise and quick." - usesound = 'sound/items/drill_use.ogg' - toolspeed = 0.5 - -/* - * Wirecutters - */ -/obj/item/wirecutters - name = "wirecutters" - desc = "This cuts wires." - icon = 'icons/obj/tools.dmi' - icon_state = null - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 6 - throw_speed = 3 - throw_range = 7 - w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL=80) - attack_verb = list("pinched", "nipped") - hitsound = 'sound/items/wirecutter.ogg' - usesound = 'sound/items/wirecutter.ogg' - origin_tech = "materials=1;engineering=1" - toolspeed = 1 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) - - -/obj/item/wirecutters/New(loc, var/param_color = null) - ..() - if(!icon_state) - if(!param_color) - param_color = pick("yellow","red") - icon_state = "cutters_[param_color]" - -/obj/item/wirecutters/attack(mob/living/carbon/C, mob/user) - if(istype(C) && C.handcuffed && istype(C.handcuffed, /obj/item/restraints/handcuffs/cable)) - user.visible_message("[user] cuts [C]'s restraints with [src]!") - qdel(C.handcuffed) - C.handcuffed = null - if(C.buckled && C.buckled.buckle_requires_restraints) - C.buckled.unbuckle_mob(C) - C.update_handcuffed() - return - else - ..() - -/obj/item/wirecutters/suicide_act(mob/user) - user.visible_message("[user] is cutting at [user.p_their()] arteries with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, usesound, 50, 1, -1) - return (BRUTELOSS) - -/obj/item/wirecutters/brass - name = "brass wirecutters" - desc = "A pair of wirecutters made of brass. The handle feels freezing cold to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "cutters_brass" - toolspeed = 0.5 - -/obj/item/wirecutters/abductor - name = "alien wirecutters" - desc = "Extremely sharp wirecutters, made out of a silvery-green metal." - icon = 'icons/obj/abductor.dmi' - icon_state = "cutters" - toolspeed = 0.1 - origin_tech = "materials=5;engineering=4;abductor=3" - -/obj/item/wirecutters/cyborg - name = "wirecutters" - desc = "This cuts wires." - toolspeed = 0.5 - -/obj/item/wirecutters/power - name = "jaws of life" - desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a cutting head." - icon_state = "jaws_cutter" - item_state = "jawsoflife" - origin_tech = "materials=2;engineering=2" - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - usesound = 'sound/items/jaws_cut.ogg' - toolspeed = 0.25 - -/obj/item/wirecutters/power/suicide_act(mob/user) - user.visible_message("[user] is wrapping \the [src] around [user.p_their()] neck. It looks like [user.p_theyre()] trying to rip [user.p_their()] head off!") - playsound(loc, 'sound/items/jaws_cut.ogg', 50, 1, -1) - if(iscarbon(user)) - var/mob/living/carbon/C = user - var/obj/item/bodypart/BP = C.get_bodypart("head") - if(BP) - BP.drop_limb() - playsound(loc,pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg') ,50, 1, -1) - return (BRUTELOSS) - -/obj/item/wirecutters/power/attack_self(mob/user) - playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) - var/obj/item/crowbar/power/pryjaws = new /obj/item/crowbar/power - to_chat(user, "You attach the pry jaws to [src].") - qdel(src) - user.put_in_active_hand(pryjaws) -/* - * Welding Tool - */ -/obj/item/weldingtool - name = "welding tool" - desc = "A standard edition welder provided by NanoTrasen." - icon = 'icons/obj/tools.dmi' - icon_state = "welder" - item_state = "welder" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 3 - throwforce = 5 - hitsound = "swing_hit" - usesound = 'sound/items/welder.ogg' - var/acti_sound = 'sound/items/welderactivate.ogg' - var/deac_sound = 'sound/items/welderdeactivate.ogg' - throw_speed = 3 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 30) - resistance_flags = FIRE_PROOF - - materials = list(MAT_METAL=70, MAT_GLASS=30) - origin_tech = "engineering=1;plasmatech=1" - var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) - var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) - var/max_fuel = 20 //The max amount of fuel the welder can hold - var/change_icons = 1 - var/can_off_process = 0 - var/light_intensity = 2 //how powerful the emitted light is when used. - var/burned_fuel_for = 0 //when fuel was last removed - heat = 3800 - toolspeed = 1 - -/obj/item/weldingtool/Initialize() - . = ..() - create_reagents(max_fuel) - reagents.add_reagent("welding_fuel", max_fuel) - update_icon() - - -/obj/item/weldingtool/proc/update_torch() - if(welding) - add_overlay("[initial(icon_state)]-on") - item_state = "[initial(item_state)]1" - else - item_state = "[initial(item_state)]" - - -/obj/item/weldingtool/update_icon() - cut_overlays() - if(change_icons) - var/ratio = get_fuel() / max_fuel - ratio = Ceiling(ratio*4) * 25 - add_overlay("[initial(icon_state)][ratio]") - update_torch() - return - - -/obj/item/weldingtool/process() - switch(welding) - if(0) - force = 3 - damtype = "brute" - update_icon() - if(!can_off_process) - STOP_PROCESSING(SSobj, src) - return - //Welders left on now use up fuel, but lets not have them run out quite that fast - if(1) - force = 15 - damtype = "fire" - ++burned_fuel_for - if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL) - remove_fuel(1) - update_icon() - - //This is to start fires. process() is only called if the welder is on. - open_flame() - - -/obj/item/weldingtool/suicide_act(mob/user) - user.visible_message("[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!") - return (FIRELOSS) - - -/obj/item/weldingtool/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/screwdriver)) - flamethrower_screwdriver(I, user) - else if(istype(I, /obj/item/stack/rods)) - flamethrower_rods(I, user) - else - return ..() - - -/obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) - if(!istype(H)) - return ..() - - var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) - - if(affecting && affecting.status == BODYPART_ROBOTIC && user.a_intent != INTENT_HARM) - if(src.remove_fuel(1)) - playsound(loc, usesound, 50, 1) - if(user == H) - user.visible_message("[user] starts to fix some of the dents on [H]'s [affecting.name].", "You start fixing some of the dents on [H]'s [affecting.name].") - if(!do_mob(user, H, 50)) - return - item_heal_robotic(H, user, 15, 0) - else - return ..() - - -/obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) - if(!proximity) return - - if(welding) - remove_fuel(1) - var/turf/location = get_turf(user) - location.hotspot_expose(700, 50, 1) - if(get_fuel() <= 0) - set_light(0) - - if(isliving(O)) - var/mob/living/L = O - if(L.IgniteMob()) - message_admins("[key_name_admin(user)] set [key_name_admin(L)] on fire") - log_game("[key_name(user)] set [key_name(L)] on fire") - - -/obj/item/weldingtool/attack_self(mob/user) - switched_on(user) - if(welding) - set_light(light_intensity) - - update_icon() - - -//Returns the amount of fuel in the welder -/obj/item/weldingtool/proc/get_fuel() - return reagents.get_reagent_amount("welding_fuel") - - -//Removes fuel from the welding tool. If a mob is passed, it will try to flash the mob's eyes. This should probably be renamed to use() -/obj/item/weldingtool/proc/remove_fuel(amount = 1, mob/living/M = null) - if(!welding || !check_fuel()) - return 0 - if(amount) - burned_fuel_for = 0 - if(get_fuel() >= amount) - reagents.remove_reagent("welding_fuel", amount) - check_fuel() - if(M) - M.flash_act(light_intensity) - return TRUE - else - if(M) - to_chat(M, "You need more welding fuel to complete this task!") - return FALSE - - -//Turns off the welder if there is no more fuel (does this really need to be its own proc?) -/obj/item/weldingtool/proc/check_fuel(mob/user) - if(get_fuel() <= 0 && welding) - switched_on(user) - update_icon() - //mob icon update - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands(0) - - return 0 - return 1 - -//Switches the welder on -/obj/item/weldingtool/proc/switched_on(mob/user) - if(!status) - to_chat(user, "[src] can't be turned on while unsecured!") - return - welding = !welding - if(welding) - if(get_fuel() >= 1) - to_chat(user, "You switch [src] on.") - playsound(loc, acti_sound, 50, 1) - force = 15 - damtype = "fire" - hitsound = 'sound/items/welder.ogg' - update_icon() - START_PROCESSING(SSobj, src) - else - to_chat(user, "You need more fuel!") - switched_off(user) - else - to_chat(user, "You switch [src] off.") - playsound(loc, deac_sound, 50, 1) - switched_off(user) - -//Switches the welder off -/obj/item/weldingtool/proc/switched_off(mob/user) - welding = 0 - set_light(0) - - force = 3 - damtype = "brute" - hitsound = "swing_hit" - update_icon() - - -/obj/item/weldingtool/examine(mob/user) - ..() - to_chat(user, "It contains [get_fuel()] unit\s of fuel out of [max_fuel].") - -/obj/item/weldingtool/is_hot() - return welding * heat - -//Returns whether or not the welding tool is currently on. -/obj/item/weldingtool/proc/isOn() - return welding - - -/obj/item/weldingtool/proc/flamethrower_screwdriver(obj/item/I, mob/user) - if(welding) - to_chat(user, "Turn it off first!") - return - status = !status - if(status) - to_chat(user, "You resecure [src].") - else - to_chat(user, "[src] can now be attached and modified.") - add_fingerprint(user) - -/obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) - if(!status) - var/obj/item/stack/rods/R = I - if (R.use(1)) - var/obj/item/flamethrower/F = new /obj/item/flamethrower(user.loc) - if(!remove_item_from_storage(F)) - user.transferItemToLoc(src, F, TRUE) - F.weldtool = src - add_fingerprint(user) - to_chat(user, "You add a rod to a welder, starting to build a flamethrower.") - user.put_in_hands(F) - else - to_chat(user, "You need one rod to start building a flamethrower!") - -/obj/item/weldingtool/ignition_effect(atom/A, mob/user) - if(welding && remove_fuel(1, user)) - . = "[user] casually lights [A] with [src], what a badass." - else - . = "" - -/obj/item/weldingtool/largetank - name = "industrial welding tool" - desc = "A slightly larger welder with a larger tank." - icon_state = "indwelder" - max_fuel = 40 - materials = list(MAT_GLASS=60) - origin_tech = "engineering=2;plasmatech=2" - -/obj/item/weldingtool/largetank/cyborg - name = "integrated welding tool" - desc = "An advanced welder designed to be used in robotic systems." - toolspeed = 0.5 - -/obj/item/weldingtool/largetank/flamethrower_screwdriver() - return - - -/obj/item/weldingtool/mini - name = "emergency welding tool" - desc = "A miniature welder used during emergencies." - icon_state = "miniwelder" - max_fuel = 10 - w_class = WEIGHT_CLASS_TINY - materials = list(MAT_METAL=30, MAT_GLASS=10) - change_icons = 0 - -/obj/item/weldingtool/mini/flamethrower_screwdriver() - return - -/obj/item/weldingtool/abductor - name = "alien welding tool" - desc = "An alien welding tool. Whatever fuel it uses, it never runs out." - icon = 'icons/obj/abductor.dmi' - icon_state = "welder" - toolspeed = 0.1 - light_intensity = 0 - change_icons = 0 - origin_tech = "plasmatech=5;engineering=5;abductor=3" - -/obj/item/weldingtool/abductor/process() - if(get_fuel() <= max_fuel) - reagents.add_reagent("welding_fuel", 1) - ..() - -/obj/item/weldingtool/hugetank - name = "upgraded industrial welding tool" - desc = "An upgraded welder based of the industrial welder." - icon_state = "upindwelder" - item_state = "upindwelder" - max_fuel = 80 - materials = list(MAT_METAL=70, MAT_GLASS=120) - origin_tech = "engineering=3;plasmatech=2" - -/obj/item/weldingtool/experimental - name = "experimental welding tool" - desc = "An experimental welder capable of self-fuel generation and less harmful to the eyes." - icon_state = "exwelder" - item_state = "exwelder" - max_fuel = 40 - materials = list(MAT_METAL=70, MAT_GLASS=120) - origin_tech = "materials=4;engineering=4;bluespace=3;plasmatech=4" - var/last_gen = 0 - change_icons = 0 - can_off_process = 1 - light_intensity = 1 - toolspeed = 0.5 - var/nextrefueltick = 0 - -/obj/item/weldingtool/experimental/brass - name = "brass welding tool" - desc = "A brass welder that seems to constantly refuel itself. It is faintly warm to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "brasswelder" - item_state = "brasswelder" - - -/obj/item/weldingtool/experimental/process() - ..() - if(get_fuel() < max_fuel && nextrefueltick < world.time) - nextrefueltick = world.time + 10 - reagents.add_reagent("welding_fuel", 1) - - -/* - * Crowbar - */ - -/obj/item/crowbar - name = "pocket crowbar" - desc = "A small crowbar. This handy tool is useful for lots of things, such as prying floor tiles or opening unpowered doors." - icon = 'icons/obj/tools.dmi' - icon_state = "crowbar" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - usesound = 'sound/items/crowbar.ogg' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 5 - throwforce = 7 - w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL=50) - origin_tech = "engineering=1;combat=1" - attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked") - toolspeed = 1 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) - -/obj/item/crowbar/suicide_act(mob/user) - user.visible_message("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) - return (BRUTELOSS) - -/obj/item/crowbar/red - icon_state = "crowbar_red" - force = 8 - -/obj/item/crowbar/brass - name = "brass crowbar" - desc = "A brass crowbar. It feels faintly warm to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "crowbar_brass" - toolspeed = 0.5 - -/obj/item/crowbar/abductor - name = "alien crowbar" - desc = "A hard-light crowbar. It appears to pry by itself, without any effort required." - icon = 'icons/obj/abductor.dmi' - usesound = 'sound/weapons/sonic_jackhammer.ogg' - icon_state = "crowbar" - toolspeed = 0.1 - origin_tech = "combat=4;engineering=4;abductor=3" - -/obj/item/crowbar/large - name = "crowbar" - desc = "It's a big crowbar. It doesn't fit in your pockets, because it's big." - force = 12 - w_class = WEIGHT_CLASS_NORMAL - throw_speed = 3 - throw_range = 3 - materials = list(MAT_METAL=70) - icon_state = "crowbar_large" - item_state = "crowbar" - toolspeed = 0.5 - -/obj/item/crowbar/cyborg - name = "hydraulic crowbar" - desc = "A hydraulic prying tool, compact but powerful. Designed to replace crowbar in construction cyborgs." - usesound = 'sound/items/jaws_pry.ogg' - force = 10 - toolspeed = 0.5 - -/obj/item/crowbar/power - name = "jaws of life" - desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a prying head." - icon_state = "jaws_pry" - item_state = "jawsoflife" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" - usesound = 'sound/items/jaws_pry.ogg' - force = 15 - toolspeed = 0.25 - -/obj/item/crowbar/power/suicide_act(mob/user) - user.visible_message("[user] is putting [user.p_their()] head in [src], it looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/items/jaws_pry.ogg', 50, 1, -1) - return (BRUTELOSS) - -/obj/item/crowbar/power/attack_self(mob/user) - playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) - var/obj/item/wirecutters/power/cutjaws = new /obj/item/wirecutters/power - to_chat(user, "You attach the cutting jaws to [src].") - qdel(src) - user.put_in_active_hand(cutjaws) - -#undef WELDER_FUEL_BURN_INTERVAL -======= +#define WELDER_FUEL_BURN_INTERVAL 13 + +/* Tools! + * Note: Multitools are /obj/item/device + * + * Contains: + * Wrench + * Screwdriver + * Wirecutters + * Welding Tool + * Crowbar + */ + +/* + * Wrench + */ +/obj/item/wrench + name = "wrench" + desc = "A wrench with common uses. Can be found in your hand." + icon = 'icons/obj/tools.dmi' + icon_state = "wrench" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + force = 5 + throwforce = 7 + w_class = WEIGHT_CLASS_SMALL + usesound = 'sound/items/ratchet.ogg' + materials = list(MAT_METAL=150) + origin_tech = "materials=1;engineering=1" + attack_verb = list("bashed", "battered", "bludgeoned", "whacked") + toolspeed = 1 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) + +/obj/item/wrench/suicide_act(mob/user) + user.visible_message("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") + playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) + return (BRUTELOSS) + +/obj/item/wrench/cyborg + name = "automatic wrench" + desc = "An advanced robotic wrench. Can be found in construction cyborgs." + toolspeed = 0.5 + +/obj/item/wrench/brass + name = "brass wrench" + desc = "A brass wrench. It's faintly warm to the touch." + resistance_flags = FIRE_PROOF | ACID_PROOF + icon_state = "wrench_brass" + toolspeed = 0.5 + +/obj/item/wrench/abductor + name = "alien wrench" + desc = "A polarized wrench. It causes anything placed between the jaws to turn." + icon = 'icons/obj/abductor.dmi' + icon_state = "wrench" + usesound = 'sound/effects/empulse.ogg' + toolspeed = 0.1 + origin_tech = "materials=5;engineering=5;abductor=3" + +/obj/item/wrench/power + name = "hand drill" + desc = "A simple powered hand drill. It's fitted with a bolt bit." + icon_state = "drill_bolt" + item_state = "drill" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + usesound = 'sound/items/drill_use.ogg' + materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) + origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get + force = 8 //might or might not be too high, subject to change + w_class = WEIGHT_CLASS_SMALL + throwforce = 8 + attack_verb = list("drilled", "screwed", "jabbed") + toolspeed = 0.25 + +/obj/item/wrench/power/attack_self(mob/user) + playsound(get_turf(user),'sound/items/change_drill.ogg',50,1) + var/obj/item/wirecutters/power/s_drill = new /obj/item/screwdriver/power + to_chat(user, "You attach the screw driver bit to [src].") + qdel(src) + user.put_in_active_hand(s_drill) + +/obj/item/wrench/power/suicide_act(mob/user) + user.visible_message("[user] is pressing [src] against [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide!") + return (BRUTELOSS) + +/obj/item/wrench/medical + name = "medical wrench" + desc = "A medical wrench with common(medical?) uses. Can be found in your hand." + icon_state = "wrench_medical" + force = 2 //MEDICAL + throwforce = 4 + origin_tech = "materials=1;engineering=1;biotech=3" + attack_verb = list("wrenched", "medicaled", "tapped", "jabbed", "whacked") + +/obj/item/wrench/medical/suicide_act(mob/living/user) + user.visible_message("[user] is praying to the medical wrench to take [user.p_their()] soul. It looks like [user.p_theyre()] trying to commit suicide!") + // TODO Make them glow with the power of the M E D I C A L W R E N C H + // during their ascension + + // Stun stops them from wandering off + user.Stun(100, ignore_canstun = TRUE) + playsound(loc, 'sound/effects/pray.ogg', 50, 1, -1) + + // Let the sound effect finish playing + sleep(20) + + if(!user) + return + + for(var/obj/item/W in user) + user.dropItemToGround(W) + + var/obj/item/wrench/medical/W = new /obj/item/wrench/medical(loc) + W.add_fingerprint(user) + W.desc += " For some reason, it reminds you of [user.name]." + + if(!user) + return + + user.dust() + + return OXYLOSS + +/* + * Screwdriver + */ +/obj/item/screwdriver + name = "screwdriver" + desc = "You can be totally screwy with this." + icon = 'icons/obj/tools.dmi' + icon_state = "screwdriver" + item_state = "screwdriver" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + force = 5 + w_class = WEIGHT_CLASS_TINY + throwforce = 5 + throw_speed = 3 + throw_range = 5 + materials = list(MAT_METAL=75) + attack_verb = list("stabbed") + hitsound = 'sound/weapons/bladeslice.ogg' + usesound = 'sound/items/screwdriver.ogg' + toolspeed = 1 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) + var/random_color = TRUE //if the screwdriver uses random coloring + var/static/list/screwdriver_colors = list(\ + "blue" = rgb(24, 97, 213), \ + "red" = rgb(149, 23, 16), \ + "pink" = rgb(213, 24, 141), \ + "brown" = rgb(160, 82, 18), \ + "green" = rgb(14, 127, 27), \ + "cyan" = rgb(24, 162, 213), \ + "yellow" = rgb(213, 140, 24), \ + ) + +/obj/item/screwdriver/suicide_act(mob/user) + user.visible_message("[user] is stabbing [src] into [user.p_their()] [pick("temple", "heart")]! It looks like [user.p_theyre()] trying to commit suicide!") + return(BRUTELOSS) + +/obj/item/screwdriver/Initialize() + . = ..() + if(random_color) //random colors! + var/our_color = pick(screwdriver_colors) + add_atom_colour(screwdriver_colors[our_color], FIXED_COLOUR_PRIORITY) + update_icon() + if(prob(75)) + pixel_y = rand(0, 16) + +/obj/item/screwdriver/update_icon() + if(!random_color) //icon override + return + cut_overlays() + var/mutable_appearance/base_overlay = mutable_appearance(icon, "screwdriver_screwybits") + base_overlay.appearance_flags = RESET_COLOR + add_overlay(base_overlay) + +/obj/item/screwdriver/worn_overlays(isinhands = FALSE, icon_file) + . = list() + if(isinhands && random_color) + var/mutable_appearance/M = mutable_appearance(icon_file, "screwdriver_head") + M.appearance_flags = RESET_COLOR + . += M + +/obj/item/screwdriver/get_belt_overlay() + if(random_color) + var/mutable_appearance/body = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver") + var/mutable_appearance/head = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver_head") + body.color = color + head.overlays += body + return head + else + return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state) + +/obj/item/screwdriver/attack(mob/living/carbon/M, mob/living/carbon/user) + if(!istype(M)) + return ..() + if(user.zone_selected != "eyes" && user.zone_selected != "head") + return ..() + if(user.disabilities & CLUMSY && prob(50)) + M = user + return eyestab(M,user) + +/obj/item/screwdriver/brass + name = "brass screwdriver" + desc = "A screwdriver made of brass. The handle feels freezing cold." + resistance_flags = FIRE_PROOF | ACID_PROOF + icon_state = "screwdriver_brass" + item_state = "screwdriver_brass" + toolspeed = 0.5 + random_color = FALSE + +/obj/item/screwdriver/abductor + name = "alien screwdriver" + desc = "An ultrasonic screwdriver." + icon = 'icons/obj/abductor.dmi' + icon_state = "screwdriver_a" + item_state = "screwdriver_nuke" + usesound = 'sound/items/pshoom.ogg' + toolspeed = 0.1 + random_color = FALSE + +/obj/item/screwdriver/power + name = "hand drill" + desc = "A simple powered hand drill. It's fitted with a screw bit." + icon_state = "drill_screw" + item_state = "drill" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) + origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get + force = 8 //might or might not be too high, subject to change + w_class = WEIGHT_CLASS_SMALL + throwforce = 8 + throw_speed = 2 + throw_range = 3//it's heavier than a screw driver/wrench, so it does more damage, but can't be thrown as far + attack_verb = list("drilled", "screwed", "jabbed","whacked") + hitsound = 'sound/items/drill_hit.ogg' + usesound = 'sound/items/drill_use.ogg' + toolspeed = 0.25 + random_color = FALSE + +/obj/item/screwdriver/power/suicide_act(mob/user) + user.visible_message("[user] is putting [src] to [user.p_their()] temple. It looks like [user.p_theyre()] trying to commit suicide!") + return(BRUTELOSS) + +/obj/item/screwdriver/power/attack_self(mob/user) + playsound(get_turf(user),'sound/items/change_drill.ogg',50,1) + var/obj/item/wrench/power/b_drill = new /obj/item/wrench/power + to_chat(user, "You attach the bolt driver bit to [src].") + qdel(src) + user.put_in_active_hand(b_drill) + +/obj/item/screwdriver/cyborg + name = "powered screwdriver" + desc = "An electrical screwdriver, designed to be both precise and quick." + usesound = 'sound/items/drill_use.ogg' + toolspeed = 0.5 + +/* + * Wirecutters + */ +/obj/item/wirecutters + name = "wirecutters" + desc = "This cuts wires." + icon = 'icons/obj/tools.dmi' + icon_state = null + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + force = 6 + throw_speed = 3 + throw_range = 7 + w_class = WEIGHT_CLASS_SMALL + materials = list(MAT_METAL=80) + attack_verb = list("pinched", "nipped") + hitsound = 'sound/items/wirecutter.ogg' + usesound = 'sound/items/wirecutter.ogg' + origin_tech = "materials=1;engineering=1" + toolspeed = 1 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) + + +/obj/item/wirecutters/New(loc, var/param_color = null) + ..() + if(!icon_state) + if(!param_color) + param_color = pick("yellow","red") + icon_state = "cutters_[param_color]" + +/obj/item/wirecutters/attack(mob/living/carbon/C, mob/user) + if(istype(C) && C.handcuffed && istype(C.handcuffed, /obj/item/restraints/handcuffs/cable)) + user.visible_message("[user] cuts [C]'s restraints with [src]!") + qdel(C.handcuffed) + C.handcuffed = null + if(C.buckled && C.buckled.buckle_requires_restraints) + C.buckled.unbuckle_mob(C) + C.update_handcuffed() + return + else + ..() + +/obj/item/wirecutters/suicide_act(mob/user) + user.visible_message("[user] is cutting at [user.p_their()] arteries with [src]! It looks like [user.p_theyre()] trying to commit suicide!") + playsound(loc, usesound, 50, 1, -1) + return (BRUTELOSS) + +/obj/item/wirecutters/brass + name = "brass wirecutters" + desc = "A pair of wirecutters made of brass. The handle feels freezing cold to the touch." + resistance_flags = FIRE_PROOF | ACID_PROOF + icon_state = "cutters_brass" + toolspeed = 0.5 + +/obj/item/wirecutters/abductor + name = "alien wirecutters" + desc = "Extremely sharp wirecutters, made out of a silvery-green metal." + icon = 'icons/obj/abductor.dmi' + icon_state = "cutters" + toolspeed = 0.1 + origin_tech = "materials=5;engineering=4;abductor=3" + +/obj/item/wirecutters/cyborg + name = "wirecutters" + desc = "This cuts wires." + toolspeed = 0.5 + +/obj/item/wirecutters/power + name = "jaws of life" + desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a cutting head." + icon_state = "jaws_cutter" + item_state = "jawsoflife" + origin_tech = "materials=2;engineering=2" + materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) + usesound = 'sound/items/jaws_cut.ogg' + toolspeed = 0.25 + +/obj/item/wirecutters/power/suicide_act(mob/user) + user.visible_message("[user] is wrapping \the [src] around [user.p_their()] neck. It looks like [user.p_theyre()] trying to rip [user.p_their()] head off!") + playsound(loc, 'sound/items/jaws_cut.ogg', 50, 1, -1) + if(iscarbon(user)) + var/mob/living/carbon/C = user + var/obj/item/bodypart/BP = C.get_bodypart("head") + if(BP) + BP.drop_limb() + playsound(loc,pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg') ,50, 1, -1) + return (BRUTELOSS) + +/obj/item/wirecutters/power/attack_self(mob/user) + playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) + var/obj/item/crowbar/power/pryjaws = new /obj/item/crowbar/power + to_chat(user, "You attach the pry jaws to [src].") + qdel(src) + user.put_in_active_hand(pryjaws) +/* + * Welding Tool + */ +/obj/item/weldingtool + name = "welding tool" + desc = "A standard edition welder provided by NanoTrasen." + icon = 'icons/obj/tools.dmi' + icon_state = "welder" + item_state = "welder" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + force = 3 + throwforce = 5 + hitsound = "swing_hit" + usesound = 'sound/items/welder.ogg' + var/acti_sound = 'sound/items/welderactivate.ogg' + var/deac_sound = 'sound/items/welderdeactivate.ogg' + throw_speed = 3 + throw_range = 5 + w_class = WEIGHT_CLASS_SMALL + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 30) + resistance_flags = FIRE_PROOF + + materials = list(MAT_METAL=70, MAT_GLASS=30) + origin_tech = "engineering=1;plasmatech=1" + var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) + var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) + var/max_fuel = 20 //The max amount of fuel the welder can hold + var/change_icons = 1 + var/can_off_process = 0 + var/light_intensity = 2 //how powerful the emitted light is when used. + var/burned_fuel_for = 0 //when fuel was last removed + heat = 3800 + toolspeed = 1 + +/obj/item/weldingtool/Initialize() + . = ..() + create_reagents(max_fuel) + reagents.add_reagent("welding_fuel", max_fuel) + update_icon() + + +/obj/item/weldingtool/proc/update_torch() + if(welding) + add_overlay("[initial(icon_state)]-on") + item_state = "[initial(item_state)]1" + else + item_state = "[initial(item_state)]" + + +/obj/item/weldingtool/update_icon() + cut_overlays() + if(change_icons) + var/ratio = get_fuel() / max_fuel + ratio = Ceiling(ratio*4) * 25 + add_overlay("[initial(icon_state)][ratio]") + update_torch() + return + + +/obj/item/weldingtool/process() + switch(welding) + if(0) + force = 3 + damtype = "brute" + update_icon() + if(!can_off_process) + STOP_PROCESSING(SSobj, src) + return + //Welders left on now use up fuel, but lets not have them run out quite that fast + if(1) + force = 15 + damtype = "fire" + ++burned_fuel_for + if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL) + remove_fuel(1) + update_icon() + + //This is to start fires. process() is only called if the welder is on. + open_flame() + + +/obj/item/weldingtool/suicide_act(mob/user) + user.visible_message("[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!") + return (FIRELOSS) + + +/obj/item/weldingtool/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/screwdriver)) + flamethrower_screwdriver(I, user) + else if(istype(I, /obj/item/stack/rods)) + flamethrower_rods(I, user) + else + return ..() + + +/obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) + if(!istype(H)) + return ..() + + var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) + + if(affecting && affecting.status == BODYPART_ROBOTIC && user.a_intent != INTENT_HARM) + if(src.remove_fuel(1)) + playsound(loc, usesound, 50, 1) + if(user == H) + user.visible_message("[user] starts to fix some of the dents on [H]'s [affecting.name].", "You start fixing some of the dents on [H]'s [affecting.name].") + if(!do_mob(user, H, 50)) + return + item_heal_robotic(H, user, 15, 0) + else + return ..() + + +/obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) + if(!proximity) return + + if(welding) + remove_fuel(1) + var/turf/location = get_turf(user) + location.hotspot_expose(700, 50, 1) + if(get_fuel() <= 0) + set_light(0) + + if(isliving(O)) + var/mob/living/L = O + if(L.IgniteMob()) + message_admins("[key_name_admin(user)] set [key_name_admin(L)] on fire") + log_game("[key_name(user)] set [key_name(L)] on fire") + + +/obj/item/weldingtool/attack_self(mob/user) + switched_on(user) + if(welding) + set_light(light_intensity) + + update_icon() + + +//Returns the amount of fuel in the welder +/obj/item/weldingtool/proc/get_fuel() + return reagents.get_reagent_amount("welding_fuel") + + +//Removes fuel from the welding tool. If a mob is passed, it will try to flash the mob's eyes. This should probably be renamed to use() +/obj/item/weldingtool/proc/remove_fuel(amount = 1, mob/living/M = null) + if(!welding || !check_fuel()) + return 0 + if(amount) + burned_fuel_for = 0 + if(get_fuel() >= amount) + reagents.remove_reagent("welding_fuel", amount) + check_fuel() + if(M) + M.flash_act(light_intensity) + return TRUE + else + if(M) + to_chat(M, "You need more welding fuel to complete this task!") + return FALSE + + +//Turns off the welder if there is no more fuel (does this really need to be its own proc?) +/obj/item/weldingtool/proc/check_fuel(mob/user) + if(get_fuel() <= 0 && welding) + switched_on(user) + update_icon() + //mob icon update + if(ismob(loc)) + var/mob/M = loc + M.update_inv_hands(0) + + return 0 + return 1 + +//Switches the welder on +/obj/item/weldingtool/proc/switched_on(mob/user) + if(!status) + to_chat(user, "[src] can't be turned on while unsecured!") + return + welding = !welding + if(welding) + if(get_fuel() >= 1) + to_chat(user, "You switch [src] on.") + playsound(loc, acti_sound, 50, 1) + force = 15 + damtype = "fire" + hitsound = 'sound/items/welder.ogg' + update_icon() + START_PROCESSING(SSobj, src) + else + to_chat(user, "You need more fuel!") + switched_off(user) + else + to_chat(user, "You switch [src] off.") + playsound(loc, deac_sound, 50, 1) + switched_off(user) + +//Switches the welder off +/obj/item/weldingtool/proc/switched_off(mob/user) + welding = 0 + set_light(0) + + force = 3 + damtype = "brute" + hitsound = "swing_hit" + update_icon() + + +/obj/item/weldingtool/examine(mob/user) + ..() + to_chat(user, "It contains [get_fuel()] unit\s of fuel out of [max_fuel].") + +/obj/item/weldingtool/is_hot() + return welding * heat + +//Returns whether or not the welding tool is currently on. +/obj/item/weldingtool/proc/isOn() + return welding + + +/obj/item/weldingtool/proc/flamethrower_screwdriver(obj/item/I, mob/user) + if(welding) + to_chat(user, "Turn it off first!") + return + status = !status + if(status) + to_chat(user, "You resecure [src].") + else + to_chat(user, "[src] can now be attached and modified.") + add_fingerprint(user) + +/obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) + if(!status) + var/obj/item/stack/rods/R = I + if (R.use(1)) + var/obj/item/flamethrower/F = new /obj/item/flamethrower(user.loc) + if(!remove_item_from_storage(F)) + user.transferItemToLoc(src, F, TRUE) + F.weldtool = src + add_fingerprint(user) + to_chat(user, "You add a rod to a welder, starting to build a flamethrower.") + user.put_in_hands(F) + else + to_chat(user, "You need one rod to start building a flamethrower!") + +/obj/item/weldingtool/ignition_effect(atom/A, mob/user) + if(welding && remove_fuel(1, user)) + . = "[user] casually lights [A] with [src], what a badass." + else + . = "" + +/obj/item/weldingtool/largetank + name = "industrial welding tool" + desc = "A slightly larger welder with a larger tank." + icon_state = "indwelder" + max_fuel = 40 + materials = list(MAT_GLASS=60) + origin_tech = "engineering=2;plasmatech=2" + +/obj/item/weldingtool/largetank/cyborg + name = "integrated welding tool" + desc = "An advanced welder designed to be used in robotic systems." + toolspeed = 0.5 + +/obj/item/weldingtool/largetank/flamethrower_screwdriver() + return + + +/obj/item/weldingtool/mini + name = "emergency welding tool" + desc = "A miniature welder used during emergencies." + icon_state = "miniwelder" + max_fuel = 10 + w_class = WEIGHT_CLASS_TINY + materials = list(MAT_METAL=30, MAT_GLASS=10) + change_icons = 0 + +/obj/item/weldingtool/mini/flamethrower_screwdriver() + return + +/obj/item/weldingtool/abductor + name = "alien welding tool" + desc = "An alien welding tool. Whatever fuel it uses, it never runs out." + icon = 'icons/obj/abductor.dmi' + icon_state = "welder" + toolspeed = 0.1 + light_intensity = 0 + change_icons = 0 + origin_tech = "plasmatech=5;engineering=5;abductor=3" + +/obj/item/weldingtool/abductor/process() + if(get_fuel() <= max_fuel) + reagents.add_reagent("welding_fuel", 1) + ..() + +/obj/item/weldingtool/hugetank + name = "upgraded industrial welding tool" + desc = "An upgraded welder based of the industrial welder." + icon_state = "upindwelder" + item_state = "upindwelder" + max_fuel = 80 + materials = list(MAT_METAL=70, MAT_GLASS=120) + origin_tech = "engineering=3;plasmatech=2" + +/obj/item/weldingtool/experimental + name = "experimental welding tool" + desc = "An experimental welder capable of self-fuel generation and less harmful to the eyes." + icon_state = "exwelder" + item_state = "exwelder" + max_fuel = 40 + materials = list(MAT_METAL=70, MAT_GLASS=120) + origin_tech = "materials=4;engineering=4;bluespace=3;plasmatech=4" + var/last_gen = 0 + change_icons = 0 + can_off_process = 1 + light_intensity = 1 + toolspeed = 0.5 + var/nextrefueltick = 0 + +/obj/item/weldingtool/experimental/brass + name = "brass welding tool" + desc = "A brass welder that seems to constantly refuel itself. It is faintly warm to the touch." + resistance_flags = FIRE_PROOF | ACID_PROOF + icon_state = "brasswelder" + item_state = "brasswelder" + + +/obj/item/weldingtool/experimental/process() + ..() + if(get_fuel() < max_fuel && nextrefueltick < world.time) + nextrefueltick = world.time + 10 + reagents.add_reagent("welding_fuel", 1) + + +/* + * Crowbar + */ + +/obj/item/crowbar + name = "pocket crowbar" + desc = "A small crowbar. This handy tool is useful for lots of things, such as prying floor tiles or opening unpowered doors." + icon = 'icons/obj/tools.dmi' + icon_state = "crowbar" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + usesound = 'sound/items/crowbar.ogg' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + force = 5 + throwforce = 7 + w_class = WEIGHT_CLASS_SMALL + materials = list(MAT_METAL=50) + origin_tech = "engineering=1;combat=1" + attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked") + toolspeed = 1 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) + +/obj/item/crowbar/suicide_act(mob/user) + user.visible_message("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") + playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) + return (BRUTELOSS) + +/obj/item/crowbar/red + icon_state = "crowbar_red" + force = 8 + +/obj/item/crowbar/brass + name = "brass crowbar" + desc = "A brass crowbar. It feels faintly warm to the touch." + resistance_flags = FIRE_PROOF | ACID_PROOF + icon_state = "crowbar_brass" + toolspeed = 0.5 + +/obj/item/crowbar/abductor + name = "alien crowbar" + desc = "A hard-light crowbar. It appears to pry by itself, without any effort required." + icon = 'icons/obj/abductor.dmi' + usesound = 'sound/weapons/sonic_jackhammer.ogg' + icon_state = "crowbar" + toolspeed = 0.1 + origin_tech = "combat=4;engineering=4;abductor=3" + +/obj/item/crowbar/large + name = "crowbar" + desc = "It's a big crowbar. It doesn't fit in your pockets, because it's big." + force = 12 + w_class = WEIGHT_CLASS_NORMAL + throw_speed = 3 + throw_range = 3 + materials = list(MAT_METAL=70) + icon_state = "crowbar_large" + item_state = "crowbar" + toolspeed = 0.5 + +/obj/item/crowbar/cyborg + name = "hydraulic crowbar" + desc = "A hydraulic prying tool, compact but powerful. Designed to replace crowbar in construction cyborgs." + usesound = 'sound/items/jaws_pry.ogg' + force = 10 + toolspeed = 0.5 + +/obj/item/crowbar/power + name = "jaws of life" + desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a prying head." + icon_state = "jaws_pry" + item_state = "jawsoflife" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) + origin_tech = "materials=2;engineering=2" + usesound = 'sound/items/jaws_pry.ogg' + force = 15 + toolspeed = 0.25 + +/obj/item/crowbar/power/suicide_act(mob/user) + user.visible_message("[user] is putting [user.p_their()] head in [src], it looks like [user.p_theyre()] trying to commit suicide!") + playsound(loc, 'sound/items/jaws_pry.ogg', 50, 1, -1) + return (BRUTELOSS) + +/obj/item/crowbar/power/attack_self(mob/user) + playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) + var/obj/item/wirecutters/power/cutjaws = new /obj/item/wirecutters/power + to_chat(user, "You attach the cutting jaws to [src].") + qdel(src) + user.put_in_active_hand(cutjaws) + +#undef WELDER_FUEL_BURN_INTERVAL #define WELDER_FUEL_BURN_INTERVAL 13 /* Tools! @@ -1580,4 +1578,3 @@ user.put_in_active_hand(cutjaws) #undef WELDER_FUEL_BURN_INTERVAL ->>>>>>> 2240756... Gets rid of manual overlay manipulation (#30454) From 3dbfac920ae6b0360a49d93e7ecc180c8faa277a Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 10 Sep 2017 11:48:28 -0500 Subject: [PATCH 235/262] Update weaponry.dm --- code/game/objects/items/weaponry.dm | 1175 +++++++++++++-------------- 1 file changed, 586 insertions(+), 589 deletions(-) diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index fe9c9485cd..443518ec0a 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -1,596 +1,594 @@ -/obj/item/banhammer - desc = "A banhammer" - name = "banhammer" - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "toyhammer" - slot_flags = SLOT_BELT - throwforce = 0 - w_class = WEIGHT_CLASS_TINY - throw_speed = 3 - throw_range = 7 - attack_verb = list("banned") - max_integrity = 200 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 70) - resistance_flags = FIRE_PROOF - -/obj/item/banhammer/suicide_act(mob/user) - user.visible_message("[user] is hitting [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to ban [user.p_them()]self from life.") - return (BRUTELOSS|FIRELOSS|TOXLOSS|OXYLOSS) - -/obj/item/banhammer/attack(mob/M, mob/user) +/obj/item/banhammer + desc = "A banhammer" + name = "banhammer" + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "toyhammer" + slot_flags = SLOT_BELT + throwforce = 0 + w_class = WEIGHT_CLASS_TINY + throw_speed = 3 + throw_range = 7 + attack_verb = list("banned") + max_integrity = 200 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 70) + resistance_flags = FIRE_PROOF + +/obj/item/banhammer/suicide_act(mob/user) + user.visible_message("[user] is hitting [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to ban [user.p_them()]self from life.") + return (BRUTELOSS|FIRELOSS|TOXLOSS|OXYLOSS) + +/obj/item/banhammer/attack(mob/M, mob/user) if(user.zone_selected == "head") M.visible_message("[user] are stroking the head of [M] with a bangammer", "[user] are stroking the head with a bangammer", "you hear a bangammer stroking a head"); else M.visible_message("[M] has been banned FOR NO REISIN by [user]", "You have been banned FOR NO REISIN by [user]", "you hear a banhammer banning someone") -<<<<<<< HEAD - playsound(loc, 'sound/effects/adminhelp.ogg', 15) //keep it at 15% volume so people don't jump out of their skin too much - -/obj/item/sord - name = "\improper SORD" - desc = "This thing is so unspeakably shitty you are having a hard time even holding it." - icon_state = "sord" - item_state = "sord" - lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' - slot_flags = SLOT_BELT - force = 2 - throwforce = 1 - w_class = WEIGHT_CLASS_NORMAL - hitsound = 'sound/weapons/bladeslice.ogg' - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - -/obj/item/sord/suicide_act(mob/user) - user.visible_message("[user] is trying to impale [user.p_them()]self with [src]! It might be a suicide attempt if it weren't so shitty.", \ - "You try to impale yourself with [src], but it's USELESS...") - return SHAME - -/obj/item/claymore - name = "claymore" - desc = "What are you standing around staring at this for? Get to killing!" - icon_state = "claymore" - item_state = "claymore" - lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' - hitsound = 'sound/weapons/bladeslice.ogg' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT | SLOT_BACK - force = 40 - throwforce = 10 - w_class = WEIGHT_CLASS_NORMAL - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - block_chance = 50 - sharpness = IS_SHARP - max_integrity = 200 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50) - resistance_flags = FIRE_PROOF - -/obj/item/claymore/suicide_act(mob/user) - user.visible_message("[user] is falling on [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return(BRUTELOSS) - -/obj/item/claymore/highlander //ALL COMMENTS MADE REGARDING THIS SWORD MUST BE MADE IN ALL CAPS - desc = "THERE CAN BE ONLY ONE, AND IT WILL BE YOU!!!\nActivate it in your hand to point to the nearest victim." - flags_1 = CONDUCT_1 | NODROP_1 | DROPDEL_1 - slot_flags = null - block_chance = 0 //RNG WON'T HELP YOU NOW, PANSY - luminosity = 3 - attack_verb = list("brutalized", "eviscerated", "disemboweled", "hacked", "carved", "cleaved") //ONLY THE MOST VISCERAL ATTACK VERBS - var/notches = 0 //HOW MANY PEOPLE HAVE BEEN SLAIN WITH THIS BLADE - var/obj/item/disk/nuclear/nuke_disk //OUR STORED NUKE DISK - -/obj/item/claymore/highlander/Initialize() - . = ..() - START_PROCESSING(SSobj, src) - -/obj/item/claymore/highlander/Destroy() - if(nuke_disk) - nuke_disk.forceMove(get_turf(src)) - nuke_disk.visible_message("The nuke disk is vulnerable!") - nuke_disk = null - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/claymore/highlander/process() - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - loc.layer = LARGE_MOB_LAYER //NO HIDING BEHIND PLANTS FOR YOU, DICKWEED (HA GET IT, BECAUSE WEEDS ARE PLANTS) - H.bleedsuppress = TRUE //AND WE WON'T BLEED OUT LIKE COWARDS - else - if(!admin_spawned) - qdel(src) - - -/obj/item/claymore/highlander/pickup(mob/living/user) - to_chat(user, "The power of Scotland protects you! You are shielded from all stuns and knockdowns.") - user.add_stun_absorption("highlander", INFINITY, 1, " is protected by the power of Scotland!", "The power of Scotland absorbs the stun!", " is protected by the power of Scotland!") - user.status_flags += IGNORESLOWDOWN - -/obj/item/claymore/highlander/dropped(mob/living/user) - user.status_flags -= IGNORESLOWDOWN - qdel(src) //If this ever happens, it's because you lost an arm - -/obj/item/claymore/highlander/examine(mob/user) - ..() - to_chat(user, "It has [!notches ? "nothing" : "[notches] notches"] scratched into the blade.") - if(nuke_disk) - to_chat(user, "It's holding the nuke disk!") - -/obj/item/claymore/highlander/attack(mob/living/target, mob/living/user) - . = ..() - if(target && target.stat == DEAD && target.mind && target.mind.special_role == "highlander") - user.fully_heal() //STEAL THE LIFE OF OUR FALLEN FOES - add_notch(user) - target.visible_message("[target] crumbles to dust beneath [user]'s blows!", "As you fall, your body crumbles to dust!") - target.dust() - -/obj/item/claymore/highlander/attack_self(mob/living/user) - var/closest_victim - var/closest_distance = 255 - for(var/mob/living/carbon/human/H in GLOB.player_list - user) - if(H.client && H.mind.special_role == "highlander" && (!closest_victim || get_dist(user, closest_victim) < closest_distance)) - closest_victim = H - if(!closest_victim) - to_chat(user, "[src] thrums for a moment and falls dark. Perhaps there's nobody nearby.") - return - to_chat(user, "[src] thrums and points to the [dir2text(get_dir(user, closest_victim))].") - -/obj/item/claymore/highlander/IsReflect() - return 1 //YOU THINK YOUR PUNY LASERS CAN STOP ME? - -/obj/item/claymore/highlander/proc/add_notch(mob/living/user) //DYNAMIC CLAYMORE PROGRESSION SYSTEM - THIS IS THE FUTURE - notches++ - force++ - var/new_name = name - switch(notches) - if(1) - to_chat(user, "Your first kill - hopefully one of many. You scratch a notch into [src]'s blade.") - to_chat(user, "You feel your fallen foe's soul entering your blade, restoring your wounds!") - new_name = "notched claymore" - if(2) - to_chat(user, "Another falls before you. Another soul fuses with your own. Another notch in the blade.") - new_name = "double-notched claymore" - add_atom_colour(rgb(255, 235, 235), ADMIN_COLOUR_PRIORITY) - if(3) - to_chat(user, "You're beginning to relish the thrill of battle.") - new_name = "triple-notched claymore" - add_atom_colour(rgb(255, 215, 215), ADMIN_COLOUR_PRIORITY) - if(4) - to_chat(user, "You've lost count of how many you've killed.") - new_name = "many-notched claymore" - add_atom_colour(rgb(255, 195, 195), ADMIN_COLOUR_PRIORITY) - if(5) - to_chat(user, "Five voices now echo in your mind, cheering the slaughter.") - new_name = "battle-tested claymore" - add_atom_colour(rgb(255, 175, 175), ADMIN_COLOUR_PRIORITY) - if(6) - to_chat(user, "Is this what the vikings felt like? Visions of glory fill your head as you slay your sixth foe.") - new_name = "battle-scarred claymore" - add_atom_colour(rgb(255, 155, 155), ADMIN_COLOUR_PRIORITY) - if(7) - to_chat(user, "Kill. Butcher. Conquer.") - new_name = "vicious claymore" - add_atom_colour(rgb(255, 135, 135), ADMIN_COLOUR_PRIORITY) - if(8) - to_chat(user, "IT NEVER GETS OLD. THE SCREAMING. THE BLOOD AS IT SPRAYS ACROSS YOUR FACE.") - new_name = "bloodthirsty claymore" - add_atom_colour(rgb(255, 115, 115), ADMIN_COLOUR_PRIORITY) - if(9) - to_chat(user, "ANOTHER ONE FALLS TO YOUR BLOWS. ANOTHER WEAKLING UNFIT TO LIVE.") - new_name = "gore-stained claymore" - add_atom_colour(rgb(255, 95, 95), ADMIN_COLOUR_PRIORITY) - if(10) - user.visible_message("[user]'s eyes light up with a vengeful fire!", \ - "YOU FEEL THE POWER OF VALHALLA FLOWING THROUGH YOU! THERE CAN BE ONLY ONE!!!") - user.update_icons() - new_name = "GORE-DRENCHED CLAYMORE OF [pick("THE WHIMSICAL SLAUGHTER", "A THOUSAND SLAUGHTERED CATTLE", "GLORY AND VALHALLA", "ANNIHILATION", "OBLITERATION")]" - icon_state = "claymore_valhalla" - item_state = "cultblade" - remove_atom_colour(ADMIN_COLOUR_PRIORITY) - - name = new_name - playsound(user, 'sound/items/screwdriver2.ogg', 50, 1) - -/obj/item/katana - name = "katana" - desc = "Woefully underpowered in D20" - icon_state = "katana" - item_state = "katana" - lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT | SLOT_BACK - force = 40 - throwforce = 10 - w_class = WEIGHT_CLASS_NORMAL - hitsound = 'sound/weapons/bladeslice.ogg' - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - block_chance = 50 - sharpness = IS_SHARP - max_integrity = 200 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50) - resistance_flags = FIRE_PROOF - -/obj/item/katana/cursed - slot_flags = null - -/obj/item/katana/suicide_act(mob/user) - user.visible_message("[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!") - return(BRUTELOSS) - -/obj/item/wirerod - name = "wired rod" - desc = "A rod with some wire wrapped around the top. It'd be easy to attach something to the top bit." - icon_state = "wiredrod" - item_state = "rods" - flags_1 = CONDUCT_1 - force = 9 - throwforce = 10 - w_class = WEIGHT_CLASS_NORMAL - materials = list(MAT_METAL=1150, MAT_GLASS=75) - attack_verb = list("hit", "bludgeoned", "whacked", "bonked") - -/obj/item/wirerod/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/shard)) - var/obj/item/twohanded/spear/S = new /obj/item/twohanded/spear - - remove_item_from_storage(user) - qdel(I) - qdel(src) - - user.put_in_hands(S) - to_chat(user, "You fasten the glass shard to the top of the rod with the cable.") - - else if(istype(I, /obj/item/device/assembly/igniter) && !(I.flags_1 & NODROP_1)) - var/obj/item/melee/baton/cattleprod/P = new /obj/item/melee/baton/cattleprod - - remove_item_from_storage(user) - - to_chat(user, "You fasten [I] to the top of the rod with the cable.") - - qdel(I) - qdel(src) - - user.put_in_hands(P) - else - return ..() - - -/obj/item/throwing_star - name = "throwing star" - desc = "An ancient weapon still used to this day due to it's ease of lodging itself into victim's body parts" - icon_state = "throwingstar" - item_state = "eshield0" - lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi' - force = 2 - throwforce = 20 //This is never used on mobs since this has a 100% embed chance. - throw_speed = 4 - embedded_pain_multiplier = 4 - w_class = WEIGHT_CLASS_SMALL - embed_chance = 100 - embedded_fall_chance = 0 //Hahaha! - sharpness = IS_SHARP - materials = list(MAT_METAL=500, MAT_GLASS=500) - resistance_flags = FIRE_PROOF - - -/obj/item/switchblade - name = "switchblade" - icon_state = "switchblade" - lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' - desc = "A sharp, concealable, spring-loaded knife." - flags_1 = CONDUCT_1 - force = 3 - w_class = WEIGHT_CLASS_SMALL - throwforce = 5 - throw_speed = 3 - throw_range = 6 - materials = list(MAT_METAL=12000) - origin_tech = "engineering=3;combat=2" - hitsound = 'sound/weapons/genhit.ogg' - attack_verb = list("stubbed", "poked") - resistance_flags = FIRE_PROOF - var/extended = 0 - -/obj/item/switchblade/attack_self(mob/user) - extended = !extended - playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1) - if(extended) - force = 20 - w_class = WEIGHT_CLASS_NORMAL - throwforce = 23 - icon_state = "switchblade_ext" - attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - hitsound = 'sound/weapons/bladeslice.ogg' - sharpness = IS_SHARP - else - force = 3 - w_class = WEIGHT_CLASS_SMALL - throwforce = 5 - icon_state = "switchblade" - attack_verb = list("stubbed", "poked") - hitsound = 'sound/weapons/genhit.ogg' - sharpness = IS_BLUNT - -/obj/item/switchblade/suicide_act(mob/user) - user.visible_message("[user] is slitting [user.p_their()] own throat with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) - -/obj/item/phone - name = "red phone" - desc = "Should anything ever go wrong..." - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "red_phone" - force = 3 - throwforce = 2 - throw_speed = 3 - throw_range = 4 - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("called", "rang") - hitsound = 'sound/weapons/ring.ogg' - -/obj/item/phone/suicide_act(mob/user) - if(locate(/obj/structure/chair/stool) in user.loc) - user.visible_message("[user] begins to tie a noose with [src]'s cord! It looks like [user.p_theyre()] trying to commit suicide!") - else - user.visible_message("[user] is strangling [user.p_them()]self with [src]'s cord! It looks like [user.p_theyre()] trying to commit suicide!") - return(OXYLOSS) - -/obj/item/cane - name = "cane" - desc = "A cane used by a true gentleman. Or a clown." - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "cane" - item_state = "stick" - lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' - force = 5 - throwforce = 5 - w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL=50) - attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed") - -/obj/item/staff - name = "wizard staff" - desc = "Apparently a staff used by the wizard." - icon = 'icons/obj/wizard.dmi' - icon_state = "staff" - lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi' - force = 3 - throwforce = 5 - throw_speed = 2 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - armour_penetration = 100 - attack_verb = list("bludgeoned", "whacked", "disciplined") - resistance_flags = FLAMMABLE - -/obj/item/staff/broom - name = "broom" - desc = "Used for sweeping, and flying into the night while cackling. Black cat not included." - icon = 'icons/obj/wizard.dmi' - icon_state = "broom" - resistance_flags = FLAMMABLE - -/obj/item/staff/stick - name = "stick" - desc = "A great tool to drag someone else's drinks across the bar." - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "stick" - item_state = "stick" - lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' - force = 3 - throwforce = 5 - throw_speed = 2 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - -/obj/item/ectoplasm - name = "ectoplasm" - desc = "spooky" - gender = PLURAL - icon = 'icons/obj/wizard.dmi' - icon_state = "ectoplasm" - -/obj/item/ectoplasm/suicide_act(mob/user) - user.visible_message("[user] is inhaling [src]! It looks like [user.p_theyre()] trying to visit the astral plane.") - return (OXYLOSS) - -/obj/item/mounted_chainsaw - name = "mounted chainsaw" - desc = "A chainsaw that has replaced your arm." - icon_state = "chainsaw_on" - item_state = "mounted_chainsaw" - lefthand_file = 'icons/mob/inhands/weapons/chainsaw_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/chainsaw_righthand.dmi' - flags_1 = NODROP_1 | ABSTRACT_1 | DROPDEL_1 - w_class = WEIGHT_CLASS_HUGE - force = 21 - throwforce = 0 - throw_range = 0 - throw_speed = 0 - sharpness = IS_SHARP - attack_verb = list("sawed", "torn", "cut", "chopped", "diced") - hitsound = 'sound/weapons/chainsawhit.ogg' - -/obj/item/mounted_chainsaw/Destroy() - var/obj/item/bodypart/part - new /obj/item/twohanded/required/chainsaw(get_turf(src)) - if(iscarbon(loc)) - var/mob/living/carbon/holder = loc - var/index = holder.get_held_index_of_item(src) - if(index) - part = holder.hand_bodyparts[index] - . = ..() - if(part) - part.drop_limb() - -/obj/item/statuebust - name = "bust" - desc = "A priceless ancient marble bust, the kind that belongs in a museum." //or you can hit people with it - icon = 'icons/obj/statue.dmi' - icon_state = "bust" - force = 15 - throwforce = 10 - throw_speed = 5 - throw_range = 2 - attack_verb = list("busted") - -/obj/item/tailclub - name = "tail club" - desc = "For the beating to death of lizards with their own tails." - icon_state = "tailclub" - force = 14 - throwforce = 1 // why are you throwing a club do you even weapon - throw_speed = 1 - throw_range = 1 - attack_verb = list("clubbed", "bludgeoned") - -/obj/item/melee/chainofcommand/tailwhip - name = "liz o' nine tails" - desc = "A whip fashioned from the severed tails of lizards." - icon_state = "tailwhip" - origin_tech = "engineering=3;combat=3;biotech=3" - needs_permit = 0 - -/obj/item/melee/chainofcommand/tailwhip/kitty - name = "cat o' nine tails" - desc = "A whip fashioned from the severed tails of cats." - icon_state = "catwhip" - -/obj/item/melee/skateboard - name = "skateboard" - desc = "A skateboard. It can be placed on its wheels and ridden, or used as a strong weapon." - icon_state = "skateboard" - item_state = "skateboard" - force = 12 - throwforce = 4 - w_class = WEIGHT_CLASS_HUGE - attack_verb = list("smacked", "whacked", "slammed", "smashed") - -/obj/item/melee/skateboard/attack_self(mob/user) - new /obj/vehicle/scooter/skateboard(get_turf(user)) - qdel(src) - -/obj/item/melee/baseball_bat - name = "baseball bat" - desc = "There ain't a skull in the league that can withstand a swatter." - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "baseball_bat" - item_state = "baseball_bat" - lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' - force = 10 - throwforce = 12 - attack_verb = list("beat", "smacked") - w_class = WEIGHT_CLASS_HUGE - var/homerun_ready = 0 - var/homerun_able = 0 - -/obj/item/melee/baseball_bat/homerun - name = "home run bat" - desc = "This thing looks dangerous... Dangerously good at baseball, that is." - homerun_able = 1 - -/obj/item/melee/baseball_bat/attack_self(mob/user) - if(!homerun_able) - ..() - return - if(homerun_ready) - to_chat(user, "You're already ready to do a home run!") - ..() - return - to_chat(user, "You begin gathering strength...") - playsound(get_turf(src), 'sound/magic/lightning_chargeup.ogg', 65, 1) - if(do_after(user, 90, target = src)) - to_chat(user, "You gather power! Time for a home run!") - homerun_ready = 1 - ..() - -/obj/item/melee/baseball_bat/attack(mob/living/target, mob/living/user) - . = ..() - var/atom/throw_target = get_edge_target_turf(target, user.dir) - if(homerun_ready) - user.visible_message("It's a home run!") - target.throw_at(throw_target, rand(8,10), 14, user) - target.ex_act(EXPLODE_HEAVY) - playsound(get_turf(src), 'sound/weapons/homerun.ogg', 100, 1) - homerun_ready = 0 - return - else if(!target.anchored) - target.throw_at(throw_target, rand(1,2), 7, user) - -/obj/item/melee/baseball_bat/ablative - name = "metal baseball bat" - desc = "This bat is made of highly reflective, highly armored material." - icon_state = "baseball_bat_metal" - item_state = "baseball_bat_metal" - force = 12 - throwforce = 15 - -/obj/item/melee/baseball_bat/ablative/IsReflect()//some day this will reflect thrown items instead of lasers - var/picksound = rand(1,2) - var/turf = get_turf(src) - if(picksound == 1) - playsound(turf, 'sound/weapons/effects/batreflect1.ogg', 50, 1) - if(picksound == 2) - playsound(turf, 'sound/weapons/effects/batreflect2.ogg', 50, 1) - return 1 - -/obj/item/melee/flyswatter - name = "flyswatter" - desc = "Useful for killing insects of all sizes." - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "flyswatter" - item_state = "flyswatter" - lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' - force = 1 - throwforce = 1 - attack_verb = list("swatted", "smacked") - hitsound = 'sound/effects/snap.ogg' - w_class = WEIGHT_CLASS_SMALL - //Things in this list will be instantly splatted. Flyman weakness is handled in the flyman species weakness proc. - var/list/strong_against - -/obj/item/melee/flyswatter/Initialize() - . = ..() - strong_against = typecacheof(list( - /mob/living/simple_animal/hostile/poison/bees/, - /mob/living/simple_animal/butterfly, - /mob/living/simple_animal/cockroach, - /obj/item/queen_bee - )) - - -/obj/item/melee/flyswatter/afterattack(atom/target, mob/user, proximity_flag) - if(proximity_flag) - if(is_type_in_typecache(target, strong_against)) - new /obj/effect/decal/cleanable/deadcockroach(get_turf(target)) - to_chat(user, "You easily splat the [target].") - if(istype(target, /mob/living/)) - var/mob/living/bug = target - bug.death(1) - else - qdel(target) - -/obj/item/circlegame - name = "circled hand" - desc = "If somebody looks at this while it's below your waist, you get to bop them." - icon_state = "madeyoulook" - force = 0 - throwforce = 0 - flags_1 = DROPDEL_1 | ABSTRACT_1 - attack_verb = list("bopped") - -/obj/item/proc/can_trigger_gun(mob/living/user) - if(!user.can_use_guns(src)) - return FALSE -======= + playsound(loc, 'sound/effects/adminhelp.ogg', 15) //keep it at 15% volume so people don't jump out of their skin too much + +/obj/item/sord + name = "\improper SORD" + desc = "This thing is so unspeakably shitty you are having a hard time even holding it." + icon_state = "sord" + item_state = "sord" + lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' + slot_flags = SLOT_BELT + force = 2 + throwforce = 1 + w_class = WEIGHT_CLASS_NORMAL + hitsound = 'sound/weapons/bladeslice.ogg' + attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + +/obj/item/sord/suicide_act(mob/user) + user.visible_message("[user] is trying to impale [user.p_them()]self with [src]! It might be a suicide attempt if it weren't so shitty.", \ + "You try to impale yourself with [src], but it's USELESS...") + return SHAME + +/obj/item/claymore + name = "claymore" + desc = "What are you standing around staring at this for? Get to killing!" + icon_state = "claymore" + item_state = "claymore" + lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' + hitsound = 'sound/weapons/bladeslice.ogg' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT | SLOT_BACK + force = 40 + throwforce = 10 + w_class = WEIGHT_CLASS_NORMAL + attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + block_chance = 50 + sharpness = IS_SHARP + max_integrity = 200 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50) + resistance_flags = FIRE_PROOF + +/obj/item/claymore/suicide_act(mob/user) + user.visible_message("[user] is falling on [src]! It looks like [user.p_theyre()] trying to commit suicide!") + return(BRUTELOSS) + +/obj/item/claymore/highlander //ALL COMMENTS MADE REGARDING THIS SWORD MUST BE MADE IN ALL CAPS + desc = "THERE CAN BE ONLY ONE, AND IT WILL BE YOU!!!\nActivate it in your hand to point to the nearest victim." + flags_1 = CONDUCT_1 | NODROP_1 | DROPDEL_1 + slot_flags = null + block_chance = 0 //RNG WON'T HELP YOU NOW, PANSY + luminosity = 3 + attack_verb = list("brutalized", "eviscerated", "disemboweled", "hacked", "carved", "cleaved") //ONLY THE MOST VISCERAL ATTACK VERBS + var/notches = 0 //HOW MANY PEOPLE HAVE BEEN SLAIN WITH THIS BLADE + var/obj/item/disk/nuclear/nuke_disk //OUR STORED NUKE DISK + +/obj/item/claymore/highlander/Initialize() + . = ..() + START_PROCESSING(SSobj, src) + +/obj/item/claymore/highlander/Destroy() + if(nuke_disk) + nuke_disk.forceMove(get_turf(src)) + nuke_disk.visible_message("The nuke disk is vulnerable!") + nuke_disk = null + STOP_PROCESSING(SSobj, src) + return ..() + +/obj/item/claymore/highlander/process() + if(ishuman(loc)) + var/mob/living/carbon/human/H = loc + loc.layer = LARGE_MOB_LAYER //NO HIDING BEHIND PLANTS FOR YOU, DICKWEED (HA GET IT, BECAUSE WEEDS ARE PLANTS) + H.bleedsuppress = TRUE //AND WE WON'T BLEED OUT LIKE COWARDS + else + if(!admin_spawned) + qdel(src) + + +/obj/item/claymore/highlander/pickup(mob/living/user) + to_chat(user, "The power of Scotland protects you! You are shielded from all stuns and knockdowns.") + user.add_stun_absorption("highlander", INFINITY, 1, " is protected by the power of Scotland!", "The power of Scotland absorbs the stun!", " is protected by the power of Scotland!") + user.status_flags += IGNORESLOWDOWN + +/obj/item/claymore/highlander/dropped(mob/living/user) + user.status_flags -= IGNORESLOWDOWN + qdel(src) //If this ever happens, it's because you lost an arm + +/obj/item/claymore/highlander/examine(mob/user) + ..() + to_chat(user, "It has [!notches ? "nothing" : "[notches] notches"] scratched into the blade.") + if(nuke_disk) + to_chat(user, "It's holding the nuke disk!") + +/obj/item/claymore/highlander/attack(mob/living/target, mob/living/user) + . = ..() + if(target && target.stat == DEAD && target.mind && target.mind.special_role == "highlander") + user.fully_heal() //STEAL THE LIFE OF OUR FALLEN FOES + add_notch(user) + target.visible_message("[target] crumbles to dust beneath [user]'s blows!", "As you fall, your body crumbles to dust!") + target.dust() + +/obj/item/claymore/highlander/attack_self(mob/living/user) + var/closest_victim + var/closest_distance = 255 + for(var/mob/living/carbon/human/H in GLOB.player_list - user) + if(H.client && H.mind.special_role == "highlander" && (!closest_victim || get_dist(user, closest_victim) < closest_distance)) + closest_victim = H + if(!closest_victim) + to_chat(user, "[src] thrums for a moment and falls dark. Perhaps there's nobody nearby.") + return + to_chat(user, "[src] thrums and points to the [dir2text(get_dir(user, closest_victim))].") + +/obj/item/claymore/highlander/IsReflect() + return 1 //YOU THINK YOUR PUNY LASERS CAN STOP ME? + +/obj/item/claymore/highlander/proc/add_notch(mob/living/user) //DYNAMIC CLAYMORE PROGRESSION SYSTEM - THIS IS THE FUTURE + notches++ + force++ + var/new_name = name + switch(notches) + if(1) + to_chat(user, "Your first kill - hopefully one of many. You scratch a notch into [src]'s blade.") + to_chat(user, "You feel your fallen foe's soul entering your blade, restoring your wounds!") + new_name = "notched claymore" + if(2) + to_chat(user, "Another falls before you. Another soul fuses with your own. Another notch in the blade.") + new_name = "double-notched claymore" + add_atom_colour(rgb(255, 235, 235), ADMIN_COLOUR_PRIORITY) + if(3) + to_chat(user, "You're beginning to relish the thrill of battle.") + new_name = "triple-notched claymore" + add_atom_colour(rgb(255, 215, 215), ADMIN_COLOUR_PRIORITY) + if(4) + to_chat(user, "You've lost count of how many you've killed.") + new_name = "many-notched claymore" + add_atom_colour(rgb(255, 195, 195), ADMIN_COLOUR_PRIORITY) + if(5) + to_chat(user, "Five voices now echo in your mind, cheering the slaughter.") + new_name = "battle-tested claymore" + add_atom_colour(rgb(255, 175, 175), ADMIN_COLOUR_PRIORITY) + if(6) + to_chat(user, "Is this what the vikings felt like? Visions of glory fill your head as you slay your sixth foe.") + new_name = "battle-scarred claymore" + add_atom_colour(rgb(255, 155, 155), ADMIN_COLOUR_PRIORITY) + if(7) + to_chat(user, "Kill. Butcher. Conquer.") + new_name = "vicious claymore" + add_atom_colour(rgb(255, 135, 135), ADMIN_COLOUR_PRIORITY) + if(8) + to_chat(user, "IT NEVER GETS OLD. THE SCREAMING. THE BLOOD AS IT SPRAYS ACROSS YOUR FACE.") + new_name = "bloodthirsty claymore" + add_atom_colour(rgb(255, 115, 115), ADMIN_COLOUR_PRIORITY) + if(9) + to_chat(user, "ANOTHER ONE FALLS TO YOUR BLOWS. ANOTHER WEAKLING UNFIT TO LIVE.") + new_name = "gore-stained claymore" + add_atom_colour(rgb(255, 95, 95), ADMIN_COLOUR_PRIORITY) + if(10) + user.visible_message("[user]'s eyes light up with a vengeful fire!", \ + "YOU FEEL THE POWER OF VALHALLA FLOWING THROUGH YOU! THERE CAN BE ONLY ONE!!!") + user.update_icons() + new_name = "GORE-DRENCHED CLAYMORE OF [pick("THE WHIMSICAL SLAUGHTER", "A THOUSAND SLAUGHTERED CATTLE", "GLORY AND VALHALLA", "ANNIHILATION", "OBLITERATION")]" + icon_state = "claymore_valhalla" + item_state = "cultblade" + remove_atom_colour(ADMIN_COLOUR_PRIORITY) + + name = new_name + playsound(user, 'sound/items/screwdriver2.ogg', 50, 1) + +/obj/item/katana + name = "katana" + desc = "Woefully underpowered in D20" + icon_state = "katana" + item_state = "katana" + lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT | SLOT_BACK + force = 40 + throwforce = 10 + w_class = WEIGHT_CLASS_NORMAL + hitsound = 'sound/weapons/bladeslice.ogg' + attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + block_chance = 50 + sharpness = IS_SHARP + max_integrity = 200 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50) + resistance_flags = FIRE_PROOF + +/obj/item/katana/cursed + slot_flags = null + +/obj/item/katana/suicide_act(mob/user) + user.visible_message("[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!") + return(BRUTELOSS) + +/obj/item/wirerod + name = "wired rod" + desc = "A rod with some wire wrapped around the top. It'd be easy to attach something to the top bit." + icon_state = "wiredrod" + item_state = "rods" + flags_1 = CONDUCT_1 + force = 9 + throwforce = 10 + w_class = WEIGHT_CLASS_NORMAL + materials = list(MAT_METAL=1150, MAT_GLASS=75) + attack_verb = list("hit", "bludgeoned", "whacked", "bonked") + +/obj/item/wirerod/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/shard)) + var/obj/item/twohanded/spear/S = new /obj/item/twohanded/spear + + remove_item_from_storage(user) + qdel(I) + qdel(src) + + user.put_in_hands(S) + to_chat(user, "You fasten the glass shard to the top of the rod with the cable.") + + else if(istype(I, /obj/item/device/assembly/igniter) && !(I.flags_1 & NODROP_1)) + var/obj/item/melee/baton/cattleprod/P = new /obj/item/melee/baton/cattleprod + + remove_item_from_storage(user) + + to_chat(user, "You fasten [I] to the top of the rod with the cable.") + + qdel(I) + qdel(src) + + user.put_in_hands(P) + else + return ..() + + +/obj/item/throwing_star + name = "throwing star" + desc = "An ancient weapon still used to this day due to it's ease of lodging itself into victim's body parts" + icon_state = "throwingstar" + item_state = "eshield0" + lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi' + force = 2 + throwforce = 20 //This is never used on mobs since this has a 100% embed chance. + throw_speed = 4 + embedded_pain_multiplier = 4 + w_class = WEIGHT_CLASS_SMALL + embed_chance = 100 + embedded_fall_chance = 0 //Hahaha! + sharpness = IS_SHARP + materials = list(MAT_METAL=500, MAT_GLASS=500) + resistance_flags = FIRE_PROOF + + +/obj/item/switchblade + name = "switchblade" + icon_state = "switchblade" + lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' + desc = "A sharp, concealable, spring-loaded knife." + flags_1 = CONDUCT_1 + force = 3 + w_class = WEIGHT_CLASS_SMALL + throwforce = 5 + throw_speed = 3 + throw_range = 6 + materials = list(MAT_METAL=12000) + origin_tech = "engineering=3;combat=2" + hitsound = 'sound/weapons/genhit.ogg' + attack_verb = list("stubbed", "poked") + resistance_flags = FIRE_PROOF + var/extended = 0 + +/obj/item/switchblade/attack_self(mob/user) + extended = !extended + playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1) + if(extended) + force = 20 + w_class = WEIGHT_CLASS_NORMAL + throwforce = 23 + icon_state = "switchblade_ext" + attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") + hitsound = 'sound/weapons/bladeslice.ogg' + sharpness = IS_SHARP + else + force = 3 + w_class = WEIGHT_CLASS_SMALL + throwforce = 5 + icon_state = "switchblade" + attack_verb = list("stubbed", "poked") + hitsound = 'sound/weapons/genhit.ogg' + sharpness = IS_BLUNT + +/obj/item/switchblade/suicide_act(mob/user) + user.visible_message("[user] is slitting [user.p_their()] own throat with [src]! It looks like [user.p_theyre()] trying to commit suicide!") + return (BRUTELOSS) + +/obj/item/phone + name = "red phone" + desc = "Should anything ever go wrong..." + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "red_phone" + force = 3 + throwforce = 2 + throw_speed = 3 + throw_range = 4 + w_class = WEIGHT_CLASS_SMALL + attack_verb = list("called", "rang") + hitsound = 'sound/weapons/ring.ogg' + +/obj/item/phone/suicide_act(mob/user) + if(locate(/obj/structure/chair/stool) in user.loc) + user.visible_message("[user] begins to tie a noose with [src]'s cord! It looks like [user.p_theyre()] trying to commit suicide!") + else + user.visible_message("[user] is strangling [user.p_them()]self with [src]'s cord! It looks like [user.p_theyre()] trying to commit suicide!") + return(OXYLOSS) + +/obj/item/cane + name = "cane" + desc = "A cane used by a true gentleman. Or a clown." + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "cane" + item_state = "stick" + lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' + force = 5 + throwforce = 5 + w_class = WEIGHT_CLASS_SMALL + materials = list(MAT_METAL=50) + attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed") + +/obj/item/staff + name = "wizard staff" + desc = "Apparently a staff used by the wizard." + icon = 'icons/obj/wizard.dmi' + icon_state = "staff" + lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi' + force = 3 + throwforce = 5 + throw_speed = 2 + throw_range = 5 + w_class = WEIGHT_CLASS_SMALL + armour_penetration = 100 + attack_verb = list("bludgeoned", "whacked", "disciplined") + resistance_flags = FLAMMABLE + +/obj/item/staff/broom + name = "broom" + desc = "Used for sweeping, and flying into the night while cackling. Black cat not included." + icon = 'icons/obj/wizard.dmi' + icon_state = "broom" + resistance_flags = FLAMMABLE + +/obj/item/staff/stick + name = "stick" + desc = "A great tool to drag someone else's drinks across the bar." + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "stick" + item_state = "stick" + lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' + force = 3 + throwforce = 5 + throw_speed = 2 + throw_range = 5 + w_class = WEIGHT_CLASS_SMALL + +/obj/item/ectoplasm + name = "ectoplasm" + desc = "spooky" + gender = PLURAL + icon = 'icons/obj/wizard.dmi' + icon_state = "ectoplasm" + +/obj/item/ectoplasm/suicide_act(mob/user) + user.visible_message("[user] is inhaling [src]! It looks like [user.p_theyre()] trying to visit the astral plane.") + return (OXYLOSS) + +/obj/item/mounted_chainsaw + name = "mounted chainsaw" + desc = "A chainsaw that has replaced your arm." + icon_state = "chainsaw_on" + item_state = "mounted_chainsaw" + lefthand_file = 'icons/mob/inhands/weapons/chainsaw_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/chainsaw_righthand.dmi' + flags_1 = NODROP_1 | ABSTRACT_1 | DROPDEL_1 + w_class = WEIGHT_CLASS_HUGE + force = 21 + throwforce = 0 + throw_range = 0 + throw_speed = 0 + sharpness = IS_SHARP + attack_verb = list("sawed", "torn", "cut", "chopped", "diced") + hitsound = 'sound/weapons/chainsawhit.ogg' + +/obj/item/mounted_chainsaw/Destroy() + var/obj/item/bodypart/part + new /obj/item/twohanded/required/chainsaw(get_turf(src)) + if(iscarbon(loc)) + var/mob/living/carbon/holder = loc + var/index = holder.get_held_index_of_item(src) + if(index) + part = holder.hand_bodyparts[index] + . = ..() + if(part) + part.drop_limb() + +/obj/item/statuebust + name = "bust" + desc = "A priceless ancient marble bust, the kind that belongs in a museum." //or you can hit people with it + icon = 'icons/obj/statue.dmi' + icon_state = "bust" + force = 15 + throwforce = 10 + throw_speed = 5 + throw_range = 2 + attack_verb = list("busted") + +/obj/item/tailclub + name = "tail club" + desc = "For the beating to death of lizards with their own tails." + icon_state = "tailclub" + force = 14 + throwforce = 1 // why are you throwing a club do you even weapon + throw_speed = 1 + throw_range = 1 + attack_verb = list("clubbed", "bludgeoned") + +/obj/item/melee/chainofcommand/tailwhip + name = "liz o' nine tails" + desc = "A whip fashioned from the severed tails of lizards." + icon_state = "tailwhip" + origin_tech = "engineering=3;combat=3;biotech=3" + needs_permit = 0 + +/obj/item/melee/chainofcommand/tailwhip/kitty + name = "cat o' nine tails" + desc = "A whip fashioned from the severed tails of cats." + icon_state = "catwhip" + +/obj/item/melee/skateboard + name = "skateboard" + desc = "A skateboard. It can be placed on its wheels and ridden, or used as a strong weapon." + icon_state = "skateboard" + item_state = "skateboard" + force = 12 + throwforce = 4 + w_class = WEIGHT_CLASS_HUGE + attack_verb = list("smacked", "whacked", "slammed", "smashed") + +/obj/item/melee/skateboard/attack_self(mob/user) + new /obj/vehicle/scooter/skateboard(get_turf(user)) + qdel(src) + +/obj/item/melee/baseball_bat + name = "baseball bat" + desc = "There ain't a skull in the league that can withstand a swatter." + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "baseball_bat" + item_state = "baseball_bat" + lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' + force = 10 + throwforce = 12 + attack_verb = list("beat", "smacked") + w_class = WEIGHT_CLASS_HUGE + var/homerun_ready = 0 + var/homerun_able = 0 + +/obj/item/melee/baseball_bat/homerun + name = "home run bat" + desc = "This thing looks dangerous... Dangerously good at baseball, that is." + homerun_able = 1 + +/obj/item/melee/baseball_bat/attack_self(mob/user) + if(!homerun_able) + ..() + return + if(homerun_ready) + to_chat(user, "You're already ready to do a home run!") + ..() + return + to_chat(user, "You begin gathering strength...") + playsound(get_turf(src), 'sound/magic/lightning_chargeup.ogg', 65, 1) + if(do_after(user, 90, target = src)) + to_chat(user, "You gather power! Time for a home run!") + homerun_ready = 1 + ..() + +/obj/item/melee/baseball_bat/attack(mob/living/target, mob/living/user) + . = ..() + var/atom/throw_target = get_edge_target_turf(target, user.dir) + if(homerun_ready) + user.visible_message("It's a home run!") + target.throw_at(throw_target, rand(8,10), 14, user) + target.ex_act(EXPLODE_HEAVY) + playsound(get_turf(src), 'sound/weapons/homerun.ogg', 100, 1) + homerun_ready = 0 + return + else if(!target.anchored) + target.throw_at(throw_target, rand(1,2), 7, user) + +/obj/item/melee/baseball_bat/ablative + name = "metal baseball bat" + desc = "This bat is made of highly reflective, highly armored material." + icon_state = "baseball_bat_metal" + item_state = "baseball_bat_metal" + force = 12 + throwforce = 15 + +/obj/item/melee/baseball_bat/ablative/IsReflect()//some day this will reflect thrown items instead of lasers + var/picksound = rand(1,2) + var/turf = get_turf(src) + if(picksound == 1) + playsound(turf, 'sound/weapons/effects/batreflect1.ogg', 50, 1) + if(picksound == 2) + playsound(turf, 'sound/weapons/effects/batreflect2.ogg', 50, 1) + return 1 + +/obj/item/melee/flyswatter + name = "flyswatter" + desc = "Useful for killing insects of all sizes." + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "flyswatter" + item_state = "flyswatter" + lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' + force = 1 + throwforce = 1 + attack_verb = list("swatted", "smacked") + hitsound = 'sound/effects/snap.ogg' + w_class = WEIGHT_CLASS_SMALL + //Things in this list will be instantly splatted. Flyman weakness is handled in the flyman species weakness proc. + var/list/strong_against + +/obj/item/melee/flyswatter/Initialize() + . = ..() + strong_against = typecacheof(list( + /mob/living/simple_animal/hostile/poison/bees/, + /mob/living/simple_animal/butterfly, + /mob/living/simple_animal/cockroach, + /obj/item/queen_bee + )) + + +/obj/item/melee/flyswatter/afterattack(atom/target, mob/user, proximity_flag) + if(proximity_flag) + if(is_type_in_typecache(target, strong_against)) + new /obj/effect/decal/cleanable/deadcockroach(get_turf(target)) + to_chat(user, "You easily splat the [target].") + if(istype(target, /mob/living/)) + var/mob/living/bug = target + bug.death(1) + else + qdel(target) + +/obj/item/circlegame + name = "circled hand" + desc = "If somebody looks at this while it's below your waist, you get to bop them." + icon_state = "madeyoulook" + force = 0 + throwforce = 0 + flags_1 = DROPDEL_1 | ABSTRACT_1 + attack_verb = list("bopped") + +/obj/item/proc/can_trigger_gun(mob/living/user) + if(!user.can_use_guns(src)) + return FALSE playsound(loc, 'sound/effects/adminhelp.ogg', 15) //keep it at 15% volume so people don't jump out of their skin too much /obj/item/sord @@ -1157,5 +1155,4 @@ /obj/item/proc/can_trigger_gun(mob/living/user) if(!user.can_use_guns(src)) return FALSE ->>>>>>> 129a7b9... Fixes brains counting towards highlander killstreaks (#30396) return TRUE From 1e0297f9ef613f626c49ae6395959660beee5c22 Mon Sep 17 00:00:00 2001 From: Firecage Date: Sun, 10 Sep 2017 21:31:21 +0200 Subject: [PATCH 236/262] Adds cybernetic lungs(and an upgraded and actually useful variety) to the game. (#30382) * Adds cybernetic lungs * Added better cold thresholds to the upgraded cybernetic lungs. Heat threshold remains the same though for balance reasons. * Adds an EMP effect to cybernetic lungs. --- .../research/designs/medical_designs.dm | 20 ++++++++++++++++ code/modules/surgery/organs/lungs.dm | 23 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 525cb7cd74..89767a1c55 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -430,3 +430,23 @@ materials = list(MAT_METAL = 500, MAT_GLASS = 500) build_path = /obj/item/organ/liver/cybernetic/upgraded category = list("Medical Designs") + +/datum/design/cybernetic_lungs + name = "Cybernetic Lungs" + desc = "A pair of cybernetic lungs." + id = "cybernetic_lungs" + req_tech = list("biotech" = 4, "materials" = 4) + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500) + build_path = /obj/item/organ/lungs/cybernetic + category = list("Medical Designs") + +/datum/design/cybernetic_lungs_u + name = "Upgraded Cybernetic Lungs" + desc = "A pair of upgraded cybernetic lungs." + id = "cybernetic_lungs_u" + req_tech = list("biotech" = 5, "materials" = 5, "engineering" = 5) + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 500) + build_path = /obj/item/organ/lungs/cybernetic/upgraded + category = list("Medical Designs") \ No newline at end of file diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index f95e2cd996..27b0406a04 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -316,6 +316,29 @@ safe_toxins_min = 16 //We breath THIS! safe_toxins_max = 0 +/obj/item/organ/lungs/cybernetic + name = "cybernetic lungs" + desc = "A cybernetic version of the lungs found in traditional humanoid entities. It functions the same as an organic lung and is merely meant as a replacement." + icon_state = "lungs-c" + origin_tech = "biotech=4" + +/obj/item/organ/lungs/cybernetic/emp_act() + owner.losebreath = 20 + + +/obj/item/organ/lungs/cybernetic/upgraded + name = "upgraded cybernetic lungs" + desc = "A more advanced version of the stock cybernetic lungs. They are capable of filtering out lower levels of toxins and carbon-dioxide." + icon_state = "lungs-c-u" + origin_tech = "biotech=5" + + safe_toxins_max = 20 + safe_co2_max = 20 + + cold_level_1_threshold = 200 + cold_level_2_threshold = 140 + cold_level_3_threshold = 100 + #undef HUMAN_MAX_OXYLOSS #undef HUMAN_CRIT_MAX_OXYLOSS #undef HEAT_GAS_DAMAGE_LEVEL_1 From c3fed32afbcb55111662e13473554c504cf7085f Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 10 Sep 2017 15:17:25 -0500 Subject: [PATCH 238/262] Update prolonging_prism.dm --- .../clock_structures/prolonging_prism.dm | 903 +++++++++++++++--- 1 file changed, 779 insertions(+), 124 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_structures/prolonging_prism.dm b/code/game/gamemodes/clock_cult/clock_structures/prolonging_prism.dm index a6bc9a7f38..c6692073b0 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/prolonging_prism.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/prolonging_prism.dm @@ -1,135 +1,790 @@ -//Prolonging Prism: A prism that consumes power to delay the shuttle -/obj/structure/destructible/clockwork/powered/prolonging_prism - name = "prolonging prism" - desc = "A dark onyx prism, held in midair by spiraling tendrils of stone." - clockwork_desc = "A powerful prism that will delay the arrival of an emergency shuttle." - icon_state = "prolonging_prism_inactive" - active_icon = "prolonging_prism" - inactive_icon = "prolonging_prism_inactive" - unanchored_icon = "prolonging_prism_unwrenched" - construction_value = 20 - max_integrity = 125 - break_message = "The prism falls to the ground with a heavy thud!" - debris = list(/obj/item/clockwork/alloy_shards/small = 3, \ - /obj/item/clockwork/alloy_shards/medium = 1, \ - /obj/item/clockwork/alloy_shards/large = 1, \ - /obj/item/clockwork/component/vanguard_cogwheel/onyx_prism = 1) - var/static/list/component_refund = list(VANGUARD_COGWHEEL = 2, GEIS_CAPACITOR = 1, REPLICANT_ALLOY = 1) - var/static/delay_cost = 3000 - var/static/delay_cost_increase = 1250 - var/static/delay_remaining = 0 +#define WELDER_FUEL_BURN_INTERVAL 13 -/obj/structure/destructible/clockwork/powered/prolonging_prism/examine(mob/user) - ..() - if(is_servant_of_ratvar(user) || isobserver(user)) - if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE) - to_chat(user, "An emergency shuttle has arrived and this prism is no longer useful; attempt to activate it to gain a partial refund of components used.") - else - var/efficiency = get_efficiency_mod(TRUE) - to_chat(user, "It requires at least [get_delay_cost()]W of power to attempt to delay the arrival of an emergency shuttle by [2 * efficiency] minutes.") - to_chat(user, "This cost increases by [delay_cost_increase]W for every previous activation.") +/* Tools! + * Note: Multitools are /obj/item/device + * + * Contains: + * Wrench + * Screwdriver + * Wirecutters + * Welding Tool + * Crowbar + */ -/obj/structure/destructible/clockwork/powered/prolonging_prism/forced_disable(bad_effects) - if(active) - if(bad_effects) - try_use_power(MIN_CLOCKCULT_POWER*4) - visible_message("[src] emits an airy chuckling sound and falls dark!") - toggle() - return TRUE +/* + * Wrench + */ +/obj/item/wrench + name = "wrench" + desc = "A wrench with common uses. Can be found in your hand." + icon = 'icons/obj/tools.dmi' + icon_state = "wrench" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + force = 5 + throwforce = 7 + w_class = WEIGHT_CLASS_SMALL + usesound = 'sound/items/ratchet.ogg' + materials = list(MAT_METAL=150) + origin_tech = "materials=1;engineering=1" + attack_verb = list("bashed", "battered", "bludgeoned", "whacked") + toolspeed = 1 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) -/obj/structure/destructible/clockwork/powered/prolonging_prism/attack_hand(mob/living/user) - if(user.canUseTopic(src, !issilicon(user), NO_DEXTERY) && is_servant_of_ratvar(user)) - if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE) - to_chat(user, "You break [src] apart, refunding some of the components used.") - for(var/i in component_refund) - generate_cache_component(i, src) - take_damage(max_integrity) - return 0 - if(active) - return 0 - var/turf/T = get_turf(src) - if(!T || T.z != ZLEVEL_STATION) - to_chat(user, "[src] must be on the station to function!") - return 0 - if(SSshuttle.emergency.mode != SHUTTLE_CALL) - to_chat(user, "No emergency shuttles are attempting to arrive at the station!") - return 0 - if(!try_use_power(get_delay_cost())) - to_chat(user, "[src] needs more power to function!") - return 0 - delay_cost += delay_cost_increase - delay_remaining += PRISM_DELAY_DURATION - toggle(0, user) +/obj/item/wrench/suicide_act(mob/user) + user.visible_message("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") + playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) + return (BRUTELOSS) -/obj/structure/destructible/clockwork/powered/prolonging_prism/process() - var/turf/own_turf = get_turf(src) - if(SSshuttle.emergency.mode != SHUTTLE_CALL || delay_remaining <= 0 || !own_turf || own_turf.z != ZLEVEL_STATION) - forced_disable(FALSE) +/obj/item/wrench/cyborg + name = "automatic wrench" + desc = "An advanced robotic wrench. Can be found in construction cyborgs." + toolspeed = 0.5 + +/obj/item/wrench/brass + name = "brass wrench" + desc = "A brass wrench. It's faintly warm to the touch." + resistance_flags = FIRE_PROOF | ACID_PROOF + icon_state = "wrench_brass" + toolspeed = 0.5 + +/obj/item/wrench/abductor + name = "alien wrench" + desc = "A polarized wrench. It causes anything placed between the jaws to turn." + icon = 'icons/obj/abductor.dmi' + icon_state = "wrench" + usesound = 'sound/effects/empulse.ogg' + toolspeed = 0.1 + origin_tech = "materials=5;engineering=5;abductor=3" + +/obj/item/wrench/power + name = "hand drill" + desc = "A simple powered hand drill. It's fitted with a bolt bit." + icon_state = "drill_bolt" + item_state = "drill" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + usesound = 'sound/items/drill_use.ogg' + materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) + origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get + force = 8 //might or might not be too high, subject to change + w_class = WEIGHT_CLASS_SMALL + throwforce = 8 + attack_verb = list("drilled", "screwed", "jabbed") + toolspeed = 0.25 + +/obj/item/wrench/power/attack_self(mob/user) + playsound(get_turf(user),'sound/items/change_drill.ogg',50,1) + var/obj/item/wirecutters/power/s_drill = new /obj/item/screwdriver/power + to_chat(user, "You attach the screw driver bit to [src].") + qdel(src) + user.put_in_active_hand(s_drill) + +/obj/item/wrench/power/suicide_act(mob/user) + user.visible_message("[user] is pressing [src] against [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide!") + return (BRUTELOSS) + +/obj/item/wrench/medical + name = "medical wrench" + desc = "A medical wrench with common(medical?) uses. Can be found in your hand." + icon_state = "wrench_medical" + force = 2 //MEDICAL + throwforce = 4 + origin_tech = "materials=1;engineering=1;biotech=3" + attack_verb = list("wrenched", "medicaled", "tapped", "jabbed", "whacked") + +/obj/item/wrench/medical/suicide_act(mob/living/user) + user.visible_message("[user] is praying to the medical wrench to take [user.p_their()] soul. It looks like [user.p_theyre()] trying to commit suicide!") + // TODO Make them glow with the power of the M E D I C A L W R E N C H + // during their ascension + + // Stun stops them from wandering off + user.Stun(100, ignore_canstun = TRUE) + playsound(loc, 'sound/effects/pray.ogg', 50, 1, -1) + + // Let the sound effect finish playing + sleep(20) + + if(!user) return + + for(var/obj/item/W in user) + user.dropItemToGround(W) + + var/obj/item/wrench/medical/W = new /obj/item/wrench/medical(loc) + W.add_fingerprint(user) + W.desc += " For some reason, it reminds you of [user.name]." + + if(!user) + return + + user.dust() + + return OXYLOSS + +/* + * Screwdriver + */ +/obj/item/screwdriver + name = "screwdriver" + desc = "You can be totally screwy with this." + icon = 'icons/obj/tools.dmi' + icon_state = "screwdriver" + item_state = "screwdriver" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + force = 5 + w_class = WEIGHT_CLASS_TINY + throwforce = 5 + throw_speed = 3 + throw_range = 5 + materials = list(MAT_METAL=75) + attack_verb = list("stabbed") + hitsound = 'sound/weapons/bladeslice.ogg' + usesound = 'sound/items/screwdriver.ogg' + toolspeed = 1 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) + var/random_color = TRUE //if the screwdriver uses random coloring + var/static/list/screwdriver_colors = list(\ + "blue" = rgb(24, 97, 213), \ + "red" = rgb(149, 23, 16), \ + "pink" = rgb(213, 24, 141), \ + "brown" = rgb(160, 82, 18), \ + "green" = rgb(14, 127, 27), \ + "cyan" = rgb(24, 162, 213), \ + "yellow" = rgb(213, 140, 24), \ + ) + +/obj/item/screwdriver/suicide_act(mob/user) + user.visible_message("[user] is stabbing [src] into [user.p_their()] [pick("temple", "heart")]! It looks like [user.p_theyre()] trying to commit suicide!") + return(BRUTELOSS) + +/obj/item/screwdriver/Initialize() . = ..() - var/delay_amount = 40 - delay_remaining -= delay_amount - var/efficiency = get_efficiency_mod() - SSshuttle.emergency.setTimer(SSshuttle.emergency.timeLeft(1) + (delay_amount * efficiency)) - var/highest_y - var/highest_x - var/lowest_y - var/lowest_x - var/list/prism_turfs = list() - for(var/t in SSshuttle.emergency.ripple_area(SSshuttle.getDock("emergency_home"))) - prism_turfs[t] = TRUE - var/turf/T = t - if(!highest_y || T.y > highest_y) - highest_y = T.y - if(!highest_x || T.x > highest_x) - highest_x = T.x - if(!lowest_y || T.y < lowest_y) - lowest_y = T.y - if(!lowest_x || T.x < lowest_x) - lowest_x = T.x - var/mean_y = Lerp(lowest_y, highest_y) - var/mean_x = Lerp(lowest_x, highest_x) - if(prob(50)) - mean_y = Ceiling(mean_y) + if(random_color) //random colors! + var/our_color = pick(screwdriver_colors) + add_atom_colour(screwdriver_colors[our_color], FIXED_COLOUR_PRIORITY) + update_icon() + if(prob(75)) + pixel_y = rand(0, 16) + +/obj/item/screwdriver/update_icon() + if(!random_color) //icon override + return + cut_overlays() + var/mutable_appearance/base_overlay = mutable_appearance(icon, "screwdriver_screwybits") + base_overlay.appearance_flags = RESET_COLOR + add_overlay(base_overlay) + +/obj/item/screwdriver/worn_overlays(isinhands = FALSE, icon_file) + . = list() + if(isinhands && random_color) + var/mutable_appearance/M = mutable_appearance(icon_file, "screwdriver_head") + M.appearance_flags = RESET_COLOR + . += M + +/obj/item/screwdriver/get_belt_overlay() + if(random_color) + var/mutable_appearance/body = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver") + var/mutable_appearance/head = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver_head") + body.color = color + head.add_overlay(body) + return head else - mean_y = Floor(mean_y) - if(prob(50)) - mean_x = Ceiling(mean_x) + return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state) + +/obj/item/screwdriver/attack(mob/living/carbon/M, mob/living/carbon/user) + if(!istype(M)) + return ..() + if(user.zone_selected != "eyes" && user.zone_selected != "head") + return ..() + if(user.disabilities & CLUMSY && prob(50)) + M = user + return eyestab(M,user) + +/obj/item/screwdriver/brass + name = "brass screwdriver" + desc = "A screwdriver made of brass. The handle feels freezing cold." + resistance_flags = FIRE_PROOF | ACID_PROOF + icon_state = "screwdriver_brass" + item_state = "screwdriver_brass" + toolspeed = 0.5 + random_color = FALSE + +/obj/item/screwdriver/abductor + name = "alien screwdriver" + desc = "An ultrasonic screwdriver." + icon = 'icons/obj/abductor.dmi' + icon_state = "screwdriver_a" + item_state = "screwdriver_nuke" + usesound = 'sound/items/pshoom.ogg' + toolspeed = 0.1 + random_color = FALSE + +/obj/item/screwdriver/power + name = "hand drill" + desc = "A simple powered hand drill. It's fitted with a screw bit." + icon_state = "drill_screw" + item_state = "drill" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) + origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get + force = 8 //might or might not be too high, subject to change + w_class = WEIGHT_CLASS_SMALL + throwforce = 8 + throw_speed = 2 + throw_range = 3//it's heavier than a screw driver/wrench, so it does more damage, but can't be thrown as far + attack_verb = list("drilled", "screwed", "jabbed","whacked") + hitsound = 'sound/items/drill_hit.ogg' + usesound = 'sound/items/drill_use.ogg' + toolspeed = 0.25 + random_color = FALSE + +/obj/item/screwdriver/power/suicide_act(mob/user) + user.visible_message("[user] is putting [src] to [user.p_their()] temple. It looks like [user.p_theyre()] trying to commit suicide!") + return(BRUTELOSS) + +/obj/item/screwdriver/power/attack_self(mob/user) + playsound(get_turf(user),'sound/items/change_drill.ogg',50,1) + var/obj/item/wrench/power/b_drill = new /obj/item/wrench/power + to_chat(user, "You attach the bolt driver bit to [src].") + qdel(src) + user.put_in_active_hand(b_drill) + +/obj/item/screwdriver/cyborg + name = "powered screwdriver" + desc = "An electrical screwdriver, designed to be both precise and quick." + usesound = 'sound/items/drill_use.ogg' + toolspeed = 0.5 + +/* + * Wirecutters + */ +/obj/item/wirecutters + name = "wirecutters" + desc = "This cuts wires." + icon = 'icons/obj/tools.dmi' + icon_state = null + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + force = 6 + throw_speed = 3 + throw_range = 7 + w_class = WEIGHT_CLASS_SMALL + materials = list(MAT_METAL=80) + attack_verb = list("pinched", "nipped") + hitsound = 'sound/items/wirecutter.ogg' + usesound = 'sound/items/wirecutter.ogg' + origin_tech = "materials=1;engineering=1" + toolspeed = 1 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) + + +/obj/item/wirecutters/New(loc, var/param_color = null) + ..() + if(!icon_state) + if(!param_color) + param_color = pick("yellow","red") + icon_state = "cutters_[param_color]" + +/obj/item/wirecutters/attack(mob/living/carbon/C, mob/user) + if(istype(C) && C.handcuffed && istype(C.handcuffed, /obj/item/restraints/handcuffs/cable)) + user.visible_message("[user] cuts [C]'s restraints with [src]!") + qdel(C.handcuffed) + C.handcuffed = null + if(C.buckled && C.buckled.buckle_requires_restraints) + C.buckled.unbuckle_mob(C) + C.update_handcuffed() + return else - mean_x = Floor(mean_x) - var/turf/semi_random_center_turf = locate(mean_x, mean_y, ZLEVEL_STATION) - for(var/t in getline(src, semi_random_center_turf)) - prism_turfs[t] = TRUE - var/placement_style = prob(50) - for(var/t in prism_turfs) - var/turf/T = t - if(placement_style) - if(IsOdd(T.x + T.y)) - seven_random_hexes(T, efficiency) - else if(prob(50 * efficiency)) - new /obj/effect/temp_visual/ratvar/prolonging_prism(T) + ..() + +/obj/item/wirecutters/suicide_act(mob/user) + user.visible_message("[user] is cutting at [user.p_their()] arteries with [src]! It looks like [user.p_theyre()] trying to commit suicide!") + playsound(loc, usesound, 50, 1, -1) + return (BRUTELOSS) + +/obj/item/wirecutters/brass + name = "brass wirecutters" + desc = "A pair of wirecutters made of brass. The handle feels freezing cold to the touch." + resistance_flags = FIRE_PROOF | ACID_PROOF + icon_state = "cutters_brass" + toolspeed = 0.5 + +/obj/item/wirecutters/abductor + name = "alien wirecutters" + desc = "Extremely sharp wirecutters, made out of a silvery-green metal." + icon = 'icons/obj/abductor.dmi' + icon_state = "cutters" + toolspeed = 0.1 + origin_tech = "materials=5;engineering=4;abductor=3" + +/obj/item/wirecutters/cyborg + name = "wirecutters" + desc = "This cuts wires." + toolspeed = 0.5 + +/obj/item/wirecutters/power + name = "jaws of life" + desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a cutting head." + icon_state = "jaws_cutter" + item_state = "jawsoflife" + origin_tech = "materials=2;engineering=2" + materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) + usesound = 'sound/items/jaws_cut.ogg' + toolspeed = 0.25 + +/obj/item/wirecutters/power/suicide_act(mob/user) + user.visible_message("[user] is wrapping \the [src] around [user.p_their()] neck. It looks like [user.p_theyre()] trying to rip [user.p_their()] head off!") + playsound(loc, 'sound/items/jaws_cut.ogg', 50, 1, -1) + if(iscarbon(user)) + var/mob/living/carbon/C = user + var/obj/item/bodypart/BP = C.get_bodypart("head") + if(BP) + BP.drop_limb() + playsound(loc,pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg') ,50, 1, -1) + return (BRUTELOSS) + +/obj/item/wirecutters/power/attack_self(mob/user) + playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) + var/obj/item/crowbar/power/pryjaws = new /obj/item/crowbar/power + to_chat(user, "You attach the pry jaws to [src].") + qdel(src) + user.put_in_active_hand(pryjaws) +/* + * Welding Tool + */ +/obj/item/weldingtool + name = "welding tool" + desc = "A standard edition welder provided by Nanotrasen." + icon = 'icons/obj/tools.dmi' + icon_state = "welder" + item_state = "welder" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + force = 3 + throwforce = 5 + hitsound = "swing_hit" + usesound = 'sound/items/welder.ogg' + var/acti_sound = 'sound/items/welderactivate.ogg' + var/deac_sound = 'sound/items/welderdeactivate.ogg' + throw_speed = 3 + throw_range = 5 + w_class = WEIGHT_CLASS_SMALL + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 30) + resistance_flags = FIRE_PROOF + + materials = list(MAT_METAL=70, MAT_GLASS=30) + origin_tech = "engineering=1;plasmatech=1" + var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) + var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) + var/max_fuel = 20 //The max amount of fuel the welder can hold + var/change_icons = 1 + var/can_off_process = 0 + var/light_intensity = 2 //how powerful the emitted light is when used. + var/burned_fuel_for = 0 //when fuel was last removed + heat = 3800 + toolspeed = 1 + +/obj/item/weldingtool/Initialize() + . = ..() + create_reagents(max_fuel) + reagents.add_reagent("welding_fuel", max_fuel) + update_icon() + + +/obj/item/weldingtool/proc/update_torch() + if(welding) + add_overlay("[initial(icon_state)]-on") + item_state = "[initial(item_state)]1" + else + item_state = "[initial(item_state)]" + + +/obj/item/weldingtool/update_icon() + cut_overlays() + if(change_icons) + var/ratio = get_fuel() / max_fuel + ratio = Ceiling(ratio*4) * 25 + add_overlay("[initial(icon_state)][ratio]") + update_torch() + return + + +/obj/item/weldingtool/process() + switch(welding) + if(0) + force = 3 + damtype = "brute" + update_icon() + if(!can_off_process) + STOP_PROCESSING(SSobj, src) + return + //Welders left on now use up fuel, but lets not have them run out quite that fast + if(1) + force = 15 + damtype = "fire" + ++burned_fuel_for + if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL) + remove_fuel(1) + update_icon() + + //This is to start fires. process() is only called if the welder is on. + open_flame() + + +/obj/item/weldingtool/suicide_act(mob/user) + user.visible_message("[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!") + return (FIRELOSS) + + +/obj/item/weldingtool/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/screwdriver)) + flamethrower_screwdriver(I, user) + else if(istype(I, /obj/item/stack/rods)) + flamethrower_rods(I, user) + else + return ..() + + +/obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) + if(!istype(H)) + return ..() + + var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) + + if(affecting && affecting.status == BODYPART_ROBOTIC && user.a_intent != INTENT_HARM) + if(src.remove_fuel(1)) + playsound(loc, usesound, 50, 1) + if(user == H) + user.visible_message("[user] starts to fix some of the dents on [H]'s [affecting.name].", "You start fixing some of the dents on [H]'s [affecting.name].") + if(!do_mob(user, H, 50)) + return + item_heal_robotic(H, user, 15, 0) + else + return ..() + + +/obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) + if(!proximity) return + + if(welding) + remove_fuel(1) + var/turf/location = get_turf(user) + location.hotspot_expose(700, 50, 1) + if(get_fuel() <= 0) + set_light(0) + + if(isliving(O)) + var/mob/living/L = O + if(L.IgniteMob()) + message_admins("[key_name_admin(user)] set [key_name_admin(L)] on fire") + log_game("[key_name(user)] set [key_name(L)] on fire") + + +/obj/item/weldingtool/attack_self(mob/user) + switched_on(user) + if(welding) + set_light(light_intensity) + + update_icon() + + +//Returns the amount of fuel in the welder +/obj/item/weldingtool/proc/get_fuel() + return reagents.get_reagent_amount("welding_fuel") + + +//Removes fuel from the welding tool. If a mob is passed, it will try to flash the mob's eyes. This should probably be renamed to use() +/obj/item/weldingtool/proc/remove_fuel(amount = 1, mob/living/M = null) + if(!welding || !check_fuel()) + return 0 + if(amount) + burned_fuel_for = 0 + if(get_fuel() >= amount) + reagents.remove_reagent("welding_fuel", amount) + check_fuel() + if(M) + M.flash_act(light_intensity) + return TRUE + else + if(M) + to_chat(M, "You need more welding fuel to complete this task!") + return FALSE + + +//Turns off the welder if there is no more fuel (does this really need to be its own proc?) +/obj/item/weldingtool/proc/check_fuel(mob/user) + if(get_fuel() <= 0 && welding) + switched_on(user) + update_icon() + //mob icon update + if(ismob(loc)) + var/mob/M = loc + M.update_inv_hands(0) + + return 0 + return 1 + +//Switches the welder on +/obj/item/weldingtool/proc/switched_on(mob/user) + if(!status) + to_chat(user, "[src] can't be turned on while unsecured!") + return + welding = !welding + if(welding) + if(get_fuel() >= 1) + to_chat(user, "You switch [src] on.") + playsound(loc, acti_sound, 50, 1) + force = 15 + damtype = "fire" + hitsound = 'sound/items/welder.ogg' + update_icon() + START_PROCESSING(SSobj, src) else - if(IsEven(T.x + T.y)) - seven_random_hexes(T, efficiency) - else if(prob(50 * efficiency)) - new /obj/effect/temp_visual/ratvar/prolonging_prism(T) - CHECK_TICK //we may be going over a hell of a lot of turfs + to_chat(user, "You need more fuel!") + switched_off(user) + else + to_chat(user, "You switch [src] off.") + playsound(loc, deac_sound, 50, 1) + switched_off(user) -/obj/structure/destructible/clockwork/powered/prolonging_prism/proc/get_delay_cost() - return Floor(delay_cost, MIN_CLOCKCULT_POWER) +//Switches the welder off +/obj/item/weldingtool/proc/switched_off(mob/user) + welding = 0 + set_light(0) -/obj/structure/destructible/clockwork/powered/prolonging_prism/proc/seven_random_hexes(turf/T, efficiency) - var/static/list/hex_states = list("prismhex1", "prismhex2", "prismhex3", "prismhex4", "prismhex5", "prismhex6", "prismhex7") - var/mutable_appearance/hex_combo - for(var/n in hex_states) //BUILD ME A HEXAGON - if(prob(50 * efficiency)) - if(!hex_combo) - hex_combo = mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER) - else - hex_combo.add_overlay(mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER)) - if(hex_combo) //YOU BUILT A HEXAGON - hex_combo.pixel_x = -16 - hex_combo.pixel_y = -16 - hex_combo.mouse_opacity = MOUSE_OPACITY_TRANSPARENT - hex_combo.plane = GAME_PLANE - new /obj/effect/temp_visual/ratvar/prolonging_prism(T, hex_combo) + force = 3 + damtype = "brute" + hitsound = "swing_hit" + update_icon() + + +/obj/item/weldingtool/examine(mob/user) + ..() + to_chat(user, "It contains [get_fuel()] unit\s of fuel out of [max_fuel].") + +/obj/item/weldingtool/is_hot() + return welding * heat + +//Returns whether or not the welding tool is currently on. +/obj/item/weldingtool/proc/isOn() + return welding + + +/obj/item/weldingtool/proc/flamethrower_screwdriver(obj/item/I, mob/user) + if(welding) + to_chat(user, "Turn it off first!") + return + status = !status + if(status) + to_chat(user, "You resecure [src].") + else + to_chat(user, "[src] can now be attached and modified.") + add_fingerprint(user) + +/obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) + if(!status) + var/obj/item/stack/rods/R = I + if (R.use(1)) + var/obj/item/flamethrower/F = new /obj/item/flamethrower(user.loc) + if(!remove_item_from_storage(F)) + user.transferItemToLoc(src, F, TRUE) + F.weldtool = src + add_fingerprint(user) + to_chat(user, "You add a rod to a welder, starting to build a flamethrower.") + user.put_in_hands(F) + else + to_chat(user, "You need one rod to start building a flamethrower!") + +/obj/item/weldingtool/ignition_effect(atom/A, mob/user) + if(welding && remove_fuel(1, user)) + . = "[user] casually lights [A] with [src], what a badass." + else + . = "" + +/obj/item/weldingtool/largetank + name = "industrial welding tool" + desc = "A slightly larger welder with a larger tank." + icon_state = "indwelder" + max_fuel = 40 + materials = list(MAT_GLASS=60) + origin_tech = "engineering=2;plasmatech=2" + +/obj/item/weldingtool/largetank/cyborg + name = "integrated welding tool" + desc = "An advanced welder designed to be used in robotic systems." + toolspeed = 0.5 + +/obj/item/weldingtool/largetank/flamethrower_screwdriver() + return + + +/obj/item/weldingtool/mini + name = "emergency welding tool" + desc = "A miniature welder used during emergencies." + icon_state = "miniwelder" + max_fuel = 10 + w_class = WEIGHT_CLASS_TINY + materials = list(MAT_METAL=30, MAT_GLASS=10) + change_icons = 0 + +/obj/item/weldingtool/mini/flamethrower_screwdriver() + return + +/obj/item/weldingtool/abductor + name = "alien welding tool" + desc = "An alien welding tool. Whatever fuel it uses, it never runs out." + icon = 'icons/obj/abductor.dmi' + icon_state = "welder" + toolspeed = 0.1 + light_intensity = 0 + change_icons = 0 + origin_tech = "plasmatech=5;engineering=5;abductor=3" + +/obj/item/weldingtool/abductor/process() + if(get_fuel() <= max_fuel) + reagents.add_reagent("welding_fuel", 1) + ..() + +/obj/item/weldingtool/hugetank + name = "upgraded industrial welding tool" + desc = "An upgraded welder based of the industrial welder." + icon_state = "upindwelder" + item_state = "upindwelder" + max_fuel = 80 + materials = list(MAT_METAL=70, MAT_GLASS=120) + origin_tech = "engineering=3;plasmatech=2" + +/obj/item/weldingtool/experimental + name = "experimental welding tool" + desc = "An experimental welder capable of self-fuel generation and less harmful to the eyes." + icon_state = "exwelder" + item_state = "exwelder" + max_fuel = 40 + materials = list(MAT_METAL=70, MAT_GLASS=120) + origin_tech = "materials=4;engineering=4;bluespace=3;plasmatech=4" + var/last_gen = 0 + change_icons = 0 + can_off_process = 1 + light_intensity = 1 + toolspeed = 0.5 + var/nextrefueltick = 0 + +/obj/item/weldingtool/experimental/brass + name = "brass welding tool" + desc = "A brass welder that seems to constantly refuel itself. It is faintly warm to the touch." + resistance_flags = FIRE_PROOF | ACID_PROOF + icon_state = "brasswelder" + item_state = "brasswelder" + + +/obj/item/weldingtool/experimental/process() + ..() + if(get_fuel() < max_fuel && nextrefueltick < world.time) + nextrefueltick = world.time + 10 + reagents.add_reagent("welding_fuel", 1) + + +/* + * Crowbar + */ + +/obj/item/crowbar + name = "pocket crowbar" + desc = "A small crowbar. This handy tool is useful for lots of things, such as prying floor tiles or opening unpowered doors." + icon = 'icons/obj/tools.dmi' + icon_state = "crowbar" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + usesound = 'sound/items/crowbar.ogg' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + force = 5 + throwforce = 7 + w_class = WEIGHT_CLASS_SMALL + materials = list(MAT_METAL=50) + origin_tech = "engineering=1;combat=1" + attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked") + toolspeed = 1 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) + +/obj/item/crowbar/suicide_act(mob/user) + user.visible_message("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") + playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) + return (BRUTELOSS) + +/obj/item/crowbar/red + icon_state = "crowbar_red" + force = 8 + +/obj/item/crowbar/brass + name = "brass crowbar" + desc = "A brass crowbar. It feels faintly warm to the touch." + resistance_flags = FIRE_PROOF | ACID_PROOF + icon_state = "crowbar_brass" + toolspeed = 0.5 + +/obj/item/crowbar/abductor + name = "alien crowbar" + desc = "A hard-light crowbar. It appears to pry by itself, without any effort required." + icon = 'icons/obj/abductor.dmi' + usesound = 'sound/weapons/sonic_jackhammer.ogg' + icon_state = "crowbar" + toolspeed = 0.1 + origin_tech = "combat=4;engineering=4;abductor=3" + +/obj/item/crowbar/large + name = "crowbar" + desc = "It's a big crowbar. It doesn't fit in your pockets, because it's big." + force = 12 + w_class = WEIGHT_CLASS_NORMAL + throw_speed = 3 + throw_range = 3 + materials = list(MAT_METAL=70) + icon_state = "crowbar_large" + item_state = "crowbar" + toolspeed = 0.5 + +/obj/item/crowbar/cyborg + name = "hydraulic crowbar" + desc = "A hydraulic prying tool, compact but powerful. Designed to replace crowbar in construction cyborgs." + usesound = 'sound/items/jaws_pry.ogg' + force = 10 + toolspeed = 0.5 + +/obj/item/crowbar/power + name = "jaws of life" + desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a prying head." + icon_state = "jaws_pry" + item_state = "jawsoflife" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) + origin_tech = "materials=2;engineering=2" + usesound = 'sound/items/jaws_pry.ogg' + force = 15 + toolspeed = 0.25 + +/obj/item/crowbar/power/suicide_act(mob/user) + user.visible_message("[user] is putting [user.p_their()] head in [src], it looks like [user.p_theyre()] trying to commit suicide!") + playsound(loc, 'sound/items/jaws_pry.ogg', 50, 1, -1) + return (BRUTELOSS) + +/obj/item/crowbar/power/attack_self(mob/user) + playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) + var/obj/item/wirecutters/power/cutjaws = new /obj/item/wirecutters/power + to_chat(user, "You attach the cutting jaws to [src].") + qdel(src) + user.put_in_active_hand(cutjaws) + +#undef WELDER_FUEL_BURN_INTERVAL From 50587ea679a7df29066ac10d4675f9888e3491ee Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 10 Sep 2017 15:18:30 -0500 Subject: [PATCH 239/262] Update tools.dm --- code/game/objects/items/tools.dm | 1579 ------------------------------ 1 file changed, 1579 deletions(-) diff --git a/code/game/objects/items/tools.dm b/code/game/objects/items/tools.dm index 5c901ca4bd..d3f5a12faa 100644 --- a/code/game/objects/items/tools.dm +++ b/code/game/objects/items/tools.dm @@ -1,1580 +1 @@ -#define WELDER_FUEL_BURN_INTERVAL 13 -/* Tools! - * Note: Multitools are /obj/item/device - * - * Contains: - * Wrench - * Screwdriver - * Wirecutters - * Welding Tool - * Crowbar - */ - -/* - * Wrench - */ -/obj/item/wrench - name = "wrench" - desc = "A wrench with common uses. Can be found in your hand." - icon = 'icons/obj/tools.dmi' - icon_state = "wrench" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 5 - throwforce = 7 - w_class = WEIGHT_CLASS_SMALL - usesound = 'sound/items/ratchet.ogg' - materials = list(MAT_METAL=150) - origin_tech = "materials=1;engineering=1" - attack_verb = list("bashed", "battered", "bludgeoned", "whacked") - toolspeed = 1 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) - -/obj/item/wrench/suicide_act(mob/user) - user.visible_message("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) - return (BRUTELOSS) - -/obj/item/wrench/cyborg - name = "automatic wrench" - desc = "An advanced robotic wrench. Can be found in construction cyborgs." - toolspeed = 0.5 - -/obj/item/wrench/brass - name = "brass wrench" - desc = "A brass wrench. It's faintly warm to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "wrench_brass" - toolspeed = 0.5 - -/obj/item/wrench/abductor - name = "alien wrench" - desc = "A polarized wrench. It causes anything placed between the jaws to turn." - icon = 'icons/obj/abductor.dmi' - icon_state = "wrench" - usesound = 'sound/effects/empulse.ogg' - toolspeed = 0.1 - origin_tech = "materials=5;engineering=5;abductor=3" - -/obj/item/wrench/power - name = "hand drill" - desc = "A simple powered hand drill. It's fitted with a bolt bit." - icon_state = "drill_bolt" - item_state = "drill" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - usesound = 'sound/items/drill_use.ogg' - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get - force = 8 //might or might not be too high, subject to change - w_class = WEIGHT_CLASS_SMALL - throwforce = 8 - attack_verb = list("drilled", "screwed", "jabbed") - toolspeed = 0.25 - -/obj/item/wrench/power/attack_self(mob/user) - playsound(get_turf(user),'sound/items/change_drill.ogg',50,1) - var/obj/item/wirecutters/power/s_drill = new /obj/item/screwdriver/power - to_chat(user, "You attach the screw driver bit to [src].") - qdel(src) - user.put_in_active_hand(s_drill) - -/obj/item/wrench/power/suicide_act(mob/user) - user.visible_message("[user] is pressing [src] against [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) - -/obj/item/wrench/medical - name = "medical wrench" - desc = "A medical wrench with common(medical?) uses. Can be found in your hand." - icon_state = "wrench_medical" - force = 2 //MEDICAL - throwforce = 4 - origin_tech = "materials=1;engineering=1;biotech=3" - attack_verb = list("wrenched", "medicaled", "tapped", "jabbed", "whacked") - -/obj/item/wrench/medical/suicide_act(mob/living/user) - user.visible_message("[user] is praying to the medical wrench to take [user.p_their()] soul. It looks like [user.p_theyre()] trying to commit suicide!") - // TODO Make them glow with the power of the M E D I C A L W R E N C H - // during their ascension - - // Stun stops them from wandering off - user.Stun(100, ignore_canstun = TRUE) - playsound(loc, 'sound/effects/pray.ogg', 50, 1, -1) - - // Let the sound effect finish playing - sleep(20) - - if(!user) - return - - for(var/obj/item/W in user) - user.dropItemToGround(W) - - var/obj/item/wrench/medical/W = new /obj/item/wrench/medical(loc) - W.add_fingerprint(user) - W.desc += " For some reason, it reminds you of [user.name]." - - if(!user) - return - - user.dust() - - return OXYLOSS - -/* - * Screwdriver - */ -/obj/item/screwdriver - name = "screwdriver" - desc = "You can be totally screwy with this." - icon = 'icons/obj/tools.dmi' - icon_state = "screwdriver" - item_state = "screwdriver" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 5 - w_class = WEIGHT_CLASS_TINY - throwforce = 5 - throw_speed = 3 - throw_range = 5 - materials = list(MAT_METAL=75) - attack_verb = list("stabbed") - hitsound = 'sound/weapons/bladeslice.ogg' - usesound = 'sound/items/screwdriver.ogg' - toolspeed = 1 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) - var/random_color = TRUE //if the screwdriver uses random coloring - var/static/list/screwdriver_colors = list(\ - "blue" = rgb(24, 97, 213), \ - "red" = rgb(149, 23, 16), \ - "pink" = rgb(213, 24, 141), \ - "brown" = rgb(160, 82, 18), \ - "green" = rgb(14, 127, 27), \ - "cyan" = rgb(24, 162, 213), \ - "yellow" = rgb(213, 140, 24), \ - ) - -/obj/item/screwdriver/suicide_act(mob/user) - user.visible_message("[user] is stabbing [src] into [user.p_their()] [pick("temple", "heart")]! It looks like [user.p_theyre()] trying to commit suicide!") - return(BRUTELOSS) - -/obj/item/screwdriver/Initialize() - . = ..() - if(random_color) //random colors! - var/our_color = pick(screwdriver_colors) - add_atom_colour(screwdriver_colors[our_color], FIXED_COLOUR_PRIORITY) - update_icon() - if(prob(75)) - pixel_y = rand(0, 16) - -/obj/item/screwdriver/update_icon() - if(!random_color) //icon override - return - cut_overlays() - var/mutable_appearance/base_overlay = mutable_appearance(icon, "screwdriver_screwybits") - base_overlay.appearance_flags = RESET_COLOR - add_overlay(base_overlay) - -/obj/item/screwdriver/worn_overlays(isinhands = FALSE, icon_file) - . = list() - if(isinhands && random_color) - var/mutable_appearance/M = mutable_appearance(icon_file, "screwdriver_head") - M.appearance_flags = RESET_COLOR - . += M - -/obj/item/screwdriver/get_belt_overlay() - if(random_color) - var/mutable_appearance/body = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver") - var/mutable_appearance/head = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver_head") - body.color = color - head.overlays += body - return head - else - return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state) - -/obj/item/screwdriver/attack(mob/living/carbon/M, mob/living/carbon/user) - if(!istype(M)) - return ..() - if(user.zone_selected != "eyes" && user.zone_selected != "head") - return ..() - if(user.disabilities & CLUMSY && prob(50)) - M = user - return eyestab(M,user) - -/obj/item/screwdriver/brass - name = "brass screwdriver" - desc = "A screwdriver made of brass. The handle feels freezing cold." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "screwdriver_brass" - item_state = "screwdriver_brass" - toolspeed = 0.5 - random_color = FALSE - -/obj/item/screwdriver/abductor - name = "alien screwdriver" - desc = "An ultrasonic screwdriver." - icon = 'icons/obj/abductor.dmi' - icon_state = "screwdriver_a" - item_state = "screwdriver_nuke" - usesound = 'sound/items/pshoom.ogg' - toolspeed = 0.1 - random_color = FALSE - -/obj/item/screwdriver/power - name = "hand drill" - desc = "A simple powered hand drill. It's fitted with a screw bit." - icon_state = "drill_screw" - item_state = "drill" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get - force = 8 //might or might not be too high, subject to change - w_class = WEIGHT_CLASS_SMALL - throwforce = 8 - throw_speed = 2 - throw_range = 3//it's heavier than a screw driver/wrench, so it does more damage, but can't be thrown as far - attack_verb = list("drilled", "screwed", "jabbed","whacked") - hitsound = 'sound/items/drill_hit.ogg' - usesound = 'sound/items/drill_use.ogg' - toolspeed = 0.25 - random_color = FALSE - -/obj/item/screwdriver/power/suicide_act(mob/user) - user.visible_message("[user] is putting [src] to [user.p_their()] temple. It looks like [user.p_theyre()] trying to commit suicide!") - return(BRUTELOSS) - -/obj/item/screwdriver/power/attack_self(mob/user) - playsound(get_turf(user),'sound/items/change_drill.ogg',50,1) - var/obj/item/wrench/power/b_drill = new /obj/item/wrench/power - to_chat(user, "You attach the bolt driver bit to [src].") - qdel(src) - user.put_in_active_hand(b_drill) - -/obj/item/screwdriver/cyborg - name = "powered screwdriver" - desc = "An electrical screwdriver, designed to be both precise and quick." - usesound = 'sound/items/drill_use.ogg' - toolspeed = 0.5 - -/* - * Wirecutters - */ -/obj/item/wirecutters - name = "wirecutters" - desc = "This cuts wires." - icon = 'icons/obj/tools.dmi' - icon_state = null - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 6 - throw_speed = 3 - throw_range = 7 - w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL=80) - attack_verb = list("pinched", "nipped") - hitsound = 'sound/items/wirecutter.ogg' - usesound = 'sound/items/wirecutter.ogg' - origin_tech = "materials=1;engineering=1" - toolspeed = 1 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) - - -/obj/item/wirecutters/New(loc, var/param_color = null) - ..() - if(!icon_state) - if(!param_color) - param_color = pick("yellow","red") - icon_state = "cutters_[param_color]" - -/obj/item/wirecutters/attack(mob/living/carbon/C, mob/user) - if(istype(C) && C.handcuffed && istype(C.handcuffed, /obj/item/restraints/handcuffs/cable)) - user.visible_message("[user] cuts [C]'s restraints with [src]!") - qdel(C.handcuffed) - C.handcuffed = null - if(C.buckled && C.buckled.buckle_requires_restraints) - C.buckled.unbuckle_mob(C) - C.update_handcuffed() - return - else - ..() - -/obj/item/wirecutters/suicide_act(mob/user) - user.visible_message("[user] is cutting at [user.p_their()] arteries with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, usesound, 50, 1, -1) - return (BRUTELOSS) - -/obj/item/wirecutters/brass - name = "brass wirecutters" - desc = "A pair of wirecutters made of brass. The handle feels freezing cold to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "cutters_brass" - toolspeed = 0.5 - -/obj/item/wirecutters/abductor - name = "alien wirecutters" - desc = "Extremely sharp wirecutters, made out of a silvery-green metal." - icon = 'icons/obj/abductor.dmi' - icon_state = "cutters" - toolspeed = 0.1 - origin_tech = "materials=5;engineering=4;abductor=3" - -/obj/item/wirecutters/cyborg - name = "wirecutters" - desc = "This cuts wires." - toolspeed = 0.5 - -/obj/item/wirecutters/power - name = "jaws of life" - desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a cutting head." - icon_state = "jaws_cutter" - item_state = "jawsoflife" - origin_tech = "materials=2;engineering=2" - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - usesound = 'sound/items/jaws_cut.ogg' - toolspeed = 0.25 - -/obj/item/wirecutters/power/suicide_act(mob/user) - user.visible_message("[user] is wrapping \the [src] around [user.p_their()] neck. It looks like [user.p_theyre()] trying to rip [user.p_their()] head off!") - playsound(loc, 'sound/items/jaws_cut.ogg', 50, 1, -1) - if(iscarbon(user)) - var/mob/living/carbon/C = user - var/obj/item/bodypart/BP = C.get_bodypart("head") - if(BP) - BP.drop_limb() - playsound(loc,pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg') ,50, 1, -1) - return (BRUTELOSS) - -/obj/item/wirecutters/power/attack_self(mob/user) - playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) - var/obj/item/crowbar/power/pryjaws = new /obj/item/crowbar/power - to_chat(user, "You attach the pry jaws to [src].") - qdel(src) - user.put_in_active_hand(pryjaws) -/* - * Welding Tool - */ -/obj/item/weldingtool - name = "welding tool" - desc = "A standard edition welder provided by NanoTrasen." - icon = 'icons/obj/tools.dmi' - icon_state = "welder" - item_state = "welder" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 3 - throwforce = 5 - hitsound = "swing_hit" - usesound = 'sound/items/welder.ogg' - var/acti_sound = 'sound/items/welderactivate.ogg' - var/deac_sound = 'sound/items/welderdeactivate.ogg' - throw_speed = 3 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 30) - resistance_flags = FIRE_PROOF - - materials = list(MAT_METAL=70, MAT_GLASS=30) - origin_tech = "engineering=1;plasmatech=1" - var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) - var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) - var/max_fuel = 20 //The max amount of fuel the welder can hold - var/change_icons = 1 - var/can_off_process = 0 - var/light_intensity = 2 //how powerful the emitted light is when used. - var/burned_fuel_for = 0 //when fuel was last removed - heat = 3800 - toolspeed = 1 - -/obj/item/weldingtool/Initialize() - . = ..() - create_reagents(max_fuel) - reagents.add_reagent("welding_fuel", max_fuel) - update_icon() - - -/obj/item/weldingtool/proc/update_torch() - if(welding) - add_overlay("[initial(icon_state)]-on") - item_state = "[initial(item_state)]1" - else - item_state = "[initial(item_state)]" - - -/obj/item/weldingtool/update_icon() - cut_overlays() - if(change_icons) - var/ratio = get_fuel() / max_fuel - ratio = Ceiling(ratio*4) * 25 - add_overlay("[initial(icon_state)][ratio]") - update_torch() - return - - -/obj/item/weldingtool/process() - switch(welding) - if(0) - force = 3 - damtype = "brute" - update_icon() - if(!can_off_process) - STOP_PROCESSING(SSobj, src) - return - //Welders left on now use up fuel, but lets not have them run out quite that fast - if(1) - force = 15 - damtype = "fire" - ++burned_fuel_for - if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL) - remove_fuel(1) - update_icon() - - //This is to start fires. process() is only called if the welder is on. - open_flame() - - -/obj/item/weldingtool/suicide_act(mob/user) - user.visible_message("[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!") - return (FIRELOSS) - - -/obj/item/weldingtool/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/screwdriver)) - flamethrower_screwdriver(I, user) - else if(istype(I, /obj/item/stack/rods)) - flamethrower_rods(I, user) - else - return ..() - - -/obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) - if(!istype(H)) - return ..() - - var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) - - if(affecting && affecting.status == BODYPART_ROBOTIC && user.a_intent != INTENT_HARM) - if(src.remove_fuel(1)) - playsound(loc, usesound, 50, 1) - if(user == H) - user.visible_message("[user] starts to fix some of the dents on [H]'s [affecting.name].", "You start fixing some of the dents on [H]'s [affecting.name].") - if(!do_mob(user, H, 50)) - return - item_heal_robotic(H, user, 15, 0) - else - return ..() - - -/obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) - if(!proximity) return - - if(welding) - remove_fuel(1) - var/turf/location = get_turf(user) - location.hotspot_expose(700, 50, 1) - if(get_fuel() <= 0) - set_light(0) - - if(isliving(O)) - var/mob/living/L = O - if(L.IgniteMob()) - message_admins("[key_name_admin(user)] set [key_name_admin(L)] on fire") - log_game("[key_name(user)] set [key_name(L)] on fire") - - -/obj/item/weldingtool/attack_self(mob/user) - switched_on(user) - if(welding) - set_light(light_intensity) - - update_icon() - - -//Returns the amount of fuel in the welder -/obj/item/weldingtool/proc/get_fuel() - return reagents.get_reagent_amount("welding_fuel") - - -//Removes fuel from the welding tool. If a mob is passed, it will try to flash the mob's eyes. This should probably be renamed to use() -/obj/item/weldingtool/proc/remove_fuel(amount = 1, mob/living/M = null) - if(!welding || !check_fuel()) - return 0 - if(amount) - burned_fuel_for = 0 - if(get_fuel() >= amount) - reagents.remove_reagent("welding_fuel", amount) - check_fuel() - if(M) - M.flash_act(light_intensity) - return TRUE - else - if(M) - to_chat(M, "You need more welding fuel to complete this task!") - return FALSE - - -//Turns off the welder if there is no more fuel (does this really need to be its own proc?) -/obj/item/weldingtool/proc/check_fuel(mob/user) - if(get_fuel() <= 0 && welding) - switched_on(user) - update_icon() - //mob icon update - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands(0) - - return 0 - return 1 - -//Switches the welder on -/obj/item/weldingtool/proc/switched_on(mob/user) - if(!status) - to_chat(user, "[src] can't be turned on while unsecured!") - return - welding = !welding - if(welding) - if(get_fuel() >= 1) - to_chat(user, "You switch [src] on.") - playsound(loc, acti_sound, 50, 1) - force = 15 - damtype = "fire" - hitsound = 'sound/items/welder.ogg' - update_icon() - START_PROCESSING(SSobj, src) - else - to_chat(user, "You need more fuel!") - switched_off(user) - else - to_chat(user, "You switch [src] off.") - playsound(loc, deac_sound, 50, 1) - switched_off(user) - -//Switches the welder off -/obj/item/weldingtool/proc/switched_off(mob/user) - welding = 0 - set_light(0) - - force = 3 - damtype = "brute" - hitsound = "swing_hit" - update_icon() - - -/obj/item/weldingtool/examine(mob/user) - ..() - to_chat(user, "It contains [get_fuel()] unit\s of fuel out of [max_fuel].") - -/obj/item/weldingtool/is_hot() - return welding * heat - -//Returns whether or not the welding tool is currently on. -/obj/item/weldingtool/proc/isOn() - return welding - - -/obj/item/weldingtool/proc/flamethrower_screwdriver(obj/item/I, mob/user) - if(welding) - to_chat(user, "Turn it off first!") - return - status = !status - if(status) - to_chat(user, "You resecure [src].") - else - to_chat(user, "[src] can now be attached and modified.") - add_fingerprint(user) - -/obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) - if(!status) - var/obj/item/stack/rods/R = I - if (R.use(1)) - var/obj/item/flamethrower/F = new /obj/item/flamethrower(user.loc) - if(!remove_item_from_storage(F)) - user.transferItemToLoc(src, F, TRUE) - F.weldtool = src - add_fingerprint(user) - to_chat(user, "You add a rod to a welder, starting to build a flamethrower.") - user.put_in_hands(F) - else - to_chat(user, "You need one rod to start building a flamethrower!") - -/obj/item/weldingtool/ignition_effect(atom/A, mob/user) - if(welding && remove_fuel(1, user)) - . = "[user] casually lights [A] with [src], what a badass." - else - . = "" - -/obj/item/weldingtool/largetank - name = "industrial welding tool" - desc = "A slightly larger welder with a larger tank." - icon_state = "indwelder" - max_fuel = 40 - materials = list(MAT_GLASS=60) - origin_tech = "engineering=2;plasmatech=2" - -/obj/item/weldingtool/largetank/cyborg - name = "integrated welding tool" - desc = "An advanced welder designed to be used in robotic systems." - toolspeed = 0.5 - -/obj/item/weldingtool/largetank/flamethrower_screwdriver() - return - - -/obj/item/weldingtool/mini - name = "emergency welding tool" - desc = "A miniature welder used during emergencies." - icon_state = "miniwelder" - max_fuel = 10 - w_class = WEIGHT_CLASS_TINY - materials = list(MAT_METAL=30, MAT_GLASS=10) - change_icons = 0 - -/obj/item/weldingtool/mini/flamethrower_screwdriver() - return - -/obj/item/weldingtool/abductor - name = "alien welding tool" - desc = "An alien welding tool. Whatever fuel it uses, it never runs out." - icon = 'icons/obj/abductor.dmi' - icon_state = "welder" - toolspeed = 0.1 - light_intensity = 0 - change_icons = 0 - origin_tech = "plasmatech=5;engineering=5;abductor=3" - -/obj/item/weldingtool/abductor/process() - if(get_fuel() <= max_fuel) - reagents.add_reagent("welding_fuel", 1) - ..() - -/obj/item/weldingtool/hugetank - name = "upgraded industrial welding tool" - desc = "An upgraded welder based of the industrial welder." - icon_state = "upindwelder" - item_state = "upindwelder" - max_fuel = 80 - materials = list(MAT_METAL=70, MAT_GLASS=120) - origin_tech = "engineering=3;plasmatech=2" - -/obj/item/weldingtool/experimental - name = "experimental welding tool" - desc = "An experimental welder capable of self-fuel generation and less harmful to the eyes." - icon_state = "exwelder" - item_state = "exwelder" - max_fuel = 40 - materials = list(MAT_METAL=70, MAT_GLASS=120) - origin_tech = "materials=4;engineering=4;bluespace=3;plasmatech=4" - var/last_gen = 0 - change_icons = 0 - can_off_process = 1 - light_intensity = 1 - toolspeed = 0.5 - var/nextrefueltick = 0 - -/obj/item/weldingtool/experimental/brass - name = "brass welding tool" - desc = "A brass welder that seems to constantly refuel itself. It is faintly warm to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "brasswelder" - item_state = "brasswelder" - - -/obj/item/weldingtool/experimental/process() - ..() - if(get_fuel() < max_fuel && nextrefueltick < world.time) - nextrefueltick = world.time + 10 - reagents.add_reagent("welding_fuel", 1) - - -/* - * Crowbar - */ - -/obj/item/crowbar - name = "pocket crowbar" - desc = "A small crowbar. This handy tool is useful for lots of things, such as prying floor tiles or opening unpowered doors." - icon = 'icons/obj/tools.dmi' - icon_state = "crowbar" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - usesound = 'sound/items/crowbar.ogg' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 5 - throwforce = 7 - w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL=50) - origin_tech = "engineering=1;combat=1" - attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked") - toolspeed = 1 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) - -/obj/item/crowbar/suicide_act(mob/user) - user.visible_message("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) - return (BRUTELOSS) - -/obj/item/crowbar/red - icon_state = "crowbar_red" - force = 8 - -/obj/item/crowbar/brass - name = "brass crowbar" - desc = "A brass crowbar. It feels faintly warm to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "crowbar_brass" - toolspeed = 0.5 - -/obj/item/crowbar/abductor - name = "alien crowbar" - desc = "A hard-light crowbar. It appears to pry by itself, without any effort required." - icon = 'icons/obj/abductor.dmi' - usesound = 'sound/weapons/sonic_jackhammer.ogg' - icon_state = "crowbar" - toolspeed = 0.1 - origin_tech = "combat=4;engineering=4;abductor=3" - -/obj/item/crowbar/large - name = "crowbar" - desc = "It's a big crowbar. It doesn't fit in your pockets, because it's big." - force = 12 - w_class = WEIGHT_CLASS_NORMAL - throw_speed = 3 - throw_range = 3 - materials = list(MAT_METAL=70) - icon_state = "crowbar_large" - item_state = "crowbar" - toolspeed = 0.5 - -/obj/item/crowbar/cyborg - name = "hydraulic crowbar" - desc = "A hydraulic prying tool, compact but powerful. Designed to replace crowbar in construction cyborgs." - usesound = 'sound/items/jaws_pry.ogg' - force = 10 - toolspeed = 0.5 - -/obj/item/crowbar/power - name = "jaws of life" - desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a prying head." - icon_state = "jaws_pry" - item_state = "jawsoflife" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" - usesound = 'sound/items/jaws_pry.ogg' - force = 15 - toolspeed = 0.25 - -/obj/item/crowbar/power/suicide_act(mob/user) - user.visible_message("[user] is putting [user.p_their()] head in [src], it looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/items/jaws_pry.ogg', 50, 1, -1) - return (BRUTELOSS) - -/obj/item/crowbar/power/attack_self(mob/user) - playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) - var/obj/item/wirecutters/power/cutjaws = new /obj/item/wirecutters/power - to_chat(user, "You attach the cutting jaws to [src].") - qdel(src) - user.put_in_active_hand(cutjaws) - -#undef WELDER_FUEL_BURN_INTERVAL -#define WELDER_FUEL_BURN_INTERVAL 13 - -/* Tools! - * Note: Multitools are /obj/item/device - * - * Contains: - * Wrench - * Screwdriver - * Wirecutters - * Welding Tool - * Crowbar - */ - -/* - * Wrench - */ -/obj/item/wrench - name = "wrench" - desc = "A wrench with common uses. Can be found in your hand." - icon = 'icons/obj/tools.dmi' - icon_state = "wrench" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 5 - throwforce = 7 - w_class = WEIGHT_CLASS_SMALL - usesound = 'sound/items/ratchet.ogg' - materials = list(MAT_METAL=150) - origin_tech = "materials=1;engineering=1" - attack_verb = list("bashed", "battered", "bludgeoned", "whacked") - toolspeed = 1 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) - -/obj/item/wrench/suicide_act(mob/user) - user.visible_message("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) - return (BRUTELOSS) - -/obj/item/wrench/cyborg - name = "automatic wrench" - desc = "An advanced robotic wrench. Can be found in construction cyborgs." - toolspeed = 0.5 - -/obj/item/wrench/brass - name = "brass wrench" - desc = "A brass wrench. It's faintly warm to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "wrench_brass" - toolspeed = 0.5 - -/obj/item/wrench/abductor - name = "alien wrench" - desc = "A polarized wrench. It causes anything placed between the jaws to turn." - icon = 'icons/obj/abductor.dmi' - icon_state = "wrench" - usesound = 'sound/effects/empulse.ogg' - toolspeed = 0.1 - origin_tech = "materials=5;engineering=5;abductor=3" - -/obj/item/wrench/power - name = "hand drill" - desc = "A simple powered hand drill. It's fitted with a bolt bit." - icon_state = "drill_bolt" - item_state = "drill" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - usesound = 'sound/items/drill_use.ogg' - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get - force = 8 //might or might not be too high, subject to change - w_class = WEIGHT_CLASS_SMALL - throwforce = 8 - attack_verb = list("drilled", "screwed", "jabbed") - toolspeed = 0.25 - -/obj/item/wrench/power/attack_self(mob/user) - playsound(get_turf(user),'sound/items/change_drill.ogg',50,1) - var/obj/item/wirecutters/power/s_drill = new /obj/item/screwdriver/power - to_chat(user, "You attach the screw driver bit to [src].") - qdel(src) - user.put_in_active_hand(s_drill) - -/obj/item/wrench/power/suicide_act(mob/user) - user.visible_message("[user] is pressing [src] against [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) - -/obj/item/wrench/medical - name = "medical wrench" - desc = "A medical wrench with common(medical?) uses. Can be found in your hand." - icon_state = "wrench_medical" - force = 2 //MEDICAL - throwforce = 4 - origin_tech = "materials=1;engineering=1;biotech=3" - attack_verb = list("wrenched", "medicaled", "tapped", "jabbed", "whacked") - -/obj/item/wrench/medical/suicide_act(mob/living/user) - user.visible_message("[user] is praying to the medical wrench to take [user.p_their()] soul. It looks like [user.p_theyre()] trying to commit suicide!") - // TODO Make them glow with the power of the M E D I C A L W R E N C H - // during their ascension - - // Stun stops them from wandering off - user.Stun(100, ignore_canstun = TRUE) - playsound(loc, 'sound/effects/pray.ogg', 50, 1, -1) - - // Let the sound effect finish playing - sleep(20) - - if(!user) - return - - for(var/obj/item/W in user) - user.dropItemToGround(W) - - var/obj/item/wrench/medical/W = new /obj/item/wrench/medical(loc) - W.add_fingerprint(user) - W.desc += " For some reason, it reminds you of [user.name]." - - if(!user) - return - - user.dust() - - return OXYLOSS - -/* - * Screwdriver - */ -/obj/item/screwdriver - name = "screwdriver" - desc = "You can be totally screwy with this." - icon = 'icons/obj/tools.dmi' - icon_state = "screwdriver" - item_state = "screwdriver" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 5 - w_class = WEIGHT_CLASS_TINY - throwforce = 5 - throw_speed = 3 - throw_range = 5 - materials = list(MAT_METAL=75) - attack_verb = list("stabbed") - hitsound = 'sound/weapons/bladeslice.ogg' - usesound = 'sound/items/screwdriver.ogg' - toolspeed = 1 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) - var/random_color = TRUE //if the screwdriver uses random coloring - var/static/list/screwdriver_colors = list(\ - "blue" = rgb(24, 97, 213), \ - "red" = rgb(149, 23, 16), \ - "pink" = rgb(213, 24, 141), \ - "brown" = rgb(160, 82, 18), \ - "green" = rgb(14, 127, 27), \ - "cyan" = rgb(24, 162, 213), \ - "yellow" = rgb(213, 140, 24), \ - ) - -/obj/item/screwdriver/suicide_act(mob/user) - user.visible_message("[user] is stabbing [src] into [user.p_their()] [pick("temple", "heart")]! It looks like [user.p_theyre()] trying to commit suicide!") - return(BRUTELOSS) - -/obj/item/screwdriver/Initialize() - . = ..() - if(random_color) //random colors! - var/our_color = pick(screwdriver_colors) - add_atom_colour(screwdriver_colors[our_color], FIXED_COLOUR_PRIORITY) - update_icon() - if(prob(75)) - pixel_y = rand(0, 16) - -/obj/item/screwdriver/update_icon() - if(!random_color) //icon override - return - cut_overlays() - var/mutable_appearance/base_overlay = mutable_appearance(icon, "screwdriver_screwybits") - base_overlay.appearance_flags = RESET_COLOR - add_overlay(base_overlay) - -/obj/item/screwdriver/worn_overlays(isinhands = FALSE, icon_file) - . = list() - if(isinhands && random_color) - var/mutable_appearance/M = mutable_appearance(icon_file, "screwdriver_head") - M.appearance_flags = RESET_COLOR - . += M - -/obj/item/screwdriver/get_belt_overlay() - if(random_color) - var/mutable_appearance/body = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver") - var/mutable_appearance/head = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver_head") - body.color = color - head.add_overlay(body) - return head - else - return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state) - -/obj/item/screwdriver/attack(mob/living/carbon/M, mob/living/carbon/user) - if(!istype(M)) - return ..() - if(user.zone_selected != "eyes" && user.zone_selected != "head") - return ..() - if(user.disabilities & CLUMSY && prob(50)) - M = user - return eyestab(M,user) - -/obj/item/screwdriver/brass - name = "brass screwdriver" - desc = "A screwdriver made of brass. The handle feels freezing cold." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "screwdriver_brass" - item_state = "screwdriver_brass" - toolspeed = 0.5 - random_color = FALSE - -/obj/item/screwdriver/abductor - name = "alien screwdriver" - desc = "An ultrasonic screwdriver." - icon = 'icons/obj/abductor.dmi' - icon_state = "screwdriver_a" - item_state = "screwdriver_nuke" - usesound = 'sound/items/pshoom.ogg' - toolspeed = 0.1 - random_color = FALSE - -/obj/item/screwdriver/power - name = "hand drill" - desc = "A simple powered hand drill. It's fitted with a screw bit." - icon_state = "drill_screw" - item_state = "drill" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get - force = 8 //might or might not be too high, subject to change - w_class = WEIGHT_CLASS_SMALL - throwforce = 8 - throw_speed = 2 - throw_range = 3//it's heavier than a screw driver/wrench, so it does more damage, but can't be thrown as far - attack_verb = list("drilled", "screwed", "jabbed","whacked") - hitsound = 'sound/items/drill_hit.ogg' - usesound = 'sound/items/drill_use.ogg' - toolspeed = 0.25 - random_color = FALSE - -/obj/item/screwdriver/power/suicide_act(mob/user) - user.visible_message("[user] is putting [src] to [user.p_their()] temple. It looks like [user.p_theyre()] trying to commit suicide!") - return(BRUTELOSS) - -/obj/item/screwdriver/power/attack_self(mob/user) - playsound(get_turf(user),'sound/items/change_drill.ogg',50,1) - var/obj/item/wrench/power/b_drill = new /obj/item/wrench/power - to_chat(user, "You attach the bolt driver bit to [src].") - qdel(src) - user.put_in_active_hand(b_drill) - -/obj/item/screwdriver/cyborg - name = "powered screwdriver" - desc = "An electrical screwdriver, designed to be both precise and quick." - usesound = 'sound/items/drill_use.ogg' - toolspeed = 0.5 - -/* - * Wirecutters - */ -/obj/item/wirecutters - name = "wirecutters" - desc = "This cuts wires." - icon = 'icons/obj/tools.dmi' - icon_state = null - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 6 - throw_speed = 3 - throw_range = 7 - w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL=80) - attack_verb = list("pinched", "nipped") - hitsound = 'sound/items/wirecutter.ogg' - usesound = 'sound/items/wirecutter.ogg' - origin_tech = "materials=1;engineering=1" - toolspeed = 1 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) - - -/obj/item/wirecutters/New(loc, var/param_color = null) - ..() - if(!icon_state) - if(!param_color) - param_color = pick("yellow","red") - icon_state = "cutters_[param_color]" - -/obj/item/wirecutters/attack(mob/living/carbon/C, mob/user) - if(istype(C) && C.handcuffed && istype(C.handcuffed, /obj/item/restraints/handcuffs/cable)) - user.visible_message("[user] cuts [C]'s restraints with [src]!") - qdel(C.handcuffed) - C.handcuffed = null - if(C.buckled && C.buckled.buckle_requires_restraints) - C.buckled.unbuckle_mob(C) - C.update_handcuffed() - return - else - ..() - -/obj/item/wirecutters/suicide_act(mob/user) - user.visible_message("[user] is cutting at [user.p_their()] arteries with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, usesound, 50, 1, -1) - return (BRUTELOSS) - -/obj/item/wirecutters/brass - name = "brass wirecutters" - desc = "A pair of wirecutters made of brass. The handle feels freezing cold to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "cutters_brass" - toolspeed = 0.5 - -/obj/item/wirecutters/abductor - name = "alien wirecutters" - desc = "Extremely sharp wirecutters, made out of a silvery-green metal." - icon = 'icons/obj/abductor.dmi' - icon_state = "cutters" - toolspeed = 0.1 - origin_tech = "materials=5;engineering=4;abductor=3" - -/obj/item/wirecutters/cyborg - name = "wirecutters" - desc = "This cuts wires." - toolspeed = 0.5 - -/obj/item/wirecutters/power - name = "jaws of life" - desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a cutting head." - icon_state = "jaws_cutter" - item_state = "jawsoflife" - origin_tech = "materials=2;engineering=2" - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - usesound = 'sound/items/jaws_cut.ogg' - toolspeed = 0.25 - -/obj/item/wirecutters/power/suicide_act(mob/user) - user.visible_message("[user] is wrapping \the [src] around [user.p_their()] neck. It looks like [user.p_theyre()] trying to rip [user.p_their()] head off!") - playsound(loc, 'sound/items/jaws_cut.ogg', 50, 1, -1) - if(iscarbon(user)) - var/mob/living/carbon/C = user - var/obj/item/bodypart/BP = C.get_bodypart("head") - if(BP) - BP.drop_limb() - playsound(loc,pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg') ,50, 1, -1) - return (BRUTELOSS) - -/obj/item/wirecutters/power/attack_self(mob/user) - playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) - var/obj/item/crowbar/power/pryjaws = new /obj/item/crowbar/power - to_chat(user, "You attach the pry jaws to [src].") - qdel(src) - user.put_in_active_hand(pryjaws) -/* - * Welding Tool - */ -/obj/item/weldingtool - name = "welding tool" - desc = "A standard edition welder provided by Nanotrasen." - icon = 'icons/obj/tools.dmi' - icon_state = "welder" - item_state = "welder" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 3 - throwforce = 5 - hitsound = "swing_hit" - usesound = 'sound/items/welder.ogg' - var/acti_sound = 'sound/items/welderactivate.ogg' - var/deac_sound = 'sound/items/welderdeactivate.ogg' - throw_speed = 3 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 30) - resistance_flags = FIRE_PROOF - - materials = list(MAT_METAL=70, MAT_GLASS=30) - origin_tech = "engineering=1;plasmatech=1" - var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) - var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) - var/max_fuel = 20 //The max amount of fuel the welder can hold - var/change_icons = 1 - var/can_off_process = 0 - var/light_intensity = 2 //how powerful the emitted light is when used. - var/burned_fuel_for = 0 //when fuel was last removed - heat = 3800 - toolspeed = 1 - -/obj/item/weldingtool/Initialize() - . = ..() - create_reagents(max_fuel) - reagents.add_reagent("welding_fuel", max_fuel) - update_icon() - - -/obj/item/weldingtool/proc/update_torch() - if(welding) - add_overlay("[initial(icon_state)]-on") - item_state = "[initial(item_state)]1" - else - item_state = "[initial(item_state)]" - - -/obj/item/weldingtool/update_icon() - cut_overlays() - if(change_icons) - var/ratio = get_fuel() / max_fuel - ratio = Ceiling(ratio*4) * 25 - add_overlay("[initial(icon_state)][ratio]") - update_torch() - return - - -/obj/item/weldingtool/process() - switch(welding) - if(0) - force = 3 - damtype = "brute" - update_icon() - if(!can_off_process) - STOP_PROCESSING(SSobj, src) - return - //Welders left on now use up fuel, but lets not have them run out quite that fast - if(1) - force = 15 - damtype = "fire" - ++burned_fuel_for - if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL) - remove_fuel(1) - update_icon() - - //This is to start fires. process() is only called if the welder is on. - open_flame() - - -/obj/item/weldingtool/suicide_act(mob/user) - user.visible_message("[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!") - return (FIRELOSS) - - -/obj/item/weldingtool/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/screwdriver)) - flamethrower_screwdriver(I, user) - else if(istype(I, /obj/item/stack/rods)) - flamethrower_rods(I, user) - else - return ..() - - -/obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) - if(!istype(H)) - return ..() - - var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) - - if(affecting && affecting.status == BODYPART_ROBOTIC && user.a_intent != INTENT_HARM) - if(src.remove_fuel(1)) - playsound(loc, usesound, 50, 1) - if(user == H) - user.visible_message("[user] starts to fix some of the dents on [H]'s [affecting.name].", "You start fixing some of the dents on [H]'s [affecting.name].") - if(!do_mob(user, H, 50)) - return - item_heal_robotic(H, user, 15, 0) - else - return ..() - - -/obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) - if(!proximity) return - - if(welding) - remove_fuel(1) - var/turf/location = get_turf(user) - location.hotspot_expose(700, 50, 1) - if(get_fuel() <= 0) - set_light(0) - - if(isliving(O)) - var/mob/living/L = O - if(L.IgniteMob()) - message_admins("[key_name_admin(user)] set [key_name_admin(L)] on fire") - log_game("[key_name(user)] set [key_name(L)] on fire") - - -/obj/item/weldingtool/attack_self(mob/user) - switched_on(user) - if(welding) - set_light(light_intensity) - - update_icon() - - -//Returns the amount of fuel in the welder -/obj/item/weldingtool/proc/get_fuel() - return reagents.get_reagent_amount("welding_fuel") - - -//Removes fuel from the welding tool. If a mob is passed, it will try to flash the mob's eyes. This should probably be renamed to use() -/obj/item/weldingtool/proc/remove_fuel(amount = 1, mob/living/M = null) - if(!welding || !check_fuel()) - return 0 - if(amount) - burned_fuel_for = 0 - if(get_fuel() >= amount) - reagents.remove_reagent("welding_fuel", amount) - check_fuel() - if(M) - M.flash_act(light_intensity) - return TRUE - else - if(M) - to_chat(M, "You need more welding fuel to complete this task!") - return FALSE - - -//Turns off the welder if there is no more fuel (does this really need to be its own proc?) -/obj/item/weldingtool/proc/check_fuel(mob/user) - if(get_fuel() <= 0 && welding) - switched_on(user) - update_icon() - //mob icon update - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands(0) - - return 0 - return 1 - -//Switches the welder on -/obj/item/weldingtool/proc/switched_on(mob/user) - if(!status) - to_chat(user, "[src] can't be turned on while unsecured!") - return - welding = !welding - if(welding) - if(get_fuel() >= 1) - to_chat(user, "You switch [src] on.") - playsound(loc, acti_sound, 50, 1) - force = 15 - damtype = "fire" - hitsound = 'sound/items/welder.ogg' - update_icon() - START_PROCESSING(SSobj, src) - else - to_chat(user, "You need more fuel!") - switched_off(user) - else - to_chat(user, "You switch [src] off.") - playsound(loc, deac_sound, 50, 1) - switched_off(user) - -//Switches the welder off -/obj/item/weldingtool/proc/switched_off(mob/user) - welding = 0 - set_light(0) - - force = 3 - damtype = "brute" - hitsound = "swing_hit" - update_icon() - - -/obj/item/weldingtool/examine(mob/user) - ..() - to_chat(user, "It contains [get_fuel()] unit\s of fuel out of [max_fuel].") - -/obj/item/weldingtool/is_hot() - return welding * heat - -//Returns whether or not the welding tool is currently on. -/obj/item/weldingtool/proc/isOn() - return welding - - -/obj/item/weldingtool/proc/flamethrower_screwdriver(obj/item/I, mob/user) - if(welding) - to_chat(user, "Turn it off first!") - return - status = !status - if(status) - to_chat(user, "You resecure [src].") - else - to_chat(user, "[src] can now be attached and modified.") - add_fingerprint(user) - -/obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) - if(!status) - var/obj/item/stack/rods/R = I - if (R.use(1)) - var/obj/item/flamethrower/F = new /obj/item/flamethrower(user.loc) - if(!remove_item_from_storage(F)) - user.transferItemToLoc(src, F, TRUE) - F.weldtool = src - add_fingerprint(user) - to_chat(user, "You add a rod to a welder, starting to build a flamethrower.") - user.put_in_hands(F) - else - to_chat(user, "You need one rod to start building a flamethrower!") - -/obj/item/weldingtool/ignition_effect(atom/A, mob/user) - if(welding && remove_fuel(1, user)) - . = "[user] casually lights [A] with [src], what a badass." - else - . = "" - -/obj/item/weldingtool/largetank - name = "industrial welding tool" - desc = "A slightly larger welder with a larger tank." - icon_state = "indwelder" - max_fuel = 40 - materials = list(MAT_GLASS=60) - origin_tech = "engineering=2;plasmatech=2" - -/obj/item/weldingtool/largetank/cyborg - name = "integrated welding tool" - desc = "An advanced welder designed to be used in robotic systems." - toolspeed = 0.5 - -/obj/item/weldingtool/largetank/flamethrower_screwdriver() - return - - -/obj/item/weldingtool/mini - name = "emergency welding tool" - desc = "A miniature welder used during emergencies." - icon_state = "miniwelder" - max_fuel = 10 - w_class = WEIGHT_CLASS_TINY - materials = list(MAT_METAL=30, MAT_GLASS=10) - change_icons = 0 - -/obj/item/weldingtool/mini/flamethrower_screwdriver() - return - -/obj/item/weldingtool/abductor - name = "alien welding tool" - desc = "An alien welding tool. Whatever fuel it uses, it never runs out." - icon = 'icons/obj/abductor.dmi' - icon_state = "welder" - toolspeed = 0.1 - light_intensity = 0 - change_icons = 0 - origin_tech = "plasmatech=5;engineering=5;abductor=3" - -/obj/item/weldingtool/abductor/process() - if(get_fuel() <= max_fuel) - reagents.add_reagent("welding_fuel", 1) - ..() - -/obj/item/weldingtool/hugetank - name = "upgraded industrial welding tool" - desc = "An upgraded welder based of the industrial welder." - icon_state = "upindwelder" - item_state = "upindwelder" - max_fuel = 80 - materials = list(MAT_METAL=70, MAT_GLASS=120) - origin_tech = "engineering=3;plasmatech=2" - -/obj/item/weldingtool/experimental - name = "experimental welding tool" - desc = "An experimental welder capable of self-fuel generation and less harmful to the eyes." - icon_state = "exwelder" - item_state = "exwelder" - max_fuel = 40 - materials = list(MAT_METAL=70, MAT_GLASS=120) - origin_tech = "materials=4;engineering=4;bluespace=3;plasmatech=4" - var/last_gen = 0 - change_icons = 0 - can_off_process = 1 - light_intensity = 1 - toolspeed = 0.5 - var/nextrefueltick = 0 - -/obj/item/weldingtool/experimental/brass - name = "brass welding tool" - desc = "A brass welder that seems to constantly refuel itself. It is faintly warm to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "brasswelder" - item_state = "brasswelder" - - -/obj/item/weldingtool/experimental/process() - ..() - if(get_fuel() < max_fuel && nextrefueltick < world.time) - nextrefueltick = world.time + 10 - reagents.add_reagent("welding_fuel", 1) - - -/* - * Crowbar - */ - -/obj/item/crowbar - name = "pocket crowbar" - desc = "A small crowbar. This handy tool is useful for lots of things, such as prying floor tiles or opening unpowered doors." - icon = 'icons/obj/tools.dmi' - icon_state = "crowbar" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - usesound = 'sound/items/crowbar.ogg' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 5 - throwforce = 7 - w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL=50) - origin_tech = "engineering=1;combat=1" - attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked") - toolspeed = 1 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) - -/obj/item/crowbar/suicide_act(mob/user) - user.visible_message("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) - return (BRUTELOSS) - -/obj/item/crowbar/red - icon_state = "crowbar_red" - force = 8 - -/obj/item/crowbar/brass - name = "brass crowbar" - desc = "A brass crowbar. It feels faintly warm to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "crowbar_brass" - toolspeed = 0.5 - -/obj/item/crowbar/abductor - name = "alien crowbar" - desc = "A hard-light crowbar. It appears to pry by itself, without any effort required." - icon = 'icons/obj/abductor.dmi' - usesound = 'sound/weapons/sonic_jackhammer.ogg' - icon_state = "crowbar" - toolspeed = 0.1 - origin_tech = "combat=4;engineering=4;abductor=3" - -/obj/item/crowbar/large - name = "crowbar" - desc = "It's a big crowbar. It doesn't fit in your pockets, because it's big." - force = 12 - w_class = WEIGHT_CLASS_NORMAL - throw_speed = 3 - throw_range = 3 - materials = list(MAT_METAL=70) - icon_state = "crowbar_large" - item_state = "crowbar" - toolspeed = 0.5 - -/obj/item/crowbar/cyborg - name = "hydraulic crowbar" - desc = "A hydraulic prying tool, compact but powerful. Designed to replace crowbar in construction cyborgs." - usesound = 'sound/items/jaws_pry.ogg' - force = 10 - toolspeed = 0.5 - -/obj/item/crowbar/power - name = "jaws of life" - desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a prying head." - icon_state = "jaws_pry" - item_state = "jawsoflife" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" - usesound = 'sound/items/jaws_pry.ogg' - force = 15 - toolspeed = 0.25 - -/obj/item/crowbar/power/suicide_act(mob/user) - user.visible_message("[user] is putting [user.p_their()] head in [src], it looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/items/jaws_pry.ogg', 50, 1, -1) - return (BRUTELOSS) - -/obj/item/crowbar/power/attack_self(mob/user) - playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) - var/obj/item/wirecutters/power/cutjaws = new /obj/item/wirecutters/power - to_chat(user, "You attach the cutting jaws to [src].") - qdel(src) - user.put_in_active_hand(cutjaws) - -#undef WELDER_FUEL_BURN_INTERVAL From e5aed03bcb29a0865808e1b0e8777de585e17058 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Sun, 10 Sep 2017 15:20:58 -0500 Subject: [PATCH 240/262] all of my HATE --- code/game/objects/items/tools.dm | 789 +++++++++++++++++++++++++++++++ 1 file changed, 789 insertions(+) diff --git a/code/game/objects/items/tools.dm b/code/game/objects/items/tools.dm index d3f5a12faa..8bfc90decb 100644 --- a/code/game/objects/items/tools.dm +++ b/code/game/objects/items/tools.dm @@ -1 +1,790 @@ +#define WELDER_FUEL_BURN_INTERVAL 13 +/* Tools! + * Note: Multitools are /obj/item/device + * + * Contains: + * Wrench + * Screwdriver + * Wirecutters + * Welding Tool + * Crowbar + */ + +/* + * Wrench + */ +/obj/item/wrench + name = "wrench" + desc = "A wrench with common uses. Can be found in your hand." + icon = 'icons/obj/tools.dmi' + icon_state = "wrench" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + force = 5 + throwforce = 7 + w_class = WEIGHT_CLASS_SMALL + usesound = 'sound/items/ratchet.ogg' + materials = list(MAT_METAL=150) + origin_tech = "materials=1;engineering=1" + attack_verb = list("bashed", "battered", "bludgeoned", "whacked") + toolspeed = 1 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) + +/obj/item/wrench/suicide_act(mob/user) + user.visible_message("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") + playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) + return (BRUTELOSS) + +/obj/item/wrench/cyborg + name = "automatic wrench" + desc = "An advanced robotic wrench. Can be found in construction cyborgs." + toolspeed = 0.5 + +/obj/item/wrench/brass + name = "brass wrench" + desc = "A brass wrench. It's faintly warm to the touch." + resistance_flags = FIRE_PROOF | ACID_PROOF + icon_state = "wrench_brass" + toolspeed = 0.5 + +/obj/item/wrench/abductor + name = "alien wrench" + desc = "A polarized wrench. It causes anything placed between the jaws to turn." + icon = 'icons/obj/abductor.dmi' + icon_state = "wrench" + usesound = 'sound/effects/empulse.ogg' + toolspeed = 0.1 + origin_tech = "materials=5;engineering=5;abductor=3" + +/obj/item/wrench/power + name = "hand drill" + desc = "A simple powered hand drill. It's fitted with a bolt bit." + icon_state = "drill_bolt" + item_state = "drill" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + usesound = 'sound/items/drill_use.ogg' + materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) + origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get + force = 8 //might or might not be too high, subject to change + w_class = WEIGHT_CLASS_SMALL + throwforce = 8 + attack_verb = list("drilled", "screwed", "jabbed") + toolspeed = 0.25 + +/obj/item/wrench/power/attack_self(mob/user) + playsound(get_turf(user),'sound/items/change_drill.ogg',50,1) + var/obj/item/wirecutters/power/s_drill = new /obj/item/screwdriver/power + to_chat(user, "You attach the screw driver bit to [src].") + qdel(src) + user.put_in_active_hand(s_drill) + +/obj/item/wrench/power/suicide_act(mob/user) + user.visible_message("[user] is pressing [src] against [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide!") + return (BRUTELOSS) + +/obj/item/wrench/medical + name = "medical wrench" + desc = "A medical wrench with common(medical?) uses. Can be found in your hand." + icon_state = "wrench_medical" + force = 2 //MEDICAL + throwforce = 4 + origin_tech = "materials=1;engineering=1;biotech=3" + attack_verb = list("wrenched", "medicaled", "tapped", "jabbed", "whacked") + +/obj/item/wrench/medical/suicide_act(mob/living/user) + user.visible_message("[user] is praying to the medical wrench to take [user.p_their()] soul. It looks like [user.p_theyre()] trying to commit suicide!") + // TODO Make them glow with the power of the M E D I C A L W R E N C H + // during their ascension + + // Stun stops them from wandering off + user.Stun(100, ignore_canstun = TRUE) + playsound(loc, 'sound/effects/pray.ogg', 50, 1, -1) + + // Let the sound effect finish playing + sleep(20) + + if(!user) + return + + for(var/obj/item/W in user) + user.dropItemToGround(W) + + var/obj/item/wrench/medical/W = new /obj/item/wrench/medical(loc) + W.add_fingerprint(user) + W.desc += " For some reason, it reminds you of [user.name]." + + if(!user) + return + + user.dust() + + return OXYLOSS + +/* + * Screwdriver + */ +/obj/item/screwdriver + name = "screwdriver" + desc = "You can be totally screwy with this." + icon = 'icons/obj/tools.dmi' + icon_state = "screwdriver" + item_state = "screwdriver" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + force = 5 + w_class = WEIGHT_CLASS_TINY + throwforce = 5 + throw_speed = 3 + throw_range = 5 + materials = list(MAT_METAL=75) + attack_verb = list("stabbed") + hitsound = 'sound/weapons/bladeslice.ogg' + usesound = 'sound/items/screwdriver.ogg' + toolspeed = 1 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) + var/random_color = TRUE //if the screwdriver uses random coloring + var/static/list/screwdriver_colors = list(\ + "blue" = rgb(24, 97, 213), \ + "red" = rgb(149, 23, 16), \ + "pink" = rgb(213, 24, 141), \ + "brown" = rgb(160, 82, 18), \ + "green" = rgb(14, 127, 27), \ + "cyan" = rgb(24, 162, 213), \ + "yellow" = rgb(213, 140, 24), \ + ) + +/obj/item/screwdriver/suicide_act(mob/user) + user.visible_message("[user] is stabbing [src] into [user.p_their()] [pick("temple", "heart")]! It looks like [user.p_theyre()] trying to commit suicide!") + return(BRUTELOSS) + +/obj/item/screwdriver/Initialize() + . = ..() + if(random_color) //random colors! + var/our_color = pick(screwdriver_colors) + add_atom_colour(screwdriver_colors[our_color], FIXED_COLOUR_PRIORITY) + update_icon() + if(prob(75)) + pixel_y = rand(0, 16) + +/obj/item/screwdriver/update_icon() + if(!random_color) //icon override + return + cut_overlays() + var/mutable_appearance/base_overlay = mutable_appearance(icon, "screwdriver_screwybits") + base_overlay.appearance_flags = RESET_COLOR + add_overlay(base_overlay) + +/obj/item/screwdriver/worn_overlays(isinhands = FALSE, icon_file) + . = list() + if(isinhands && random_color) + var/mutable_appearance/M = mutable_appearance(icon_file, "screwdriver_head") + M.appearance_flags = RESET_COLOR + . += M + +/obj/item/screwdriver/get_belt_overlay() + if(random_color) + var/mutable_appearance/body = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver") + var/mutable_appearance/head = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver_head") + body.color = color + head.add_overlay(body) + return head + else + return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state) + +/obj/item/screwdriver/attack(mob/living/carbon/M, mob/living/carbon/user) + if(!istype(M)) + return ..() + if(user.zone_selected != "eyes" && user.zone_selected != "head") + return ..() + if(user.disabilities & CLUMSY && prob(50)) + M = user + return eyestab(M,user) + +/obj/item/screwdriver/brass + name = "brass screwdriver" + desc = "A screwdriver made of brass. The handle feels freezing cold." + resistance_flags = FIRE_PROOF | ACID_PROOF + icon_state = "screwdriver_brass" + item_state = "screwdriver_brass" + toolspeed = 0.5 + random_color = FALSE + +/obj/item/screwdriver/abductor + name = "alien screwdriver" + desc = "An ultrasonic screwdriver." + icon = 'icons/obj/abductor.dmi' + icon_state = "screwdriver_a" + item_state = "screwdriver_nuke" + usesound = 'sound/items/pshoom.ogg' + toolspeed = 0.1 + random_color = FALSE + +/obj/item/screwdriver/power + name = "hand drill" + desc = "A simple powered hand drill. It's fitted with a screw bit." + icon_state = "drill_screw" + item_state = "drill" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) + origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get + force = 8 //might or might not be too high, subject to change + w_class = WEIGHT_CLASS_SMALL + throwforce = 8 + throw_speed = 2 + throw_range = 3//it's heavier than a screw driver/wrench, so it does more damage, but can't be thrown as far + attack_verb = list("drilled", "screwed", "jabbed","whacked") + hitsound = 'sound/items/drill_hit.ogg' + usesound = 'sound/items/drill_use.ogg' + toolspeed = 0.25 + random_color = FALSE + +/obj/item/screwdriver/power/suicide_act(mob/user) + user.visible_message("[user] is putting [src] to [user.p_their()] temple. It looks like [user.p_theyre()] trying to commit suicide!") + return(BRUTELOSS) + +/obj/item/screwdriver/power/attack_self(mob/user) + playsound(get_turf(user),'sound/items/change_drill.ogg',50,1) + var/obj/item/wrench/power/b_drill = new /obj/item/wrench/power + to_chat(user, "You attach the bolt driver bit to [src].") + qdel(src) + user.put_in_active_hand(b_drill) + +/obj/item/screwdriver/cyborg + name = "powered screwdriver" + desc = "An electrical screwdriver, designed to be both precise and quick." + usesound = 'sound/items/drill_use.ogg' + toolspeed = 0.5 + +/* + * Wirecutters + */ +/obj/item/wirecutters + name = "wirecutters" + desc = "This cuts wires." + icon = 'icons/obj/tools.dmi' + icon_state = null + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + force = 6 + throw_speed = 3 + throw_range = 7 + w_class = WEIGHT_CLASS_SMALL + materials = list(MAT_METAL=80) + attack_verb = list("pinched", "nipped") + hitsound = 'sound/items/wirecutter.ogg' + usesound = 'sound/items/wirecutter.ogg' + origin_tech = "materials=1;engineering=1" + toolspeed = 1 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) + + +/obj/item/wirecutters/New(loc, var/param_color = null) + ..() + if(!icon_state) + if(!param_color) + param_color = pick("yellow","red") + icon_state = "cutters_[param_color]" + +/obj/item/wirecutters/attack(mob/living/carbon/C, mob/user) + if(istype(C) && C.handcuffed && istype(C.handcuffed, /obj/item/restraints/handcuffs/cable)) + user.visible_message("[user] cuts [C]'s restraints with [src]!") + qdel(C.handcuffed) + C.handcuffed = null + if(C.buckled && C.buckled.buckle_requires_restraints) + C.buckled.unbuckle_mob(C) + C.update_handcuffed() + return + else + ..() + +/obj/item/wirecutters/suicide_act(mob/user) + user.visible_message("[user] is cutting at [user.p_their()] arteries with [src]! It looks like [user.p_theyre()] trying to commit suicide!") + playsound(loc, usesound, 50, 1, -1) + return (BRUTELOSS) + +/obj/item/wirecutters/brass + name = "brass wirecutters" + desc = "A pair of wirecutters made of brass. The handle feels freezing cold to the touch." + resistance_flags = FIRE_PROOF | ACID_PROOF + icon_state = "cutters_brass" + toolspeed = 0.5 + +/obj/item/wirecutters/abductor + name = "alien wirecutters" + desc = "Extremely sharp wirecutters, made out of a silvery-green metal." + icon = 'icons/obj/abductor.dmi' + icon_state = "cutters" + toolspeed = 0.1 + origin_tech = "materials=5;engineering=4;abductor=3" + +/obj/item/wirecutters/cyborg + name = "wirecutters" + desc = "This cuts wires." + toolspeed = 0.5 + +/obj/item/wirecutters/power + name = "jaws of life" + desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a cutting head." + icon_state = "jaws_cutter" + item_state = "jawsoflife" + origin_tech = "materials=2;engineering=2" + materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) + usesound = 'sound/items/jaws_cut.ogg' + toolspeed = 0.25 + +/obj/item/wirecutters/power/suicide_act(mob/user) + user.visible_message("[user] is wrapping \the [src] around [user.p_their()] neck. It looks like [user.p_theyre()] trying to rip [user.p_their()] head off!") + playsound(loc, 'sound/items/jaws_cut.ogg', 50, 1, -1) + if(iscarbon(user)) + var/mob/living/carbon/C = user + var/obj/item/bodypart/BP = C.get_bodypart("head") + if(BP) + BP.drop_limb() + playsound(loc,pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg') ,50, 1, -1) + return (BRUTELOSS) + +/obj/item/wirecutters/power/attack_self(mob/user) + playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) + var/obj/item/crowbar/power/pryjaws = new /obj/item/crowbar/power + to_chat(user, "You attach the pry jaws to [src].") + qdel(src) + user.put_in_active_hand(pryjaws) +/* + * Welding Tool + */ +/obj/item/weldingtool + name = "welding tool" + desc = "A standard edition welder provided by Nanotrasen." + icon = 'icons/obj/tools.dmi' + icon_state = "welder" + item_state = "welder" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + force = 3 + throwforce = 5 + hitsound = "swing_hit" + usesound = 'sound/items/welder.ogg' + var/acti_sound = 'sound/items/welderactivate.ogg' + var/deac_sound = 'sound/items/welderdeactivate.ogg' + throw_speed = 3 + throw_range = 5 + w_class = WEIGHT_CLASS_SMALL + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 30) + resistance_flags = FIRE_PROOF + + materials = list(MAT_METAL=70, MAT_GLASS=30) + origin_tech = "engineering=1;plasmatech=1" + var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) + var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) + var/max_fuel = 20 //The max amount of fuel the welder can hold + var/change_icons = 1 + var/can_off_process = 0 + var/light_intensity = 2 //how powerful the emitted light is when used. + var/burned_fuel_for = 0 //when fuel was last removed + heat = 3800 + toolspeed = 1 + +/obj/item/weldingtool/Initialize() + . = ..() + create_reagents(max_fuel) + reagents.add_reagent("welding_fuel", max_fuel) + update_icon() + + +/obj/item/weldingtool/proc/update_torch() + if(welding) + add_overlay("[initial(icon_state)]-on") + item_state = "[initial(item_state)]1" + else + item_state = "[initial(item_state)]" + + +/obj/item/weldingtool/update_icon() + cut_overlays() + if(change_icons) + var/ratio = get_fuel() / max_fuel + ratio = Ceiling(ratio*4) * 25 + add_overlay("[initial(icon_state)][ratio]") + update_torch() + return + + +/obj/item/weldingtool/process() + switch(welding) + if(0) + force = 3 + damtype = "brute" + update_icon() + if(!can_off_process) + STOP_PROCESSING(SSobj, src) + return + //Welders left on now use up fuel, but lets not have them run out quite that fast + if(1) + force = 15 + damtype = "fire" + ++burned_fuel_for + if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL) + remove_fuel(1) + update_icon() + + //This is to start fires. process() is only called if the welder is on. + open_flame() + + +/obj/item/weldingtool/suicide_act(mob/user) + user.visible_message("[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!") + return (FIRELOSS) + + +/obj/item/weldingtool/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/screwdriver)) + flamethrower_screwdriver(I, user) + else if(istype(I, /obj/item/stack/rods)) + flamethrower_rods(I, user) + else + return ..() + + +/obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) + if(!istype(H)) + return ..() + + var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) + + if(affecting && affecting.status == BODYPART_ROBOTIC && user.a_intent != INTENT_HARM) + if(src.remove_fuel(1)) + playsound(loc, usesound, 50, 1) + if(user == H) + user.visible_message("[user] starts to fix some of the dents on [H]'s [affecting.name].", "You start fixing some of the dents on [H]'s [affecting.name].") + if(!do_mob(user, H, 50)) + return + item_heal_robotic(H, user, 15, 0) + else + return ..() + + +/obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) + if(!proximity) return + + if(welding) + remove_fuel(1) + var/turf/location = get_turf(user) + location.hotspot_expose(700, 50, 1) + if(get_fuel() <= 0) + set_light(0) + + if(isliving(O)) + var/mob/living/L = O + if(L.IgniteMob()) + message_admins("[key_name_admin(user)] set [key_name_admin(L)] on fire") + log_game("[key_name(user)] set [key_name(L)] on fire") + + +/obj/item/weldingtool/attack_self(mob/user) + switched_on(user) + if(welding) + set_light(light_intensity) + + update_icon() + + +//Returns the amount of fuel in the welder +/obj/item/weldingtool/proc/get_fuel() + return reagents.get_reagent_amount("welding_fuel") + + +//Removes fuel from the welding tool. If a mob is passed, it will try to flash the mob's eyes. This should probably be renamed to use() +/obj/item/weldingtool/proc/remove_fuel(amount = 1, mob/living/M = null) + if(!welding || !check_fuel()) + return 0 + if(amount) + burned_fuel_for = 0 + if(get_fuel() >= amount) + reagents.remove_reagent("welding_fuel", amount) + check_fuel() + if(M) + M.flash_act(light_intensity) + return TRUE + else + if(M) + to_chat(M, "You need more welding fuel to complete this task!") + return FALSE + + +//Turns off the welder if there is no more fuel (does this really need to be its own proc?) +/obj/item/weldingtool/proc/check_fuel(mob/user) + if(get_fuel() <= 0 && welding) + switched_on(user) + update_icon() + //mob icon update + if(ismob(loc)) + var/mob/M = loc + M.update_inv_hands(0) + + return 0 + return 1 + +//Switches the welder on +/obj/item/weldingtool/proc/switched_on(mob/user) + if(!status) + to_chat(user, "[src] can't be turned on while unsecured!") + return + welding = !welding + if(welding) + if(get_fuel() >= 1) + to_chat(user, "You switch [src] on.") + playsound(loc, acti_sound, 50, 1) + force = 15 + damtype = "fire" + hitsound = 'sound/items/welder.ogg' + update_icon() + START_PROCESSING(SSobj, src) + else + to_chat(user, "You need more fuel!") + switched_off(user) + else + to_chat(user, "You switch [src] off.") + playsound(loc, deac_sound, 50, 1) + switched_off(user) + +//Switches the welder off +/obj/item/weldingtool/proc/switched_off(mob/user) + welding = 0 + set_light(0) + + force = 3 + damtype = "brute" + hitsound = "swing_hit" + update_icon() + + +/obj/item/weldingtool/examine(mob/user) + ..() + to_chat(user, "It contains [get_fuel()] unit\s of fuel out of [max_fuel].") + +/obj/item/weldingtool/is_hot() + return welding * heat + +//Returns whether or not the welding tool is currently on. +/obj/item/weldingtool/proc/isOn() + return welding + + +/obj/item/weldingtool/proc/flamethrower_screwdriver(obj/item/I, mob/user) + if(welding) + to_chat(user, "Turn it off first!") + return + status = !status + if(status) + to_chat(user, "You resecure [src].") + else + to_chat(user, "[src] can now be attached and modified.") + add_fingerprint(user) + +/obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) + if(!status) + var/obj/item/stack/rods/R = I + if (R.use(1)) + var/obj/item/flamethrower/F = new /obj/item/flamethrower(user.loc) + if(!remove_item_from_storage(F)) + user.transferItemToLoc(src, F, TRUE) + F.weldtool = src + add_fingerprint(user) + to_chat(user, "You add a rod to a welder, starting to build a flamethrower.") + user.put_in_hands(F) + else + to_chat(user, "You need one rod to start building a flamethrower!") + +/obj/item/weldingtool/ignition_effect(atom/A, mob/user) + if(welding && remove_fuel(1, user)) + . = "[user] casually lights [A] with [src], what a badass." + else + . = "" + +/obj/item/weldingtool/largetank + name = "industrial welding tool" + desc = "A slightly larger welder with a larger tank." + icon_state = "indwelder" + max_fuel = 40 + materials = list(MAT_GLASS=60) + origin_tech = "engineering=2;plasmatech=2" + +/obj/item/weldingtool/largetank/cyborg + name = "integrated welding tool" + desc = "An advanced welder designed to be used in robotic systems." + toolspeed = 0.5 + +/obj/item/weldingtool/largetank/flamethrower_screwdriver() + return + + +/obj/item/weldingtool/mini + name = "emergency welding tool" + desc = "A miniature welder used during emergencies." + icon_state = "miniwelder" + max_fuel = 10 + w_class = WEIGHT_CLASS_TINY + materials = list(MAT_METAL=30, MAT_GLASS=10) + change_icons = 0 + +/obj/item/weldingtool/mini/flamethrower_screwdriver() + return + +/obj/item/weldingtool/abductor + name = "alien welding tool" + desc = "An alien welding tool. Whatever fuel it uses, it never runs out." + icon = 'icons/obj/abductor.dmi' + icon_state = "welder" + toolspeed = 0.1 + light_intensity = 0 + change_icons = 0 + origin_tech = "plasmatech=5;engineering=5;abductor=3" + +/obj/item/weldingtool/abductor/process() + if(get_fuel() <= max_fuel) + reagents.add_reagent("welding_fuel", 1) + ..() + +/obj/item/weldingtool/hugetank + name = "upgraded industrial welding tool" + desc = "An upgraded welder based of the industrial welder." + icon_state = "upindwelder" + item_state = "upindwelder" + max_fuel = 80 + materials = list(MAT_METAL=70, MAT_GLASS=120) + origin_tech = "engineering=3;plasmatech=2" + +/obj/item/weldingtool/experimental + name = "experimental welding tool" + desc = "An experimental welder capable of self-fuel generation and less harmful to the eyes." + icon_state = "exwelder" + item_state = "exwelder" + max_fuel = 40 + materials = list(MAT_METAL=70, MAT_GLASS=120) + origin_tech = "materials=4;engineering=4;bluespace=3;plasmatech=4" + var/last_gen = 0 + change_icons = 0 + can_off_process = 1 + light_intensity = 1 + toolspeed = 0.5 + var/nextrefueltick = 0 + +/obj/item/weldingtool/experimental/brass + name = "brass welding tool" + desc = "A brass welder that seems to constantly refuel itself. It is faintly warm to the touch." + resistance_flags = FIRE_PROOF | ACID_PROOF + icon_state = "brasswelder" + item_state = "brasswelder" + + +/obj/item/weldingtool/experimental/process() + ..() + if(get_fuel() < max_fuel && nextrefueltick < world.time) + nextrefueltick = world.time + 10 + reagents.add_reagent("welding_fuel", 1) + + +/* + * Crowbar + */ + +/obj/item/crowbar + name = "pocket crowbar" + desc = "A small crowbar. This handy tool is useful for lots of things, such as prying floor tiles or opening unpowered doors." + icon = 'icons/obj/tools.dmi' + icon_state = "crowbar" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + usesound = 'sound/items/crowbar.ogg' + flags_1 = CONDUCT_1 + slot_flags = SLOT_BELT + force = 5 + throwforce = 7 + w_class = WEIGHT_CLASS_SMALL + materials = list(MAT_METAL=50) + origin_tech = "engineering=1;combat=1" + attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked") + toolspeed = 1 + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) + +/obj/item/crowbar/suicide_act(mob/user) + user.visible_message("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") + playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) + return (BRUTELOSS) + +/obj/item/crowbar/red + icon_state = "crowbar_red" + force = 8 + +/obj/item/crowbar/brass + name = "brass crowbar" + desc = "A brass crowbar. It feels faintly warm to the touch." + resistance_flags = FIRE_PROOF | ACID_PROOF + icon_state = "crowbar_brass" + toolspeed = 0.5 + +/obj/item/crowbar/abductor + name = "alien crowbar" + desc = "A hard-light crowbar. It appears to pry by itself, without any effort required." + icon = 'icons/obj/abductor.dmi' + usesound = 'sound/weapons/sonic_jackhammer.ogg' + icon_state = "crowbar" + toolspeed = 0.1 + origin_tech = "combat=4;engineering=4;abductor=3" + +/obj/item/crowbar/large + name = "crowbar" + desc = "It's a big crowbar. It doesn't fit in your pockets, because it's big." + force = 12 + w_class = WEIGHT_CLASS_NORMAL + throw_speed = 3 + throw_range = 3 + materials = list(MAT_METAL=70) + icon_state = "crowbar_large" + item_state = "crowbar" + toolspeed = 0.5 + +/obj/item/crowbar/cyborg + name = "hydraulic crowbar" + desc = "A hydraulic prying tool, compact but powerful. Designed to replace crowbar in construction cyborgs." + usesound = 'sound/items/jaws_pry.ogg' + force = 10 + toolspeed = 0.5 + +/obj/item/crowbar/power + name = "jaws of life" + desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a prying head." + icon_state = "jaws_pry" + item_state = "jawsoflife" + lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' + materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) + origin_tech = "materials=2;engineering=2" + usesound = 'sound/items/jaws_pry.ogg' + force = 15 + toolspeed = 0.25 + +/obj/item/crowbar/power/suicide_act(mob/user) + user.visible_message("[user] is putting [user.p_their()] head in [src], it looks like [user.p_theyre()] trying to commit suicide!") + playsound(loc, 'sound/items/jaws_pry.ogg', 50, 1, -1) + return (BRUTELOSS) + +/obj/item/crowbar/power/attack_self(mob/user) + playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) + var/obj/item/wirecutters/power/cutjaws = new /obj/item/wirecutters/power + to_chat(user, "You attach the cutting jaws to [src].") + qdel(src) + user.put_in_active_hand(cutjaws) + +#undef WELDER_FUEL_BURN_INTERVAL From be3881bbf40f29195421494828340efa556d60d6 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 10 Sep 2017 15:53:05 -0500 Subject: [PATCH 241/262] Automatic changelog generation for PR #2688 [ci skip] --- html/changelogs/AutoChangeLog-pr-2688.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-2688.yml diff --git a/html/changelogs/AutoChangeLog-pr-2688.yml b/html/changelogs/AutoChangeLog-pr-2688.yml new file mode 100644 index 0000000000..5a58322884 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2688.yml @@ -0,0 +1,4 @@ +author: "Firecage" +delete-after: True +changes: + - rscadd: "The NanoTrasen Department for Cybernetics (NDC) would like to announce the creation of Cybernetic Lungs. Both a stock variety to replace traditional stock human lungs in emergencies, and a more enhanced variety allowing greater tolerance of breathing cold air, toxins, and CO2." From 8ee6fdb76a6dac9f892287db2f48b8dd4dc2308e Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 10 Sep 2017 22:29:12 -0500 Subject: [PATCH 242/262] [MIRROR] Fixes stop-sounds not force-stopping internet midis (#2692) * Fixes stop-sounds not force-stopping internet midis (#30571) * Update playsound.dm * Update preferences_toggles.dm (#17) * Fixes stop-sounds not force-stopping internet midis --- code/modules/admin/verbs/playsound.dm | 3 +++ code/modules/client/preferences_toggles.dm | 3 +++ 2 files changed, 6 insertions(+) diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm index 20c1d91fd2..bfc4701012 100644 --- a/code/modules/admin/verbs/playsound.dm +++ b/code/modules/admin/verbs/playsound.dm @@ -135,4 +135,7 @@ for(var/mob/M in GLOB.player_list) if(M.client) SEND_SOUND(M, sound(null)) + var/client/C = M.client + if(C && C.chatOutput && !C.chatOutput.broken && C.chatOutput.loaded) + C.chatOutput.sendMusic(" ") SSblackbox.add_details("admin_verb","Stop All Playing Sounds") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index 8e8690bde3..adf775f0e8 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -233,6 +233,9 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, toggleprayersounds)() set category = "Preferences" set desc = "Stop Current Sounds" SEND_SOUND(usr, sound(null)) + var/client/C = usr.client + if(C && C.chatOutput && !C.chatOutput.broken && C.chatOutput.loaded) + C.chatOutput.sendMusic(" ") SSblackbox.add_details("preferences_verb","Stop Self Sounds") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! From a6e280cbad4e8109e3a9cb4cfefd5703e1cb2311 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 11 Sep 2017 13:16:16 -0500 Subject: [PATCH 243/262] Automatic changelog generation for PR #2600 [ci skip] --- html/changelogs/AutoChangeLog-pr-2600.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-2600.yml diff --git a/html/changelogs/AutoChangeLog-pr-2600.yml b/html/changelogs/AutoChangeLog-pr-2600.yml new file mode 100644 index 0000000000..79380038d4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2600.yml @@ -0,0 +1,4 @@ +author: "Jay" +delete-after: True +changes: + - tweak: "Removes the lisp lizards have when talking" From af5ffcc83ae824da42e181b671b9f846ee8f6d63 Mon Sep 17 00:00:00 2001 From: Ashe Higgs Date: Mon, 11 Sep 2017 14:37:09 -0400 Subject: [PATCH 244/262] Adds departmental banners --- code/game/objects/items/religion.dm | 200 ++++++++++++++++++++++++++-- 1 file changed, 187 insertions(+), 13 deletions(-) diff --git a/code/game/objects/items/religion.dm b/code/game/objects/items/religion.dm index 1edbba1f56..007c590cac 100644 --- a/code/game/objects/items/religion.dm +++ b/code/game/objects/items/religion.dm @@ -1,27 +1,201 @@ /obj/item/banner name = "banner" + desc = "A banner with Nanotrasen's logo on it." icon = 'icons/obj/items_and_weapons.dmi' icon_state = "banner" item_state = "banner" + force = 8 + attack_verb = list("forcefully inspired", "violently encouraged", "relentlessly galvanized") lefthand_file = 'icons/mob/inhands/equipment/banners_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/banners_righthand.dmi' - desc = "A banner with Nanotrasen's logo on it." - var/moralecooldown = 0 - var/moralewait = 600 + var/inspiration_available = TRUE //If this banner can be used to inspire crew + var/morale_time = 0 + var/morale_cooldown = 600 //How many deciseconds between uses + var/list/job_loyalties //Mobs with any of these assigned roles will be inspired + var/list/role_loyalties //Mobs with any of these special roles will be inspired + var/warcry + +/obj/item/banner/examine(mob/user) + ..() + if(inspiration_available) + to_chat(user, "Activate it in your hand to inspire nearby allies of this banner's allegiance!") /obj/item/banner/attack_self(mob/living/carbon/human/user) - if(moralecooldown + moralewait > world.time) + if(!inspiration_available) return - to_chat(user, "You increase the morale of your fellows!") - moralecooldown = world.time + if(morale_time > world.time) + to_chat(user, "You aren't feeling inspired enough to flourish [src] again yet.") + return + user.visible_message("[user] flourishes [src]!", \ + "You raise [src] skywards, inspiring your allies!") + playsound(src, "rustle", 100, FALSE) + if(warcry) + user.say("[warcry]") + var/old_transform = user.transform + user.transform *= 1.2 + animate(user, transform = old_transform, time = 10) + morale_time = world.time + morale_cooldown - for(var/mob/living/carbon/human/H in range(4,get_turf(src))) - to_chat(H, "Your morale is increased by [user]'s banner!") - H.adjustBruteLoss(-15) - H.adjustFireLoss(-15) - H.AdjustStun(-40) - H.AdjustKnockdown(-40) - H.AdjustUnconscious(-40) + var/list/inspired = list() + var/has_job_loyalties = LAZYLEN(job_loyalties) + var/has_role_loyalties = LAZYLEN(role_loyalties) + inspired += user //The user is always inspired, regardless of loyalties + for(var/mob/living/carbon/human/H in range(4, get_turf(src))) + if(H.stat == DEAD || H == user) + continue + if(H.mind && (has_job_loyalties || has_role_loyalties)) + if(has_job_loyalties && H.mind.assigned_role in job_loyalties) + inspired += H + else if(has_role_loyalties && H.mind.special_role in role_loyalties) + inspired += H + else if(check_inspiration(H)) + inspired += H + + for(var/V in inspired) + var/mob/living/carbon/human/H = V + if(H != user) + to_chat(H, "Your confidence surges as [user] flourishes [user.p_their()] [name]!") + inspiration(H) + special_inspiration(H) + +/obj/item/banner/proc/check_inspiration(mob/living/carbon/human/H) //Banner-specific conditions for being eligible + return + +/obj/item/banner/proc/inspiration(mob/living/carbon/human/H) + H.adjustBruteLoss(-15) + H.adjustFireLoss(-15) + H.AdjustStun(-40) + H.AdjustKnockdown(-40) + H.AdjustUnconscious(-40) + playsound(H, 'sound/magic/staff_healing.ogg', 25, FALSE) + +/obj/item/banner/proc/special_inspiration(mob/living/carbon/human/H) //Any banner-specific inspiration effects go here + return + +/obj/item/banner/security + name = "securistan banner" + desc = "The banner of Securistan, ruling the station with an iron fist." + icon_state = "banner_security" + job_loyalties = list("Security Officer", "Warden", "Detective", "Head of Security") + warcry = "EVERYONE DOWN ON THE GROUND!!" + +/obj/item/banner/security/mundane + inspiration_available = FALSE + +/datum/crafting_recipe/security_banner + name = "Securistan Banner" + result = /obj/item/banner/security/mundane + time = 40 + reqs = list(/obj/item/stack/rods = 2, + /obj/item/clothing/under/rank/security = 1) + category = CAT_MISC + +/obj/item/banner/medical + name = "meditopia banner" + desc = "The banner of Meditopia, generous benefactors that cure wounds and shelter the weak." + icon_state = "banner_medical" + job_loyalties = list("Medical Doctor", "Chemist", "Geneticist", "Virologist", "Chief Medical Officer") + warcry = "No wounds cannot be healed!" + +/obj/item/banner/medical/mundane + inspiration_available = FALSE + +/obj/item/banner/medical/check_inspiration(mob/living/carbon/human/H) + return H.stat //Meditopia is moved to help those in need + +/datum/crafting_recipe/medical_banner + name = "Meditopia Banner" + result = /obj/item/banner/medical/mundane + time = 40 + reqs = list(/obj/item/stack/rods = 2, + /obj/item/clothing/under/rank/medical = 1) + category = CAT_MISC + +/obj/item/banner/medical/special_inspiration(mob/living/carbon/human/H) + H.adjustToxLoss(-15) + H.setOxyLoss(0) + H.reagents.add_reagent("inaprovaline", 5) + +/obj/item/banner/science + name = "sciencia banner" + desc = "The banner of Sciencia, bold and daring thaumaturges and researchers that take the path less traveled." + icon_state = "banner_science" + job_loyalties = list("Scientist", "Roboticist", "Research Director") + warcry = "For Cuban Pete!" + +/obj/item/banner/science/mundane + inspiration_available = FALSE + +/obj/item/banner/science/check_inspiration(mob/living/carbon/human/H) + return H.on_fire //Sciencia is pleased by dedication to the art of Toxins + +/datum/crafting_recipe/science_banner + name = "Sciencia Banner" + result = /obj/item/banner/science/mundane + time = 40 + reqs = list(/obj/item/stack/rods = 2, + /obj/item/clothing/under/rank/scientist = 1) + category = CAT_MISC + +/obj/item/banner/cargo + name = "cargonia banner" + desc = "The banner of the eternal Cargonia, with the mystical power of conjuring any object into existence." + icon_state = "banner_cargo" + job_loyalties = list("Cargo Technician", "Shaft Miner", "Quartermaster") + warcry = "Hail Cargonia!" + +/obj/item/banner/cargo/mundane + inspiration_available = FALSE + +/datum/crafting_recipe/cargo_banner + name = "Cargonia Banner" + result = /obj/item/banner/cargo/mundane + time = 40 + reqs = list(/obj/item/stack/rods = 2, + /obj/item/clothing/under/rank/cargotech = 1) + category = CAT_MISC + +/obj/item/banner/engineering + name = "engitopia banner" + desc = "The banner of Engitopia, wielders of limitless power." + icon_state = "banner_engineering" + job_loyalties = list("Station Engineer", "Atmospheric Technician", "Chief Engineer") + warcry = "All hail lord Singuloth!!" + +/obj/item/banner/engineering/mundane + inspiration_available = FALSE + +/obj/item/banner/engineering/special_inspiration(mob/living/carbon/human/H) + H.radiation = 0 + +/datum/crafting_recipe/engineering_banner + name = "Engitopia Banner" + result = /obj/item/banner/engineering/mundane + time = 40 + reqs = list(/obj/item/stack/rods = 2, + /obj/item/clothing/under/rank/engineer = 1) + category = CAT_MISC + +/obj/item/banner/command + name = "command banner" + desc = "The banner of Command, a staunch and ancient line of bueraucratic kings and queens." + //No icon state here since the default one is the NT banner + job_loyalties = list("Captain", "Head of Personnel", "Chief Engineer", "Head of Security", "Research Director", "Chief Medical Officer") + warcry = "Hail Nanotrasen!" + +/obj/item/banner/command/mundane + inspiration_available = FALSE + +/obj/item/banner/command/check_inspiration(mob/living/carbon/human/H) + return H.isloyal() //Command is stalwart but rewards their allies. + +/datum/crafting_recipe/command_banner + name = "Command Banner" + result = /obj/item/banner/command/mundane + time = 40 + reqs = list(/obj/item/stack/rods = 2, + /obj/item/clothing/under/captainparade = 1) + category = CAT_MISC /obj/item/banner/red name = "red banner" From b008cdada03721c701a19833e6ac52f624f7caac Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 11 Sep 2017 13:47:33 -0500 Subject: [PATCH 245/262] oopsie woopsie --- .../clock_structures/prolonging_prism.dm | 905 +++--------------- 1 file changed, 125 insertions(+), 780 deletions(-) diff --git a/code/game/gamemodes/clock_cult/clock_structures/prolonging_prism.dm b/code/game/gamemodes/clock_cult/clock_structures/prolonging_prism.dm index c6692073b0..9ef7fa4ab7 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/prolonging_prism.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/prolonging_prism.dm @@ -1,790 +1,135 @@ -#define WELDER_FUEL_BURN_INTERVAL 13 +//Prolonging Prism: A prism that consumes power to delay the shuttle +/obj/structure/destructible/clockwork/powered/prolonging_prism + name = "prolonging prism" + desc = "A dark onyx prism, held in midair by spiraling tendrils of stone." + clockwork_desc = "A powerful prism that will delay the arrival of an emergency shuttle." + icon_state = "prolonging_prism_inactive" + active_icon = "prolonging_prism" + inactive_icon = "prolonging_prism_inactive" + unanchored_icon = "prolonging_prism_unwrenched" + construction_value = 20 + max_integrity = 125 + break_message = "The prism falls to the ground with a heavy thud!" + debris = list(/obj/item/clockwork/alloy_shards/small = 3, \ + /obj/item/clockwork/alloy_shards/medium = 1, \ + /obj/item/clockwork/alloy_shards/large = 1, \ + /obj/item/clockwork/component/vanguard_cogwheel/onyx_prism = 1) + var/static/list/component_refund = list(VANGUARD_COGWHEEL = 2, GEIS_CAPACITOR = 1, REPLICANT_ALLOY = 1) + var/static/delay_cost = 3000 + var/static/delay_cost_increase = 1250 + var/static/delay_remaining = 0 -/* Tools! - * Note: Multitools are /obj/item/device - * - * Contains: - * Wrench - * Screwdriver - * Wirecutters - * Welding Tool - * Crowbar - */ - -/* - * Wrench - */ -/obj/item/wrench - name = "wrench" - desc = "A wrench with common uses. Can be found in your hand." - icon = 'icons/obj/tools.dmi' - icon_state = "wrench" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 5 - throwforce = 7 - w_class = WEIGHT_CLASS_SMALL - usesound = 'sound/items/ratchet.ogg' - materials = list(MAT_METAL=150) - origin_tech = "materials=1;engineering=1" - attack_verb = list("bashed", "battered", "bludgeoned", "whacked") - toolspeed = 1 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) - -/obj/item/wrench/suicide_act(mob/user) - user.visible_message("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) - return (BRUTELOSS) - -/obj/item/wrench/cyborg - name = "automatic wrench" - desc = "An advanced robotic wrench. Can be found in construction cyborgs." - toolspeed = 0.5 - -/obj/item/wrench/brass - name = "brass wrench" - desc = "A brass wrench. It's faintly warm to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "wrench_brass" - toolspeed = 0.5 - -/obj/item/wrench/abductor - name = "alien wrench" - desc = "A polarized wrench. It causes anything placed between the jaws to turn." - icon = 'icons/obj/abductor.dmi' - icon_state = "wrench" - usesound = 'sound/effects/empulse.ogg' - toolspeed = 0.1 - origin_tech = "materials=5;engineering=5;abductor=3" - -/obj/item/wrench/power - name = "hand drill" - desc = "A simple powered hand drill. It's fitted with a bolt bit." - icon_state = "drill_bolt" - item_state = "drill" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - usesound = 'sound/items/drill_use.ogg' - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get - force = 8 //might or might not be too high, subject to change - w_class = WEIGHT_CLASS_SMALL - throwforce = 8 - attack_verb = list("drilled", "screwed", "jabbed") - toolspeed = 0.25 - -/obj/item/wrench/power/attack_self(mob/user) - playsound(get_turf(user),'sound/items/change_drill.ogg',50,1) - var/obj/item/wirecutters/power/s_drill = new /obj/item/screwdriver/power - to_chat(user, "You attach the screw driver bit to [src].") - qdel(src) - user.put_in_active_hand(s_drill) - -/obj/item/wrench/power/suicide_act(mob/user) - user.visible_message("[user] is pressing [src] against [user.p_their()] head! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) - -/obj/item/wrench/medical - name = "medical wrench" - desc = "A medical wrench with common(medical?) uses. Can be found in your hand." - icon_state = "wrench_medical" - force = 2 //MEDICAL - throwforce = 4 - origin_tech = "materials=1;engineering=1;biotech=3" - attack_verb = list("wrenched", "medicaled", "tapped", "jabbed", "whacked") - -/obj/item/wrench/medical/suicide_act(mob/living/user) - user.visible_message("[user] is praying to the medical wrench to take [user.p_their()] soul. It looks like [user.p_theyre()] trying to commit suicide!") - // TODO Make them glow with the power of the M E D I C A L W R E N C H - // during their ascension - - // Stun stops them from wandering off - user.Stun(100, ignore_canstun = TRUE) - playsound(loc, 'sound/effects/pray.ogg', 50, 1, -1) - - // Let the sound effect finish playing - sleep(20) - - if(!user) - return - - for(var/obj/item/W in user) - user.dropItemToGround(W) - - var/obj/item/wrench/medical/W = new /obj/item/wrench/medical(loc) - W.add_fingerprint(user) - W.desc += " For some reason, it reminds you of [user.name]." - - if(!user) - return - - user.dust() - - return OXYLOSS - -/* - * Screwdriver - */ -/obj/item/screwdriver - name = "screwdriver" - desc = "You can be totally screwy with this." - icon = 'icons/obj/tools.dmi' - icon_state = "screwdriver" - item_state = "screwdriver" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 5 - w_class = WEIGHT_CLASS_TINY - throwforce = 5 - throw_speed = 3 - throw_range = 5 - materials = list(MAT_METAL=75) - attack_verb = list("stabbed") - hitsound = 'sound/weapons/bladeslice.ogg' - usesound = 'sound/items/screwdriver.ogg' - toolspeed = 1 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) - var/random_color = TRUE //if the screwdriver uses random coloring - var/static/list/screwdriver_colors = list(\ - "blue" = rgb(24, 97, 213), \ - "red" = rgb(149, 23, 16), \ - "pink" = rgb(213, 24, 141), \ - "brown" = rgb(160, 82, 18), \ - "green" = rgb(14, 127, 27), \ - "cyan" = rgb(24, 162, 213), \ - "yellow" = rgb(213, 140, 24), \ - ) - -/obj/item/screwdriver/suicide_act(mob/user) - user.visible_message("[user] is stabbing [src] into [user.p_their()] [pick("temple", "heart")]! It looks like [user.p_theyre()] trying to commit suicide!") - return(BRUTELOSS) - -/obj/item/screwdriver/Initialize() - . = ..() - if(random_color) //random colors! - var/our_color = pick(screwdriver_colors) - add_atom_colour(screwdriver_colors[our_color], FIXED_COLOUR_PRIORITY) - update_icon() - if(prob(75)) - pixel_y = rand(0, 16) - -/obj/item/screwdriver/update_icon() - if(!random_color) //icon override - return - cut_overlays() - var/mutable_appearance/base_overlay = mutable_appearance(icon, "screwdriver_screwybits") - base_overlay.appearance_flags = RESET_COLOR - add_overlay(base_overlay) - -/obj/item/screwdriver/worn_overlays(isinhands = FALSE, icon_file) - . = list() - if(isinhands && random_color) - var/mutable_appearance/M = mutable_appearance(icon_file, "screwdriver_head") - M.appearance_flags = RESET_COLOR - . += M - -/obj/item/screwdriver/get_belt_overlay() - if(random_color) - var/mutable_appearance/body = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver") - var/mutable_appearance/head = mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "screwdriver_head") - body.color = color - head.add_overlay(body) - return head - else - return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state) - -/obj/item/screwdriver/attack(mob/living/carbon/M, mob/living/carbon/user) - if(!istype(M)) - return ..() - if(user.zone_selected != "eyes" && user.zone_selected != "head") - return ..() - if(user.disabilities & CLUMSY && prob(50)) - M = user - return eyestab(M,user) - -/obj/item/screwdriver/brass - name = "brass screwdriver" - desc = "A screwdriver made of brass. The handle feels freezing cold." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "screwdriver_brass" - item_state = "screwdriver_brass" - toolspeed = 0.5 - random_color = FALSE - -/obj/item/screwdriver/abductor - name = "alien screwdriver" - desc = "An ultrasonic screwdriver." - icon = 'icons/obj/abductor.dmi' - icon_state = "screwdriver_a" - item_state = "screwdriver_nuke" - usesound = 'sound/items/pshoom.ogg' - toolspeed = 0.1 - random_color = FALSE - -/obj/item/screwdriver/power - name = "hand drill" - desc = "A simple powered hand drill. It's fitted with a screw bit." - icon_state = "drill_screw" - item_state = "drill" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get - force = 8 //might or might not be too high, subject to change - w_class = WEIGHT_CLASS_SMALL - throwforce = 8 - throw_speed = 2 - throw_range = 3//it's heavier than a screw driver/wrench, so it does more damage, but can't be thrown as far - attack_verb = list("drilled", "screwed", "jabbed","whacked") - hitsound = 'sound/items/drill_hit.ogg' - usesound = 'sound/items/drill_use.ogg' - toolspeed = 0.25 - random_color = FALSE - -/obj/item/screwdriver/power/suicide_act(mob/user) - user.visible_message("[user] is putting [src] to [user.p_their()] temple. It looks like [user.p_theyre()] trying to commit suicide!") - return(BRUTELOSS) - -/obj/item/screwdriver/power/attack_self(mob/user) - playsound(get_turf(user),'sound/items/change_drill.ogg',50,1) - var/obj/item/wrench/power/b_drill = new /obj/item/wrench/power - to_chat(user, "You attach the bolt driver bit to [src].") - qdel(src) - user.put_in_active_hand(b_drill) - -/obj/item/screwdriver/cyborg - name = "powered screwdriver" - desc = "An electrical screwdriver, designed to be both precise and quick." - usesound = 'sound/items/drill_use.ogg' - toolspeed = 0.5 - -/* - * Wirecutters - */ -/obj/item/wirecutters - name = "wirecutters" - desc = "This cuts wires." - icon = 'icons/obj/tools.dmi' - icon_state = null - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 6 - throw_speed = 3 - throw_range = 7 - w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL=80) - attack_verb = list("pinched", "nipped") - hitsound = 'sound/items/wirecutter.ogg' - usesound = 'sound/items/wirecutter.ogg' - origin_tech = "materials=1;engineering=1" - toolspeed = 1 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) - - -/obj/item/wirecutters/New(loc, var/param_color = null) +/obj/structure/destructible/clockwork/powered/prolonging_prism/examine(mob/user) ..() - if(!icon_state) - if(!param_color) - param_color = pick("yellow","red") - icon_state = "cutters_[param_color]" + if(is_servant_of_ratvar(user) || isobserver(user)) + if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE) + to_chat(user, "An emergency shuttle has arrived and this prism is no longer useful; attempt to activate it to gain a partial refund of components used.") + else + var/efficiency = get_efficiency_mod(TRUE) + to_chat(user, "It requires at least [DisplayPower(get_delay_cost())] of power to attempt to delay the arrival of an emergency shuttle by [2 * efficiency] minutes.") + to_chat(user, "This cost increases by [DisplayPower(delay_cost_increase)] for every previous activation.") -/obj/item/wirecutters/attack(mob/living/carbon/C, mob/user) - if(istype(C) && C.handcuffed && istype(C.handcuffed, /obj/item/restraints/handcuffs/cable)) - user.visible_message("[user] cuts [C]'s restraints with [src]!") - qdel(C.handcuffed) - C.handcuffed = null - if(C.buckled && C.buckled.buckle_requires_restraints) - C.buckled.unbuckle_mob(C) - C.update_handcuffed() - return - else - ..() - -/obj/item/wirecutters/suicide_act(mob/user) - user.visible_message("[user] is cutting at [user.p_their()] arteries with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, usesound, 50, 1, -1) - return (BRUTELOSS) - -/obj/item/wirecutters/brass - name = "brass wirecutters" - desc = "A pair of wirecutters made of brass. The handle feels freezing cold to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "cutters_brass" - toolspeed = 0.5 - -/obj/item/wirecutters/abductor - name = "alien wirecutters" - desc = "Extremely sharp wirecutters, made out of a silvery-green metal." - icon = 'icons/obj/abductor.dmi' - icon_state = "cutters" - toolspeed = 0.1 - origin_tech = "materials=5;engineering=4;abductor=3" - -/obj/item/wirecutters/cyborg - name = "wirecutters" - desc = "This cuts wires." - toolspeed = 0.5 - -/obj/item/wirecutters/power - name = "jaws of life" - desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a cutting head." - icon_state = "jaws_cutter" - item_state = "jawsoflife" - origin_tech = "materials=2;engineering=2" - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - usesound = 'sound/items/jaws_cut.ogg' - toolspeed = 0.25 - -/obj/item/wirecutters/power/suicide_act(mob/user) - user.visible_message("[user] is wrapping \the [src] around [user.p_their()] neck. It looks like [user.p_theyre()] trying to rip [user.p_their()] head off!") - playsound(loc, 'sound/items/jaws_cut.ogg', 50, 1, -1) - if(iscarbon(user)) - var/mob/living/carbon/C = user - var/obj/item/bodypart/BP = C.get_bodypart("head") - if(BP) - BP.drop_limb() - playsound(loc,pick('sound/misc/desceration-01.ogg','sound/misc/desceration-02.ogg','sound/misc/desceration-01.ogg') ,50, 1, -1) - return (BRUTELOSS) - -/obj/item/wirecutters/power/attack_self(mob/user) - playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) - var/obj/item/crowbar/power/pryjaws = new /obj/item/crowbar/power - to_chat(user, "You attach the pry jaws to [src].") - qdel(src) - user.put_in_active_hand(pryjaws) -/* - * Welding Tool - */ -/obj/item/weldingtool - name = "welding tool" - desc = "A standard edition welder provided by Nanotrasen." - icon = 'icons/obj/tools.dmi' - icon_state = "welder" - item_state = "welder" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 3 - throwforce = 5 - hitsound = "swing_hit" - usesound = 'sound/items/welder.ogg' - var/acti_sound = 'sound/items/welderactivate.ogg' - var/deac_sound = 'sound/items/welderdeactivate.ogg' - throw_speed = 3 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 30) - resistance_flags = FIRE_PROOF - - materials = list(MAT_METAL=70, MAT_GLASS=30) - origin_tech = "engineering=1;plasmatech=1" - var/welding = 0 //Whether or not the welding tool is off(0), on(1) or currently welding(2) - var/status = TRUE //Whether the welder is secured or unsecured (able to attach rods to it to make a flamethrower) - var/max_fuel = 20 //The max amount of fuel the welder can hold - var/change_icons = 1 - var/can_off_process = 0 - var/light_intensity = 2 //how powerful the emitted light is when used. - var/burned_fuel_for = 0 //when fuel was last removed - heat = 3800 - toolspeed = 1 - -/obj/item/weldingtool/Initialize() - . = ..() - create_reagents(max_fuel) - reagents.add_reagent("welding_fuel", max_fuel) - update_icon() - - -/obj/item/weldingtool/proc/update_torch() - if(welding) - add_overlay("[initial(icon_state)]-on") - item_state = "[initial(item_state)]1" - else - item_state = "[initial(item_state)]" - - -/obj/item/weldingtool/update_icon() - cut_overlays() - if(change_icons) - var/ratio = get_fuel() / max_fuel - ratio = Ceiling(ratio*4) * 25 - add_overlay("[initial(icon_state)][ratio]") - update_torch() - return - - -/obj/item/weldingtool/process() - switch(welding) - if(0) - force = 3 - damtype = "brute" - update_icon() - if(!can_off_process) - STOP_PROCESSING(SSobj, src) - return - //Welders left on now use up fuel, but lets not have them run out quite that fast - if(1) - force = 15 - damtype = "fire" - ++burned_fuel_for - if(burned_fuel_for >= WELDER_FUEL_BURN_INTERVAL) - remove_fuel(1) - update_icon() - - //This is to start fires. process() is only called if the welder is on. - open_flame() - - -/obj/item/weldingtool/suicide_act(mob/user) - user.visible_message("[user] welds [user.p_their()] every orifice closed! It looks like [user.p_theyre()] trying to commit suicide!") - return (FIRELOSS) - - -/obj/item/weldingtool/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/screwdriver)) - flamethrower_screwdriver(I, user) - else if(istype(I, /obj/item/stack/rods)) - flamethrower_rods(I, user) - else - return ..() - - -/obj/item/weldingtool/attack(mob/living/carbon/human/H, mob/user) - if(!istype(H)) - return ..() - - var/obj/item/bodypart/affecting = H.get_bodypart(check_zone(user.zone_selected)) - - if(affecting && affecting.status == BODYPART_ROBOTIC && user.a_intent != INTENT_HARM) - if(src.remove_fuel(1)) - playsound(loc, usesound, 50, 1) - if(user == H) - user.visible_message("[user] starts to fix some of the dents on [H]'s [affecting.name].", "You start fixing some of the dents on [H]'s [affecting.name].") - if(!do_mob(user, H, 50)) - return - item_heal_robotic(H, user, 15, 0) - else - return ..() - - -/obj/item/weldingtool/afterattack(atom/O, mob/user, proximity) - if(!proximity) return - - if(welding) - remove_fuel(1) - var/turf/location = get_turf(user) - location.hotspot_expose(700, 50, 1) - if(get_fuel() <= 0) - set_light(0) - - if(isliving(O)) - var/mob/living/L = O - if(L.IgniteMob()) - message_admins("[key_name_admin(user)] set [key_name_admin(L)] on fire") - log_game("[key_name(user)] set [key_name(L)] on fire") - - -/obj/item/weldingtool/attack_self(mob/user) - switched_on(user) - if(welding) - set_light(light_intensity) - - update_icon() - - -//Returns the amount of fuel in the welder -/obj/item/weldingtool/proc/get_fuel() - return reagents.get_reagent_amount("welding_fuel") - - -//Removes fuel from the welding tool. If a mob is passed, it will try to flash the mob's eyes. This should probably be renamed to use() -/obj/item/weldingtool/proc/remove_fuel(amount = 1, mob/living/M = null) - if(!welding || !check_fuel()) - return 0 - if(amount) - burned_fuel_for = 0 - if(get_fuel() >= amount) - reagents.remove_reagent("welding_fuel", amount) - check_fuel() - if(M) - M.flash_act(light_intensity) +/obj/structure/destructible/clockwork/powered/prolonging_prism/forced_disable(bad_effects) + if(active) + if(bad_effects) + try_use_power(MIN_CLOCKCULT_POWER*4) + visible_message("[src] emits an airy chuckling sound and falls dark!") + toggle() return TRUE - else - if(M) - to_chat(M, "You need more welding fuel to complete this task!") - return FALSE +/obj/structure/destructible/clockwork/powered/prolonging_prism/attack_hand(mob/living/user) + if(user.canUseTopic(src, !issilicon(user), NO_DEXTERY) && is_servant_of_ratvar(user)) + if(SSshuttle.emergency.mode == SHUTTLE_DOCKED || SSshuttle.emergency.mode == SHUTTLE_IGNITING || SSshuttle.emergency.mode == SHUTTLE_STRANDED || SSshuttle.emergency.mode == SHUTTLE_ESCAPE) + to_chat(user, "You break [src] apart, refunding some of the components used.") + for(var/i in component_refund) + generate_cache_component(i, src) + take_damage(max_integrity) + return 0 + if(active) + return 0 + var/turf/T = get_turf(src) + if(!T || T.z != ZLEVEL_STATION) + to_chat(user, "[src] must be on the station to function!") + return 0 + if(SSshuttle.emergency.mode != SHUTTLE_CALL) + to_chat(user, "No emergency shuttles are attempting to arrive at the station!") + return 0 + if(!try_use_power(get_delay_cost())) + to_chat(user, "[src] needs more power to function!") + return 0 + delay_cost += delay_cost_increase + delay_remaining += PRISM_DELAY_DURATION + toggle(0, user) -//Turns off the welder if there is no more fuel (does this really need to be its own proc?) -/obj/item/weldingtool/proc/check_fuel(mob/user) - if(get_fuel() <= 0 && welding) - switched_on(user) - update_icon() - //mob icon update - if(ismob(loc)) - var/mob/M = loc - M.update_inv_hands(0) - - return 0 - return 1 - -//Switches the welder on -/obj/item/weldingtool/proc/switched_on(mob/user) - if(!status) - to_chat(user, "[src] can't be turned on while unsecured!") +/obj/structure/destructible/clockwork/powered/prolonging_prism/process() + var/turf/own_turf = get_turf(src) + if(SSshuttle.emergency.mode != SHUTTLE_CALL || delay_remaining <= 0 || !own_turf || own_turf.z != ZLEVEL_STATION) + forced_disable(FALSE) return - welding = !welding - if(welding) - if(get_fuel() >= 1) - to_chat(user, "You switch [src] on.") - playsound(loc, acti_sound, 50, 1) - force = 15 - damtype = "fire" - hitsound = 'sound/items/welder.ogg' - update_icon() - START_PROCESSING(SSobj, src) + . = ..() + var/delay_amount = 40 + delay_remaining -= delay_amount + var/efficiency = get_efficiency_mod() + SSshuttle.emergency.setTimer(SSshuttle.emergency.timeLeft(1) + (delay_amount * efficiency)) + var/highest_y + var/highest_x + var/lowest_y + var/lowest_x + var/list/prism_turfs = list() + for(var/t in SSshuttle.emergency.ripple_area(SSshuttle.getDock("emergency_home"))) + prism_turfs[t] = TRUE + var/turf/T = t + if(!highest_y || T.y > highest_y) + highest_y = T.y + if(!highest_x || T.x > highest_x) + highest_x = T.x + if(!lowest_y || T.y < lowest_y) + lowest_y = T.y + if(!lowest_x || T.x < lowest_x) + lowest_x = T.x + var/mean_y = Lerp(lowest_y, highest_y) + var/mean_x = Lerp(lowest_x, highest_x) + if(prob(50)) + mean_y = Ceiling(mean_y) + else + mean_y = Floor(mean_y) + if(prob(50)) + mean_x = Ceiling(mean_x) + else + mean_x = Floor(mean_x) + var/turf/semi_random_center_turf = locate(mean_x, mean_y, ZLEVEL_STATION) + for(var/t in getline(src, semi_random_center_turf)) + prism_turfs[t] = TRUE + var/placement_style = prob(50) + for(var/t in prism_turfs) + var/turf/T = t + if(placement_style) + if(IsOdd(T.x + T.y)) + seven_random_hexes(T, efficiency) + else if(prob(50 * efficiency)) + new /obj/effect/temp_visual/ratvar/prolonging_prism(T) else - to_chat(user, "You need more fuel!") - switched_off(user) - else - to_chat(user, "You switch [src] off.") - playsound(loc, deac_sound, 50, 1) - switched_off(user) + if(IsEven(T.x + T.y)) + seven_random_hexes(T, efficiency) + else if(prob(50 * efficiency)) + new /obj/effect/temp_visual/ratvar/prolonging_prism(T) + CHECK_TICK //we may be going over a hell of a lot of turfs -//Switches the welder off -/obj/item/weldingtool/proc/switched_off(mob/user) - welding = 0 - set_light(0) +/obj/structure/destructible/clockwork/powered/prolonging_prism/proc/get_delay_cost() + return Floor(delay_cost, MIN_CLOCKCULT_POWER) - force = 3 - damtype = "brute" - hitsound = "swing_hit" - update_icon() - - -/obj/item/weldingtool/examine(mob/user) - ..() - to_chat(user, "It contains [get_fuel()] unit\s of fuel out of [max_fuel].") - -/obj/item/weldingtool/is_hot() - return welding * heat - -//Returns whether or not the welding tool is currently on. -/obj/item/weldingtool/proc/isOn() - return welding - - -/obj/item/weldingtool/proc/flamethrower_screwdriver(obj/item/I, mob/user) - if(welding) - to_chat(user, "Turn it off first!") - return - status = !status - if(status) - to_chat(user, "You resecure [src].") - else - to_chat(user, "[src] can now be attached and modified.") - add_fingerprint(user) - -/obj/item/weldingtool/proc/flamethrower_rods(obj/item/I, mob/user) - if(!status) - var/obj/item/stack/rods/R = I - if (R.use(1)) - var/obj/item/flamethrower/F = new /obj/item/flamethrower(user.loc) - if(!remove_item_from_storage(F)) - user.transferItemToLoc(src, F, TRUE) - F.weldtool = src - add_fingerprint(user) - to_chat(user, "You add a rod to a welder, starting to build a flamethrower.") - user.put_in_hands(F) - else - to_chat(user, "You need one rod to start building a flamethrower!") - -/obj/item/weldingtool/ignition_effect(atom/A, mob/user) - if(welding && remove_fuel(1, user)) - . = "[user] casually lights [A] with [src], what a badass." - else - . = "" - -/obj/item/weldingtool/largetank - name = "industrial welding tool" - desc = "A slightly larger welder with a larger tank." - icon_state = "indwelder" - max_fuel = 40 - materials = list(MAT_GLASS=60) - origin_tech = "engineering=2;plasmatech=2" - -/obj/item/weldingtool/largetank/cyborg - name = "integrated welding tool" - desc = "An advanced welder designed to be used in robotic systems." - toolspeed = 0.5 - -/obj/item/weldingtool/largetank/flamethrower_screwdriver() - return - - -/obj/item/weldingtool/mini - name = "emergency welding tool" - desc = "A miniature welder used during emergencies." - icon_state = "miniwelder" - max_fuel = 10 - w_class = WEIGHT_CLASS_TINY - materials = list(MAT_METAL=30, MAT_GLASS=10) - change_icons = 0 - -/obj/item/weldingtool/mini/flamethrower_screwdriver() - return - -/obj/item/weldingtool/abductor - name = "alien welding tool" - desc = "An alien welding tool. Whatever fuel it uses, it never runs out." - icon = 'icons/obj/abductor.dmi' - icon_state = "welder" - toolspeed = 0.1 - light_intensity = 0 - change_icons = 0 - origin_tech = "plasmatech=5;engineering=5;abductor=3" - -/obj/item/weldingtool/abductor/process() - if(get_fuel() <= max_fuel) - reagents.add_reagent("welding_fuel", 1) - ..() - -/obj/item/weldingtool/hugetank - name = "upgraded industrial welding tool" - desc = "An upgraded welder based of the industrial welder." - icon_state = "upindwelder" - item_state = "upindwelder" - max_fuel = 80 - materials = list(MAT_METAL=70, MAT_GLASS=120) - origin_tech = "engineering=3;plasmatech=2" - -/obj/item/weldingtool/experimental - name = "experimental welding tool" - desc = "An experimental welder capable of self-fuel generation and less harmful to the eyes." - icon_state = "exwelder" - item_state = "exwelder" - max_fuel = 40 - materials = list(MAT_METAL=70, MAT_GLASS=120) - origin_tech = "materials=4;engineering=4;bluespace=3;plasmatech=4" - var/last_gen = 0 - change_icons = 0 - can_off_process = 1 - light_intensity = 1 - toolspeed = 0.5 - var/nextrefueltick = 0 - -/obj/item/weldingtool/experimental/brass - name = "brass welding tool" - desc = "A brass welder that seems to constantly refuel itself. It is faintly warm to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "brasswelder" - item_state = "brasswelder" - - -/obj/item/weldingtool/experimental/process() - ..() - if(get_fuel() < max_fuel && nextrefueltick < world.time) - nextrefueltick = world.time + 10 - reagents.add_reagent("welding_fuel", 1) - - -/* - * Crowbar - */ - -/obj/item/crowbar - name = "pocket crowbar" - desc = "A small crowbar. This handy tool is useful for lots of things, such as prying floor tiles or opening unpowered doors." - icon = 'icons/obj/tools.dmi' - icon_state = "crowbar" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - usesound = 'sound/items/crowbar.ogg' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT - force = 5 - throwforce = 7 - w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL=50) - origin_tech = "engineering=1;combat=1" - attack_verb = list("attacked", "bashed", "battered", "bludgeoned", "whacked") - toolspeed = 1 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30) - -/obj/item/crowbar/suicide_act(mob/user) - user.visible_message("[user] is beating [user.p_them()]self to death with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/weapons/genhit.ogg', 50, 1, -1) - return (BRUTELOSS) - -/obj/item/crowbar/red - icon_state = "crowbar_red" - force = 8 - -/obj/item/crowbar/brass - name = "brass crowbar" - desc = "A brass crowbar. It feels faintly warm to the touch." - resistance_flags = FIRE_PROOF | ACID_PROOF - icon_state = "crowbar_brass" - toolspeed = 0.5 - -/obj/item/crowbar/abductor - name = "alien crowbar" - desc = "A hard-light crowbar. It appears to pry by itself, without any effort required." - icon = 'icons/obj/abductor.dmi' - usesound = 'sound/weapons/sonic_jackhammer.ogg' - icon_state = "crowbar" - toolspeed = 0.1 - origin_tech = "combat=4;engineering=4;abductor=3" - -/obj/item/crowbar/large - name = "crowbar" - desc = "It's a big crowbar. It doesn't fit in your pockets, because it's big." - force = 12 - w_class = WEIGHT_CLASS_NORMAL - throw_speed = 3 - throw_range = 3 - materials = list(MAT_METAL=70) - icon_state = "crowbar_large" - item_state = "crowbar" - toolspeed = 0.5 - -/obj/item/crowbar/cyborg - name = "hydraulic crowbar" - desc = "A hydraulic prying tool, compact but powerful. Designed to replace crowbar in construction cyborgs." - usesound = 'sound/items/jaws_pry.ogg' - force = 10 - toolspeed = 0.5 - -/obj/item/crowbar/power - name = "jaws of life" - desc = "A set of jaws of life, compressed through the magic of science. It's fitted with a prying head." - icon_state = "jaws_pry" - item_state = "jawsoflife" - lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi' - materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25) - origin_tech = "materials=2;engineering=2" - usesound = 'sound/items/jaws_pry.ogg' - force = 15 - toolspeed = 0.25 - -/obj/item/crowbar/power/suicide_act(mob/user) - user.visible_message("[user] is putting [user.p_their()] head in [src], it looks like [user.p_theyre()] trying to commit suicide!") - playsound(loc, 'sound/items/jaws_pry.ogg', 50, 1, -1) - return (BRUTELOSS) - -/obj/item/crowbar/power/attack_self(mob/user) - playsound(get_turf(user), 'sound/items/change_jaws.ogg', 50, 1) - var/obj/item/wirecutters/power/cutjaws = new /obj/item/wirecutters/power - to_chat(user, "You attach the cutting jaws to [src].") - qdel(src) - user.put_in_active_hand(cutjaws) - -#undef WELDER_FUEL_BURN_INTERVAL +/obj/structure/destructible/clockwork/powered/prolonging_prism/proc/seven_random_hexes(turf/T, efficiency) + var/static/list/hex_states = list("prismhex1", "prismhex2", "prismhex3", "prismhex4", "prismhex5", "prismhex6", "prismhex7") + var/mutable_appearance/hex_combo + for(var/n in hex_states) //BUILD ME A HEXAGON + if(prob(50 * efficiency)) + if(!hex_combo) + hex_combo = mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER) + else + hex_combo.add_overlay(mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER)) + if(hex_combo) //YOU BUILT A HEXAGON + hex_combo.pixel_x = -16 + hex_combo.pixel_y = -16 + hex_combo.mouse_opacity = MOUSE_OPACITY_TRANSPARENT + hex_combo.plane = GAME_PLANE + new /obj/effect/temp_visual/ratvar/prolonging_prism(T, hex_combo) From 447937477e391c299195cf418fdc6c33f7350664 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 11 Sep 2017 13:50:49 -0500 Subject: [PATCH 246/262] more oopsies --- code/game/objects/items/weaponry.dm | 566 ---------------------------- 1 file changed, 566 deletions(-) diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 443518ec0a..17bbb0a12f 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -23,572 +23,6 @@ else M.visible_message("[M] has been banned FOR NO REISIN by [user]", "You have been banned FOR NO REISIN by [user]", "you hear a banhammer banning someone") - playsound(loc, 'sound/effects/adminhelp.ogg', 15) //keep it at 15% volume so people don't jump out of their skin too much - -/obj/item/sord - name = "\improper SORD" - desc = "This thing is so unspeakably shitty you are having a hard time even holding it." - icon_state = "sord" - item_state = "sord" - lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' - slot_flags = SLOT_BELT - force = 2 - throwforce = 1 - w_class = WEIGHT_CLASS_NORMAL - hitsound = 'sound/weapons/bladeslice.ogg' - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - -/obj/item/sord/suicide_act(mob/user) - user.visible_message("[user] is trying to impale [user.p_them()]self with [src]! It might be a suicide attempt if it weren't so shitty.", \ - "You try to impale yourself with [src], but it's USELESS...") - return SHAME - -/obj/item/claymore - name = "claymore" - desc = "What are you standing around staring at this for? Get to killing!" - icon_state = "claymore" - item_state = "claymore" - lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' - hitsound = 'sound/weapons/bladeslice.ogg' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT | SLOT_BACK - force = 40 - throwforce = 10 - w_class = WEIGHT_CLASS_NORMAL - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - block_chance = 50 - sharpness = IS_SHARP - max_integrity = 200 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50) - resistance_flags = FIRE_PROOF - -/obj/item/claymore/suicide_act(mob/user) - user.visible_message("[user] is falling on [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return(BRUTELOSS) - -/obj/item/claymore/highlander //ALL COMMENTS MADE REGARDING THIS SWORD MUST BE MADE IN ALL CAPS - desc = "THERE CAN BE ONLY ONE, AND IT WILL BE YOU!!!\nActivate it in your hand to point to the nearest victim." - flags_1 = CONDUCT_1 | NODROP_1 | DROPDEL_1 - slot_flags = null - block_chance = 0 //RNG WON'T HELP YOU NOW, PANSY - luminosity = 3 - attack_verb = list("brutalized", "eviscerated", "disemboweled", "hacked", "carved", "cleaved") //ONLY THE MOST VISCERAL ATTACK VERBS - var/notches = 0 //HOW MANY PEOPLE HAVE BEEN SLAIN WITH THIS BLADE - var/obj/item/disk/nuclear/nuke_disk //OUR STORED NUKE DISK - -/obj/item/claymore/highlander/Initialize() - . = ..() - START_PROCESSING(SSobj, src) - -/obj/item/claymore/highlander/Destroy() - if(nuke_disk) - nuke_disk.forceMove(get_turf(src)) - nuke_disk.visible_message("The nuke disk is vulnerable!") - nuke_disk = null - STOP_PROCESSING(SSobj, src) - return ..() - -/obj/item/claymore/highlander/process() - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - loc.layer = LARGE_MOB_LAYER //NO HIDING BEHIND PLANTS FOR YOU, DICKWEED (HA GET IT, BECAUSE WEEDS ARE PLANTS) - H.bleedsuppress = TRUE //AND WE WON'T BLEED OUT LIKE COWARDS - else - if(!admin_spawned) - qdel(src) - - -/obj/item/claymore/highlander/pickup(mob/living/user) - to_chat(user, "The power of Scotland protects you! You are shielded from all stuns and knockdowns.") - user.add_stun_absorption("highlander", INFINITY, 1, " is protected by the power of Scotland!", "The power of Scotland absorbs the stun!", " is protected by the power of Scotland!") - user.status_flags += IGNORESLOWDOWN - -/obj/item/claymore/highlander/dropped(mob/living/user) - user.status_flags -= IGNORESLOWDOWN - qdel(src) //If this ever happens, it's because you lost an arm - -/obj/item/claymore/highlander/examine(mob/user) - ..() - to_chat(user, "It has [!notches ? "nothing" : "[notches] notches"] scratched into the blade.") - if(nuke_disk) - to_chat(user, "It's holding the nuke disk!") - -/obj/item/claymore/highlander/attack(mob/living/target, mob/living/user) - . = ..() - if(target && target.stat == DEAD && target.mind && target.mind.special_role == "highlander") - user.fully_heal() //STEAL THE LIFE OF OUR FALLEN FOES - add_notch(user) - target.visible_message("[target] crumbles to dust beneath [user]'s blows!", "As you fall, your body crumbles to dust!") - target.dust() - -/obj/item/claymore/highlander/attack_self(mob/living/user) - var/closest_victim - var/closest_distance = 255 - for(var/mob/living/carbon/human/H in GLOB.player_list - user) - if(H.client && H.mind.special_role == "highlander" && (!closest_victim || get_dist(user, closest_victim) < closest_distance)) - closest_victim = H - if(!closest_victim) - to_chat(user, "[src] thrums for a moment and falls dark. Perhaps there's nobody nearby.") - return - to_chat(user, "[src] thrums and points to the [dir2text(get_dir(user, closest_victim))].") - -/obj/item/claymore/highlander/IsReflect() - return 1 //YOU THINK YOUR PUNY LASERS CAN STOP ME? - -/obj/item/claymore/highlander/proc/add_notch(mob/living/user) //DYNAMIC CLAYMORE PROGRESSION SYSTEM - THIS IS THE FUTURE - notches++ - force++ - var/new_name = name - switch(notches) - if(1) - to_chat(user, "Your first kill - hopefully one of many. You scratch a notch into [src]'s blade.") - to_chat(user, "You feel your fallen foe's soul entering your blade, restoring your wounds!") - new_name = "notched claymore" - if(2) - to_chat(user, "Another falls before you. Another soul fuses with your own. Another notch in the blade.") - new_name = "double-notched claymore" - add_atom_colour(rgb(255, 235, 235), ADMIN_COLOUR_PRIORITY) - if(3) - to_chat(user, "You're beginning to relish the thrill of battle.") - new_name = "triple-notched claymore" - add_atom_colour(rgb(255, 215, 215), ADMIN_COLOUR_PRIORITY) - if(4) - to_chat(user, "You've lost count of how many you've killed.") - new_name = "many-notched claymore" - add_atom_colour(rgb(255, 195, 195), ADMIN_COLOUR_PRIORITY) - if(5) - to_chat(user, "Five voices now echo in your mind, cheering the slaughter.") - new_name = "battle-tested claymore" - add_atom_colour(rgb(255, 175, 175), ADMIN_COLOUR_PRIORITY) - if(6) - to_chat(user, "Is this what the vikings felt like? Visions of glory fill your head as you slay your sixth foe.") - new_name = "battle-scarred claymore" - add_atom_colour(rgb(255, 155, 155), ADMIN_COLOUR_PRIORITY) - if(7) - to_chat(user, "Kill. Butcher. Conquer.") - new_name = "vicious claymore" - add_atom_colour(rgb(255, 135, 135), ADMIN_COLOUR_PRIORITY) - if(8) - to_chat(user, "IT NEVER GETS OLD. THE SCREAMING. THE BLOOD AS IT SPRAYS ACROSS YOUR FACE.") - new_name = "bloodthirsty claymore" - add_atom_colour(rgb(255, 115, 115), ADMIN_COLOUR_PRIORITY) - if(9) - to_chat(user, "ANOTHER ONE FALLS TO YOUR BLOWS. ANOTHER WEAKLING UNFIT TO LIVE.") - new_name = "gore-stained claymore" - add_atom_colour(rgb(255, 95, 95), ADMIN_COLOUR_PRIORITY) - if(10) - user.visible_message("[user]'s eyes light up with a vengeful fire!", \ - "YOU FEEL THE POWER OF VALHALLA FLOWING THROUGH YOU! THERE CAN BE ONLY ONE!!!") - user.update_icons() - new_name = "GORE-DRENCHED CLAYMORE OF [pick("THE WHIMSICAL SLAUGHTER", "A THOUSAND SLAUGHTERED CATTLE", "GLORY AND VALHALLA", "ANNIHILATION", "OBLITERATION")]" - icon_state = "claymore_valhalla" - item_state = "cultblade" - remove_atom_colour(ADMIN_COLOUR_PRIORITY) - - name = new_name - playsound(user, 'sound/items/screwdriver2.ogg', 50, 1) - -/obj/item/katana - name = "katana" - desc = "Woefully underpowered in D20" - icon_state = "katana" - item_state = "katana" - lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' - flags_1 = CONDUCT_1 - slot_flags = SLOT_BELT | SLOT_BACK - force = 40 - throwforce = 10 - w_class = WEIGHT_CLASS_NORMAL - hitsound = 'sound/weapons/bladeslice.ogg' - attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - block_chance = 50 - sharpness = IS_SHARP - max_integrity = 200 - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50) - resistance_flags = FIRE_PROOF - -/obj/item/katana/cursed - slot_flags = null - -/obj/item/katana/suicide_act(mob/user) - user.visible_message("[user] is slitting [user.p_their()] stomach open with [src]! It looks like [user.p_theyre()] trying to commit seppuku!") - return(BRUTELOSS) - -/obj/item/wirerod - name = "wired rod" - desc = "A rod with some wire wrapped around the top. It'd be easy to attach something to the top bit." - icon_state = "wiredrod" - item_state = "rods" - flags_1 = CONDUCT_1 - force = 9 - throwforce = 10 - w_class = WEIGHT_CLASS_NORMAL - materials = list(MAT_METAL=1150, MAT_GLASS=75) - attack_verb = list("hit", "bludgeoned", "whacked", "bonked") - -/obj/item/wirerod/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/shard)) - var/obj/item/twohanded/spear/S = new /obj/item/twohanded/spear - - remove_item_from_storage(user) - qdel(I) - qdel(src) - - user.put_in_hands(S) - to_chat(user, "You fasten the glass shard to the top of the rod with the cable.") - - else if(istype(I, /obj/item/device/assembly/igniter) && !(I.flags_1 & NODROP_1)) - var/obj/item/melee/baton/cattleprod/P = new /obj/item/melee/baton/cattleprod - - remove_item_from_storage(user) - - to_chat(user, "You fasten [I] to the top of the rod with the cable.") - - qdel(I) - qdel(src) - - user.put_in_hands(P) - else - return ..() - - -/obj/item/throwing_star - name = "throwing star" - desc = "An ancient weapon still used to this day due to it's ease of lodging itself into victim's body parts" - icon_state = "throwingstar" - item_state = "eshield0" - lefthand_file = 'icons/mob/inhands/equipment/shields_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/shields_righthand.dmi' - force = 2 - throwforce = 20 //This is never used on mobs since this has a 100% embed chance. - throw_speed = 4 - embedded_pain_multiplier = 4 - w_class = WEIGHT_CLASS_SMALL - embed_chance = 100 - embedded_fall_chance = 0 //Hahaha! - sharpness = IS_SHARP - materials = list(MAT_METAL=500, MAT_GLASS=500) - resistance_flags = FIRE_PROOF - - -/obj/item/switchblade - name = "switchblade" - icon_state = "switchblade" - lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi' - desc = "A sharp, concealable, spring-loaded knife." - flags_1 = CONDUCT_1 - force = 3 - w_class = WEIGHT_CLASS_SMALL - throwforce = 5 - throw_speed = 3 - throw_range = 6 - materials = list(MAT_METAL=12000) - origin_tech = "engineering=3;combat=2" - hitsound = 'sound/weapons/genhit.ogg' - attack_verb = list("stubbed", "poked") - resistance_flags = FIRE_PROOF - var/extended = 0 - -/obj/item/switchblade/attack_self(mob/user) - extended = !extended - playsound(src.loc, 'sound/weapons/batonextend.ogg', 50, 1) - if(extended) - force = 20 - w_class = WEIGHT_CLASS_NORMAL - throwforce = 23 - icon_state = "switchblade_ext" - attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") - hitsound = 'sound/weapons/bladeslice.ogg' - sharpness = IS_SHARP - else - force = 3 - w_class = WEIGHT_CLASS_SMALL - throwforce = 5 - icon_state = "switchblade" - attack_verb = list("stubbed", "poked") - hitsound = 'sound/weapons/genhit.ogg' - sharpness = IS_BLUNT - -/obj/item/switchblade/suicide_act(mob/user) - user.visible_message("[user] is slitting [user.p_their()] own throat with [src]! It looks like [user.p_theyre()] trying to commit suicide!") - return (BRUTELOSS) - -/obj/item/phone - name = "red phone" - desc = "Should anything ever go wrong..." - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "red_phone" - force = 3 - throwforce = 2 - throw_speed = 3 - throw_range = 4 - w_class = WEIGHT_CLASS_SMALL - attack_verb = list("called", "rang") - hitsound = 'sound/weapons/ring.ogg' - -/obj/item/phone/suicide_act(mob/user) - if(locate(/obj/structure/chair/stool) in user.loc) - user.visible_message("[user] begins to tie a noose with [src]'s cord! It looks like [user.p_theyre()] trying to commit suicide!") - else - user.visible_message("[user] is strangling [user.p_them()]self with [src]'s cord! It looks like [user.p_theyre()] trying to commit suicide!") - return(OXYLOSS) - -/obj/item/cane - name = "cane" - desc = "A cane used by a true gentleman. Or a clown." - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "cane" - item_state = "stick" - lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' - force = 5 - throwforce = 5 - w_class = WEIGHT_CLASS_SMALL - materials = list(MAT_METAL=50) - attack_verb = list("bludgeoned", "whacked", "disciplined", "thrashed") - -/obj/item/staff - name = "wizard staff" - desc = "Apparently a staff used by the wizard." - icon = 'icons/obj/wizard.dmi' - icon_state = "staff" - lefthand_file = 'icons/mob/inhands/weapons/staves_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/staves_righthand.dmi' - force = 3 - throwforce = 5 - throw_speed = 2 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - armour_penetration = 100 - attack_verb = list("bludgeoned", "whacked", "disciplined") - resistance_flags = FLAMMABLE - -/obj/item/staff/broom - name = "broom" - desc = "Used for sweeping, and flying into the night while cackling. Black cat not included." - icon = 'icons/obj/wizard.dmi' - icon_state = "broom" - resistance_flags = FLAMMABLE - -/obj/item/staff/stick - name = "stick" - desc = "A great tool to drag someone else's drinks across the bar." - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "stick" - item_state = "stick" - lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' - force = 3 - throwforce = 5 - throw_speed = 2 - throw_range = 5 - w_class = WEIGHT_CLASS_SMALL - -/obj/item/ectoplasm - name = "ectoplasm" - desc = "spooky" - gender = PLURAL - icon = 'icons/obj/wizard.dmi' - icon_state = "ectoplasm" - -/obj/item/ectoplasm/suicide_act(mob/user) - user.visible_message("[user] is inhaling [src]! It looks like [user.p_theyre()] trying to visit the astral plane.") - return (OXYLOSS) - -/obj/item/mounted_chainsaw - name = "mounted chainsaw" - desc = "A chainsaw that has replaced your arm." - icon_state = "chainsaw_on" - item_state = "mounted_chainsaw" - lefthand_file = 'icons/mob/inhands/weapons/chainsaw_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/chainsaw_righthand.dmi' - flags_1 = NODROP_1 | ABSTRACT_1 | DROPDEL_1 - w_class = WEIGHT_CLASS_HUGE - force = 21 - throwforce = 0 - throw_range = 0 - throw_speed = 0 - sharpness = IS_SHARP - attack_verb = list("sawed", "torn", "cut", "chopped", "diced") - hitsound = 'sound/weapons/chainsawhit.ogg' - -/obj/item/mounted_chainsaw/Destroy() - var/obj/item/bodypart/part - new /obj/item/twohanded/required/chainsaw(get_turf(src)) - if(iscarbon(loc)) - var/mob/living/carbon/holder = loc - var/index = holder.get_held_index_of_item(src) - if(index) - part = holder.hand_bodyparts[index] - . = ..() - if(part) - part.drop_limb() - -/obj/item/statuebust - name = "bust" - desc = "A priceless ancient marble bust, the kind that belongs in a museum." //or you can hit people with it - icon = 'icons/obj/statue.dmi' - icon_state = "bust" - force = 15 - throwforce = 10 - throw_speed = 5 - throw_range = 2 - attack_verb = list("busted") - -/obj/item/tailclub - name = "tail club" - desc = "For the beating to death of lizards with their own tails." - icon_state = "tailclub" - force = 14 - throwforce = 1 // why are you throwing a club do you even weapon - throw_speed = 1 - throw_range = 1 - attack_verb = list("clubbed", "bludgeoned") - -/obj/item/melee/chainofcommand/tailwhip - name = "liz o' nine tails" - desc = "A whip fashioned from the severed tails of lizards." - icon_state = "tailwhip" - origin_tech = "engineering=3;combat=3;biotech=3" - needs_permit = 0 - -/obj/item/melee/chainofcommand/tailwhip/kitty - name = "cat o' nine tails" - desc = "A whip fashioned from the severed tails of cats." - icon_state = "catwhip" - -/obj/item/melee/skateboard - name = "skateboard" - desc = "A skateboard. It can be placed on its wheels and ridden, or used as a strong weapon." - icon_state = "skateboard" - item_state = "skateboard" - force = 12 - throwforce = 4 - w_class = WEIGHT_CLASS_HUGE - attack_verb = list("smacked", "whacked", "slammed", "smashed") - -/obj/item/melee/skateboard/attack_self(mob/user) - new /obj/vehicle/scooter/skateboard(get_turf(user)) - qdel(src) - -/obj/item/melee/baseball_bat - name = "baseball bat" - desc = "There ain't a skull in the league that can withstand a swatter." - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "baseball_bat" - item_state = "baseball_bat" - lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' - force = 10 - throwforce = 12 - attack_verb = list("beat", "smacked") - w_class = WEIGHT_CLASS_HUGE - var/homerun_ready = 0 - var/homerun_able = 0 - -/obj/item/melee/baseball_bat/homerun - name = "home run bat" - desc = "This thing looks dangerous... Dangerously good at baseball, that is." - homerun_able = 1 - -/obj/item/melee/baseball_bat/attack_self(mob/user) - if(!homerun_able) - ..() - return - if(homerun_ready) - to_chat(user, "You're already ready to do a home run!") - ..() - return - to_chat(user, "You begin gathering strength...") - playsound(get_turf(src), 'sound/magic/lightning_chargeup.ogg', 65, 1) - if(do_after(user, 90, target = src)) - to_chat(user, "You gather power! Time for a home run!") - homerun_ready = 1 - ..() - -/obj/item/melee/baseball_bat/attack(mob/living/target, mob/living/user) - . = ..() - var/atom/throw_target = get_edge_target_turf(target, user.dir) - if(homerun_ready) - user.visible_message("It's a home run!") - target.throw_at(throw_target, rand(8,10), 14, user) - target.ex_act(EXPLODE_HEAVY) - playsound(get_turf(src), 'sound/weapons/homerun.ogg', 100, 1) - homerun_ready = 0 - return - else if(!target.anchored) - target.throw_at(throw_target, rand(1,2), 7, user) - -/obj/item/melee/baseball_bat/ablative - name = "metal baseball bat" - desc = "This bat is made of highly reflective, highly armored material." - icon_state = "baseball_bat_metal" - item_state = "baseball_bat_metal" - force = 12 - throwforce = 15 - -/obj/item/melee/baseball_bat/ablative/IsReflect()//some day this will reflect thrown items instead of lasers - var/picksound = rand(1,2) - var/turf = get_turf(src) - if(picksound == 1) - playsound(turf, 'sound/weapons/effects/batreflect1.ogg', 50, 1) - if(picksound == 2) - playsound(turf, 'sound/weapons/effects/batreflect2.ogg', 50, 1) - return 1 - -/obj/item/melee/flyswatter - name = "flyswatter" - desc = "Useful for killing insects of all sizes." - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "flyswatter" - item_state = "flyswatter" - lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' - force = 1 - throwforce = 1 - attack_verb = list("swatted", "smacked") - hitsound = 'sound/effects/snap.ogg' - w_class = WEIGHT_CLASS_SMALL - //Things in this list will be instantly splatted. Flyman weakness is handled in the flyman species weakness proc. - var/list/strong_against - -/obj/item/melee/flyswatter/Initialize() - . = ..() - strong_against = typecacheof(list( - /mob/living/simple_animal/hostile/poison/bees/, - /mob/living/simple_animal/butterfly, - /mob/living/simple_animal/cockroach, - /obj/item/queen_bee - )) - - -/obj/item/melee/flyswatter/afterattack(atom/target, mob/user, proximity_flag) - if(proximity_flag) - if(is_type_in_typecache(target, strong_against)) - new /obj/effect/decal/cleanable/deadcockroach(get_turf(target)) - to_chat(user, "You easily splat the [target].") - if(istype(target, /mob/living/)) - var/mob/living/bug = target - bug.death(1) - else - qdel(target) - -/obj/item/circlegame - name = "circled hand" - desc = "If somebody looks at this while it's below your waist, you get to bop them." - icon_state = "madeyoulook" - force = 0 - throwforce = 0 - flags_1 = DROPDEL_1 | ABSTRACT_1 - attack_verb = list("bopped") - -/obj/item/proc/can_trigger_gun(mob/living/user) - if(!user.can_use_guns(src)) - return FALSE playsound(loc, 'sound/effects/adminhelp.ogg', 15) //keep it at 15% volume so people don't jump out of their skin too much /obj/item/sord From 9e0cb0fa7c6a9a484f6a2eb82292bcbfc3eb5c61 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 11 Sep 2017 13:53:18 -0500 Subject: [PATCH 247/262] Update datumvars.dm --- code/datums/datumvars.dm | 2282 +++++++++++++++++++------------------- 1 file changed, 1138 insertions(+), 1144 deletions(-) diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index cb9be25f05..6df724c737 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -1,492 +1,490 @@ -/datum - var/var_edited = FALSE //Warrenty void if seal is broken - var/fingerprintslast = null - -/datum/proc/can_vv_get(var_name) - return TRUE - -/datum/proc/vv_edit_var(var_name, var_value) //called whenever a var is edited - switch(var_name) - if ("vars") - return FALSE - if ("var_edited") - return FALSE - var_edited = TRUE - vars[var_name] = var_value - -/datum/proc/vv_get_var(var_name) - switch(var_name) - if ("vars") - return debug_variable(var_name, list(), 0, src) - return debug_variable(var_name, vars[var_name], 0, src) - -//please call . = ..() first and append to the result, that way parent items are always at the top and child items are further down +/datum + var/var_edited = FALSE //Warrenty void if seal is broken + var/fingerprintslast = null + +/datum/proc/can_vv_get(var_name) + return TRUE + +/datum/proc/vv_edit_var(var_name, var_value) //called whenever a var is edited + switch(var_name) + if ("vars") + return FALSE + if ("var_edited") + return FALSE + var_edited = TRUE + vars[var_name] = var_value + +/datum/proc/vv_get_var(var_name) + switch(var_name) + if ("vars") + return debug_variable(var_name, list(), 0, src) + return debug_variable(var_name, vars[var_name], 0, src) + +//please call . = ..() first and append to the result, that way parent items are always at the top and child items are further down //add separaters by doing . += "---" -<<<<<<< HEAD -/datum/proc/vv_get_dropdown() - . = list() - . += "---" - .["Call Proc"] = "?_src_=vars;proc_call=\ref[src]" - .["Mark Object"] = "?_src_=vars;mark_object=\ref[src]" - .["Delete"] = "?_src_=vars;delete=\ref[src]" - - -/datum/proc/on_reagent_change() - return - - -/client/proc/debug_variables(datum/D in world) - set category = "Debug" - set name = "View Variables" - //set src in world - var/static/cookieoffset = rand(1, 9999) //to force cookies to reset after the round. - - if(!usr.client || !usr.client.holder) - to_chat(usr, "You need to be an administrator to access this.") - return - - if(!D) - return - - var/islist = islist(D) - if (!islist && !istype(D)) - return - - var/title = "" - var/refid = "\ref[D]" - var/icon/sprite - var/hash - - var/type = /list - if (!islist) - type = D.type - - - +/datum/proc/vv_get_dropdown() + . = list() + . += "---" + .["Call Proc"] = "?_src_=vars;proc_call=\ref[src]" + .["Mark Object"] = "?_src_=vars;mark_object=\ref[src]" + .["Delete"] = "?_src_=vars;delete=\ref[src]" + + +/datum/proc/on_reagent_change() + return + + +/client/proc/debug_variables(datum/D in world) + set category = "Debug" + set name = "View Variables" + //set src in world + var/static/cookieoffset = rand(1, 9999) //to force cookies to reset after the round. + + if(!usr.client || !usr.client.holder) + to_chat(usr, "You need to be an administrator to access this.") + return + + if(!D) + return + + var/islist = islist(D) + if (!islist && !istype(D)) + return + + var/title = "" + var/refid = "\ref[D]" + var/icon/sprite + var/hash + + var/type = /list + if (!islist) + type = D.type + + + if(istype(D, /atom)) - var/atom/AT = D - if(AT.icon && AT.icon_state) - sprite = new /icon(AT.icon, AT.icon_state) - hash = md5(AT.icon) - hash = md5(hash + AT.icon_state) - usr << browse_rsc(sprite, "vv[hash].png") - - title = "[D] (\ref[D]) = [type]" - - var/sprite_text - if(sprite) - sprite_text = "" - var/list/atomsnowflake = list() - + var/atom/AT = D + if(AT.icon && AT.icon_state) + sprite = new /icon(AT.icon, AT.icon_state) + hash = md5(AT.icon) + hash = md5(hash + AT.icon_state) + usr << browse_rsc(sprite, "vv[hash].png") + + title = "[D] (\ref[D]) = [type]" + + var/sprite_text + if(sprite) + sprite_text = "" + var/list/atomsnowflake = list() + if(istype(D, /atom)) - var/atom/A = D - if(isliving(A)) - atomsnowflake += "[D]" - if(A.dir) - atomsnowflake += "
    << [dir2text(A.dir)] >>" - var/mob/living/M = A - atomsnowflake += {" -
    [M.ckey ? M.ckey : "No ckey"] / [M.real_name ? M.real_name : "No real name"] -
    - BRUTE:[M.getBruteLoss()] - FIRE:[M.getFireLoss()] - TOXIN:[M.getToxLoss()] - OXY:[M.getOxyLoss()] - CLONE:[M.getCloneLoss()] - BRAIN:[M.getBrainLoss()] - STAMINA:[M.getStaminaLoss()] - - "} - else - atomsnowflake += "[D]" - if(A.dir) - atomsnowflake += "
    << [dir2text(A.dir)] >>" - else - atomsnowflake += "[D]" - - var/formatted_type = "[type]" - if(length(formatted_type) > 25) - var/middle_point = length(formatted_type) / 2 - var/splitpoint = findtext(formatted_type,"/",middle_point) - if(splitpoint) - formatted_type = "[copytext(formatted_type,1,splitpoint)]
    [copytext(formatted_type,splitpoint)]" - else - formatted_type = "Type too long" //No suitable splitpoint (/) found. - - var/marked - if(holder.marked_datum && holder.marked_datum == D) - marked = "
    Marked Object" - var/varedited_line = "" - if(!islist && D.var_edited) - varedited_line = "
    Var Edited" - - var/list/dropdownoptions = list() - if (islist) - dropdownoptions = list( - "---", - "Add Item" = "?_src_=vars;listadd=[refid]", - "Remove Nulls" = "?_src_=vars;listnulls=[refid]", - "Remove Dupes" = "?_src_=vars;listdupes=[refid]", - "Set len" = "?_src_=vars;listlen=[refid]", - "Shuffle" = "?_src_=vars;listshuffle=[refid]" - ) - else - dropdownoptions = D.vv_get_dropdown() - var/list/dropdownoptions_html = list() - - for (var/name in dropdownoptions) - var/link = dropdownoptions[name] - if (link) - dropdownoptions_html += "" - else - dropdownoptions_html += "" - - var/list/names = list() - if (!islist) - for (var/V in D.vars) - names += V - sleep(1)//For some reason, without this sleep, VVing will cause client to disconnect on certain objects. - - var/list/variable_html = list() - if (islist) - var/list/L = D - for (var/i in 1 to L.len) - var/key = L[i] - var/value - if (IS_NORMAL_LIST(L) && !isnum(key)) - value = L[key] - variable_html += debug_variable(i, value, 0, D) - else - - names = sortList(names) - for (var/V in names) - if(D.can_vv_get(V)) - variable_html += D.vv_get_var(V) - - var/html = {" - - - [title] - - - - -
    - - - - - -
    - - - - -
    - [sprite_text] -
    - [atomsnowflake.Join()] -
    -
    -
    - [formatted_type] - [marked] - [varedited_line] -
    -
    -
    - Refresh -
    - -
    -
    -
    -
    -
    - - E - Edit, tries to determine the variable type by itself.
    - C - Change, asks you for the var type first.
    - M - Mass modify: changes this variable for all objects of this type.
    -
    -
    - - - - - -
    -
    - Search: -
    -
    - -
    -
    -
      - [variable_html.Join()] -
    - - - -"} - - usr << browse(html, "window=variables[refid];size=475x650") - - -#define VV_HTML_ENCODE(thing) ( sanitize ? html_encode(thing) : thing ) -/proc/debug_variable(name, value, level, datum/DA = null, sanitize = TRUE) - var/header - if(DA) - if (islist(DA)) - var/index = name - if (value) - name = DA[name] //name is really the index until this line - else - value = DA[name] - header = "
  • (E) (C) (-) " - else - header = "
  • (E) (C) (M) " - else - header = "
  • " - - var/item - if (isnull(value)) - item = "[VV_HTML_ENCODE(name)] = null" - - else if (istext(value)) - item = "[VV_HTML_ENCODE(name)] = \"[VV_HTML_ENCODE(value)]\"" - - else if (isicon(value)) - #ifdef VARSICON - var/icon/I = new/icon(value) - var/rnd = rand(1,10000) - var/rname = "tmp\ref[I][rnd].png" - usr << browse_rsc(I, rname) - item = "[VV_HTML_ENCODE(name)] = ([value]) " - #else - item = "[VV_HTML_ENCODE(name)] = /icon ([value])" - #endif - -/* else if (istype(value, /image)) - #ifdef VARSICON - var/rnd = rand(1, 10000) - var/image/I = value - - src << browse_rsc(I.icon, "tmp\ref[value][rnd].png") - html += "[name] = " - #else - html += "[name] = /image ([value])" - #endif -*/ - else if (isfile(value)) - item = "[VV_HTML_ENCODE(name)] = '[value]'" - - //else if (istype(value, /client)) - // var/client/C = value - // item = "[VV_HTML_ENCODE(name)] \ref[value] = [C] [C.type]" - - else if (istype(value, /datum)) - var/datum/D = value - if ("[D]" != "[D.type]") //if the thing as a name var, lets use it. - item = "[VV_HTML_ENCODE(name)] \ref[value] = [D] [D.type]" - else - item = "[VV_HTML_ENCODE(name)] \ref[value] = [D.type]" - - else if (islist(value)) - var/list/L = value - var/list/items = list() - - if (L.len > 0 && !(name == "underlays" || name == "overlays" || L.len > (IS_NORMAL_LIST(L) ? 50 : 150))) - for (var/i in 1 to L.len) - var/key = L[i] - var/val - if (IS_NORMAL_LIST(L) && !isnum(key)) - val = L[key] - if (!val) - val = key - key = i - - items += debug_variable(key, val, level + 1, sanitize = sanitize) - - item = "[VV_HTML_ENCODE(name)] = /list ([L.len])
      [items.Join()]
    " - else - item = "[VV_HTML_ENCODE(name)] = /list ([L.len])" - - else - item = "[VV_HTML_ENCODE(name)] = [VV_HTML_ENCODE(value)]" - - return "[header][item]
  • " - -#undef VV_HTML_ENCODE - -/client/proc/view_var_Topic(href, href_list, hsrc) - if( (usr.client != src) || !src.holder ) - return - if(href_list["Vars"]) - debug_variables(locate(href_list["Vars"])) - - else if(href_list["datumrefresh"]) - var/datum/DAT = locate(href_list["datumrefresh"]) - if(!DAT) //can't be an istype() because /client etc aren't datums - return - src.debug_variables(DAT) - - else if(href_list["mob_player_panel"]) - if(!check_rights(0)) - return - -======= + var/atom/A = D + if(isliving(A)) + atomsnowflake += "[D]" + if(A.dir) + atomsnowflake += "
    << [dir2text(A.dir)] >>" + var/mob/living/M = A + atomsnowflake += {" +
    [M.ckey ? M.ckey : "No ckey"] / [M.real_name ? M.real_name : "No real name"] +
    + BRUTE:[M.getBruteLoss()] + FIRE:[M.getFireLoss()] + TOXIN:[M.getToxLoss()] + OXY:[M.getOxyLoss()] + CLONE:[M.getCloneLoss()] + BRAIN:[M.getBrainLoss()] + STAMINA:[M.getStaminaLoss()] + + "} + else + atomsnowflake += "[D]" + if(A.dir) + atomsnowflake += "
    << [dir2text(A.dir)] >>" + else + atomsnowflake += "[D]" + + var/formatted_type = "[type]" + if(length(formatted_type) > 25) + var/middle_point = length(formatted_type) / 2 + var/splitpoint = findtext(formatted_type,"/",middle_point) + if(splitpoint) + formatted_type = "[copytext(formatted_type,1,splitpoint)]
    [copytext(formatted_type,splitpoint)]" + else + formatted_type = "Type too long" //No suitable splitpoint (/) found. + + var/marked + if(holder.marked_datum && holder.marked_datum == D) + marked = "
    Marked Object" + var/varedited_line = "" + if(!islist && D.var_edited) + varedited_line = "
    Var Edited" + + var/list/dropdownoptions = list() + if (islist) + dropdownoptions = list( + "---", + "Add Item" = "?_src_=vars;listadd=[refid]", + "Remove Nulls" = "?_src_=vars;listnulls=[refid]", + "Remove Dupes" = "?_src_=vars;listdupes=[refid]", + "Set len" = "?_src_=vars;listlen=[refid]", + "Shuffle" = "?_src_=vars;listshuffle=[refid]" + ) + else + dropdownoptions = D.vv_get_dropdown() + var/list/dropdownoptions_html = list() + + for (var/name in dropdownoptions) + var/link = dropdownoptions[name] + if (link) + dropdownoptions_html += "" + else + dropdownoptions_html += "" + + var/list/names = list() + if (!islist) + for (var/V in D.vars) + names += V + sleep(1)//For some reason, without this sleep, VVing will cause client to disconnect on certain objects. + + var/list/variable_html = list() + if (islist) + var/list/L = D + for (var/i in 1 to L.len) + var/key = L[i] + var/value + if (IS_NORMAL_LIST(L) && !isnum(key)) + value = L[key] + variable_html += debug_variable(i, value, 0, D) + else + + names = sortList(names) + for (var/V in names) + if(D.can_vv_get(V)) + variable_html += D.vv_get_var(V) + + var/html = {" + + + [title] + + + + +
    + + + + + +
    + + + + +
    + [sprite_text] +
    + [atomsnowflake.Join()] +
    +
    +
    + [formatted_type] + [marked] + [varedited_line] +
    +
    +
    + Refresh +
    + +
    +
    +
    +
    +
    + + E - Edit, tries to determine the variable type by itself.
    + C - Change, asks you for the var type first.
    + M - Mass modify: changes this variable for all objects of this type.
    +
    +
    + + + + + +
    +
    + Search: +
    +
    + +
    +
    +
      + [variable_html.Join()] +
    + + + +"} + + usr << browse(html, "window=variables[refid];size=475x650") + + +#define VV_HTML_ENCODE(thing) ( sanitize ? html_encode(thing) : thing ) +/proc/debug_variable(name, value, level, datum/DA = null, sanitize = TRUE) + var/header + if(DA) + if (islist(DA)) + var/index = name + if (value) + name = DA[name] //name is really the index until this line + else + value = DA[name] + header = "
  • (E) (C) (-) " + else + header = "
  • (E) (C) (M) " + else + header = "
  • " + + var/item + if (isnull(value)) + item = "[VV_HTML_ENCODE(name)] = null" + + else if (istext(value)) + item = "[VV_HTML_ENCODE(name)] = \"[VV_HTML_ENCODE(value)]\"" + + else if (isicon(value)) + #ifdef VARSICON + var/icon/I = new/icon(value) + var/rnd = rand(1,10000) + var/rname = "tmp\ref[I][rnd].png" + usr << browse_rsc(I, rname) + item = "[VV_HTML_ENCODE(name)] = ([value]) " + #else + item = "[VV_HTML_ENCODE(name)] = /icon ([value])" + #endif + +/* else if (istype(value, /image)) + #ifdef VARSICON + var/rnd = rand(1, 10000) + var/image/I = value + + src << browse_rsc(I.icon, "tmp\ref[value][rnd].png") + html += "[name] = " + #else + html += "[name] = /image ([value])" + #endif +*/ + else if (isfile(value)) + item = "[VV_HTML_ENCODE(name)] = '[value]'" + + //else if (istype(value, /client)) + // var/client/C = value + // item = "[VV_HTML_ENCODE(name)] \ref[value] = [C] [C.type]" + + else if (istype(value, /datum)) + var/datum/D = value + if ("[D]" != "[D.type]") //if the thing as a name var, lets use it. + item = "[VV_HTML_ENCODE(name)] \ref[value] = [D] [D.type]" + else + item = "[VV_HTML_ENCODE(name)] \ref[value] = [D.type]" + + else if (islist(value)) + var/list/L = value + var/list/items = list() + + if (L.len > 0 && !(name == "underlays" || name == "overlays" || L.len > (IS_NORMAL_LIST(L) ? 50 : 150))) + for (var/i in 1 to L.len) + var/key = L[i] + var/val + if (IS_NORMAL_LIST(L) && !isnum(key)) + val = L[key] + if (!val) + val = key + key = i + + items += debug_variable(key, val, level + 1, sanitize = sanitize) + + item = "[VV_HTML_ENCODE(name)] = /list ([L.len])
      [items.Join()]
    " + else + item = "[VV_HTML_ENCODE(name)] = /list ([L.len])" + + else + item = "[VV_HTML_ENCODE(name)] = [VV_HTML_ENCODE(value)]" + + return "[header][item]
  • " + +#undef VV_HTML_ENCODE + +/client/proc/view_var_Topic(href, href_list, hsrc) + if( (usr.client != src) || !src.holder ) + return + if(href_list["Vars"]) + debug_variables(locate(href_list["Vars"])) + + else if(href_list["datumrefresh"]) + var/datum/DAT = locate(href_list["datumrefresh"]) + if(!DAT) //can't be an istype() because /client etc aren't datums + return + src.debug_variables(DAT) + + else if(href_list["mob_player_panel"]) + if(!check_rights(0)) + return + /datum/proc/vv_get_dropdown() . = list() . += "---" @@ -951,81 +949,78 @@ if(!check_rights(0)) return ->>>>>>> 6656ce6... Gives admins the ability to show a read only vv window to a player (#30463) var/mob/M = locate(href_list["mob_player_panel"]) in GLOB.mob_list - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - src.holder.show_player_panel(M) - href_list["datumrefresh"] = href_list["mob_player_panel"] - - else if(href_list["godmode"]) - if(!check_rights(R_ADMIN)) - return - + if(!istype(M)) + to_chat(usr, "This can only be used on instances of type /mob") + return + + src.holder.show_player_panel(M) + href_list["datumrefresh"] = href_list["mob_player_panel"] + + else if(href_list["godmode"]) + if(!check_rights(R_ADMIN)) + return + var/mob/M = locate(href_list["godmode"]) in GLOB.mob_list - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - src.cmd_admin_godmode(M) - href_list["datumrefresh"] = href_list["godmode"] - - else if(href_list["mark_object"]) - if(!check_rights(0)) - return - - var/datum/D = locate(href_list["mark_object"]) - if(!istype(D)) - to_chat(usr, "This can only be done to instances of type /datum") - return - - src.holder.marked_datum = D - href_list["datumrefresh"] = href_list["mark_object"] - - else if(href_list["proc_call"]) - if(!check_rights(0)) - return - - var/T = locate(href_list["proc_call"]) - - if(T) - callproc_datum(T) - - else if(href_list["delete"]) - if(!check_rights(R_DEBUG, 0)) - return - - var/datum/D = locate(href_list["delete"]) - if(!D) - to_chat(usr, "Unable to locate item!") - admin_delete(D) - href_list["datumrefresh"] = href_list["delete"] - - else if(href_list["regenerateicons"]) - if(!check_rights(0)) - return - + if(!istype(M)) + to_chat(usr, "This can only be used on instances of type /mob") + return + + src.cmd_admin_godmode(M) + href_list["datumrefresh"] = href_list["godmode"] + + else if(href_list["mark_object"]) + if(!check_rights(0)) + return + + var/datum/D = locate(href_list["mark_object"]) + if(!istype(D)) + to_chat(usr, "This can only be done to instances of type /datum") + return + + src.holder.marked_datum = D + href_list["datumrefresh"] = href_list["mark_object"] + + else if(href_list["proc_call"]) + if(!check_rights(0)) + return + + var/T = locate(href_list["proc_call"]) + + if(T) + callproc_datum(T) + + else if(href_list["delete"]) + if(!check_rights(R_DEBUG, 0)) + return + + var/datum/D = locate(href_list["delete"]) + if(!D) + to_chat(usr, "Unable to locate item!") + admin_delete(D) + href_list["datumrefresh"] = href_list["delete"] + + else if(href_list["regenerateicons"]) + if(!check_rights(0)) + return + var/mob/M = locate(href_list["regenerateicons"]) in GLOB.mob_list -<<<<<<< HEAD - if(!ismob(M)) - to_chat(usr, "This can only be done to instances of type /mob") - return - M.regenerate_icons() - -//Needs +VAREDIT past this point - - else if(check_rights(R_VAREDIT)) - - - //~CARN: for renaming mobs (updates their name, real_name, mind.name, their ID/PDA and datacore records). - - if(href_list["rename"]) - if(!check_rights(0)) - return - -======= + if(!ismob(M)) + to_chat(usr, "This can only be done to instances of type /mob") + return + M.regenerate_icons() + +//Needs +VAREDIT past this point + + else if(check_rights(R_VAREDIT)) + + + //~CARN: for renaming mobs (updates their name, real_name, mind.name, their ID/PDA and datacore records). + + if(href_list["rename"]) + if(!check_rights(0)) + return + if(!ismob(M)) to_chat(usr, "This can only be done to instances of type /mob") return @@ -1062,379 +1057,378 @@ if(!check_rights(0)) return ->>>>>>> 6656ce6... Gives admins the ability to show a read only vv window to a player (#30463) var/mob/M = locate(href_list["rename"]) in GLOB.mob_list - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - var/new_name = stripped_input(usr,"What would you like to name this mob?","Input a name",M.real_name,MAX_NAME_LEN) - if( !new_name || !M ) - return - - message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].") - M.fully_replace_character_name(M.real_name,new_name) - href_list["datumrefresh"] = href_list["rename"] - - else if(href_list["varnameedit"] && href_list["datumedit"]) - if(!check_rights(0)) - return - - var/D = locate(href_list["datumedit"]) + if(!istype(M)) + to_chat(usr, "This can only be used on instances of type /mob") + return + + var/new_name = stripped_input(usr,"What would you like to name this mob?","Input a name",M.real_name,MAX_NAME_LEN) + if( !new_name || !M ) + return + + message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].") + M.fully_replace_character_name(M.real_name,new_name) + href_list["datumrefresh"] = href_list["rename"] + + else if(href_list["varnameedit"] && href_list["datumedit"]) + if(!check_rights(0)) + return + + var/D = locate(href_list["datumedit"]) if(!istype(D, /datum)) - to_chat(usr, "This can only be used on datums") - return - - modify_variables(D, href_list["varnameedit"], 1) - - else if(href_list["varnamechange"] && href_list["datumchange"]) - if(!check_rights(0)) - return - - var/D = locate(href_list["datumchange"]) + to_chat(usr, "This can only be used on datums") + return + + modify_variables(D, href_list["varnameedit"], 1) + + else if(href_list["varnamechange"] && href_list["datumchange"]) + if(!check_rights(0)) + return + + var/D = locate(href_list["datumchange"]) if(!istype(D, /datum)) - to_chat(usr, "This can only be used on datums") - return - - modify_variables(D, href_list["varnamechange"], 0) - - else if(href_list["varnamemass"] && href_list["datummass"]) - if(!check_rights(0)) - return - - var/datum/D = locate(href_list["datummass"]) - if(!istype(D)) - to_chat(usr, "This can only be used on instances of type /datum") - return - - cmd_mass_modify_object_variables(D, href_list["varnamemass"]) - - else if(href_list["listedit"] && href_list["index"]) - var/index = text2num(href_list["index"]) - if (!index) - return - - var/list/L = locate(href_list["listedit"]) - if (!istype(L)) - to_chat(usr, "This can only be used on instances of type /list") - return - - mod_list(L, null, "list", "contents", index, autodetect_class = TRUE) - - else if(href_list["listchange"] && href_list["index"]) - var/index = text2num(href_list["index"]) - if (!index) - return - - var/list/L = locate(href_list["listchange"]) - if (!istype(L)) - to_chat(usr, "This can only be used on instances of type /list") - return - - mod_list(L, null, "list", "contents", index, autodetect_class = FALSE) - - else if(href_list["listremove"] && href_list["index"]) - var/index = text2num(href_list["index"]) - if (!index) - return - - var/list/L = locate(href_list["listremove"]) - if (!istype(L)) - to_chat(usr, "This can only be used on instances of type /list") - return - - var/variable = L[index] - var/prompt = alert("Do you want to remove item number [index] from list?", "Confirm", "Yes", "No") - if (prompt != "Yes") - return - L.Cut(index, index+1) - log_world("### ListVarEdit by [src]: /list's contents: REMOVED=[html_encode("[variable]")]") - log_admin("[key_name(src)] modified list's contents: REMOVED=[variable]") - message_admins("[key_name_admin(src)] modified list's contents: REMOVED=[variable]") - - else if(href_list["listadd"]) - var/list/L = locate(href_list["listadd"]) - if (!istype(L)) - to_chat(usr, "This can only be used on instances of type /list") - return - - mod_list_add(L, null, "list", "contents") - - else if(href_list["listdupes"]) - var/list/L = locate(href_list["listdupes"]) - if (!istype(L)) - to_chat(usr, "This can only be used on instances of type /list") - return - - uniqueList_inplace(L) - log_world("### ListVarEdit by [src]: /list contents: CLEAR DUPES") - log_admin("[key_name(src)] modified list's contents: CLEAR DUPES") - message_admins("[key_name_admin(src)] modified list's contents: CLEAR DUPES") - - else if(href_list["listnulls"]) - var/list/L = locate(href_list["listnulls"]) - if (!istype(L)) - to_chat(usr, "This can only be used on instances of type /list") - return - - listclearnulls(L) - log_world("### ListVarEdit by [src]: /list contents: CLEAR NULLS") - log_admin("[key_name(src)] modified list's contents: CLEAR NULLS") - message_admins("[key_name_admin(src)] modified list's contents: CLEAR NULLS") - - else if(href_list["listlen"]) - var/list/L = locate(href_list["listlen"]) - if (!istype(L)) - to_chat(usr, "This can only be used on instances of type /list") - return - var/value = vv_get_value(VV_NUM) - if (value["class"] != VV_NUM) - return - - L.len = value["value"] - log_world("### ListVarEdit by [src]: /list len: [L.len]") - log_admin("[key_name(src)] modified list's len: [L.len]") - message_admins("[key_name_admin(src)] modified list's len: [L.len]") - - else if(href_list["listshuffle"]) - var/list/L = locate(href_list["listshuffle"]) - if (!istype(L)) - to_chat(usr, "This can only be used on instances of type /list") - return - - shuffle_inplace(L) - log_world("### ListVarEdit by [src]: /list contents: SHUFFLE") - log_admin("[key_name(src)] modified list's contents: SHUFFLE") - message_admins("[key_name_admin(src)] modified list's contents: SHUFFLE") - - else if(href_list["give_spell"]) - if(!check_rights(0)) - return - + to_chat(usr, "This can only be used on datums") + return + + modify_variables(D, href_list["varnamechange"], 0) + + else if(href_list["varnamemass"] && href_list["datummass"]) + if(!check_rights(0)) + return + + var/datum/D = locate(href_list["datummass"]) + if(!istype(D)) + to_chat(usr, "This can only be used on instances of type /datum") + return + + cmd_mass_modify_object_variables(D, href_list["varnamemass"]) + + else if(href_list["listedit"] && href_list["index"]) + var/index = text2num(href_list["index"]) + if (!index) + return + + var/list/L = locate(href_list["listedit"]) + if (!istype(L)) + to_chat(usr, "This can only be used on instances of type /list") + return + + mod_list(L, null, "list", "contents", index, autodetect_class = TRUE) + + else if(href_list["listchange"] && href_list["index"]) + var/index = text2num(href_list["index"]) + if (!index) + return + + var/list/L = locate(href_list["listchange"]) + if (!istype(L)) + to_chat(usr, "This can only be used on instances of type /list") + return + + mod_list(L, null, "list", "contents", index, autodetect_class = FALSE) + + else if(href_list["listremove"] && href_list["index"]) + var/index = text2num(href_list["index"]) + if (!index) + return + + var/list/L = locate(href_list["listremove"]) + if (!istype(L)) + to_chat(usr, "This can only be used on instances of type /list") + return + + var/variable = L[index] + var/prompt = alert("Do you want to remove item number [index] from list?", "Confirm", "Yes", "No") + if (prompt != "Yes") + return + L.Cut(index, index+1) + log_world("### ListVarEdit by [src]: /list's contents: REMOVED=[html_encode("[variable]")]") + log_admin("[key_name(src)] modified list's contents: REMOVED=[variable]") + message_admins("[key_name_admin(src)] modified list's contents: REMOVED=[variable]") + + else if(href_list["listadd"]) + var/list/L = locate(href_list["listadd"]) + if (!istype(L)) + to_chat(usr, "This can only be used on instances of type /list") + return + + mod_list_add(L, null, "list", "contents") + + else if(href_list["listdupes"]) + var/list/L = locate(href_list["listdupes"]) + if (!istype(L)) + to_chat(usr, "This can only be used on instances of type /list") + return + + uniqueList_inplace(L) + log_world("### ListVarEdit by [src]: /list contents: CLEAR DUPES") + log_admin("[key_name(src)] modified list's contents: CLEAR DUPES") + message_admins("[key_name_admin(src)] modified list's contents: CLEAR DUPES") + + else if(href_list["listnulls"]) + var/list/L = locate(href_list["listnulls"]) + if (!istype(L)) + to_chat(usr, "This can only be used on instances of type /list") + return + + listclearnulls(L) + log_world("### ListVarEdit by [src]: /list contents: CLEAR NULLS") + log_admin("[key_name(src)] modified list's contents: CLEAR NULLS") + message_admins("[key_name_admin(src)] modified list's contents: CLEAR NULLS") + + else if(href_list["listlen"]) + var/list/L = locate(href_list["listlen"]) + if (!istype(L)) + to_chat(usr, "This can only be used on instances of type /list") + return + var/value = vv_get_value(VV_NUM) + if (value["class"] != VV_NUM) + return + + L.len = value["value"] + log_world("### ListVarEdit by [src]: /list len: [L.len]") + log_admin("[key_name(src)] modified list's len: [L.len]") + message_admins("[key_name_admin(src)] modified list's len: [L.len]") + + else if(href_list["listshuffle"]) + var/list/L = locate(href_list["listshuffle"]) + if (!istype(L)) + to_chat(usr, "This can only be used on instances of type /list") + return + + shuffle_inplace(L) + log_world("### ListVarEdit by [src]: /list contents: SHUFFLE") + log_admin("[key_name(src)] modified list's contents: SHUFFLE") + message_admins("[key_name_admin(src)] modified list's contents: SHUFFLE") + + else if(href_list["give_spell"]) + if(!check_rights(0)) + return + var/mob/M = locate(href_list["give_spell"]) in GLOB.mob_list - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - src.give_spell(M) - href_list["datumrefresh"] = href_list["give_spell"] - - else if(href_list["remove_spell"]) - if(!check_rights(0)) - return - + if(!istype(M)) + to_chat(usr, "This can only be used on instances of type /mob") + return + + src.give_spell(M) + href_list["datumrefresh"] = href_list["give_spell"] + + else if(href_list["remove_spell"]) + if(!check_rights(0)) + return + var/mob/M = locate(href_list["remove_spell"]) in GLOB.mob_list - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - remove_spell(M) - href_list["datumrefresh"] = href_list["remove_spell"] - - else if(href_list["give_disease"]) - if(!check_rights(0)) - return - + if(!istype(M)) + to_chat(usr, "This can only be used on instances of type /mob") + return + + remove_spell(M) + href_list["datumrefresh"] = href_list["remove_spell"] + + else if(href_list["give_disease"]) + if(!check_rights(0)) + return + var/mob/M = locate(href_list["give_disease"]) in GLOB.mob_list - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - src.give_disease(M) - href_list["datumrefresh"] = href_list["give_spell"] - - else if(href_list["gib"]) - if(!check_rights(R_FUN)) - return - + if(!istype(M)) + to_chat(usr, "This can only be used on instances of type /mob") + return + + src.give_disease(M) + href_list["datumrefresh"] = href_list["give_spell"] + + else if(href_list["gib"]) + if(!check_rights(R_FUN)) + return + var/mob/M = locate(href_list["gib"]) in GLOB.mob_list - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - src.cmd_admin_gib(M) - - else if(href_list["build_mode"]) - if(!check_rights(R_BUILDMODE)) - return - + if(!istype(M)) + to_chat(usr, "This can only be used on instances of type /mob") + return + + src.cmd_admin_gib(M) + + else if(href_list["build_mode"]) + if(!check_rights(R_BUILDMODE)) + return + var/mob/M = locate(href_list["build_mode"]) in GLOB.mob_list - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - togglebuildmode(M) - href_list["datumrefresh"] = href_list["build_mode"] - - else if(href_list["drop_everything"]) - if(!check_rights(0)) - return - + if(!istype(M)) + to_chat(usr, "This can only be used on instances of type /mob") + return + + togglebuildmode(M) + href_list["datumrefresh"] = href_list["build_mode"] + + else if(href_list["drop_everything"]) + if(!check_rights(0)) + return + var/mob/M = locate(href_list["drop_everything"]) in GLOB.mob_list - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - if(usr.client) - usr.client.cmd_admin_drop_everything(M) - - else if(href_list["direct_control"]) - if(!check_rights(0)) - return - + if(!istype(M)) + to_chat(usr, "This can only be used on instances of type /mob") + return + + if(usr.client) + usr.client.cmd_admin_drop_everything(M) + + else if(href_list["direct_control"]) + if(!check_rights(0)) + return + var/mob/M = locate(href_list["direct_control"]) in GLOB.mob_list - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - if(usr.client) - usr.client.cmd_assume_direct_control(M) - - else if(href_list["offer_control"]) - if(!check_rights(0)) - return - + if(!istype(M)) + to_chat(usr, "This can only be used on instances of type /mob") + return + + if(usr.client) + usr.client.cmd_assume_direct_control(M) + + else if(href_list["offer_control"]) + if(!check_rights(0)) + return + var/mob/M = locate(href_list["offer_control"]) in GLOB.mob_list - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - offer_control(M) - - else if(href_list["delall"]) - if(!check_rights(R_DEBUG|R_SERVER)) - return - - var/obj/O = locate(href_list["delall"]) - if(!isobj(O)) - to_chat(usr, "This can only be used on instances of type /obj") - return - - var/action_type = alert("Strict type ([O.type]) or type and all subtypes?",,"Strict type","Type and subtypes","Cancel") - if(action_type == "Cancel" || !action_type) - return - - if(alert("Are you really sure you want to delete all objects of type [O.type]?",,"Yes","No") != "Yes") - return - - if(alert("Second confirmation required. Delete?",,"Yes","No") != "Yes") - return - - var/O_type = O.type - switch(action_type) - if("Strict type") - var/i = 0 - for(var/obj/Obj in world) - if(Obj.type == O_type) - i++ - qdel(Obj) - CHECK_TICK - if(!i) - to_chat(usr, "No objects of this type exist") - return - log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ") - message_admins("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ") - if("Type and subtypes") - var/i = 0 - for(var/obj/Obj in world) - if(istype(Obj,O_type)) - i++ - qdel(Obj) - CHECK_TICK - if(!i) - to_chat(usr, "No objects of this type exist") - return - log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ") - message_admins("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ") - - else if(href_list["addreagent"]) - if(!check_rights(0)) - return - - var/atom/A = locate(href_list["addreagent"]) - - if(!A.reagents) - var/amount = input(usr, "Specify the reagent size of [A]", "Set Reagent Size", 50) as num - if(amount) - A.create_reagents(amount) - - if(A.reagents) - var/chosen_id - var/list/reagent_options = sortList(GLOB.chemical_reagents_list) - switch(alert(usr, "Choose a method.", "Add Reagents", "Enter ID", "Choose ID")) - if("Enter ID") - var/valid_id - while(!valid_id) - chosen_id = stripped_input(usr, "Enter the ID of the reagent you want to add.") - if(!chosen_id) //Get me out of here! - break - for(var/ID in reagent_options) - if(ID == chosen_id) - valid_id = 1 - if(!valid_id) - to_chat(usr, "A reagent with that ID doesn't exist!") - if("Choose ID") - chosen_id = input(usr, "Choose a reagent to add.", "Choose a reagent.") as null|anything in reagent_options - if(chosen_id) - var/amount = input(usr, "Choose the amount to add.", "Choose the amount.", A.reagents.maximum_volume) as num - if(amount) - A.reagents.add_reagent(chosen_id, amount) - log_admin("[key_name(usr)] has added [amount] units of [chosen_id] to \the [A]") - message_admins("[key_name(usr)] has added [amount] units of [chosen_id] to \the [A]") - - href_list["datumrefresh"] = href_list["addreagent"] - - else if(href_list["explode"]) - if(!check_rights(R_FUN)) - return - - var/atom/A = locate(href_list["explode"]) - if(!isobj(A) && !ismob(A) && !isturf(A)) - to_chat(usr, "This can only be done to instances of type /obj, /mob and /turf") - return - - src.cmd_admin_explosion(A) - href_list["datumrefresh"] = href_list["explode"] - - else if(href_list["emp"]) - if(!check_rights(R_FUN)) - return - - var/atom/A = locate(href_list["emp"]) - if(!isobj(A) && !ismob(A) && !isturf(A)) - to_chat(usr, "This can only be done to instances of type /obj, /mob and /turf") - return - - src.cmd_admin_emp(A) - href_list["datumrefresh"] = href_list["emp"] - - else if(href_list["rotatedatum"]) - if(!check_rights(0)) - return - - var/atom/A = locate(href_list["rotatedatum"]) - if(!istype(A)) - to_chat(usr, "This can only be done to instances of type /atom") - return - - switch(href_list["rotatedir"]) - if("right") - A.setDir(turn(A.dir, -45)) - if("left") - A.setDir(turn(A.dir, 45)) - href_list["datumrefresh"] = href_list["rotatedatum"] - - else if(href_list["editorgans"]) - if(!check_rights(0)) - return - + if(!istype(M)) + to_chat(usr, "This can only be used on instances of type /mob") + return + offer_control(M) + + else if(href_list["delall"]) + if(!check_rights(R_DEBUG|R_SERVER)) + return + + var/obj/O = locate(href_list["delall"]) + if(!isobj(O)) + to_chat(usr, "This can only be used on instances of type /obj") + return + + var/action_type = alert("Strict type ([O.type]) or type and all subtypes?",,"Strict type","Type and subtypes","Cancel") + if(action_type == "Cancel" || !action_type) + return + + if(alert("Are you really sure you want to delete all objects of type [O.type]?",,"Yes","No") != "Yes") + return + + if(alert("Second confirmation required. Delete?",,"Yes","No") != "Yes") + return + + var/O_type = O.type + switch(action_type) + if("Strict type") + var/i = 0 + for(var/obj/Obj in world) + if(Obj.type == O_type) + i++ + qdel(Obj) + CHECK_TICK + if(!i) + to_chat(usr, "No objects of this type exist") + return + log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ") + message_admins("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ") + if("Type and subtypes") + var/i = 0 + for(var/obj/Obj in world) + if(istype(Obj,O_type)) + i++ + qdel(Obj) + CHECK_TICK + if(!i) + to_chat(usr, "No objects of this type exist") + return + log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ") + message_admins("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ") + + else if(href_list["addreagent"]) + if(!check_rights(0)) + return + + var/atom/A = locate(href_list["addreagent"]) + + if(!A.reagents) + var/amount = input(usr, "Specify the reagent size of [A]", "Set Reagent Size", 50) as num + if(amount) + A.create_reagents(amount) + + if(A.reagents) + var/chosen_id + var/list/reagent_options = sortList(GLOB.chemical_reagents_list) + switch(alert(usr, "Choose a method.", "Add Reagents", "Enter ID", "Choose ID")) + if("Enter ID") + var/valid_id + while(!valid_id) + chosen_id = stripped_input(usr, "Enter the ID of the reagent you want to add.") + if(!chosen_id) //Get me out of here! + break + for(var/ID in reagent_options) + if(ID == chosen_id) + valid_id = 1 + if(!valid_id) + to_chat(usr, "A reagent with that ID doesn't exist!") + if("Choose ID") + chosen_id = input(usr, "Choose a reagent to add.", "Choose a reagent.") as null|anything in reagent_options + if(chosen_id) + var/amount = input(usr, "Choose the amount to add.", "Choose the amount.", A.reagents.maximum_volume) as num + if(amount) + A.reagents.add_reagent(chosen_id, amount) + log_admin("[key_name(usr)] has added [amount] units of [chosen_id] to \the [A]") + message_admins("[key_name(usr)] has added [amount] units of [chosen_id] to \the [A]") + + href_list["datumrefresh"] = href_list["addreagent"] + + else if(href_list["explode"]) + if(!check_rights(R_FUN)) + return + + var/atom/A = locate(href_list["explode"]) + if(!isobj(A) && !ismob(A) && !isturf(A)) + to_chat(usr, "This can only be done to instances of type /obj, /mob and /turf") + return + + src.cmd_admin_explosion(A) + href_list["datumrefresh"] = href_list["explode"] + + else if(href_list["emp"]) + if(!check_rights(R_FUN)) + return + + var/atom/A = locate(href_list["emp"]) + if(!isobj(A) && !ismob(A) && !isturf(A)) + to_chat(usr, "This can only be done to instances of type /obj, /mob and /turf") + return + + src.cmd_admin_emp(A) + href_list["datumrefresh"] = href_list["emp"] + + else if(href_list["rotatedatum"]) + if(!check_rights(0)) + return + + var/atom/A = locate(href_list["rotatedatum"]) + if(!istype(A)) + to_chat(usr, "This can only be done to instances of type /atom") + return + + switch(href_list["rotatedir"]) + if("right") + A.setDir(turn(A.dir, -45)) + if("left") + A.setDir(turn(A.dir, 45)) + href_list["datumrefresh"] = href_list["rotatedatum"] + + else if(href_list["editorgans"]) + if(!check_rights(0)) + return + var/mob/living/carbon/C = locate(href_list["editorgans"]) in GLOB.mob_list - if(!istype(C)) - to_chat(usr, "This can only be done to instances of type /mob/living/carbon") - return - - manipulate_organs(C) - href_list["datumrefresh"] = href_list["editorgans"] - + if(!istype(C)) + to_chat(usr, "This can only be done to instances of type /mob/living/carbon") + return + + manipulate_organs(C) + href_list["datumrefresh"] = href_list["editorgans"] + else if(href_list["hallucinate"]) if(!check_rights(0)) return @@ -1455,238 +1449,238 @@ if(result) new result(C, TRUE) - else if(href_list["makehuman"]) - if(!check_rights(R_SPAWN)) - return - + else if(href_list["makehuman"]) + if(!check_rights(R_SPAWN)) + return + var/mob/living/carbon/monkey/Mo = locate(href_list["makehuman"]) in GLOB.mob_list - if(!istype(Mo)) - to_chat(usr, "This can only be done to instances of type /mob/living/carbon/monkey") - return - - if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") - return - if(!Mo) - to_chat(usr, "Mob doesn't exist anymore") - return - holder.Topic(href, list("humanone"=href_list["makehuman"])) - - else if(href_list["makemonkey"]) - if(!check_rights(R_SPAWN)) - return - + if(!istype(Mo)) + to_chat(usr, "This can only be done to instances of type /mob/living/carbon/monkey") + return + + if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") + return + if(!Mo) + to_chat(usr, "Mob doesn't exist anymore") + return + holder.Topic(href, list("humanone"=href_list["makehuman"])) + + else if(href_list["makemonkey"]) + if(!check_rights(R_SPAWN)) + return + var/mob/living/carbon/human/H = locate(href_list["makemonkey"]) in GLOB.mob_list - if(!istype(H)) - to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human") - return - - if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") - return - if(!H) - to_chat(usr, "Mob doesn't exist anymore") - return - holder.Topic(href, list("monkeyone"=href_list["makemonkey"])) - - else if(href_list["makerobot"]) - if(!check_rights(R_SPAWN)) - return - + if(!istype(H)) + to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human") + return + + if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") + return + if(!H) + to_chat(usr, "Mob doesn't exist anymore") + return + holder.Topic(href, list("monkeyone"=href_list["makemonkey"])) + + else if(href_list["makerobot"]) + if(!check_rights(R_SPAWN)) + return + var/mob/living/carbon/human/H = locate(href_list["makerobot"]) in GLOB.mob_list - if(!istype(H)) - to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human") - return - - if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") - return - if(!H) - to_chat(usr, "Mob doesn't exist anymore") - return - holder.Topic(href, list("makerobot"=href_list["makerobot"])) - - else if(href_list["makealien"]) - if(!check_rights(R_SPAWN)) - return - + if(!istype(H)) + to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human") + return + + if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") + return + if(!H) + to_chat(usr, "Mob doesn't exist anymore") + return + holder.Topic(href, list("makerobot"=href_list["makerobot"])) + + else if(href_list["makealien"]) + if(!check_rights(R_SPAWN)) + return + var/mob/living/carbon/human/H = locate(href_list["makealien"]) in GLOB.mob_list - if(!istype(H)) - to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human") - return - - if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") - return - if(!H) - to_chat(usr, "Mob doesn't exist anymore") - return - holder.Topic(href, list("makealien"=href_list["makealien"])) - - else if(href_list["makeslime"]) - if(!check_rights(R_SPAWN)) - return - + if(!istype(H)) + to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human") + return + + if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") + return + if(!H) + to_chat(usr, "Mob doesn't exist anymore") + return + holder.Topic(href, list("makealien"=href_list["makealien"])) + + else if(href_list["makeslime"]) + if(!check_rights(R_SPAWN)) + return + var/mob/living/carbon/human/H = locate(href_list["makeslime"]) in GLOB.mob_list - if(!istype(H)) - to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human") - return - - if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") - return - if(!H) - to_chat(usr, "Mob doesn't exist anymore") - return - holder.Topic(href, list("makeslime"=href_list["makeslime"])) - - else if(href_list["makeai"]) - if(!check_rights(R_SPAWN)) - return - + if(!istype(H)) + to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human") + return + + if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") + return + if(!H) + to_chat(usr, "Mob doesn't exist anymore") + return + holder.Topic(href, list("makeslime"=href_list["makeslime"])) + + else if(href_list["makeai"]) + if(!check_rights(R_SPAWN)) + return + var/mob/living/carbon/H = locate(href_list["makeai"]) in GLOB.mob_list - if(!istype(H)) - to_chat(usr, "This can only be done to instances of type /mob/living/carbon") - return - - if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") - return - if(!H) - to_chat(usr, "Mob doesn't exist anymore") - return - holder.Topic(href, list("makeai"=href_list["makeai"])) - - else if(href_list["setspecies"]) - if(!check_rights(R_SPAWN)) - return - + if(!istype(H)) + to_chat(usr, "This can only be done to instances of type /mob/living/carbon") + return + + if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") + return + if(!H) + to_chat(usr, "Mob doesn't exist anymore") + return + holder.Topic(href, list("makeai"=href_list["makeai"])) + + else if(href_list["setspecies"]) + if(!check_rights(R_SPAWN)) + return + var/mob/living/carbon/human/H = locate(href_list["setspecies"]) in GLOB.mob_list - if(!istype(H)) - to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human") - return - - var/result = input(usr, "Please choose a new species","Species") as null|anything in GLOB.species_list - - if(!H) - to_chat(usr, "Mob doesn't exist anymore") - return - - if(result) - var/newtype = GLOB.species_list[result] - admin_ticket_log("[key_name_admin(usr)] has modified the bodyparts of [H] to [result]") - H.set_species(newtype) - - else if(href_list["editbodypart"]) - if(!check_rights(R_SPAWN)) - return - + if(!istype(H)) + to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human") + return + + var/result = input(usr, "Please choose a new species","Species") as null|anything in GLOB.species_list + + if(!H) + to_chat(usr, "Mob doesn't exist anymore") + return + + if(result) + var/newtype = GLOB.species_list[result] + admin_ticket_log("[key_name_admin(usr)] has modified the bodyparts of [H] to [result]") + H.set_species(newtype) + + else if(href_list["editbodypart"]) + if(!check_rights(R_SPAWN)) + return + var/mob/living/carbon/C = locate(href_list["editbodypart"]) in GLOB.mob_list - if(!istype(C)) - to_chat(usr, "This can only be done to instances of type /mob/living/carbon") - return - - var/edit_action = input(usr, "What would you like to do?","Modify Body Part") as null|anything in list("add","remove", "augment") - if(!edit_action) - return - var/list/limb_list = list("head", "l_arm", "r_arm", "l_leg", "r_leg") - if(edit_action == "augment") - limb_list += "chest" - var/result = input(usr, "Please choose which body part to [edit_action]","[capitalize(edit_action)] Body Part") as null|anything in limb_list - - if(!C) - to_chat(usr, "Mob doesn't exist anymore") - return - - if(result) - var/obj/item/bodypart/BP = C.get_bodypart(result) - switch(edit_action) - if("remove") - if(BP) - BP.drop_limb() - else - to_chat(usr, "[C] doesn't have such bodypart.") - if("add") - if(BP) - to_chat(usr, "[C] already has such bodypart.") - else - if(!C.regenerate_limb(result)) - to_chat(usr, "[C] cannot have such bodypart.") - if("augment") - if(ishuman(C)) - if(BP) - BP.change_bodypart_status(BODYPART_ROBOTIC, TRUE, TRUE) - else - to_chat(usr, "[C] doesn't have such bodypart.") - else - to_chat(usr, "Only humans can be augmented.") - admin_ticket_log("[key_name_admin(usr)] has modified the bodyparts of [C]") - - - else if(href_list["purrbation"]) - if(!check_rights(R_SPAWN)) - return - + if(!istype(C)) + to_chat(usr, "This can only be done to instances of type /mob/living/carbon") + return + + var/edit_action = input(usr, "What would you like to do?","Modify Body Part") as null|anything in list("add","remove", "augment") + if(!edit_action) + return + var/list/limb_list = list("head", "l_arm", "r_arm", "l_leg", "r_leg") + if(edit_action == "augment") + limb_list += "chest" + var/result = input(usr, "Please choose which body part to [edit_action]","[capitalize(edit_action)] Body Part") as null|anything in limb_list + + if(!C) + to_chat(usr, "Mob doesn't exist anymore") + return + + if(result) + var/obj/item/bodypart/BP = C.get_bodypart(result) + switch(edit_action) + if("remove") + if(BP) + BP.drop_limb() + else + to_chat(usr, "[C] doesn't have such bodypart.") + if("add") + if(BP) + to_chat(usr, "[C] already has such bodypart.") + else + if(!C.regenerate_limb(result)) + to_chat(usr, "[C] cannot have such bodypart.") + if("augment") + if(ishuman(C)) + if(BP) + BP.change_bodypart_status(BODYPART_ROBOTIC, TRUE, TRUE) + else + to_chat(usr, "[C] doesn't have such bodypart.") + else + to_chat(usr, "Only humans can be augmented.") + admin_ticket_log("[key_name_admin(usr)] has modified the bodyparts of [C]") + + + else if(href_list["purrbation"]) + if(!check_rights(R_SPAWN)) + return + var/mob/living/carbon/human/H = locate(href_list["purrbation"]) in GLOB.mob_list - if(!istype(H)) - to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human") - return - if(!ishumanbasic(H)) - to_chat(usr, "This can only be done to the basic human species at the moment.") - return - - if(!H) - to_chat(usr, "Mob doesn't exist anymore") - return - - var/success = purrbation_toggle(H) - if(success) - to_chat(usr, "Put [H] on purrbation.") - log_admin("[key_name(usr)] has put [key_name(H)] on purrbation.") - var/msg = "[key_name_admin(usr)] has put [key_name(H)] on purrbation." - message_admins(msg) - admin_ticket_log(H, msg) - - else - to_chat(usr, "Removed [H] from purrbation.") - log_admin("[key_name(usr)] has removed [key_name(H)] from purrbation.") - var/msg = "[key_name_admin(usr)] has removed [key_name(H)] from purrbation." - message_admins(msg) - admin_ticket_log(H, msg) - - else if(href_list["adjustDamage"] && href_list["mobToDamage"]) - if(!check_rights(0)) - return - + if(!istype(H)) + to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human") + return + if(!ishumanbasic(H)) + to_chat(usr, "This can only be done to the basic human species at the moment.") + return + + if(!H) + to_chat(usr, "Mob doesn't exist anymore") + return + + var/success = purrbation_toggle(H) + if(success) + to_chat(usr, "Put [H] on purrbation.") + log_admin("[key_name(usr)] has put [key_name(H)] on purrbation.") + var/msg = "[key_name_admin(usr)] has put [key_name(H)] on purrbation." + message_admins(msg) + admin_ticket_log(H, msg) + + else + to_chat(usr, "Removed [H] from purrbation.") + log_admin("[key_name(usr)] has removed [key_name(H)] from purrbation.") + var/msg = "[key_name_admin(usr)] has removed [key_name(H)] from purrbation." + message_admins(msg) + admin_ticket_log(H, msg) + + else if(href_list["adjustDamage"] && href_list["mobToDamage"]) + if(!check_rights(0)) + return + var/mob/living/L = locate(href_list["mobToDamage"]) in GLOB.mob_list - if(!istype(L)) - return - - var/Text = href_list["adjustDamage"] - - var/amount = input("Deal how much damage to mob? (Negative values here heal)","Adjust [Text]loss",0) as num - - if(!L) - to_chat(usr, "Mob doesn't exist anymore") - return - - switch(Text) - if("brute") - L.adjustBruteLoss(amount) - if("fire") - L.adjustFireLoss(amount) - if("toxin") - L.adjustToxLoss(amount) - if("oxygen") - L.adjustOxyLoss(amount) - if("brain") - L.adjustBrainLoss(amount) - if("clone") - L.adjustCloneLoss(amount) - if("stamina") - L.adjustStaminaLoss(amount) - else - to_chat(usr, "You caused an error. DEBUG: Text:[Text] Mob:[L]") - return - - if(amount != 0) - log_admin("[key_name(usr)] dealt [amount] amount of [Text] damage to [L] ") - var/msg = "[key_name(usr)] dealt [amount] amount of [Text] damage to [L] " - message_admins(msg) - admin_ticket_log(L, msg) - href_list["datumrefresh"] = href_list["mobToDamage"] - + if(!istype(L)) + return + + var/Text = href_list["adjustDamage"] + + var/amount = input("Deal how much damage to mob? (Negative values here heal)","Adjust [Text]loss",0) as num + + if(!L) + to_chat(usr, "Mob doesn't exist anymore") + return + + switch(Text) + if("brute") + L.adjustBruteLoss(amount) + if("fire") + L.adjustFireLoss(amount) + if("toxin") + L.adjustToxLoss(amount) + if("oxygen") + L.adjustOxyLoss(amount) + if("brain") + L.adjustBrainLoss(amount) + if("clone") + L.adjustCloneLoss(amount) + if("stamina") + L.adjustStaminaLoss(amount) + else + to_chat(usr, "You caused an error. DEBUG: Text:[Text] Mob:[L]") + return + + if(amount != 0) + log_admin("[key_name(usr)] dealt [amount] amount of [Text] damage to [L] ") + var/msg = "[key_name(usr)] dealt [amount] amount of [Text] damage to [L] " + message_admins(msg) + admin_ticket_log(L, msg) + href_list["datumrefresh"] = href_list["mobToDamage"] + From 2f10e78ba7f8be726c18ecfecdd4738906bda2c8 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 11 Sep 2017 13:56:28 -0500 Subject: [PATCH 248/262] Update on_move.dm --- code/modules/shuttle/on_move.dm | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index e80b690737..f2c84a5aae 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -14,12 +14,9 @@ All ShuttleMove procs go here // Called from the new turf before anything has been moved // Only gets called if fromShuttleMove returns true first // returns the new move_mode (based on the old) -<<<<<<< HEAD /turf/proc/toShuttleMove(turf/oldT, shuttle_dir, move_mode) -======= /turf/proc/toShuttleMove(turf/oldT, move_mode, obj/docking_port/mobile/shuttle) var/shuttle_dir = shuttle.dir ->>>>>>> 9ac60a8... Typo for(var/i in contents) var/atom/movable/thing = i if(ismob(thing)) @@ -388,4 +385,4 @@ All ShuttleMove procs go here /obj/effect/abstract/proximity_checker/onShuttleMove(turf/newT, turf/oldT, rotation, list/movement_force, move_dir, old_dock) //timer so it only happens once - addtimer(CALLBACK(monitor, /datum/proximity_monitor/proc/SetRange, monitor.current_range, TRUE), 0, TIMER_UNIQUE) \ No newline at end of file + addtimer(CALLBACK(monitor, /datum/proximity_monitor/proc/SetRange, monitor.current_range, TRUE), 0, TIMER_UNIQUE) From ddd0d9a1fc71881596be7e274952a07893c2add8 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 11 Sep 2017 13:56:54 -0500 Subject: [PATCH 249/262] Automatic changelog generation for PR #2706 [ci skip] --- html/changelogs/AutoChangeLog-pr-2706.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-2706.yml diff --git a/html/changelogs/AutoChangeLog-pr-2706.yml b/html/changelogs/AutoChangeLog-pr-2706.yml new file mode 100644 index 0000000000..4db678dd9b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2706.yml @@ -0,0 +1,4 @@ +author: "Xhuis" +delete-after: True +changes: + - rscadd: "You can now use metal rods and departmental jumpsuits to craft departments for each banner." From 14aefe2e64e20f57ced285e782aaf8cec2c992f8 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 11 Sep 2017 14:01:42 -0500 Subject: [PATCH 250/262] commit --- .../kitchen_machinery/smartfridge.dm | 131 +++++++++--------- tgui/assets/tgui.css | 2 +- tgui/assets/tgui.js | 32 ++--- tgui/src/interfaces/smartvend.ract | 48 +++++++ 4 files changed, 131 insertions(+), 82 deletions(-) create mode 100644 tgui/src/interfaces/smartvend.ract diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm index e996429939..53b899f696 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm @@ -142,69 +142,55 @@ user.set_machine(src) interact(user) -/******************* -* SmartFridge Menu -********************/ -/obj/machinery/smartfridge/interact(mob/user) - if(stat) - return FALSE - var/dat = "Select an item:
    " +/obj/machinery/smartfridge/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "smartvend", name, 440, 550, master_ui, state) + ui.open() - if (contents.len == 0) - dat += "No product loaded!" - else - var/listofitems = list() - for (var/atom/movable/O in contents) - if (listofitems[O.name]) - listofitems[O.name]++ - else - listofitems[O.name] = 1 - sortList(listofitems) +/obj/machinery/smartfridge/ui_data(mob/user) + . = list() - for (var/O in listofitems) - if(listofitems[O] <= 0) - continue - var/N = listofitems[O] - var/itemName = url_encode(O) - dat += "[capitalize(O)]:" - dat += " [N] " - dat += "Vend " - if(N > 5) - dat += "(x5)" - if(N > 10) - dat += "(x10)" - if(N > 25) - dat += "(x25)" - if(N > 1) - dat += "(All)" + var/listofitems = list() + for (var/I in src) + var/atom/movable/O = I + if (listofitems[O.name]) + listofitems[O.name]["amount"]++ + else + listofitems[O.name] = list("name" = O.name, "type" = O.type, "amount" = 1) + sortList(listofitems) - dat += "
    " + .["contents"] = listofitems + .["name"] = name + .["isdryer"] = FALSE - dat += "
    " - user << browse("[src] supplies[dat]", "window=smartfridge") - onclose(user, "smartfridge") - return dat -/obj/machinery/smartfridge/Topic(var/href, var/list/href_list) - if(..()) +/obj/machinery/smartfridge/ui_act(action, params) + . = ..() + if(.) return - usr.set_machine(src) + switch(action) + if("Release") + var/desired = 0 - var/N = href_list["vend"] - var/amount = text2num(href_list["amount"]) + if (params["amount"]) + desired = text2num(params["amount"]) + else + desired = input("How many items?", "How many items would you like to take out?", 1) as null|num - var/i = amount - for(var/obj/O in contents) - if(i <= 0) - break - if(O.name == N) - O.loc = src.loc - i-- + if(QDELETED(src) || QDELETED(usr) || !usr.Adjacent(src)) // Sanity checkin' in case stupid stuff happens while we wait for input() + return FALSE - - updateUsrDialog() + for(var/obj/item/O in src) + if(desired <= 0) + break + if(O.name == params["name"]) + O.forceMove(drop_location()) + desired-- + return TRUE + return FALSE // ---------------------------- @@ -240,20 +226,35 @@ /obj/machinery/smartfridge/drying_rack/default_deconstruction_crowbar(obj/item/crowbar/C, ignore_panel = 1) ..() -/obj/machinery/smartfridge/drying_rack/interact(mob/user) - var/dat = ..() - if(dat) - dat += "
    " - dat += "Toggle Drying " - user << browse("[src] supplies[dat]", "window=smartfridge") - onclose(user, "smartfridge") +/obj/machinery/smartfridge/drying_rack/ui_data(mob/user) + . = list() -/obj/machinery/smartfridge/drying_rack/Topic(href, list/href_list) - ..() - if(href_list["dry"]) - toggle_drying(FALSE) - updateUsrDialog() - update_icon() + var/listofitems = list() + for (var/I in src) + var/atom/movable/O = I + + if (listofitems[O.name]) + listofitems[O.name]["amount"]++ + else + listofitems[O.name] = list("name" = O.name, "type" = O.type, "amount" = 1) + sortList(listofitems) + + .["contents"] = listofitems + .["name"] = name + .["isdryer"] = TRUE + .["verb"] = "Take" + .["drying"] = drying + + +/obj/machinery/smartfridge/drying_rack/ui_act(action, params) + . = ..() + if(.) + return + switch(action) + if("Dry") + toggle_drying(FALSE) + return TRUE + return FALSE /obj/machinery/smartfridge/drying_rack/power_change() if(powered() && anchored) diff --git a/tgui/assets/tgui.css b/tgui/assets/tgui.css index f19852971d..ffe61666b9 100644 --- a/tgui/assets/tgui.css +++ b/tgui/assets/tgui.css @@ -1 +1 @@ -@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2a2a2a',endColorstr='#ff202020',GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.clockwork{background:linear-gradient(180deg,#b18b25 0,#5f380e);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffb18b25',endColorstr='#ff5f380e',GradientType=0)}body.clockwork .normal{color:#b18b25}body.clockwork .good{color:#cfba47}body.clockwork .average{color:#896b19}body.clockwork .bad{color:#5f380e}body.clockwork .highlight{color:#b18b25}body.clockwork main{display:block;margin-top:32px;padding:2px 6px 0}body.clockwork hr{height:2px;background-color:#b18b25;border:none}body.clockwork .hidden{display:none}body.clockwork .bar .barText,body.clockwork span.button{color:#b18b25;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.clockwork .bold{font-weight:700}body.clockwork .italic{font-style:italic}body.clockwork [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.clockwork div[data-tooltip],body.clockwork span[data-tooltip]{position:relative}body.clockwork div[data-tooltip]:after,body.clockwork span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #170800;background-color:#2d1400}body.clockwork div[data-tooltip]:hover:after,body.clockwork span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.clockwork div[data-tooltip].tooltip-top:after,body.clockwork span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-left:after,body.clockwork span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #170800;background:#2d1400}body.clockwork .bar .barText{position:absolute;top:0;right:3px}body.clockwork .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#b18b25}body.clockwork .bar .barFill.good{background-color:#cfba47}body.clockwork .bar .barFill.average{background-color:#896b19}body.clockwork .bar .barFill.bad{background-color:#5f380e}body.clockwork span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #170800}body.clockwork span.button .fa{padding-right:2px}body.clockwork span.button.normal{transition:background-color .5s;background-color:#5f380e}body.clockwork span.button.normal.active:focus,body.clockwork span.button.normal.active:hover{transition:background-color .25s;background-color:#704211;outline:0}body.clockwork span.button.disabled{transition:background-color .5s;background-color:#2d1400}body.clockwork span.button.disabled.active:focus,body.clockwork span.button.disabled.active:hover{transition:background-color .25s;background-color:#441e00;outline:0}body.clockwork span.button.selected{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.selected.active:focus,body.clockwork span.button.selected.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.toggle{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.toggle.active:focus,body.clockwork span.button.toggle.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.caution{transition:background-color .5s;background-color:#be6209}body.clockwork span.button.caution.active:focus,body.clockwork span.button.caution.active:hover{transition:background-color .25s;background-color:#cd6a0a;outline:0}body.clockwork span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.clockwork span.button.danger.active:focus,body.clockwork span.button.danger.active:hover{transition:background-color .25s;background-color:#abaf00;outline:0}body.clockwork span.button.gridable{width:125px;margin:2px 0}body.clockwork span.button.gridable.center{text-align:center;width:75px}body.clockwork span.button+span:not(.button),body.clockwork span:not(.button)+span.button{margin-left:5px}body.clockwork div.display{width:100%;padding:4px;margin:6px 0;background-color:#2d1400;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400);background-color:rgba(45,20,0,.9);box-shadow:inset 0 0 5px rgba(0,0,0,.3)}body.clockwork div.display.tabular{padding:0;margin:0}body.clockwork div.display header,body.clockwork div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#cfba47;border-bottom:2px solid #b18b25}body.clockwork div.display header .buttonRight,body.clockwork div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.clockwork div.display article,body.clockwork div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.clockwork input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#b18b25;background-color:#cfba47;border:1px solid #272727}body.clockwork input.number{width:35px}body.clockwork input::-webkit-input-placeholder{color:#999}body.clockwork input::-moz-placeholder{color:#999}body.clockwork input:-ms-input-placeholder{color:#999}body.clockwork input::placeholder{color:#999}body.clockwork input::-ms-clear{display:none}body.clockwork svg.linegraph{overflow:hidden}body.clockwork div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#2d1400;font-weight:700;font-style:italic;background-color:#000;background-image:repeating-linear-gradient(-45deg,#000,#000 10px,#170800 0,#170800 20px)}body.clockwork div.notice .label{color:#2d1400}body.clockwork div.notice .content:only-of-type{padding:0}body.clockwork div.notice hr{background-color:#896b19}body.clockwork div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #5f380e;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .cell,body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.clockwork section{display:table-row;width:100%}body.clockwork section:not(:first-child){padding-top:4px}body.clockwork section.candystripe:nth-child(even){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.clockwork section .label{width:1%;padding-right:32px;white-space:nowrap;color:#b18b25}body.clockwork section .content:not(:last-child){padding-right:16px}body.clockwork section .line{width:100%}body.clockwork section .cell:not(:first-child){text-align:center;padding-top:0}body.clockwork section .cell span.button{width:75px}body.clockwork section:not(:last-child){padding-right:4px}body.clockwork div.subdisplay{width:100%;margin:0}body.clockwork header.titlebar .close,body.clockwork header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#cfba47}body.clockwork header.titlebar .close:hover,body.clockwork header.titlebar .minimize:hover{color:#d1bd50}body.clockwork header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#5f380e;border-bottom:1px solid #170800;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.clockwork header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.clockwork header.titlebar .title{position:absolute;top:6px;left:46px;color:#cfba47;font-size:16px;white-space:nowrap}body.clockwork header.titlebar .minimize{position:absolute;top:6px;right:46px}body.clockwork header.titlebar .close{position:absolute;top:4px;right:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgNDI1IDIwMCIgb3BhY2l0eT0iLjMzIj4NCiAgPHBhdGggZD0ibSAxNzguMDAzOTksMC4wMzg2OSAtNzEuMjAzOTMsMCBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTYuNzYxMzQsNi4wMjU1NSBsIDAsMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM0LDYuMDI1NTQgbCA1My4xMDcyLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xMDEuNTQ0MDE4IDcyLjIxNjI4LDEwNC42OTkzOTggYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDUuNzYwMTUsMi44NzAxNiBsIDczLjU1NDg3LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xODcuODcxNDcgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM1LC02LjAyNTU1IGwgLTU0LjcxNjQ0LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTMzLDYuMDI1NTUgbCAwLDEwMi42MTkzNSBMIDE4My43NjQxMywyLjkwODg2IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNS43NjAxNCwtMi44NzAxNyB6IiAvPg0KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPg0KICA8cGF0aCBkPSJtIDQyMC4xNTUzNSwxNzcuODkxMTkgYSAxMy40MTIwMzgsMTIuNTAxODQyIDAgMCAxIC04LjYzMjk1LDIyLjA2OTUxIGwgLTY2LjExODMyLDAgYSA1LjM2NDgxNTIsNS4wMDA3MzcgMCAwIDEgLTUuMzY0ODIsLTUuMDAwNzQgbCAwLC03OS44NzkzMSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2a2a2a',endColorstr='#ff202020',GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.toggle{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.toggle.active:focus,body.nanotrasen span.button.toggle.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button.gridable.center{text-align:center;width:75px}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display.tabular{padding:0;margin:0}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input.number{width:35px}body.nanotrasen input::-webkit-input-placeholder{color:#999}body.nanotrasen input::-moz-placeholder{color:#999}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(even){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen section .cell:not(:first-child){text-align:center;padding-top:0}body.nanotrasen section .cell span.button{width:75px}body.nanotrasen section:not(:last-child){padding-right:4px}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgMjAwIDI4OS43NDIiIG9wYWNpdHk9Ii4zMyI+DQogIDxwYXRoIGQ9Im0gOTMuNTM3Njc3LDAgYyAtMTguMTEzMTI1LDAgLTM0LjIyMDEzMywzLjExMTY0IC00OC4zMjM0ODQsOS4zMzQzNyAtMTMuOTY1MDkyLDYuMjIxNjcgLTI0LjYxMjQ0MiwxNS4wNzExNCAtMzEuOTQwNjUxLDI2LjU0NzEgLTcuMTg5OTM5OCwxMS4zMzc4OSAtMTAuMzAxMjI2NiwyNC43NDkxMSAtMTAuMzAxMjI2Niw0MC4yMzQ3OCAwLDEwLjY0NjYyIDIuNzI1MDAyNiwyMC40NjQ2NSA4LjE3NTExMTYsMjkuNDUyNTggNS42MTUyNzcsOC45ODY4NiAxNC4wMzgyNzcsMTcuMzUyMDQgMjUuMjY4ODIxLDI1LjA5NDM2IDExLjIzMDU0NCw3LjYwNTMxIDI2LjUwNzQyMSwxNS40MTgzNSA0NS44MzA1MTQsMjMuNDM3ODIgMTkuOTgzNzQ4LDguMjk1NTcgMzQuODQ4ODQ4LDE1LjU1NDcxIDQ0LjU5Mjk5OCwyMS43NzYzOCA5Ljc0NDE0LDYuMjIyNzMgMTYuNzYxNywxMi44NTg1IDIxLjA1NTcyLDE5LjkwOTUxIDQuMjk0MDQsNy4wNTIwOCA2LjQ0MTkzLDE1Ljc2NDA4IDYuNDQxOTMsMjYuMTM0NTkgMCwxNi4xNzcwMiAtNS4yMDE5NiwyOC40ODIyMiAtMTUuNjA2NzMsMzYuOTE2ODIgLTEwLjIzOTYsOC40MzQ3IC0yNS4wMjIwMywxMi42NTIzIC00NC4zNDUxNjksMTIuNjUyMyAtMTQuMDM4MTcxLDAgLTI1LjUxNTI0NywtMS42NTk0IC0zNC40MzM2MTgsLTQuOTc3NyAtOC45MTgzNywtMy40NTY2IC0xNi4xODU1NzIsLTguNzExMyAtMjEuODAwODM5LC0xNS43NjMzIC01LjYxNTI3NywtNy4wNTIxIC0xMC4wNzQ3OTUsLTE2LjY2MDg4IC0xMy4zNzc4OTksLTI4LjgyODEyIGwgLTI0Ljc3MzE2MjYyOTM5NDUsMCAwLDU2LjgyNjMyIEMgMzMuODU2NzY5LDI4Ni4wNzYwMSA2My43NDkwNCwyODkuNzQyMDEgODkuNjc4MzgzLDI4OS43NDIwMSBjIDE2LjAyMDAyNywwIDMwLjcxOTc4NywtMS4zODI3IDQ0LjA5NzMzNywtNC4xNDc5IDEzLjU0MjcyLC0yLjkwNDMgMjUuMTA0MSwtNy40Njc2IDM0LjY4MzA5LC0xMy42ODkzIDkuNzQ0MTMsLTYuMzU5NyAxNy4zNDA0MiwtMTQuNTE5NSAyMi43OTA1MiwtMjQuNDc0OCA1LjQ1MDEsLTEwLjA5MzMyIDguMTc1MTEsLTIyLjM5OTU5IDguMTc1MTEsLTM2LjkxNjgyIDAsLTEyLjk5NzY0IC0zLjMwMjEsLTI0LjMzNTM5IC05LjkwODI5LC0zNC4wMTQ2IC02LjQ0MTA1LC05LjgxNzI1IC0xNS41MjU0NSwtMTguNTI3MDcgLTI3LjI1MTQ2LC0yNi4xMzEzMyAtMTEuNTYwODUsLTcuNjA0MjcgLTI3LjkxMDgzLC0xNS44MzE0MiAtNDkuMDUwNjYsLTI0LjY4MDIyIC0xNy41MDY0NCwtNy4xOTAxMiAtMzAuNzE5NjY4LC0xMy42ODk0OCAtMzkuNjM4MDM4LC0xOS40OTcwMSAtOC45MTgzNzEsLTUuODA3NTIgLTE4LjYwNzQ3NCwtMTIuNDM0MDkgLTI0LjA5NjUyNCwtMTguODc0MTcgLTUuNDI2MDQzLC02LjM2NjE2IC05LjY1ODgyNiwtMTUuMDcwMDMgLTkuNjU4ODI2LC0yNC44ODcyOSAwLC05LjI2NDAxIDIuMDc1NDE0LC0xNy4yMTM0NSA2LjIyMzQ1NCwtMjMuODUwMzMgMTEuMDk4Mjk4LC0xNC4zOTc0OCA0MS4yODY2MzgsLTEuNzk1MDcgNDUuMDc1NjA5LDI0LjM0NzYyIDQuODM5MzkyLDYuNzc0OTEgOC44NDkzNSwxNi4yNDcyOSAxMi4wMjk1MTUsMjguNDE1NiBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNC40NzgyNSwtNS45MjQ0OCAtOS45NTQ4OCwtMTAuNjMyMjIgLTE1LjkwODM3LC0xNC4zNzQxMSAxLjY0MDU1LDAuNDc5MDUgMy4xOTAzOSwxLjAyMzc2IDQuNjM4NjUsMS42NDAyNCA2LjQ5ODYxLDIuNjI2MDcgMTIuMTY3OTMsNy4zMjc0NyAxNy4wMDczLDE0LjEwMzQ1IDQuODM5MzksNi43NzQ5MSA4Ljg0OTM1LDE2LjI0NTY3IDEyLjAyOTUyLDI4LjQxMzk3IDAsMCA4LjQ4MTI4LC0wLjEyODk0IDguNDg5NzgsLTAuMDAyIDAuNDE3NzYsNi40MTQ5NCAtMS43NTMzOSw5LjQ1Mjg2IC00LjEyMzQyLDEyLjU2MTA0IC0yLjQxNzQsMy4xNjk3OCAtNS4xNDQ4Niw2Ljc4OTczIC00LjAwMjc4LDEzLjAwMjkgMS41MDc4Niw4LjIwMzE4IDEwLjE4MzU0LDEwLjU5NjQyIDE0LjYyMTk0LDkuMzExNTQgLTMuMzE4NDIsLTAuNDk5MTEgLTUuMzE4NTUsLTEuNzQ5NDggLTUuMzE4NTUsLTEuNzQ5NDggMCwwIDEuODc2NDYsMC45OTg2OCA1LjY1MTE3LC0xLjM1OTgxIC0zLjI3Njk1LDAuOTU1NzEgLTEwLjcwNTI5LC0wLjc5NzM4IC0xMS44MDEyNSwtNi43NjMxMyAtMC45NTc1MiwtNS4yMDg2MSAwLjk0NjU0LC03LjI5NTE0IDMuNDAxMTMsLTEwLjUxNDgyIDIuNDU0NjIsLTMuMjE5NjggNS4yODQyNiwtNi45NTgzMSA0LjY4NDMsLTE0LjQ4ODI0IGwgMC4wMDMsMC4wMDIgOC45MjY3NiwwIDAsLTU1Ljk5OTY3IGMgLTE1LjA3MTI1LC0zLjg3MTY4IC0yNy42NTMxNCwtNi4zNjA0MiAtMzcuNzQ2NzEsLTcuNDY1ODYgLTkuOTU1MzEsLTEuMTA3NTUgLTIwLjE4ODIzLC0xLjY1OTgxIC0zMC42OTY2MTMsLTEuNjU5ODEgeiBtIDcwLjMyMTYwMywxNy4zMDg5MyAwLjIzODA1LDQwLjMwNDkgYyAxLjMxODA4LDEuMjI2NjYgMi40Mzk2NSwyLjI3ODE1IDMuMzQwODEsMy4xMDYwMiA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNCwxNi4yNDU2NiAxMi4wMjk1MSwyOC40MTM5NyBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNi42NzczMSwtNC41OTM4MSAtMTkuODM2NDMsLTEwLjQ3MzA5IC0zNi4xNDA3MSwtMTUuODI1MjIgeiBtIC0yOC4xMjA0OSw1LjYwNTUxIDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzcsLTYuNDY2OTcgLTEzLjg0Njc4LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDUsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gMTUuMjIxOTUsMjQuMDA4NDggOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzOCwtNi40NjY5NyAtMTMuODQ2NzksLTkuNzE3MjYgLTguNTY0NzksLTE3LjcxNjU1IHogbSAyMi43OTcwNCwwIGMgMi43NzE1LDcuOTk5MjkgMS43ODc0MSwxMS4yNDk1OCAtNC40OTM1NCwxNy43MTY1NSBsIDQuNDkzNTQsLTE3LjcxNjU1IHogbSAtOTkuMTEzODQsMi4yMDc2NCA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM4MiwtNi40NjY5NyAtMTMuODQ2NzgyLC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk1NDIsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff750000',endColorstr='#ff340404',GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.toggle{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.toggle.active:focus,body.syndicate span.button.toggle.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button.gridable.center{text-align:center;width:75px}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display.tabular{padding:0;margin:0}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input.number{width:35px}body.syndicate input::-webkit-input-placeholder{color:#999}body.syndicate input::-moz-placeholder{color:#999}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(even){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate section .cell:not(:first-child){text-align:center;padding-top:0}body.syndicate section .cell span.button{width:75px}body.syndicate section:not(:last-child){padding-right:4px}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"} \ No newline at end of file +@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.clockwork{background:linear-gradient(180deg,#b18b25 0,#5f380e);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffb18b25",endColorstr="#ff5f380e",GradientType=0)}body.clockwork .normal{color:#b18b25}body.clockwork .good{color:#cfba47}body.clockwork .average{color:#896b19}body.clockwork .bad{color:#5f380e}body.clockwork .highlight{color:#b18b25}body.clockwork main{display:block;margin-top:32px;padding:2px 6px 0}body.clockwork hr{height:2px;background-color:#b18b25;border:none}body.clockwork .hidden{display:none}body.clockwork .bar .barText,body.clockwork span.button{color:#b18b25;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.clockwork .bold{font-weight:700}body.clockwork .italic{font-style:italic}body.clockwork [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.clockwork div[data-tooltip],body.clockwork span[data-tooltip]{position:relative}body.clockwork div[data-tooltip]:after,body.clockwork span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #170800;background-color:#2d1400}body.clockwork div[data-tooltip]:hover:after,body.clockwork span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.clockwork div[data-tooltip].tooltip-top:after,body.clockwork span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-left:after,body.clockwork span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #170800;background:#2d1400}body.clockwork .bar .barText{position:absolute;top:0;right:3px}body.clockwork .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#b18b25}body.clockwork .bar .barFill.good{background-color:#cfba47}body.clockwork .bar .barFill.average{background-color:#896b19}body.clockwork .bar .barFill.bad{background-color:#5f380e}body.clockwork span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #170800}body.clockwork span.button .fa{padding-right:2px}body.clockwork span.button.normal{transition:background-color .5s;background-color:#5f380e}body.clockwork span.button.normal.active:focus,body.clockwork span.button.normal.active:hover{transition:background-color .25s;background-color:#704211;outline:0}body.clockwork span.button.disabled{transition:background-color .5s;background-color:#2d1400}body.clockwork span.button.disabled.active:focus,body.clockwork span.button.disabled.active:hover{transition:background-color .25s;background-color:#441e00;outline:0}body.clockwork span.button.selected{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.selected.active:focus,body.clockwork span.button.selected.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.toggle{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.toggle.active:focus,body.clockwork span.button.toggle.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.caution{transition:background-color .5s;background-color:#be6209}body.clockwork span.button.caution.active:focus,body.clockwork span.button.caution.active:hover{transition:background-color .25s;background-color:#cd6a0a;outline:0}body.clockwork span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.clockwork span.button.danger.active:focus,body.clockwork span.button.danger.active:hover{transition:background-color .25s;background-color:#abaf00;outline:0}body.clockwork span.button.gridable{width:125px;margin:2px 0}body.clockwork span.button.gridable.center{text-align:center;width:75px}body.clockwork span.button+span:not(.button),body.clockwork span:not(.button)+span.button{margin-left:5px}body.clockwork div.display{width:100%;padding:4px;margin:6px 0;background-color:#2d1400;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400);background-color:rgba(45,20,0,.9);box-shadow:inset 0 0 5px rgba(0,0,0,.3)}body.clockwork div.display.tabular{padding:0;margin:0}body.clockwork div.display header,body.clockwork div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#cfba47;border-bottom:2px solid #b18b25}body.clockwork div.display header .buttonRight,body.clockwork div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.clockwork div.display article,body.clockwork div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.clockwork input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#b18b25;background-color:#cfba47;border:1px solid #272727}body.clockwork input.number{width:35px}body.clockwork input::-webkit-input-placeholder{color:#999}body.clockwork input:-ms-input-placeholder{color:#999}body.clockwork input::placeholder{color:#999}body.clockwork input::-ms-clear{display:none}body.clockwork svg.linegraph{overflow:hidden}body.clockwork div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#2d1400;font-weight:700;font-style:italic;background-color:#000;background-image:repeating-linear-gradient(-45deg,#000,#000 10px,#170800 0,#170800 20px)}body.clockwork div.notice .label{color:#2d1400}body.clockwork div.notice .content:only-of-type{padding:0}body.clockwork div.notice hr{background-color:#896b19}body.clockwork div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #5f380e;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .cell,body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.clockwork section{display:table-row;width:100%}body.clockwork section:not(:first-child){padding-top:4px}body.clockwork section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.clockwork section .label{width:1%;padding-right:32px;white-space:nowrap;color:#b18b25}body.clockwork section .content:not(:last-child){padding-right:16px}body.clockwork section .line{width:100%}body.clockwork section .cell:not(:first-child){text-align:center;padding-top:0}body.clockwork section .cell span.button{width:75px}body.clockwork section:not(:last-child){padding-right:4px}body.clockwork div.subdisplay{width:100%;margin:0}body.clockwork header.titlebar .close,body.clockwork header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#cfba47}body.clockwork header.titlebar .close:hover,body.clockwork header.titlebar .minimize:hover{color:#d1bd50}body.clockwork header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#5f380e;border-bottom:1px solid #170800;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.clockwork header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.clockwork header.titlebar .title{position:absolute;top:6px;left:46px;color:#cfba47;font-size:16px;white-space:nowrap}body.clockwork header.titlebar .minimize{position:absolute;top:6px;right:46px}body.clockwork header.titlebar .close{position:absolute;top:4px;right:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgNDI1IDIwMCIgb3BhY2l0eT0iLjMzIj4NCiAgPHBhdGggZD0ibSAxNzguMDAzOTksMC4wMzg2OSAtNzEuMjAzOTMsMCBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTYuNzYxMzQsNi4wMjU1NSBsIDAsMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM0LDYuMDI1NTQgbCA1My4xMDcyLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xMDEuNTQ0MDE4IDcyLjIxNjI4LDEwNC42OTkzOTggYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDUuNzYwMTUsMi44NzAxNiBsIDczLjU1NDg3LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xODcuODcxNDcgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM1LC02LjAyNTU1IGwgLTU0LjcxNjQ0LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTMzLDYuMDI1NTUgbCAwLDEwMi42MTkzNSBMIDE4My43NjQxMywyLjkwODg2IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNS43NjAxNCwtMi44NzAxNyB6IiAvPg0KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPg0KICA8cGF0aCBkPSJtIDQyMC4xNTUzNSwxNzcuODkxMTkgYSAxMy40MTIwMzgsMTIuNTAxODQyIDAgMCAxIC04LjYzMjk1LDIyLjA2OTUxIGwgLTY2LjExODMyLDAgYSA1LjM2NDgxNTIsNS4wMDA3MzcgMCAwIDEgLTUuMzY0ODIsLTUuMDAwNzQgbCAwLC03OS44NzkzMSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.toggle{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.toggle.active:focus,body.nanotrasen span.button.toggle.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button.gridable.center{text-align:center;width:75px}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display.tabular{padding:0;margin:0}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input.number{width:35px}body.nanotrasen input::-webkit-input-placeholder{color:#999}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen section .cell:not(:first-child){text-align:center;padding-top:0}body.nanotrasen section .cell span.button{width:75px}body.nanotrasen section:not(:last-child){padding-right:4px}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgMjAwIDI4OS43NDIiIG9wYWNpdHk9Ii4zMyI+DQogIDxwYXRoIGQ9Im0gOTMuNTM3Njc3LDAgYyAtMTguMTEzMTI1LDAgLTM0LjIyMDEzMywzLjExMTY0IC00OC4zMjM0ODQsOS4zMzQzNyAtMTMuOTY1MDkyLDYuMjIxNjcgLTI0LjYxMjQ0MiwxNS4wNzExNCAtMzEuOTQwNjUxLDI2LjU0NzEgLTcuMTg5OTM5OCwxMS4zMzc4OSAtMTAuMzAxMjI2NiwyNC43NDkxMSAtMTAuMzAxMjI2Niw0MC4yMzQ3OCAwLDEwLjY0NjYyIDIuNzI1MDAyNiwyMC40NjQ2NSA4LjE3NTExMTYsMjkuNDUyNTggNS42MTUyNzcsOC45ODY4NiAxNC4wMzgyNzcsMTcuMzUyMDQgMjUuMjY4ODIxLDI1LjA5NDM2IDExLjIzMDU0NCw3LjYwNTMxIDI2LjUwNzQyMSwxNS40MTgzNSA0NS44MzA1MTQsMjMuNDM3ODIgMTkuOTgzNzQ4LDguMjk1NTcgMzQuODQ4ODQ4LDE1LjU1NDcxIDQ0LjU5Mjk5OCwyMS43NzYzOCA5Ljc0NDE0LDYuMjIyNzMgMTYuNzYxNywxMi44NTg1IDIxLjA1NTcyLDE5LjkwOTUxIDQuMjk0MDQsNy4wNTIwOCA2LjQ0MTkzLDE1Ljc2NDA4IDYuNDQxOTMsMjYuMTM0NTkgMCwxNi4xNzcwMiAtNS4yMDE5NiwyOC40ODIyMiAtMTUuNjA2NzMsMzYuOTE2ODIgLTEwLjIzOTYsOC40MzQ3IC0yNS4wMjIwMywxMi42NTIzIC00NC4zNDUxNjksMTIuNjUyMyAtMTQuMDM4MTcxLDAgLTI1LjUxNTI0NywtMS42NTk0IC0zNC40MzM2MTgsLTQuOTc3NyAtOC45MTgzNywtMy40NTY2IC0xNi4xODU1NzIsLTguNzExMyAtMjEuODAwODM5LC0xNS43NjMzIC01LjYxNTI3NywtNy4wNTIxIC0xMC4wNzQ3OTUsLTE2LjY2MDg4IC0xMy4zNzc4OTksLTI4LjgyODEyIGwgLTI0Ljc3MzE2MjYyOTM5NDUsMCAwLDU2LjgyNjMyIEMgMzMuODU2NzY5LDI4Ni4wNzYwMSA2My43NDkwNCwyODkuNzQyMDEgODkuNjc4MzgzLDI4OS43NDIwMSBjIDE2LjAyMDAyNywwIDMwLjcxOTc4NywtMS4zODI3IDQ0LjA5NzMzNywtNC4xNDc5IDEzLjU0MjcyLC0yLjkwNDMgMjUuMTA0MSwtNy40Njc2IDM0LjY4MzA5LC0xMy42ODkzIDkuNzQ0MTMsLTYuMzU5NyAxNy4zNDA0MiwtMTQuNTE5NSAyMi43OTA1MiwtMjQuNDc0OCA1LjQ1MDEsLTEwLjA5MzMyIDguMTc1MTEsLTIyLjM5OTU5IDguMTc1MTEsLTM2LjkxNjgyIDAsLTEyLjk5NzY0IC0zLjMwMjEsLTI0LjMzNTM5IC05LjkwODI5LC0zNC4wMTQ2IC02LjQ0MTA1LC05LjgxNzI1IC0xNS41MjU0NSwtMTguNTI3MDcgLTI3LjI1MTQ2LC0yNi4xMzEzMyAtMTEuNTYwODUsLTcuNjA0MjcgLTI3LjkxMDgzLC0xNS44MzE0MiAtNDkuMDUwNjYsLTI0LjY4MDIyIC0xNy41MDY0NCwtNy4xOTAxMiAtMzAuNzE5NjY4LC0xMy42ODk0OCAtMzkuNjM4MDM4LC0xOS40OTcwMSAtOC45MTgzNzEsLTUuODA3NTIgLTE4LjYwNzQ3NCwtMTIuNDM0MDkgLTI0LjA5NjUyNCwtMTguODc0MTcgLTUuNDI2MDQzLC02LjM2NjE2IC05LjY1ODgyNiwtMTUuMDcwMDMgLTkuNjU4ODI2LC0yNC44ODcyOSAwLC05LjI2NDAxIDIuMDc1NDE0LC0xNy4yMTM0NSA2LjIyMzQ1NCwtMjMuODUwMzMgMTEuMDk4Mjk4LC0xNC4zOTc0OCA0MS4yODY2MzgsLTEuNzk1MDcgNDUuMDc1NjA5LDI0LjM0NzYyIDQuODM5MzkyLDYuNzc0OTEgOC44NDkzNSwxNi4yNDcyOSAxMi4wMjk1MTUsMjguNDE1NiBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNC40NzgyNSwtNS45MjQ0OCAtOS45NTQ4OCwtMTAuNjMyMjIgLTE1LjkwODM3LC0xNC4zNzQxMSAxLjY0MDU1LDAuNDc5MDUgMy4xOTAzOSwxLjAyMzc2IDQuNjM4NjUsMS42NDAyNCA2LjQ5ODYxLDIuNjI2MDcgMTIuMTY3OTMsNy4zMjc0NyAxNy4wMDczLDE0LjEwMzQ1IDQuODM5MzksNi43NzQ5MSA4Ljg0OTM1LDE2LjI0NTY3IDEyLjAyOTUyLDI4LjQxMzk3IDAsMCA4LjQ4MTI4LC0wLjEyODk0IDguNDg5NzgsLTAuMDAyIDAuNDE3NzYsNi40MTQ5NCAtMS43NTMzOSw5LjQ1Mjg2IC00LjEyMzQyLDEyLjU2MTA0IC0yLjQxNzQsMy4xNjk3OCAtNS4xNDQ4Niw2Ljc4OTczIC00LjAwMjc4LDEzLjAwMjkgMS41MDc4Niw4LjIwMzE4IDEwLjE4MzU0LDEwLjU5NjQyIDE0LjYyMTk0LDkuMzExNTQgLTMuMzE4NDIsLTAuNDk5MTEgLTUuMzE4NTUsLTEuNzQ5NDggLTUuMzE4NTUsLTEuNzQ5NDggMCwwIDEuODc2NDYsMC45OTg2OCA1LjY1MTE3LC0xLjM1OTgxIC0zLjI3Njk1LDAuOTU1NzEgLTEwLjcwNTI5LC0wLjc5NzM4IC0xMS44MDEyNSwtNi43NjMxMyAtMC45NTc1MiwtNS4yMDg2MSAwLjk0NjU0LC03LjI5NTE0IDMuNDAxMTMsLTEwLjUxNDgyIDIuNDU0NjIsLTMuMjE5NjggNS4yODQyNiwtNi45NTgzMSA0LjY4NDMsLTE0LjQ4ODI0IGwgMC4wMDMsMC4wMDIgOC45MjY3NiwwIDAsLTU1Ljk5OTY3IGMgLTE1LjA3MTI1LC0zLjg3MTY4IC0yNy42NTMxNCwtNi4zNjA0MiAtMzcuNzQ2NzEsLTcuNDY1ODYgLTkuOTU1MzEsLTEuMTA3NTUgLTIwLjE4ODIzLC0xLjY1OTgxIC0zMC42OTY2MTMsLTEuNjU5ODEgeiBtIDcwLjMyMTYwMywxNy4zMDg5MyAwLjIzODA1LDQwLjMwNDkgYyAxLjMxODA4LDEuMjI2NjYgMi40Mzk2NSwyLjI3ODE1IDMuMzQwODEsMy4xMDYwMiA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNCwxNi4yNDU2NiAxMi4wMjk1MSwyOC40MTM5NyBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNi42NzczMSwtNC41OTM4MSAtMTkuODM2NDMsLTEwLjQ3MzA5IC0zNi4xNDA3MSwtMTUuODI1MjIgeiBtIC0yOC4xMjA0OSw1LjYwNTUxIDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzcsLTYuNDY2OTcgLTEzLjg0Njc4LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDUsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gMTUuMjIxOTUsMjQuMDA4NDggOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzOCwtNi40NjY5NyAtMTMuODQ2NzksLTkuNzE3MjYgLTguNTY0NzksLTE3LjcxNjU1IHogbSAyMi43OTcwNCwwIGMgMi43NzE1LDcuOTk5MjkgMS43ODc0MSwxMS4yNDk1OCAtNC40OTM1NCwxNy43MTY1NSBsIDQuNDkzNTQsLTE3LjcxNjU1IHogbSAtOTkuMTEzODQsMi4yMDc2NCA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM4MiwtNi40NjY5NyAtMTMuODQ2NzgyLC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk1NDIsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff750000",endColorstr="#ff340404",GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.toggle{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.toggle.active:focus,body.syndicate span.button.toggle.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button.gridable.center{text-align:center;width:75px}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display.tabular{padding:0;margin:0}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input.number{width:35px}body.syndicate input::-webkit-input-placeholder{color:#999}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate section .cell:not(:first-child){text-align:center;padding-top:0}body.syndicate section .cell span.button{width:75px}body.syndicate section:not(:last-child){padding-right:4px}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"} \ No newline at end of file diff --git a/tgui/assets/tgui.js b/tgui/assets/tgui.js index 5d42acb654..a41d648fe1 100644 --- a/tgui/assets/tgui.js +++ b/tgui/assets/tgui.js @@ -1,16 +1,16 @@ -require=function t(e,n,a){function r(o,s){if(!n[o]){if(!e[o]){var u="function"==typeof require&&require;if(!s&&u)return u(o,!0);if(i)return i(o,!0);var p=Error("Cannot find module '"+o+"'");throw p.code="MODULE_NOT_FOUND",p}var c=n[o]={exports:{}};e[o][0].call(c.exports,function(t){var n=e[o][1][t];return r(n?n:t)},c,c.exports,t,e,n,a)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o2?p[2]:void 0,l=Math.min((void 0===c?o:r(c,o))-u,o-s),f=1;for(s>u&&u+l>s&&(f=-1,u+=l-1,s+=l-1);l-- >0;)u in n?n[s]=n[u]:delete n[s],s+=f,u+=f;return n}},{76:76,79:79,80:80}],6:[function(t,e,n){"use strict";var a=t(80),r=t(76),i=t(79);e.exports=[].fill||function(t){for(var e=a(this),n=i(e.length),o=arguments,s=o.length,u=r(s>1?o[1]:void 0,n),p=s>2?o[2]:void 0,c=void 0===p?n:r(p,n);c>u;)e[u++]=t;return e}},{76:76,79:79,80:80}],7:[function(t,e,n){var a=t(78),r=t(79),i=t(76);e.exports=function(t){return function(e,n,o){var s,u=a(e),p=r(u.length),c=i(o,p);if(t&&n!=n){for(;p>c;)if(s=u[c++],s!=s)return!0}else for(;p>c;c++)if((t||c in u)&&u[c]===n)return t||c;return!t&&-1}}},{76:76,78:78,79:79}],8:[function(t,e,n){var a=t(17),r=t(34),i=t(80),o=t(79),s=t(9);e.exports=function(t){var e=1==t,n=2==t,u=3==t,p=4==t,c=6==t,l=5==t||c;return function(f,d,h){for(var m,v,g=i(f),b=r(g),y=a(d,h,3),x=o(b.length),_=0,w=e?s(f,x):n?s(f,0):void 0;x>_;_++)if((l||_ in b)&&(m=b[_],v=y(m,_,g),t))if(e)w[_]=v;else if(v)switch(t){case 3:return!0;case 5:return m;case 6:return _;case 2:w.push(m)}else if(p)return!1;return c?-1:u||p?p:w}}},{17:17,34:34,79:79,80:80,9:9}],9:[function(t,e,n){var a=t(38),r=t(36),i=t(83)("species");e.exports=function(t,e){var n;return r(t)&&(n=t.constructor,"function"!=typeof n||n!==Array&&!r(n.prototype)||(n=void 0),a(n)&&(n=n[i],null===n&&(n=void 0))),new(void 0===n?Array:n)(e)}},{36:36,38:38,83:83}],10:[function(t,e,n){var a=t(11),r=t(83)("toStringTag"),i="Arguments"==a(function(){return arguments}());e.exports=function(t){var e,n,o;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=(e=Object(t))[r])?n:i?a(e):"Object"==(o=a(e))&&"function"==typeof e.callee?"Arguments":o}},{11:11,83:83}],11:[function(t,e,n){var a={}.toString;e.exports=function(t){return a.call(t).slice(8,-1)}},{}],12:[function(t,e,n){"use strict";var a=t(46),r=t(31),i=t(60),o=t(17),s=t(69),u=t(18),p=t(27),c=t(42),l=t(44),f=t(82)("id"),d=t(30),h=t(38),m=t(65),v=t(19),g=Object.isExtensible||h,b=v?"_s":"size",y=0,x=function(t,e){if(!h(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!d(t,f)){if(!g(t))return"F";if(!e)return"E";r(t,f,++y)}return"O"+t[f]},_=function(t,e){var n,a=x(e);if("F"!==a)return t._i[a];for(n=t._f;n;n=n.n)if(n.k==e)return n};e.exports={getConstructor:function(t,e,n,r){var c=t(function(t,i){s(t,c,e),t._i=a.create(null),t._f=void 0,t._l=void 0,t[b]=0,void 0!=i&&p(i,n,t[r],t)});return i(c.prototype,{clear:function(){for(var t=this,e=t._i,n=t._f;n;n=n.n)n.r=!0,n.p&&(n.p=n.p.n=void 0),delete e[n.i];t._f=t._l=void 0,t[b]=0},"delete":function(t){var e=this,n=_(e,t);if(n){var a=n.n,r=n.p;delete e._i[n.i],n.r=!0,r&&(r.n=a),a&&(a.p=r),e._f==n&&(e._f=a),e._l==n&&(e._l=r),e[b]--}return!!n},forEach:function(t){for(var e,n=o(t,arguments.length>1?arguments[1]:void 0,3);e=e?e.n:this._f;)for(n(e.v,e.k,this);e&&e.r;)e=e.p},has:function(t){return!!_(this,t)}}),v&&a.setDesc(c.prototype,"size",{get:function(){return u(this[b])}}),c},def:function(t,e,n){var a,r,i=_(t,e);return i?i.v=n:(t._l=i={i:r=x(e,!0),k:e,v:n,p:a=t._l,n:void 0,r:!1},t._f||(t._f=i),a&&(a.n=i),t[b]++,"F"!==r&&(t._i[r]=i)),t},getEntry:_,setStrong:function(t,e,n){c(t,e,function(t,e){this._t=t,this._k=e,this._l=void 0},function(){for(var t=this,e=t._k,n=t._l;n&&n.r;)n=n.p;return t._t&&(t._l=n=n?n.n:t._t._f)?"keys"==e?l(0,n.k):"values"==e?l(0,n.v):l(0,[n.k,n.v]):(t._t=void 0,l(1))},n?"entries":"values",!n,!0),m(e)}}},{17:17,18:18,19:19,27:27,30:30,31:31,38:38,42:42,44:44,46:46,60:60,65:65,69:69,82:82}],13:[function(t,e,n){var a=t(27),r=t(10);e.exports=function(t){return function(){if(r(this)!=t)throw TypeError(t+"#toJSON isn't generic");var e=[];return a(this,!1,e.push,e),e}}},{10:10,27:27}],14:[function(t,e,n){"use strict";var a=t(31),r=t(60),i=t(4),o=t(38),s=t(69),u=t(27),p=t(8),c=t(30),l=t(82)("weak"),f=Object.isExtensible||o,d=p(5),h=p(6),m=0,v=function(t){return t._l||(t._l=new g)},g=function(){this.a=[]},b=function(t,e){return d(t.a,function(t){return t[0]===e})};g.prototype={get:function(t){var e=b(this,t);return e?e[1]:void 0},has:function(t){return!!b(this,t)},set:function(t,e){var n=b(this,t);n?n[1]=e:this.a.push([t,e])},"delete":function(t){var e=h(this.a,function(e){return e[0]===t});return~e&&this.a.splice(e,1),!!~e}},e.exports={getConstructor:function(t,e,n,a){var i=t(function(t,r){s(t,i,e),t._i=m++,t._l=void 0,void 0!=r&&u(r,n,t[a],t)});return r(i.prototype,{"delete":function(t){return o(t)?f(t)?c(t,l)&&c(t[l],this._i)&&delete t[l][this._i]:v(this)["delete"](t):!1},has:function(t){return o(t)?f(t)?c(t,l)&&c(t[l],this._i):v(this).has(t):!1}}),i},def:function(t,e,n){return f(i(e))?(c(e,l)||a(e,l,{}),e[l][t._i]=n):v(t).set(e,n),t},frozenStore:v,WEAK:l}},{27:27,30:30,31:31,38:38,4:4,60:60,69:69,8:8,82:82}],15:[function(t,e,n){"use strict";var a=t(29),r=t(22),i=t(61),o=t(60),s=t(27),u=t(69),p=t(38),c=t(24),l=t(43),f=t(66);e.exports=function(t,e,n,d,h,m){var v=a[t],g=v,b=h?"set":"add",y=g&&g.prototype,x={},_=function(t){var e=y[t];i(y,t,"delete"==t?function(t){return m&&!p(t)?!1:e.call(this,0===t?0:t)}:"has"==t?function(t){return m&&!p(t)?!1:e.call(this,0===t?0:t)}:"get"==t?function(t){return m&&!p(t)?void 0:e.call(this,0===t?0:t)}:"add"==t?function(t){return e.call(this,0===t?0:t),this}:function(t,n){return e.call(this,0===t?0:t,n),this})};if("function"==typeof g&&(m||y.forEach&&!c(function(){(new g).entries().next()}))){var w,k=new g,E=k[b](m?{}:-0,1)!=k,S=c(function(){k.has(1)}),C=l(function(t){new g(t)});C||(g=e(function(e,n){u(e,g,t);var a=new v;return void 0!=n&&s(n,h,a[b],a),a}),g.prototype=y,y.constructor=g),m||k.forEach(function(t,e){w=1/e===-(1/0)}),(S||w)&&(_("delete"),_("has"),h&&_("get")),(w||E)&&_(b),m&&y.clear&&delete y.clear}else g=d.getConstructor(e,t,h,b),o(g.prototype,n);return f(g,t),x[t]=g,r(r.G+r.W+r.F*(g!=v),x),m||d.setStrong(g,t,h),g}},{22:22,24:24,27:27,29:29,38:38,43:43,60:60,61:61,66:66,69:69}],16:[function(t,e,n){var a=e.exports={version:"1.2.6"};"number"==typeof __e&&(__e=a)},{}],17:[function(t,e,n){var a=t(2);e.exports=function(t,e,n){if(a(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,a){return t.call(e,n,a)};case 3:return function(n,a,r){return t.call(e,n,a,r)}}return function(){return t.apply(e,arguments)}}},{2:2}],18:[function(t,e,n){e.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},{}],19:[function(t,e,n){e.exports=!t(24)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},{24:24}],20:[function(t,e,n){var a=t(38),r=t(29).document,i=a(r)&&a(r.createElement);e.exports=function(t){return i?r.createElement(t):{}}},{29:29,38:38}],21:[function(t,e,n){var a=t(46);e.exports=function(t){var e=a.getKeys(t),n=a.getSymbols;if(n)for(var r,i=n(t),o=a.isEnum,s=0;i.length>s;)o.call(t,r=i[s++])&&e.push(r);return e}},{46:46}],22:[function(t,e,n){var a=t(29),r=t(16),i=t(31),o=t(61),s=t(17),u="prototype",p=function(t,e,n){var c,l,f,d,h=t&p.F,m=t&p.G,v=t&p.S,g=t&p.P,b=t&p.B,y=m?a:v?a[e]||(a[e]={}):(a[e]||{})[u],x=m?r:r[e]||(r[e]={}),_=x[u]||(x[u]={});m&&(n=e);for(c in n)l=!h&&y&&c in y,f=(l?y:n)[c],d=b&&l?s(f,a):g&&"function"==typeof f?s(Function.call,f):f,y&&!l&&o(y,c,f),x[c]!=f&&i(x,c,d),g&&_[c]!=f&&(_[c]=f)};a.core=r,p.F=1,p.G=2,p.S=4,p.P=8,p.B=16,p.W=32,e.exports=p},{16:16,17:17,29:29,31:31,61:61}],23:[function(t,e,n){var a=t(83)("match");e.exports=function(t){var e=/./;try{"/./"[t](e)}catch(n){try{return e[a]=!1,!"/./"[t](e)}catch(r){}}return!0}},{83:83}],24:[function(t,e,n){e.exports=function(t){try{return!!t()}catch(e){return!0}}},{}],25:[function(t,e,n){"use strict";var a=t(31),r=t(61),i=t(24),o=t(18),s=t(83);e.exports=function(t,e,n){var u=s(t),p=""[t];i(function(){var e={};return e[u]=function(){return 7},7!=""[t](e)})&&(r(String.prototype,t,n(o,u,p)),a(RegExp.prototype,u,2==e?function(t,e){return p.call(t,this,e)}:function(t){return p.call(t,this)}))}},{18:18,24:24,31:31,61:61,83:83}],26:[function(t,e,n){"use strict";var a=t(4);e.exports=function(){var t=a(this),e="";return t.global&&(e+="g"),t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),t.unicode&&(e+="u"),t.sticky&&(e+="y"),e}},{4:4}],27:[function(t,e,n){var a=t(17),r=t(40),i=t(35),o=t(4),s=t(79),u=t(84);e.exports=function(t,e,n,p){var c,l,f,d=u(t),h=a(n,p,e?2:1),m=0;if("function"!=typeof d)throw TypeError(t+" is not iterable!");if(i(d))for(c=s(t.length);c>m;m++)e?h(o(l=t[m])[0],l[1]):h(t[m]);else for(f=d.call(t);!(l=f.next()).done;)r(f,h,l.value,e)}},{17:17,35:35,4:4,40:40,79:79,84:84}],28:[function(t,e,n){var a=t(78),r=t(46).getNames,i={}.toString,o="object"==typeof window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],s=function(t){try{return r(t)}catch(e){return o.slice()}};e.exports.get=function(t){return o&&"[object Window]"==i.call(t)?s(t):r(a(t))}},{46:46,78:78}],29:[function(t,e,n){var a=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=a)},{}],30:[function(t,e,n){var a={}.hasOwnProperty;e.exports=function(t,e){return a.call(t,e)}},{}],31:[function(t,e,n){var a=t(46),r=t(59);e.exports=t(19)?function(t,e,n){return a.setDesc(t,e,r(1,n))}:function(t,e,n){return t[e]=n,t}},{19:19,46:46,59:59}],32:[function(t,e,n){e.exports=t(29).document&&document.documentElement},{29:29}],33:[function(t,e,n){e.exports=function(t,e,n){var a=void 0===n;switch(e.length){case 0:return a?t():t.call(n);case 1:return a?t(e[0]):t.call(n,e[0]);case 2:return a?t(e[0],e[1]):t.call(n,e[0],e[1]);case 3:return a?t(e[0],e[1],e[2]):t.call(n,e[0],e[1],e[2]);case 4:return a?t(e[0],e[1],e[2],e[3]):t.call(n,e[0],e[1],e[2],e[3])}return t.apply(n,e)}},{}],34:[function(t,e,n){var a=t(11);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==a(t)?t.split(""):Object(t)}},{11:11}],35:[function(t,e,n){var a=t(45),r=t(83)("iterator"),i=Array.prototype;e.exports=function(t){return void 0!==t&&(a.Array===t||i[r]===t)}},{45:45,83:83}],36:[function(t,e,n){var a=t(11);e.exports=Array.isArray||function(t){return"Array"==a(t)}},{11:11}],37:[function(t,e,n){var a=t(38),r=Math.floor;e.exports=function(t){return!a(t)&&isFinite(t)&&r(t)===t}},{38:38}],38:[function(t,e,n){e.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},{}],39:[function(t,e,n){var a=t(38),r=t(11),i=t(83)("match");e.exports=function(t){var e;return a(t)&&(void 0!==(e=t[i])?!!e:"RegExp"==r(t))}},{11:11,38:38,83:83}],40:[function(t,e,n){var a=t(4);e.exports=function(t,e,n,r){try{return r?e(a(n)[0],n[1]):e(n)}catch(i){var o=t["return"];throw void 0!==o&&a(o.call(t)),i}}},{4:4}],41:[function(t,e,n){"use strict";var a=t(46),r=t(59),i=t(66),o={};t(31)(o,t(83)("iterator"),function(){return this}),e.exports=function(t,e,n){t.prototype=a.create(o,{next:r(1,n)}),i(t,e+" Iterator")}},{31:31,46:46,59:59,66:66,83:83}],42:[function(t,e,n){"use strict";var a=t(48),r=t(22),i=t(61),o=t(31),s=t(30),u=t(45),p=t(41),c=t(66),l=t(46).getProto,f=t(83)("iterator"),d=!([].keys&&"next"in[].keys()),h="@@iterator",m="keys",v="values",g=function(){return this};e.exports=function(t,e,n,b,y,x,_){p(n,e,b);var w,k,E=function(t){if(!d&&t in A)return A[t];switch(t){case m:return function(){return new n(this,t)};case v:return function(){return new n(this,t)}}return function(){return new n(this,t)}},S=e+" Iterator",C=y==v,P=!1,A=t.prototype,O=A[f]||A[h]||y&&A[y],T=O||E(y);if(O){var R=l(T.call(new t));c(R,S,!0),!a&&s(A,h)&&o(R,f,g),C&&O.name!==v&&(P=!0,T=function(){return O.call(this)})}if(a&&!_||!d&&!P&&A[f]||o(A,f,T),u[e]=T,u[S]=g,y)if(w={values:C?T:E(v),keys:x?T:E(m),entries:C?E("entries"):T},_)for(k in w)k in A||i(A,k,w[k]);else r(r.P+r.F*(d||P),e,w);return w}},{22:22,30:30,31:31,41:41,45:45,46:46,48:48,61:61,66:66,83:83}],43:[function(t,e,n){var a=t(83)("iterator"),r=!1;try{var i=[7][a]();i["return"]=function(){r=!0},Array.from(i,function(){throw 2})}catch(o){}e.exports=function(t,e){if(!e&&!r)return!1;var n=!1;try{var i=[7],o=i[a]();o.next=function(){return{done:n=!0}},i[a]=function(){return o},t(i)}catch(s){}return n}},{83:83}],44:[function(t,e,n){e.exports=function(t,e){return{value:e,done:!!t}}},{}],45:[function(t,e,n){e.exports={}},{}],46:[function(t,e,n){var a=Object;e.exports={create:a.create,getProto:a.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:a.getOwnPropertyDescriptor,setDesc:a.defineProperty,setDescs:a.defineProperties,getKeys:a.keys,getNames:a.getOwnPropertyNames,getSymbols:a.getOwnPropertySymbols,each:[].forEach}},{}],47:[function(t,e,n){var a=t(46),r=t(78);e.exports=function(t,e){for(var n,i=r(t),o=a.getKeys(i),s=o.length,u=0;s>u;)if(i[n=o[u++]]===e)return n}},{46:46,78:78}],48:[function(t,e,n){e.exports=!1},{}],49:[function(t,e,n){e.exports=Math.expm1||function(t){return 0==(t=+t)?t:t>-1e-6&&1e-6>t?t+t*t/2:Math.exp(t)-1}},{}],50:[function(t,e,n){e.exports=Math.log1p||function(t){return(t=+t)>-1e-8&&1e-8>t?t-t*t/2:Math.log(1+t)}},{}],51:[function(t,e,n){e.exports=Math.sign||function(t){return 0==(t=+t)||t!=t?t:0>t?-1:1}},{}],52:[function(t,e,n){var a,r,i,o=t(29),s=t(75).set,u=o.MutationObserver||o.WebKitMutationObserver,p=o.process,c=o.Promise,l="process"==t(11)(p),f=function(){var t,e,n;for(l&&(t=p.domain)&&(p.domain=null,t.exit());a;)e=a.domain,n=a.fn,e&&e.enter(),n(),e&&e.exit(),a=a.next;r=void 0,t&&t.enter()};if(l)i=function(){p.nextTick(f)};else if(u){var d=1,h=document.createTextNode("");new u(f).observe(h,{characterData:!0}),i=function(){h.data=d=-d}}else i=c&&c.resolve?function(){c.resolve().then(f)}:function(){s.call(o,f)};e.exports=function(t){var e={fn:t,next:void 0,domain:l&&p.domain};r&&(r.next=e),a||(a=e,i()),r=e}},{11:11,29:29,75:75}],53:[function(t,e,n){var a=t(46),r=t(80),i=t(34);e.exports=t(24)(function(){var t=Object.assign,e={},n={},a=Symbol(),r="abcdefghijklmnopqrst";return e[a]=7,r.split("").forEach(function(t){n[t]=t}),7!=t({},e)[a]||Object.keys(t({},n)).join("")!=r})?function(t,e){for(var n=r(t),o=arguments,s=o.length,u=1,p=a.getKeys,c=a.getSymbols,l=a.isEnum;s>u;)for(var f,d=i(o[u++]),h=c?p(d).concat(c(d)):p(d),m=h.length,v=0;m>v;)l.call(d,f=h[v++])&&(n[f]=d[f]);return n}:Object.assign},{24:24,34:34,46:46,80:80}],54:[function(t,e,n){var a=t(22),r=t(16),i=t(24);e.exports=function(t,e){var n=(r.Object||{})[t]||Object[t],o={};o[t]=e(n),a(a.S+a.F*i(function(){n(1)}),"Object",o)}},{16:16,22:22,24:24}],55:[function(t,e,n){var a=t(46),r=t(78),i=a.isEnum;e.exports=function(t){return function(e){for(var n,o=r(e),s=a.getKeys(o),u=s.length,p=0,c=[];u>p;)i.call(o,n=s[p++])&&c.push(t?[n,o[n]]:o[n]);return c}}},{46:46,78:78}],56:[function(t,e,n){var a=t(46),r=t(4),i=t(29).Reflect;e.exports=i&&i.ownKeys||function(t){var e=a.getNames(r(t)),n=a.getSymbols;return n?e.concat(n(t)):e}},{29:29,4:4,46:46}],57:[function(t,e,n){"use strict";var a=t(58),r=t(33),i=t(2);e.exports=function(){for(var t=i(this),e=arguments.length,n=Array(e),o=0,s=a._,u=!1;e>o;)(n[o]=arguments[o++])===s&&(u=!0);return function(){var a,i=this,o=arguments,p=o.length,c=0,l=0;if(!u&&!p)return r(t,n,i);if(a=n.slice(),u)for(;e>c;c++)a[c]===s&&(a[c]=o[l++]);for(;p>l;)a.push(o[l++]);return r(t,a,i)}}},{2:2,33:33,58:58}],58:[function(t,e,n){e.exports=t(29)},{29:29}],59:[function(t,e,n){e.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},{}],60:[function(t,e,n){var a=t(61);e.exports=function(t,e){for(var n in e)a(t,n,e[n]);return t}},{61:61}],61:[function(t,e,n){var a=t(29),r=t(31),i=t(82)("src"),o="toString",s=Function[o],u=(""+s).split(o);t(16).inspectSource=function(t){return s.call(t)},(e.exports=function(t,e,n,o){"function"==typeof n&&(n.hasOwnProperty(i)||r(n,i,t[e]?""+t[e]:u.join(e+"")),n.hasOwnProperty("name")||r(n,"name",e)),t===a?t[e]=n:(o||delete t[e],r(t,e,n))})(Function.prototype,o,function(){return"function"==typeof this&&this[i]||s.call(this)})},{16:16,29:29,31:31,82:82}],62:[function(t,e,n){e.exports=function(t,e){var n=e===Object(e)?function(t){return e[t]}:e;return function(e){return(e+"").replace(t,n)}}},{}],63:[function(t,e,n){e.exports=Object.is||function(t,e){return t===e?0!==t||1/t===1/e:t!=t&&e!=e}},{}],64:[function(t,e,n){var a=t(46).getDesc,r=t(38),i=t(4),o=function(t,e){if(i(t),!r(e)&&null!==e)throw TypeError(e+": can't set as prototype!")};e.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(e,n,r){try{r=t(17)(Function.call,a(Object.prototype,"__proto__").set,2),r(e,[]),n=!(e instanceof Array)}catch(i){n=!0}return function(t,e){return o(t,e),n?t.__proto__=e:r(t,e),t}}({},!1):void 0),check:o}},{17:17,38:38,4:4,46:46}],65:[function(t,e,n){"use strict";var a=t(29),r=t(46),i=t(19),o=t(83)("species");e.exports=function(t){var e=a[t];i&&e&&!e[o]&&r.setDesc(e,o,{configurable:!0,get:function(){return this}})}},{19:19,29:29,46:46,83:83}],66:[function(t,e,n){var a=t(46).setDesc,r=t(30),i=t(83)("toStringTag");e.exports=function(t,e,n){t&&!r(t=n?t:t.prototype,i)&&a(t,i,{configurable:!0,value:e})}},{30:30,46:46,83:83}],67:[function(t,e,n){var a=t(29),r="__core-js_shared__",i=a[r]||(a[r]={});e.exports=function(t){return i[t]||(i[t]={})}},{29:29}],68:[function(t,e,n){var a=t(4),r=t(2),i=t(83)("species");e.exports=function(t,e){var n,o=a(t).constructor;return void 0===o||void 0==(n=a(o)[i])?e:r(n)}},{2:2,4:4,83:83}],69:[function(t,e,n){e.exports=function(t,e,n){if(!(t instanceof e))throw TypeError(n+": use the 'new' operator!");return t}},{}],70:[function(t,e,n){var a=t(77),r=t(18);e.exports=function(t){return function(e,n){var i,o,s=r(e)+"",u=a(n),p=s.length;return 0>u||u>=p?t?"":void 0:(i=s.charCodeAt(u),55296>i||i>56319||u+1===p||(o=s.charCodeAt(u+1))<56320||o>57343?t?s.charAt(u):i:t?s.slice(u,u+2):(i-55296<<10)+(o-56320)+65536)}}},{18:18,77:77}],71:[function(t,e,n){var a=t(39),r=t(18);e.exports=function(t,e,n){if(a(e))throw TypeError("String#"+n+" doesn't accept regex!");return r(t)+""}},{18:18,39:39}],72:[function(t,e,n){var a=t(79),r=t(73),i=t(18);e.exports=function(t,e,n,o){var s=i(t)+"",u=s.length,p=void 0===n?" ":n+"",c=a(e);if(u>=c)return s;""==p&&(p=" ");var l=c-u,f=r.call(p,Math.ceil(l/p.length));return f.length>l&&(f=f.slice(0,l)),o?f+s:s+f}},{18:18,73:73,79:79}],73:[function(t,e,n){"use strict";var a=t(77),r=t(18);e.exports=function(t){var e=r(this)+"",n="",i=a(t);if(0>i||i==1/0)throw RangeError("Count can't be negative");for(;i>0;(i>>>=1)&&(e+=e))1&i&&(n+=e);return n}},{18:18,77:77}],74:[function(t,e,n){var a=t(22),r=t(18),i=t(24),o=" \n\x0B\f\r  ᠎ â€â€‚         âŸã€€\u2028\u2029\ufeff",s="["+o+"]",u="​…",p=RegExp("^"+s+s+"*"),c=RegExp(s+s+"*$"),l=function(t,e){var n={};n[t]=e(f),a(a.P+a.F*i(function(){return!!o[t]()||u[t]()!=u}),"String",n)},f=l.trim=function(t,e){return t=r(t)+"",1&e&&(t=t.replace(p,"")),2&e&&(t=t.replace(c,"")),t};e.exports=l},{18:18,22:22,24:24}],75:[function(t,e,n){var a,r,i,o=t(17),s=t(33),u=t(32),p=t(20),c=t(29),l=c.process,f=c.setImmediate,d=c.clearImmediate,h=c.MessageChannel,m=0,v={},g="onreadystatechange",b=function(){var t=+this;if(v.hasOwnProperty(t)){var e=v[t];delete v[t],e()}},y=function(t){b.call(t.data)};f&&d||(f=function(t){for(var e=[],n=1;arguments.length>n;)e.push(arguments[n++]);return v[++m]=function(){s("function"==typeof t?t:Function(t),e)},a(m),m},d=function(t){delete v[t]},"process"==t(11)(l)?a=function(t){l.nextTick(o(b,t,1))}:h?(r=new h,i=r.port2,r.port1.onmessage=y,a=o(i.postMessage,i,1)):c.addEventListener&&"function"==typeof postMessage&&!c.importScripts?(a=function(t){c.postMessage(t+"","*")},c.addEventListener("message",y,!1)):a=g in p("script")?function(t){u.appendChild(p("script"))[g]=function(){u.removeChild(this),b.call(t)}}:function(t){setTimeout(o(b,t,1),0)}),e.exports={set:f,clear:d}},{11:11,17:17,20:20,29:29,32:32,33:33}],76:[function(t,e,n){var a=t(77),r=Math.max,i=Math.min;e.exports=function(t,e){return t=a(t),0>t?r(t+e,0):i(t,e)}},{77:77}],77:[function(t,e,n){var a=Math.ceil,r=Math.floor;e.exports=function(t){return isNaN(t=+t)?0:(t>0?r:a)(t)}},{}],78:[function(t,e,n){var a=t(34),r=t(18);e.exports=function(t){return a(r(t))}},{18:18,34:34}],79:[function(t,e,n){var a=t(77),r=Math.min;e.exports=function(t){return t>0?r(a(t),9007199254740991):0}},{77:77}],80:[function(t,e,n){var a=t(18);e.exports=function(t){return Object(a(t))}},{18:18}],81:[function(t,e,n){var a=t(38);e.exports=function(t,e){if(!a(t))return t;var n,r;if(e&&"function"==typeof(n=t.toString)&&!a(r=n.call(t)))return r;if("function"==typeof(n=t.valueOf)&&!a(r=n.call(t)))return r;if(!e&&"function"==typeof(n=t.toString)&&!a(r=n.call(t)))return r;throw TypeError("Can't convert object to primitive value")}},{38:38}],82:[function(t,e,n){var a=0,r=Math.random();e.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++a+r).toString(36))}},{}],83:[function(t,e,n){var a=t(67)("wks"),r=t(82),i=t(29).Symbol;e.exports=function(t){return a[t]||(a[t]=i&&i[t]||(i||r)("Symbol."+t))}},{29:29,67:67,82:82}],84:[function(t,e,n){var a=t(10),r=t(83)("iterator"),i=t(45);e.exports=t(16).getIteratorMethod=function(t){return void 0!=t?t[r]||t["@@iterator"]||i[a(t)]:void 0}},{10:10,16:16,45:45,83:83}],85:[function(t,e,n){"use strict";var a,r=t(46),i=t(22),o=t(19),s=t(59),u=t(32),p=t(20),c=t(30),l=t(11),f=t(33),d=t(24),h=t(4),m=t(2),v=t(38),g=t(80),b=t(78),y=t(77),x=t(76),_=t(79),w=t(34),k=t(82)("__proto__"),E=t(8),S=t(7)(!1),C=Object.prototype,P=Array.prototype,A=P.slice,O=P.join,T=r.setDesc,R=r.getDesc,j=r.setDescs,M={};o||(a=!d(function(){return 7!=T(p("div"),"a",{get:function(){return 7}}).a}),r.setDesc=function(t,e,n){if(a)try{return T(t,e,n)}catch(r){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(h(t)[e]=n.value),t},r.getDesc=function(t,e){if(a)try{return R(t,e)}catch(n){}return c(t,e)?s(!C.propertyIsEnumerable.call(t,e),t[e]):void 0},r.setDescs=j=function(t,e){h(t);for(var n,a=r.getKeys(e),i=a.length,o=0;i>o;)r.setDesc(t,n=a[o++],e[n]);return t}),i(i.S+i.F*!o,"Object",{getOwnPropertyDescriptor:r.getDesc,defineProperty:r.setDesc,defineProperties:j});var L="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(","),D=L.concat("length","prototype"),N=L.length,F=function(){var t,e=p("iframe"),n=N,a=">";for(e.style.display="none",u.appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write(" -
    - - - - - -
    - - - - -
    - [sprite_text] -
    - [atomsnowflake.Join()] -
    -
    -
    - [formatted_type] - [marked] - [varedited_line] -
    -
    -
    - Refresh -
    - -
    -
    -
    -
    -
    - - E - Edit, tries to determine the variable type by itself.
    - C - Change, asks you for the var type first.
    - M - Mass modify: changes this variable for all objects of this type.
    -
    -
    - - - - - -
    -
    - Search: -
    -
    - -
    -
    -
      - [variable_html.Join()] -
    - - - -"} - - usr << browse(html, "window=variables[refid];size=475x650") - - -#define VV_HTML_ENCODE(thing) ( sanitize ? html_encode(thing) : thing ) -/proc/debug_variable(name, value, level, datum/DA = null, sanitize = TRUE) - var/header - if(DA) - if (islist(DA)) - var/index = name - if (value) - name = DA[name] //name is really the index until this line - else - value = DA[name] - header = "
  • (E) (C) (-) " - else - header = "
  • (E) (C) (M) " - else - header = "
  • " - - var/item - if (isnull(value)) - item = "[VV_HTML_ENCODE(name)] = null" - - else if (istext(value)) - item = "[VV_HTML_ENCODE(name)] = \"[VV_HTML_ENCODE(value)]\"" - - else if (isicon(value)) - #ifdef VARSICON - var/icon/I = new/icon(value) - var/rnd = rand(1,10000) - var/rname = "tmp\ref[I][rnd].png" - usr << browse_rsc(I, rname) - item = "[VV_HTML_ENCODE(name)] = ([value]) " - #else - item = "[VV_HTML_ENCODE(name)] = /icon ([value])" - #endif - -/* else if (istype(value, /image)) - #ifdef VARSICON - var/rnd = rand(1, 10000) - var/image/I = value - - src << browse_rsc(I.icon, "tmp\ref[value][rnd].png") - html += "[name] = " - #else - html += "[name] = /image ([value])" - #endif -*/ - else if (isfile(value)) - item = "[VV_HTML_ENCODE(name)] = '[value]'" - - //else if (istype(value, /client)) - // var/client/C = value - // item = "[VV_HTML_ENCODE(name)] \ref[value] = [C] [C.type]" - - else if (istype(value, /datum)) - var/datum/D = value - if ("[D]" != "[D.type]") //if the thing as a name var, lets use it. - item = "[VV_HTML_ENCODE(name)] \ref[value] = [D] [D.type]" - else - item = "[VV_HTML_ENCODE(name)] \ref[value] = [D.type]" - - else if (islist(value)) - var/list/L = value - var/list/items = list() - - if (L.len > 0 && !(name == "underlays" || name == "overlays" || L.len > (IS_NORMAL_LIST(L) ? 50 : 150))) - for (var/i in 1 to L.len) - var/key = L[i] - var/val - if (IS_NORMAL_LIST(L) && !isnum(key)) - val = L[key] - if (!val) - val = key - key = i - - items += debug_variable(key, val, level + 1, sanitize = sanitize) - - item = "[VV_HTML_ENCODE(name)] = /list ([L.len])
      [items.Join()]
    " - else - item = "[VV_HTML_ENCODE(name)] = /list ([L.len])" - - else - item = "[VV_HTML_ENCODE(name)] = [VV_HTML_ENCODE(value)]" - - return "[header][item]
  • " - -#undef VV_HTML_ENCODE - -/client/proc/view_var_Topic(href, href_list, hsrc) - if( (usr.client != src) || !src.holder ) - return - if(href_list["Vars"]) - debug_variables(locate(href_list["Vars"])) - - else if(href_list["datumrefresh"]) - var/datum/DAT = locate(href_list["datumrefresh"]) - if(!DAT) //can't be an istype() because /client etc aren't datums - return - src.debug_variables(DAT) - - else if(href_list["mob_player_panel"]) - if(!check_rights(0)) - return - /datum/proc/vv_get_dropdown() . = list() . += "---" @@ -1009,22 +546,6 @@ to_chat(usr, "This can only be done to instances of type /mob") return M.regenerate_icons() - -//Needs +VAREDIT past this point - - else if(check_rights(R_VAREDIT)) - - - //~CARN: for renaming mobs (updates their name, real_name, mind.name, their ID/PDA and datacore records). - - if(href_list["rename"]) - if(!check_rights(0)) - return - - if(!ismob(M)) - to_chat(usr, "This can only be done to instances of type /mob") - return - M.regenerate_icons() else if(href_list["expose"]) if(!check_rights(R_ADMIN, FALSE)) return From 726b86f3a4d48ddb1d8ce61411fd1487a812c416 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 11 Sep 2017 14:18:28 -0500 Subject: [PATCH 256/262] Update on_move.dm --- code/modules/shuttle/on_move.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index f2c84a5aae..77eec512d8 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -14,7 +14,6 @@ All ShuttleMove procs go here // Called from the new turf before anything has been moved // Only gets called if fromShuttleMove returns true first // returns the new move_mode (based on the old) -/turf/proc/toShuttleMove(turf/oldT, shuttle_dir, move_mode) /turf/proc/toShuttleMove(turf/oldT, move_mode, obj/docking_port/mobile/shuttle) var/shuttle_dir = shuttle.dir for(var/i in contents) From 6d88e3642b924c4c55a004063dd476bd86a09a06 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 11 Sep 2017 14:27:28 -0500 Subject: [PATCH 257/262] Update suit_storage_unit.dm --- code/game/machinery/suit_storage_unit.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 5d5539fc19..be89a3d2e6 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -583,7 +583,6 @@ return ..() ->>>>>>> d4d898f... Regularizes resisting out of containers (#30412) /obj/machinery/suit_storage_unit/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) From a4236145f480dfb394eb9f68aebb4cd5c663b1a0 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 11 Sep 2017 15:22:28 -0500 Subject: [PATCH 258/262] Automatic changelog generation for PR #2641 [ci skip] --- html/changelogs/AutoChangeLog-pr-2641.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-2641.yml diff --git a/html/changelogs/AutoChangeLog-pr-2641.yml b/html/changelogs/AutoChangeLog-pr-2641.yml new file mode 100644 index 0000000000..a888615c05 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2641.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Admins may now show the variables interface to players to help contributors debug their new additions" From b6e2f9bfa1e2e54fc36fa2cef06160a4c735db09 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Mon, 11 Sep 2017 15:22:51 -0500 Subject: [PATCH 259/262] Automatic changelog generation for PR #2650 [ci skip] --- html/changelogs/AutoChangeLog-pr-2650.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-2650.yml diff --git a/html/changelogs/AutoChangeLog-pr-2650.yml b/html/changelogs/AutoChangeLog-pr-2650.yml new file mode 100644 index 0000000000..4e062b977c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-2650.yml @@ -0,0 +1,4 @@ +author: "Naksu" +delete-after: True +changes: + - rscadd: "Added TGUI interfaces to various smartfridges of different kinds, drying racks and the disk compartmentalizer" From 9adcc174b3d5bf5da98fbc53883b7f8566a986f7 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 11 Sep 2017 17:09:44 -0500 Subject: [PATCH 260/262] Update shuttle.dm --- code/modules/shuttle/shuttle.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index f035777df5..4326e6298e 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -570,7 +570,7 @@ move_mode = moving_atom.beforeShuttleMove(newT, rotation, move_mode) //atoms move_mode = oldT.fromShuttleMove(newT, underlying_turf_type, baseturf_cache, move_mode) //turfs - move_mode = newT.toShuttleMove(oldT, dir, move_mode) //turfs + move_mode = newT.toShuttleMove(oldT, move_mode , src) //turfs if(move_mode & MOVE_AREA) areas_to_move[old_area] = TRUE From ea82bf9bfaf5cce8393c0c29485d5caf7dca5044 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 11 Sep 2017 17:47:48 -0500 Subject: [PATCH 261/262] Update suit_storage_unit.dm --- code/game/machinery/suit_storage_unit.dm | 244 ----------------------- 1 file changed, 244 deletions(-) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index be89a3d2e6..a78fa50a6a 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -26,100 +26,6 @@ var/uv = FALSE var/uv_super = FALSE var/uv_cycles = 6 - -/obj/machinery/suit_storage_unit/standard_unit - suit_type = /obj/item/clothing/suit/space/eva - helmet_type = /obj/item/clothing/head/helmet/space/eva - mask_type = /obj/item/clothing/mask/breath - -/obj/machinery/suit_storage_unit/captain - suit_type = /obj/item/clothing/suit/space/hardsuit/captain - mask_type = /obj/item/clothing/mask/gas/sechailer - storage_type = /obj/item/tank/jetpack/oxygen/captain - -/obj/machinery/suit_storage_unit/engine - suit_type = /obj/item/clothing/suit/space/hardsuit/engine - mask_type = /obj/item/clothing/mask/breath - -/obj/machinery/suit_storage_unit/ce - suit_type = /obj/item/clothing/suit/space/hardsuit/engine/elite - mask_type = /obj/item/clothing/mask/breath - storage_type= /obj/item/clothing/shoes/magboots/advance - -/obj/machinery/suit_storage_unit/security - suit_type = /obj/item/clothing/suit/space/hardsuit/security - mask_type = /obj/item/clothing/mask/gas/sechailer - -/obj/machinery/suit_storage_unit/hos - suit_type = /obj/item/clothing/suit/space/hardsuit/security/hos - mask_type = /obj/item/clothing/mask/gas/sechailer - storage_type = /obj/item/tank/internals/oxygen - -/obj/machinery/suit_storage_unit/atmos - suit_type = /obj/item/clothing/suit/space/hardsuit/engine/atmos - mask_type = /obj/item/clothing/mask/gas - storage_type = /obj/item/watertank/atmos - -/obj/machinery/suit_storage_unit/mining - suit_type = /obj/item/clothing/suit/hooded/explorer - mask_type = /obj/item/clothing/mask/gas/explorer - -/obj/machinery/suit_storage_unit/mining/eva - suit_type = /obj/item/clothing/suit/space/hardsuit/mining - mask_type = /obj/item/clothing/mask/breath - -/obj/machinery/suit_storage_unit/cmo - suit_type = /obj/item/clothing/suit/space/hardsuit/medical - mask_type = /obj/item/clothing/mask/breath - -/obj/machinery/suit_storage_unit/rd - suit_type = /obj/item/clothing/suit/space/hardsuit/rd - mask_type = /obj/item/clothing/mask/breath - -/obj/machinery/suit_storage_unit/syndicate - suit_type = /obj/item/clothing/suit/space/hardsuit/syndi - mask_type = /obj/item/clothing/mask/gas/syndicate - storage_type = /obj/item/tank/jetpack/oxygen/harness - -/obj/machinery/suit_storage_unit/ert/command - suit_type = /obj/item/clothing/suit/space/hardsuit/ert - mask_type = /obj/item/clothing/mask/breath - storage_type = /obj/item/tank/internals/emergency_oxygen/double - -/obj/machinery/suit_storage_unit/ert/security - suit_type = /obj/item/clothing/suit/space/hardsuit/ert/sec - mask_type = /obj/item/clothing/mask/breath - storage_type = /obj/item/tank/internals/emergency_oxygen/double - -/obj/machinery/suit_storage_unit/ert/engineer - suit_type = /obj/item/clothing/suit/space/hardsuit/ert/engi - mask_type = /obj/item/clothing/mask/breath - storage_type = /obj/item/tank/internals/emergency_oxygen/double - -/obj/machinery/suit_storage_unit/ert/medical - suit_type = /obj/item/clothing/suit/space/hardsuit/ert/med - mask_type = /obj/item/clothing/mask/breath - storage_type = /obj/item/tank/internals/emergency_oxygen/double - max_integrity = 250 - - var/obj/item/clothing/suit/space/suit = null - var/obj/item/clothing/head/helmet/space/helmet = null - var/obj/item/clothing/mask/mask = null - var/obj/item/storage = null - - var/suit_type = null - var/helmet_type = null - var/mask_type = null - var/storage_type = null - - state_open = FALSE - var/locked = FALSE - panel_open = FALSE - var/safeties = TRUE - - var/uv = FALSE - var/uv_super = FALSE - var/uv_cycles = 6 var/message_cooldown var/breakout_time = 0.5 @@ -344,156 +250,6 @@ if(electrocute_mob(user, src, src, 1, TRUE)) return 1 -/obj/machinery/suit_storage_unit/relaymove(mob/user) - container_resist(user) - -/obj/machinery/suit_storage_unit/container_resist(mob/living/user) - add_fingerprint(user) - if(locked) - visible_message("You see [user] kicking against the doors of [src]!", "You start kicking against the doors...") - addtimer(CALLBACK(src, .proc/resist_open, user), 300) - else - open_machine() - dump_contents() - -/obj/machinery/suit_storage_unit/proc/resist_open(mob/user) - if(!state_open && occupant && (user in src) && user.stat == 0) // Check they're still here. - visible_message("You see [user] bursts out of [src]!", "You escape the cramped confines of [src]!") - open_machine() - -/obj/machinery/suit_storage_unit/attackby(obj/item/I, mob/user, params) - if(state_open && is_operational()) - if(istype(I, /obj/item/clothing/suit/space)) - if(suit) - to_chat(user, "The unit already contains a suit!.") - return - if(!user.drop_item()) - return - suit = I - else if(istype(I, /obj/item/clothing/head/helmet)) - if(helmet) - to_chat(user, "The unit already contains a helmet!") - return - if(!user.drop_item()) - return - helmet = I - else if(istype(I, /obj/item/clothing/mask)) - if(mask) - to_chat(user, "The unit already contains a mask!") - return - if(!user.drop_item()) - return - mask = I - else - if(storage) - to_chat(user, "The auxiliary storage compartment is full!") - return - if(!user.drop_item()) - return - storage = I - - I.loc = src - visible_message("[user] inserts [I] into [src]", "You load [I] into [src].") - update_icon() - return - - if(panel_open && is_wire_tool(I)) - wires.interact(user) - if(!state_open) - if(default_deconstruction_screwdriver(user, "panel", "close", I)) - return - if(default_pry_open(I)) - dump_contents() - return - - return ..() - - open_machine() - dump_contents() - new /obj/item/stack/sheet/metal (loc, 2) - qdel(src) - -/obj/machinery/suit_storage_unit/MouseDrop_T(atom/A, mob/user) - if(user.stat || user.lying || !Adjacent(user) || !Adjacent(A) || !isliving(A)) - return - var/mob/living/target = A - if(!state_open) - to_chat(user, "The unit's doors are shut!") - return - if(!is_operational()) - to_chat(user, "The unit is not operational!") - return - if(occupant || helmet || suit || storage) - to_chat(user, "It's too cluttered inside to fit in!") - return - - if(target == user) - user.visible_message("[user] starts squeezing into [src]!", "You start working your way into [src]...") - else - target.visible_message("[user] starts shoving [target] into [src]!", "[user] starts shoving you into [src]!") - - if(do_mob(user, target, 30)) - if(occupant || helmet || suit || storage) - return - if(target == user) - user.visible_message("[user] slips into [src] and closes the door behind them!", "You slip into [src]'s cramped space and shut its door.") - else - target.visible_message("[user] pushes [target] into [src] and shuts its door!", "[user] shoves you into [src] and shuts the door!") - close_machine(target) - add_fingerprint(user) - -/obj/machinery/suit_storage_unit/proc/cook() - if(uv_cycles) - uv_cycles-- - uv = TRUE - locked = TRUE - update_icon() - if(occupant) - var/mob/living/mob_occupant = occupant - if(uv_super) - mob_occupant.adjustFireLoss(rand(20, 36)) - else - mob_occupant.adjustFireLoss(rand(10, 16)) - mob_occupant.emote("scream") - addtimer(CALLBACK(src, .proc/cook), 50) - else - uv_cycles = initial(uv_cycles) - uv = FALSE - locked = FALSE - if(uv_super) - visible_message("[src]'s door creaks open with a loud whining noise. A cloud of foul black smoke escapes from its chamber.") - playsound(src, 'sound/machines/airlock_alien_prying.ogg', 50, 1) - helmet = null - qdel(helmet) - suit = null - qdel(suit) // Delete everything but the occupant. - mask = null - qdel(mask) - storage = null - qdel(storage) - // The wires get damaged too. - wires.cut_all() - else - if(!occupant) - visible_message("[src]'s door slides open. The glowing yellow lights dim to a gentle green.") - else - visible_message("[src]'s door slides open, barraging you with the nauseating smell of charred flesh.") - playsound(src, 'sound/machines/airlockclose.ogg', 25, 1) - for(var/obj/item/I in src) //Scorches away blood and forensic evidence, although the SSU itself is unaffected - I.clean_blood() - I.fingerprints = list() - open_machine(FALSE) - if(occupant) - dump_contents() - -/obj/machinery/suit_storage_unit/proc/shock(mob/user, prb) - if(!prob(prb)) - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(5, 1, src) - s.start() - if(electrocute_mob(user, src, src, 1, TRUE)) - return 1 - /obj/machinery/suit_storage_unit/relaymove(mob/user) if(locked) if(message_cooldown <= world.time) From c42304737a762acd0e9160b7c7b1b9b46a069933 Mon Sep 17 00:00:00 2001 From: LetterJay Date: Mon, 11 Sep 2017 17:47:55 -0500 Subject: [PATCH 262/262] Update implantchair.dm --- .../objects/items/implants/implantchair.dm | 188 ------------------ 1 file changed, 188 deletions(-) diff --git a/code/game/objects/items/implants/implantchair.dm b/code/game/objects/items/implants/implantchair.dm index 30a55ab54e..2f59020cbe 100644 --- a/code/game/objects/items/implants/implantchair.dm +++ b/code/game/objects/items/implants/implantchair.dm @@ -1,191 +1,3 @@ - -/obj/machinery/implantchair - name = "mindshield implanter" - desc = "Used to implant occupants with mindshield implants." - icon = 'icons/obj/machines/implantchair.dmi' - icon_state = "implantchair" - density = TRUE - opacity = 0 - anchored = TRUE - - var/ready = TRUE - var/replenishing = FALSE - - var/ready_implants = 5 - var/max_implants = 5 - var/injection_cooldown = 600 - var/replenish_cooldown = 6000 - var/implant_type = /obj/item/implant/mindshield - var/auto_inject = FALSE - var/auto_replenish = TRUE - var/special = FALSE - var/special_name = "special function" - -/obj/machinery/implantchair/Initialize() - . = ..() - open_machine() - update_icon() - - -/obj/machinery/implantchair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "implantchair", name, 375, 280, master_ui, state) - ui.open() - - -/obj/machinery/implantchair/ui_data() - var/list/data = list() - data["occupied"] = occupant ? 1 : 0 - data["open"] = state_open - - data["occupant"] = list() - if(occupant) - var/mob/living/mob_occupant = occupant - data["occupant"]["name"] = mob_occupant.name - data["occupant"]["stat"] = mob_occupant.stat - - data["special_name"] = special ? special_name : null - data["ready_implants"] = ready_implants - data["ready"] = ready - data["replenishing"] = replenishing - - return data - -/obj/machinery/implantchair/ui_act(action, params) - if(..()) - return - switch(action) - if("door") - if(state_open) - close_machine() - else - open_machine() - . = TRUE - if("implant") - implant(occupant,usr) - . = TRUE - -/obj/machinery/implantchair/proc/implant(mob/living/M,mob/user) - if (!istype(M)) - return - if(!ready_implants || !ready) - return - if(implant_action(M,user)) - ready_implants-- - if(!replenishing && auto_replenish) - replenishing = TRUE - addtimer(CALLBACK(src,"replenish"),replenish_cooldown) - if(injection_cooldown > 0) - ready = FALSE - addtimer(CALLBACK(src,"set_ready"),injection_cooldown) - else - playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, 1) - update_icon() - -/obj/machinery/implantchair/proc/implant_action(mob/living/M) - var/obj/item/implant/I = new implant_type - if(I.implant(M)) - visible_message("[M] has been implanted by the [name].") - return 1 - -/obj/machinery/implantchair/update_icon() - icon_state = initial(icon_state) - if(state_open) - icon_state += "_open" - if(occupant) - icon_state += "_occupied" - if(ready) - add_overlay("ready") - else - cut_overlays() - -/obj/machinery/implantchair/proc/replenish() - if(ready_implants < max_implants) - ready_implants++ - if(ready_implants < max_implants) - addtimer(CALLBACK(src,"replenish"),replenish_cooldown) - else - replenishing = FALSE - -/obj/machinery/implantchair/proc/set_ready() - ready = TRUE - update_icon() - -/obj/machinery/implantchair/container_resist(mob/living/user) - if(state_open) - return - user.changeNext_move(CLICK_CD_BREAKOUT) - user.last_special = world.time + CLICK_CD_BREAKOUT - to_chat(user, "You lean on the back of [src] and start pushing the door open... (this will take about about a minute.)") - audible_message("You hear a metallic creaking from [src]!",hearing_distance = 2) - - if(do_after(user, 600, target = src)) - if(!user || user.stat != CONSCIOUS || user.loc != src || state_open) - return - visible_message("[user] successfully broke out of [src]!") - to_chat(user, "You successfully break out of [src]!") - open_machine() - -/obj/machinery/implantchair/relaymove(mob/user) - container_resist(user) - -/obj/machinery/implantchair/MouseDrop_T(mob/target, mob/user) - if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !isliving(target) || !user.IsAdvancedToolUser()) - return - close_machine(target) - -/obj/machinery/implantchair/close_machine(mob/living/user) - if((isnull(user) || istype(user)) && state_open) - ..(user) - if(auto_inject && ready && ready_implants > 0) - implant(user,null) - -/obj/machinery/implantchair/genepurge - name = "Genetic purifier" - desc = "Used to purge human genome of foreign influences" - special = TRUE - special_name = "Purge genome" - injection_cooldown = 0 - replenish_cooldown = 300 - -/obj/machinery/implantchair/genepurge/implant_action(mob/living/carbon/human/H,mob/user) - if(!istype(H)) - return 0 - H.set_species(/datum/species/human, 1)//lizards go home - purrbation_remove(H)//remove cats - H.dna.remove_all_mutations()//hulks out - return 1 - - -/obj/machinery/implantchair/brainwash - name = "Neural Imprinter" - desc = "Used to indoctrinate rehabilitate hardened recidivists." - special_name = "Imprint" - injection_cooldown = 3000 - auto_inject = FALSE - auto_replenish = FALSE - special = TRUE - var/objective = "Obey the law. Praise Nanotrasen." - var/custom = FALSE - -/obj/machinery/implantchair/brainwash/implant_action(mob/living/C,mob/user) - if(!istype(C) || !C.mind) // I don't know how this makes any sense for silicons but laws trump objectives anyway. - return 0 - if(custom) - if(!user || !user.Adjacent(src)) - return 0 - objective = stripped_input(usr,"What order do you want to imprint on [C]?","Enter the order","",120) - message_admins("[key_name_admin(user)] set brainwash machine objective to '[objective]'.") - log_game("[key_name_admin(user)] set brainwash machine objective to '[objective]'.") - var/datum/objective/custom_objective = new/datum/objective(objective) - custom_objective.owner = C.mind - C.mind.objectives += custom_objective - C.mind.announce_objectives() - message_admins("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.") - log_game("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.") - return 1 - /obj/machinery/implantchair name = "mindshield implanter" desc = "Used to implant occupants with mindshield implants."